]> granicus.if.org Git - postgresql/blobdiff - src/bin/pg_dump/pg_dump.c
Un-break pg_dump for pre-8.3 source servers.
[postgresql] / src / bin / pg_dump / pg_dump.c
index 082dc841e9b4c133e85a224dfaff78713feaead8..be25e94cb2007bdefe5ebf700ed6b3870002c891 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <unistd.h>
 #include <ctype.h>
+#include <limits.h>
 #ifdef HAVE_TERMIOS_H
 #include <termios.h>
 #endif
@@ -91,8 +92,6 @@ typedef enum OidOptions
 } OidOptions;
 
 /* global decls */
-bool           g_verbose;                      /* User wants verbose narration of our
-                                                                * activities. */
 static bool dosync = true;             /* Issue fsync() to make dump durable on disk. */
 
 /* subquery used to convert user ID (eg, datdba) to user name */
@@ -136,7 +135,7 @@ static const CatalogId nilCatalogId = {0, 0};
 
 /* override for standard extra_float_digits setting */
 static bool have_extra_float_digits = false;
-static int extra_float_digits;
+static int     extra_float_digits;
 
 /*
  * The default number of rows per INSERT when
@@ -153,32 +152,32 @@ static int extra_float_digits;
 
 static void help(const char *progname);
 static void setup_connection(Archive *AH,
-                                const char *dumpencoding, const char *dumpsnapshot,
-                                char *use_role);
+                                                        const char *dumpencoding, const char *dumpsnapshot,
+                                                        char *use_role);
 static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
 static void expand_schema_name_patterns(Archive *fout,
-                                                       SimpleStringList *patterns,
-                                                       SimpleOidList *oids,
-                                                       bool strict_names);
+                                                                               SimpleStringList *patterns,
+                                                                               SimpleOidList *oids,
+                                                                               bool strict_names);
 static void expand_table_name_patterns(Archive *fout,
-                                                  SimpleStringList *patterns,
-                                                  SimpleOidList *oids,
-                                                  bool strict_names);
+                                                                          SimpleStringList *patterns,
+                                                                          SimpleOidList *oids,
+                                                                          bool strict_names);
 static NamespaceInfo *findNamespace(Archive *fout, Oid nsoid);
 static void dumpTableData(Archive *fout, TableDataInfo *tdinfo);
 static void refreshMatViewData(Archive *fout, TableDataInfo *tdinfo);
 static void guessConstraintInheritance(TableInfo *tblinfo, int numTables);
 static void dumpComment(Archive *fout, const char *type, const char *name,
-                       const char *namespace, const char *owner,
-                       CatalogId catalogId, int subid, DumpId dumpId);
-static int findComments(Archive *fout, Oid classoid, Oid objoid,
-                        CommentItem **items);
+                                               const char *namespace, const char *owner,
+                                               CatalogId catalogId, int subid, DumpId dumpId);
+static int     findComments(Archive *fout, Oid classoid, Oid objoid,
+                                                CommentItem **items);
 static int     collectComments(Archive *fout, CommentItem **items);
 static void dumpSecLabel(Archive *fout, const char *type, const char *name,
-                        const char *namespace, const char *owner,
-                        CatalogId catalogId, int subid, DumpId dumpId);
-static int findSecLabels(Archive *fout, Oid classoid, Oid objoid,
-                         SecLabelItem **items);
+                                                const char *namespace, const char *owner,
+                                                CatalogId catalogId, int subid, DumpId dumpId);
+static int     findSecLabels(Archive *fout, Oid classoid, Oid objoid,
+                                                 SecLabelItem **items);
 static int     collectSecLabels(Archive *fout, SecLabelItem **items);
 static void dumpDumpableObject(Archive *fout, DumpableObject *dobj);
 static void dumpNamespace(Archive *fout, NamespaceInfo *nspinfo);
@@ -223,24 +222,24 @@ static void dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo);
 static void dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo);
 static void dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo);
 static void dumpUserMappings(Archive *fout,
-                                const char *servername, const char *namespace,
-                                const char *owner, CatalogId catalogId, DumpId dumpId);
+                                                        const char *servername, const char *namespace,
+                                                        const char *owner, CatalogId catalogId, DumpId dumpId);
 static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
 
 static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
-               const char *type, const char *name, const char *subname,
-               const char *nspname, const char *owner,
-               const char *acls, const char *racls,
-               const char *initacls, const char *initracls);
+                                       const char *type, const char *name, const char *subname,
+                                       const char *nspname, const char *owner,
+                                       const char *acls, const char *racls,
+                                       const char *initacls, const char *initracls);
 
 static void getDependencies(Archive *fout);
 static void BuildArchiveDependencies(Archive *fout);
 static void findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
-                                                DumpId **dependencies, int *nDeps, int *allocDeps);
+                                                                        DumpId **dependencies, int *nDeps, int *allocDeps);
 
 static DumpableObject *createBoundaryObjects(void);
 static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
-                                               DumpableObject *boundaryObjs);
+                                                                       DumpableObject *boundaryObjs);
 
 static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
 static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind);
@@ -248,16 +247,16 @@ static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo);
 static void buildMatViewRefreshDependencies(Archive *fout);
 static void getTableDataFKConstraints(void);
 static char *format_function_arguments(FuncInfo *finfo, char *funcargs,
-                                                 bool is_agg);
+                                                                          bool is_agg);
 static char *format_function_arguments_old(Archive *fout,
-                                                         FuncInfo *finfo, int nallargs,
-                                                         char **allargtypes,
-                                                         char **argmodes,
-                                                         char **argnames);
+                                                                                  FuncInfo *finfo, int nallargs,
+                                                                                  char **allargtypes,
+                                                                                  char **argmodes,
+                                                                                  char **argnames);
 static char *format_function_signature(Archive *fout,
-                                                 FuncInfo *finfo, bool honor_quotes);
+                                                                          FuncInfo *finfo, bool honor_quotes);
 static char *convertRegProcReference(Archive *fout,
-                                               const char *proc);
+                                                                        const char *proc);
 static char *getFormattedOperatorName(Archive *fout, const char *oproid);
 static char *convertTSFunction(Archive *fout, Oid funcOid);
 static Oid     findLastBuiltinOid_V71(Archive *fout);
@@ -271,29 +270,29 @@ static void dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo);
 static void dumpSubscription(Archive *fout, SubscriptionInfo *subinfo);
 static void dumpDatabase(Archive *AH);
 static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
-                                  const char *dbname, Oid dboid);
+                                                          const char *dbname, Oid dboid);
 static void dumpEncoding(Archive *AH);
 static void dumpStdStrings(Archive *AH);
 static void dumpSearchPath(Archive *AH);
 static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
-                                                                                PQExpBuffer upgrade_buffer,
-                                                                                Oid pg_type_oid,
-                                                                                bool force_array_type);
+                                                                                                        PQExpBuffer upgrade_buffer,
+                                                                                                        Oid pg_type_oid,
+                                                                                                        bool force_array_type);
 static bool binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
-                                                                               PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
+                                                                                                       PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
 static void binary_upgrade_set_pg_class_oids(Archive *fout,
-                                                                PQExpBuffer upgrade_buffer,
-                                                                Oid pg_class_oid, bool is_index);
+                                                                                        PQExpBuffer upgrade_buffer,
+                                                                                        Oid pg_class_oid, bool is_index);
 static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
-                                                               DumpableObject *dobj,
-                                                               const char *objtype,
-                                                               const char *objname,
-                                                               const char *objnamespace);
+                                                                                       DumpableObject *dobj,
+                                                                                       const char *objtype,
+                                                                                       const char *objname,
+                                                                                       const char *objnamespace);
 static const char *getAttrName(int attrnum, TableInfo *tblInfo);
 static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
 static bool nonemptyReloptions(const char *reloptions);
 static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
-                                               const char *prefix, Archive *fout);
+                                                                       const char *prefix, Archive *fout);
 static char *get_synchronized_snapshot(Archive *fout);
 static void setupDumpWorker(Archive *AHX);
 static TableInfo *getRootTableInfo(TableInfo *tbinfo);
@@ -315,6 +314,7 @@ main(int argc, char **argv)
        char       *endptr;
        RestoreOptions *ropt;
        Archive    *fout;                       /* the script file */
+       bool            g_verbose = false;
        const char *dumpencoding = NULL;
        const char *dumpsnapshot = NULL;
        char       *use_role = NULL;
@@ -395,6 +395,8 @@ main(int argc, char **argv)
                {NULL, 0, NULL, 0}
        };
 
+       pg_logging_init(argv[0]);
+       pg_logging_set_level(PG_LOG_WARNING);
        set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
 
        /*
@@ -403,8 +405,6 @@ main(int argc, char **argv)
         */
        init_parallel_dump_utils();
 
-       g_verbose = false;
-
        strcpy(g_comment_start, "-- ");
        g_comment_end[0] = '\0';
        strcpy(g_opaque_type, "opaque");
@@ -427,7 +427,7 @@ main(int argc, char **argv)
 
        InitDumpOptions(&dopt);
 
-       while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:oOp:RsS:t:T:U:vwWxZ:",
+       while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:",
                                                        long_options, &optindex)) != -1)
        {
                switch (c)
@@ -520,6 +520,7 @@ main(int argc, char **argv)
 
                        case 'v':                       /* verbose */
                                g_verbose = true;
+                               pg_logging_set_level(PG_LOG_INFO);
                                break;
 
                        case 'w':
@@ -538,7 +539,7 @@ main(int argc, char **argv)
                                compressLevel = atoi(optarg);
                                if (compressLevel < 0 || compressLevel > 9)
                                {
-                                       write_msg(NULL, "compression level must be in range 0..9\n");
+                                       pg_log_error("compression level must be in range 0..9");
                                        exit_nicely(1);
                                }
                                break;
@@ -576,7 +577,7 @@ main(int argc, char **argv)
                                extra_float_digits = atoi(optarg);
                                if (extra_float_digits < -15 || extra_float_digits > 3)
                                {
-                                       write_msg(NULL, "extra_float_digits must be in range -15..3\n");
+                                       pg_log_error("extra_float_digits must be in range -15..3");
                                        exit_nicely(1);
                                }
                                break;
@@ -599,8 +600,8 @@ main(int argc, char **argv)
                                        rowsPerInsert <= 0 || rowsPerInsert > INT_MAX ||
                                        errno == ERANGE)
                                {
-                                       write_msg(NULL, "rows-per-insert must be in range %d..%d\n",
-                                                         1, INT_MAX);
+                                       pg_log_error("rows-per-insert must be in range %d..%d",
+                                                                1, INT_MAX);
                                        exit_nicely(1);
                                }
                                dopt.dump_inserts = (int) rowsPerInsert;
@@ -622,8 +623,8 @@ main(int argc, char **argv)
        /* Complain if any arguments remain */
        if (optind < argc)
        {
-               fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
-                               progname, argv[optind]);
+               pg_log_error("too many command-line arguments (first is \"%s\")",
+                                        argv[optind]);
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                                progname);
                exit_nicely(1);
@@ -643,25 +644,25 @@ main(int argc, char **argv)
 
        if (dopt.dataOnly && dopt.schemaOnly)
        {
-               write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
+               pg_log_error("options -s/--schema-only and -a/--data-only cannot be used together");
                exit_nicely(1);
        }
 
        if (dopt.dataOnly && dopt.outputClean)
        {
-               write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
+               pg_log_error("options -c/--clean and -a/--data-only cannot be used together");
                exit_nicely(1);
        }
 
        if (dopt.if_exists && !dopt.outputClean)
-               exit_horribly(NULL, "option --if-exists requires option -c/--clean\n");
+               fatal("option --if-exists requires option -c/--clean");
 
        /*
         * --inserts are already implied above if --column-inserts or
         * --rows-per-insert were specified.
         */
        if (dopt.do_nothing && dopt.dump_inserts == 0)
-               exit_horribly(NULL, "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert or --column-inserts\n");
+               fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
 
        /* Identify archive format to emit */
        archiveFormat = parseArchiveFormat(format, &archiveMode);
@@ -683,8 +684,7 @@ main(int argc, char **argv)
 
 #ifndef HAVE_LIBZ
        if (compressLevel != 0)
-               write_msg(NULL, "WARNING: requested compression not available in this "
-                                 "installation -- archive will be uncompressed\n");
+               pg_log_warning("requested compression not available in this installation -- archive will be uncompressed");
        compressLevel = 0;
 #endif
 
@@ -705,11 +705,11 @@ main(int argc, char **argv)
                || numWorkers > MAXIMUM_WAIT_OBJECTS
 #endif
                )
-               exit_horribly(NULL, "invalid number of parallel jobs\n");
+               fatal("invalid number of parallel jobs");
 
        /* 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");
+               fatal("parallel backup only supported by the directory format");
 
        /* Open the output file */
        fout = CreateArchive(filename, archiveFormat, compressLevel, dosync,
@@ -724,6 +724,7 @@ main(int argc, char **argv)
        /* Let the archiver know how noisy to be */
        fout->verbose = g_verbose;
 
+
        /*
         * We allow the server to be back to 8.0, and up to any minor release of
         * our own major version.  (See also version check in pg_dumpall.c.)
@@ -763,15 +764,13 @@ main(int argc, char **argv)
        /* check the version for the synchronized snapshots feature */
        if (numWorkers > 1 && fout->remoteVersion < 90200
                && !dopt.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");
+               fatal("Synchronized snapshots are not supported by this server version.\n"
+                         "Run with --no-synchronized-snapshots instead if you do not need\n"
+                         "synchronized snapshots.");
 
        /* check the version when a snapshot is explicitly specified by user */
        if (dumpsnapshot && fout->remoteVersion < 90200)
-               exit_horribly(NULL,
-                                         "Exported snapshots are not supported by this server version.\n");
+               fatal("Exported snapshots are not supported by this server version.");
 
        /*
         * Find the last built-in OID, if needed (prior to 8.1)
@@ -783,8 +782,7 @@ main(int argc, char **argv)
        else
                g_last_builtin_oid = FirstNormalObjectId - 1;
 
-       if (g_verbose)
-               write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid);
+       pg_log_info("last built-in OID is %u", g_last_builtin_oid);
 
        /* Expand schema selection patterns into OID lists */
        if (schema_include_patterns.head != NULL)
@@ -793,7 +791,7 @@ main(int argc, char **argv)
                                                                        &schema_include_oids,
                                                                        strict_names);
                if (schema_include_oids.head == NULL)
-                       exit_horribly(NULL, "no matching schemas were found\n");
+                       fatal("no matching schemas were found");
        }
        expand_schema_name_patterns(fout, &schema_exclude_patterns,
                                                                &schema_exclude_oids,
@@ -807,7 +805,7 @@ main(int argc, char **argv)
                                                                   &table_include_oids,
                                                                   strict_names);
                if (table_include_oids.head == NULL)
-                       exit_horribly(NULL, "no matching tables were found\n");
+                       fatal("no matching tables were found");
        }
        expand_table_name_patterns(fout, &table_exclude_patterns,
                                                           &table_exclude_oids,
@@ -1071,8 +1069,8 @@ setup_connection(Archive *AH, const char *dumpencoding,
        if (dumpencoding)
        {
                if (PQsetClientEncoding(conn, dumpencoding) < 0)
-                       exit_horribly(NULL, "invalid client encoding \"%s\" specified\n",
-                                                 dumpencoding);
+                       fatal("invalid client encoding \"%s\" specified",
+                                 dumpencoding);
        }
 
        /*
@@ -1114,13 +1112,14 @@ setup_connection(Archive *AH, const char *dumpencoding,
                ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
 
        /*
-        * Use an explicitly specified extra_float_digits if it has been
-        * provided. Otherwise, set extra_float_digits so that we can dump float
-        * data exactly (given correctly implemented float I/O code, anyway).
+        * Use an explicitly specified extra_float_digits if it has been provided.
+        * Otherwise, set extra_float_digits so that we can dump float data
+        * exactly (given correctly implemented float I/O code, anyway).
         */
        if (have_extra_float_digits)
        {
                PQExpBuffer q = createPQExpBuffer();
+
                appendPQExpBuffer(q, "SET extra_float_digits TO %d",
                                                  extra_float_digits);
                ExecuteSqlStatement(AH, q->data);
@@ -1206,7 +1205,7 @@ setup_connection(Archive *AH, const char *dumpencoding,
        {
                PQExpBuffer query = createPQExpBuffer();
 
-               appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT ");
+               appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
                appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
                ExecuteSqlStatement(AH, query->data);
                destroyPQExpBuffer(query);
@@ -1216,10 +1215,9 @@ setup_connection(Archive *AH, const char *dumpencoding,
                         !dopt->no_synchronized_snapshots)
        {
                if (AH->isStandby && AH->remoteVersion < 100000)
-                       exit_horribly(NULL,
-                                                 "Synchronized snapshots on standby servers are not supported by this server version.\n"
-                                                 "Run with --no-synchronized-snapshots instead if you do not need\n"
-                                                 "synchronized snapshots.\n");
+                       fatal("Synchronized snapshots on standby servers are not supported by this server version.\n"
+                                 "Run with --no-synchronized-snapshots instead if you do not need\n"
+                                 "synchronized snapshots.");
 
 
                AH->sync_snapshot_id = get_synchronized_snapshot(AH);
@@ -1286,7 +1284,7 @@ parseArchiveFormat(const char *format, ArchiveMode *mode)
        else if (pg_strcasecmp(format, "tar") == 0)
                archiveFormat = archTar;
        else
-               exit_horribly(NULL, "invalid output format \"%s\" specified\n", format);
+               fatal("invalid output format \"%s\" specified", format);
        return archiveFormat;
 }
 
@@ -1317,14 +1315,14 @@ expand_schema_name_patterns(Archive *fout,
 
        for (cell = patterns->head; cell; cell = cell->next)
        {
-               appendPQExpBuffer(query,
-                                                 "SELECT oid FROM pg_catalog.pg_namespace n\n");
+               appendPQExpBufferStr(query,
+                                                        "SELECT oid FROM pg_catalog.pg_namespace n\n");
                processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                                                          false, NULL, "n.nspname", NULL, NULL);
 
                res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                if (strict_names && PQntuples(res) == 0)
-                       exit_horribly(NULL, "no matching schemas were found for pattern \"%s\"\n", cell->val);
+                       fatal("no matching schemas were found for pattern \"%s\"", cell->val);
 
                for (i = 0; i < PQntuples(res); i++)
                {
@@ -1389,7 +1387,7 @@ expand_table_name_patterns(Archive *fout,
                PQclear(ExecuteSqlQueryForSingleRow(fout,
                                                                                        ALWAYS_SECURE_SEARCH_PATH_SQL));
                if (strict_names && PQntuples(res) == 0)
-                       exit_horribly(NULL, "no matching tables were found for pattern \"%s\"\n", cell->val);
+                       fatal("no matching tables were found for pattern \"%s\"", cell->val);
 
                for (i = 0; i < PQntuples(res); i++)
                {
@@ -1803,9 +1801,8 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        char       *copybuf;
        const char *column_list;
 
-       if (g_verbose)
-               write_msg(NULL, "dumping contents of table \"%s.%s\"\n",
-                                 tbinfo->dobj.namespace->dobj.name, classname);
+       pg_log_info("dumping contents of table \"%s.%s\"",
+                               tbinfo->dobj.namespace->dobj.name, classname);
 
        /*
         * Specify the column list explicitly so that we have no possibility of
@@ -1905,9 +1902,9 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        if (ret == -2)
        {
                /* copy data transfer failed */
-               write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname);
-               write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
-               write_msg(NULL, "The command was: %s\n", q->data);
+               pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
+               pg_log_error("Error message from server: %s", PQerrorMessage(conn));
+               pg_log_error("The command was: %s", q->data);
                exit_nicely(1);
        }
 
@@ -1915,17 +1912,17 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        res = PQgetResult(conn);
        if (PQresultStatus(res) != PGRES_COMMAND_OK)
        {
-               write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n", classname);
-               write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
-               write_msg(NULL, "The command was: %s\n", q->data);
+               pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
+               pg_log_error("Error message from server: %s", PQerrorMessage(conn));
+               pg_log_error("The command was: %s", q->data);
                exit_nicely(1);
        }
        PQclear(res);
 
        /* Do this to ensure we've pumped libpq back to idle state */
        if (PQgetResult(conn) != NULL)
-               write_msg(NULL, "WARNING: unexpected extra results during COPY of table \"%s\"\n",
-                                 classname);
+               pg_log_warning("unexpected extra results during COPY of table \"%s\"",
+                                          classname);
 
        destroyPQExpBuffer(q);
        return 1;
@@ -2027,7 +2024,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                archputs(insertStmt->data, fout);
 
                        /*
-                        * If it is zero-column table then we've aleady written the
+                        * If it is zero-column table then we've already written the
                         * complete statement, which will mean we've disobeyed
                         * --rows-per-insert when it's set greater than 1.  We do support
                         * a way to make this multi-row with: SELECT UNION ALL SELECT
@@ -2050,6 +2047,11 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                        {
                                if (field > 0)
                                        archputs(", ", fout);
+                               if (tbinfo->attgenerated[field])
+                               {
+                                       archputs("DEFAULT", fout);
+                                       continue;
+                               }
                                if (PQgetisnull(res, tuple, field))
                                {
                                        archputs("NULL", fout);
@@ -2242,8 +2244,6 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                                                                           .owner = tbinfo->rolname,
                                                                           .description = "TABLE DATA",
                                                                           .section = SECTION_DATA,
-                                                                          .createStmt = "",
-                                                                          .dropStmt = "",
                                                                           .copyStmt = copyStmt,
                                                                           .deps = &(tbinfo->dobj.dumpId),
                                                                           .nDeps = 1,
@@ -2298,7 +2298,6 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
                                                                  .description = "MATERIALIZED VIEW DATA",
                                                                  .section = SECTION_POST_DATA,
                                                                  .createStmt = q->data,
-                                                                 .dropStmt = "",
                                                                  .deps = tdinfo->dobj.dependencies,
                                                                  .nDeps = tdinfo->dobj.nDeps));
 
@@ -2664,23 +2663,43 @@ dumpDatabase(Archive *fout)
                                minmxid;
        char       *qdatname;
 
-       if (g_verbose)
-               write_msg(NULL, "saving database definition\n");
+       pg_log_info("saving database definition");
 
-       /* Fetch the database-level properties for this database */
+       /*
+        * Fetch the database-level properties for this database.
+        *
+        * The order in which privileges are in the ACL string (the order they
+        * have been GRANT'd in, which the backend maintains) must be preserved to
+        * ensure that GRANTs WITH GRANT OPTION and subsequent GRANTs based on
+        * those are dumped in the correct order.  Note that initial privileges
+        * (pg_init_privs) are not supported on databases, so this logic cannot
+        * make use of buildACLQueries().
+        */
        if (fout->remoteVersion >= 90600)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, "
                                                  "(%s datdba) AS dba, "
                                                  "pg_encoding_to_char(encoding) AS encoding, "
                                                  "datcollate, datctype, datfrozenxid, datminmxid, "
-                                                 "(SELECT array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
-                                                 "  SELECT unnest(coalesce(datacl,acldefault('d',datdba))) AS acl "
-                                                 "  EXCEPT SELECT unnest(acldefault('d',datdba))) as datacls)"
+                                                 "(SELECT array_agg(acl ORDER BY row_n) FROM "
+                                                 "  (SELECT acl, row_n FROM "
+                                                 "     unnest(coalesce(datacl,acldefault('d',datdba))) "
+                                                 "     WITH ORDINALITY AS perm(acl,row_n) "
+                                                 "   WHERE NOT EXISTS ( "
+                                                 "     SELECT 1 "
+                                                 "     FROM unnest(acldefault('d',datdba)) "
+                                                 "       AS init(init_acl) "
+                                                 "     WHERE acl = init_acl)) AS datacls) "
                                                  " AS datacl, "
-                                                 "(SELECT array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
-                                                 "  SELECT unnest(acldefault('d',datdba)) AS acl "
-                                                 "  EXCEPT SELECT unnest(coalesce(datacl,acldefault('d',datdba)))) as rdatacls)"
+                                                 "(SELECT array_agg(acl ORDER BY row_n) FROM "
+                                                 "  (SELECT acl, row_n FROM "
+                                                 "     unnest(acldefault('d',datdba)) "
+                                                 "     WITH ORDINALITY AS initp(acl,row_n) "
+                                                 "   WHERE NOT EXISTS ( "
+                                                 "     SELECT 1 "
+                                                 "     FROM unnest(coalesce(datacl,acldefault('d',datdba))) "
+                                                 "       AS permp(orig_acl) "
+                                                 "     WHERE acl = orig_acl)) AS rdatacls) "
                                                  " AS rdatacl, "
                                                  "datistemplate, datconnlimit, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
@@ -2793,15 +2812,23 @@ dumpDatabase(Archive *fout)
                appendPQExpBufferStr(creaQry, " ENCODING = ");
                appendStringLiteralAH(creaQry, encoding, fout);
        }
-       if (strlen(collate) > 0)
+       if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
        {
-               appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
+               appendPQExpBufferStr(creaQry, " LOCALE = ");
                appendStringLiteralAH(creaQry, collate, fout);
        }
-       if (strlen(ctype) > 0)
+       else
        {
-               appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
-               appendStringLiteralAH(creaQry, ctype, fout);
+               if (strlen(collate) > 0)
+               {
+                       appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
+                       appendStringLiteralAH(creaQry, collate, fout);
+               }
+               if (strlen(ctype) > 0)
+               {
+                       appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+                       appendStringLiteralAH(creaQry, ctype, fout);
+               }
        }
 
        /*
@@ -2864,7 +2891,6 @@ dumpDatabase(Archive *fout)
                                                                          .description = "COMMENT",
                                                                          .section = SECTION_NONE,
                                                                          .createStmt = dbQry->data,
-                                                                         .dropStmt = "",
                                                                          .deps = &dbDumpId,
                                                                          .nDeps = 1));
                }
@@ -2894,7 +2920,6 @@ dumpDatabase(Archive *fout)
                                                                          .description = "SECURITY LABEL",
                                                                          .section = SECTION_NONE,
                                                                          .createStmt = seclabelQry->data,
-                                                                         .dropStmt = "",
                                                                          .deps = &dbDumpId,
                                                                          .nDeps = 1));
                destroyPQExpBuffer(seclabelQry);
@@ -3011,10 +3036,8 @@ dumpDatabase(Archive *fout)
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                         ARCHIVE_OPTS(.tag = "pg_largeobject",
                                                                  .description = "pg_largeobject",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
-                                                                 .createStmt = loOutQry->data,
-                                                                 .dropStmt = ""));
+                                                                 .createStmt = loOutQry->data));
 
                PQclear(lo_res);
 
@@ -3112,8 +3135,7 @@ dumpEncoding(Archive *AH)
        const char *encname = pg_encoding_to_char(AH->encoding);
        PQExpBuffer qry = createPQExpBuffer();
 
-       if (g_verbose)
-               write_msg(NULL, "saving encoding = %s\n", encname);
+       pg_log_info("saving encoding = %s", encname);
 
        appendPQExpBufferStr(qry, "SET client_encoding = ");
        appendStringLiteralAH(qry, encname, AH);
@@ -3122,10 +3144,8 @@ dumpEncoding(Archive *AH)
        ArchiveEntry(AH, nilCatalogId, createDumpId(),
                                 ARCHIVE_OPTS(.tag = "ENCODING",
                                                          .description = "ENCODING",
-                                                         .owner = "",
                                                          .section = SECTION_PRE_DATA,
-                                                         .createStmt = qry->data,
-                                                         .dropStmt = ""));
+                                                         .createStmt = qry->data));
 
        destroyPQExpBuffer(qry);
 }
@@ -3140,9 +3160,8 @@ dumpStdStrings(Archive *AH)
        const char *stdstrings = AH->std_strings ? "on" : "off";
        PQExpBuffer qry = createPQExpBuffer();
 
-       if (g_verbose)
-               write_msg(NULL, "saving standard_conforming_strings = %s\n",
-                                 stdstrings);
+       pg_log_info("saving standard_conforming_strings = %s",
+                               stdstrings);
 
        appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
                                          stdstrings);
@@ -3150,10 +3169,8 @@ dumpStdStrings(Archive *AH)
        ArchiveEntry(AH, nilCatalogId, createDumpId(),
                                 ARCHIVE_OPTS(.tag = "STDSTRINGS",
                                                          .description = "STDSTRINGS",
-                                                         .owner = "",
                                                          .section = SECTION_PRE_DATA,
-                                                         .createStmt = qry->data,
-                                                         .dropStmt = ""));
+                                                         .createStmt = qry->data));
 
        destroyPQExpBuffer(qry);
 }
@@ -3182,7 +3199,7 @@ dumpSearchPath(Archive *AH)
                                                                          "SELECT pg_catalog.current_schemas(false)");
 
        if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
-               exit_horribly(NULL, "could not parse result of current_schemas()\n");
+               fatal("could not parse result of current_schemas()");
 
        /*
         * We use set_config(), not a simple "SET search_path" command, because
@@ -3201,16 +3218,13 @@ dumpSearchPath(Archive *AH)
        appendStringLiteralAH(qry, path->data, AH);
        appendPQExpBufferStr(qry, ", false);\n");
 
-       if (g_verbose)
-               write_msg(NULL, "saving search_path = %s\n", path->data);
+       pg_log_info("saving search_path = %s", path->data);
 
        ArchiveEntry(AH, nilCatalogId, createDumpId(),
                                 ARCHIVE_OPTS(.tag = "SEARCHPATH",
                                                          .description = "SEARCHPATH",
-                                                         .owner = "",
                                                          .section = SECTION_PRE_DATA,
-                                                         .createStmt = qry->data,
-                                                         .dropStmt = ""));
+                                                         .createStmt = qry->data));
 
        /* Also save it in AH->searchpath, in case we're doing plain text dump */
        AH->searchpath = pg_strdup(qry->data);
@@ -3244,9 +3258,7 @@ getBlobs(Archive *fout)
        int                     i_initlomacl;
        int                     i_initrlomacl;
 
-       /* Verbose message */
-       if (g_verbose)
-               write_msg(NULL, "reading large objects\n");
+       pg_log_info("reading large objects");
 
        /* Fetch BLOB OIDs, and owner/ACL data if >= 9.0 */
        if (fout->remoteVersion >= 90600)
@@ -3428,8 +3440,7 @@ dumpBlobs(Archive *fout, void *arg)
        int                     i;
        int                     cnt;
 
-       if (g_verbose)
-               write_msg(NULL, "saving large objects\n");
+       pg_log_info("saving large objects");
 
        /*
         * Currently, we re-fetch all BLOB OIDs using a cursor.  Consider scanning
@@ -3465,8 +3476,8 @@ dumpBlobs(Archive *fout, void *arg)
                        /* Open the BLOB */
                        loFd = lo_open(conn, blobOid, INV_READ);
                        if (loFd == -1)
-                               exit_horribly(NULL, "could not open large object %u: %s",
-                                                         blobOid, PQerrorMessage(conn));
+                               fatal("could not open large object %u: %s",
+                                         blobOid, PQerrorMessage(conn));
 
                        StartBlob(fout, blobOid);
 
@@ -3475,8 +3486,8 @@ dumpBlobs(Archive *fout, void *arg)
                        {
                                cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
                                if (cnt < 0)
-                                       exit_horribly(NULL, "error reading large object %u: %s",
-                                                                 blobOid, PQerrorMessage(conn));
+                                       fatal("error reading large object %u: %s",
+                                                 blobOid, PQerrorMessage(conn));
 
                                WriteData(fout, buf, cnt);
                        } while (cnt > 0);
@@ -3527,10 +3538,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
                if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
                        continue;
 
-               if (g_verbose)
-                       write_msg(NULL, "reading row security enabled for table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("reading row security enabled for table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                /*
                 * Get row security enabled information for the table. We represent
@@ -3559,10 +3569,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
                        polinfo->polwithcheck = NULL;
                }
 
-               if (g_verbose)
-                       write_msg(NULL, "reading policies for table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("reading policies for table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                resetPQExpBuffer(query);
 
@@ -3691,7 +3700,6 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
                                                                          .description = "ROW SECURITY",
                                                                          .section = SECTION_POST_DATA,
                                                                          .createStmt = query->data,
-                                                                         .dropStmt = "",
                                                                          .deps = &(tbinfo->dobj.dumpId),
                                                                          .nDeps = 1));
 
@@ -3711,8 +3719,8 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
                cmd = " FOR DELETE";
        else
        {
-               write_msg(NULL, "unexpected policy command type: %c\n",
-                                 polinfo->polcmd);
+               pg_log_error("unexpected policy command type: %c",
+                                        polinfo->polcmd);
                exit_nicely(1);
        }
 
@@ -3733,7 +3741,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
        if (polinfo->polwithcheck != NULL)
                appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
 
-       appendPQExpBuffer(query, ";\n");
+       appendPQExpBufferStr(query, ";\n");
 
        appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
        appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
@@ -3838,8 +3846,8 @@ getPublications(Archive *fout)
                        (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
 
                if (strlen(pubinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of publication \"%s\" appears to be invalid\n",
-                                         pubinfo[i].dobj.name);
+                       pg_log_warning("owner of publication \"%s\" appears to be invalid",
+                                                  pubinfo[i].dobj.name);
 
                /* Decide whether we want to dump it */
                selectDumpableObject(&(pubinfo[i].dobj), fout);
@@ -3975,10 +3983,9 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
                if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
                        continue;
 
-               if (g_verbose)
-                       write_msg(NULL, "reading publication membership for table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("reading publication membership for table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                resetPQExpBuffer(query);
 
@@ -4052,17 +4059,15 @@ dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
                                          fmtQualifiedDumpable(tbinfo));
 
        /*
-        * There is no point in creating drop query as drop query as the drop is
-        * done by table drop.
+        * There is no point in creating drop query as the drop is done by table
+        * drop.
         */
        ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
                                 ARCHIVE_OPTS(.tag = tag,
                                                          .namespace = tbinfo->dobj.namespace->dobj.name,
                                                          .description = "PUBLICATION TABLE",
-                                                         .owner = "",
                                                          .section = SECTION_POST_DATA,
-                                                         .createStmt = query->data,
-                                                         .dropStmt = ""));
+                                                         .createStmt = query->data));
 
        free(tag);
        destroyPQExpBuffer(query);
@@ -4121,7 +4126,7 @@ getSubscriptions(Archive *fout)
                                                          PGRES_TUPLES_OK);
                n = atoi(PQgetvalue(res, 0, 0));
                if (n > 0)
-                       write_msg(NULL, "WARNING: subscriptions not dumped because current user is not a superuser\n");
+                       pg_log_warning("subscriptions not dumped because current user is not a superuser");
                PQclear(res);
                return;
        }
@@ -4175,8 +4180,8 @@ getSubscriptions(Archive *fout)
                        pg_strdup(PQgetvalue(res, i, i_subpublications));
 
                if (strlen(subinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of subscription \"%s\" appears to be invalid\n",
-                                         subinfo[i].dobj.name);
+                       pg_log_warning("owner of subscription \"%s\" appears to be invalid",
+                                                  subinfo[i].dobj.name);
 
                /* Decide whether we want to dump it */
                selectDumpableObject(&(subinfo[i].dobj), fout);
@@ -4219,8 +4224,7 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
        /* Build list of quoted publications and append them to query. */
        if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
        {
-               write_msg(NULL,
-                                 "WARNING: could not parse subpublications array\n");
+               pg_log_warning("could not parse subpublications array");
                if (pubnames)
                        free(pubnames);
                pubnames = NULL;
@@ -4353,14 +4357,20 @@ binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
        Oid                     pg_type_oid;
        bool            toast_set = false;
 
-       /* we only support old >= 8.3 for binary upgrades */
+       /*
+        * We only support old >= 8.3 for binary upgrades.
+        *
+        * We purposefully ignore toast OIDs for partitioned tables; the reason is
+        * that versions 10 and 11 have them, but 12 does not, so emitting them
+        * causes the upgrade to fail.
+        */
        appendPQExpBuffer(upgrade_query,
                                          "SELECT c.reltype AS crel, t.reltype AS trel "
                                          "FROM pg_catalog.pg_class c "
                                          "LEFT JOIN pg_catalog.pg_class t ON "
-                                         "  (c.reltoastrelid = t.oid) "
+                                         "  (c.reltoastrelid = t.oid AND c.relkind <> '%c') "
                                          "WHERE c.oid = '%u'::pg_catalog.oid;",
-                                         pg_rel_oid);
+                                         RELKIND_PARTITIONED_TABLE, pg_rel_oid);
 
        upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
 
@@ -4486,8 +4496,8 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                extobj = NULL;
        }
        if (extobj == NULL)
-               exit_horribly(NULL, "could not find parent extension for %s %s\n",
-                                         objtype, objname);
+               fatal("could not find parent extension for %s %s",
+                         objtype, objname);
 
        appendPQExpBufferStr(upgrade_buffer,
                                                 "\n-- For binary upgrade, handle extension membership the hard way\n");
@@ -4558,7 +4568,7 @@ getNamespaces(Archive *fout, int *numNamespaces)
                                                  init_acl_subquery->data,
                                                  init_racl_subquery->data);
 
-               appendPQExpBuffer(query, ") ");
+               appendPQExpBufferStr(query, ") ");
 
                destroyPQExpBuffer(acl_subquery);
                destroyPQExpBuffer(racl_subquery);
@@ -4618,8 +4628,8 @@ getNamespaces(Archive *fout, int *numNamespaces)
                        nsinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
 
                if (strlen(nsinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of schema \"%s\" appears to be invalid\n",
-                                         nsinfo[i].dobj.name);
+                       pg_log_warning("owner of schema \"%s\" appears to be invalid",
+                                                  nsinfo[i].dobj.name);
        }
 
        PQclear(res);
@@ -4641,7 +4651,7 @@ findNamespace(Archive *fout, Oid nsoid)
 
        nsinfo = findNamespaceByOid(nsoid);
        if (nsinfo == NULL)
-               exit_horribly(NULL, "schema with OID %u does not exist\n", nsoid);
+               fatal("schema with OID %u does not exist", nsoid);
        return nsinfo;
 }
 
@@ -4966,8 +4976,8 @@ getTypes(Archive *fout, int *numTypes)
                }
 
                if (strlen(tyinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of data type \"%s\" appears to be invalid\n",
-                                         tyinfo[i].dobj.name);
+                       pg_log_warning("owner of data type \"%s\" appears to be invalid",
+                                                  tyinfo[i].dobj.name);
        }
 
        *numTypes = ntups;
@@ -5051,8 +5061,8 @@ getOperators(Archive *fout, int *numOprs)
                oprinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
 
                if (strlen(oprinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of operator \"%s\" appears to be invalid\n",
-                                         oprinfo[i].dobj.name);
+                       pg_log_warning("owner of operator \"%s\" appears to be invalid",
+                                                  oprinfo[i].dobj.name);
        }
 
        PQclear(res);
@@ -5246,9 +5256,9 @@ getAccessMethods(Archive *fout, int *numAccessMethods)
        query = createPQExpBuffer();
 
        /* Select all access methods from pg_am table */
-       appendPQExpBuffer(query, "SELECT tableoid, oid, amname, amtype, "
-                                         "amhandler::pg_catalog.regproc AS amhandler "
-                                         "FROM pg_am");
+       appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
+                                                "amhandler::pg_catalog.regproc AS amhandler "
+                                                "FROM pg_am");
 
        res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -5353,8 +5363,8 @@ getOpclasses(Archive *fout, int *numOpclasses)
                opcinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
 
                if (strlen(opcinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of operator class \"%s\" appears to be invalid\n",
-                                         opcinfo[i].dobj.name);
+                       pg_log_warning("owner of operator class \"%s\" appears to be invalid",
+                                                  opcinfo[i].dobj.name);
        }
 
        PQclear(res);
@@ -5437,8 +5447,8 @@ getOpfamilies(Archive *fout, int *numOpfamilies)
                opfinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
 
                if (strlen(opfinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of operator family \"%s\" appears to be invalid\n",
-                                         opfinfo[i].dobj.name);
+                       pg_log_warning("owner of operator family \"%s\" appears to be invalid",
+                                                  opfinfo[i].dobj.name);
        }
 
        PQclear(res);
@@ -5606,8 +5616,8 @@ getAggregates(Archive *fout, int *numAggs)
                                                  atooid(PQgetvalue(res, i, i_aggnamespace)));
                agginfo[i].aggfn.rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                if (strlen(agginfo[i].aggfn.rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
-                                         agginfo[i].aggfn.dobj.name);
+                       pg_log_warning("owner of aggregate function \"%s\" appears to be invalid",
+                                                  agginfo[i].aggfn.dobj.name);
                agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
                agginfo[i].aggfn.prorettype = InvalidOid;       /* not saved */
                agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl));
@@ -5866,9 +5876,8 @@ getFuncs(Archive *fout, int *numFuncs)
                        finfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
 
                if (strlen(finfo[i].rolname) == 0)
-                       write_msg(NULL,
-                                         "WARNING: owner of function \"%s\" appears to be invalid\n",
-                                         finfo[i].dobj.name);
+                       pg_log_warning("owner of function \"%s\" appears to be invalid",
+                                                  finfo[i].dobj.name);
        }
 
        PQclear(res);
@@ -5952,6 +5961,10 @@ getTables(Archive *fout, int *numTables)
         * information about each table, basically just enough to decide if it is
         * interesting. We must fetch all tables in this phase because otherwise
         * we cannot correctly identify inherited columns, owned sequences, etc.
+        *
+        * We purposefully ignore toast OIDs for partitioned tables; the reason is
+        * that versions 10 and 11 have them, but 12 does not, so emitting them
+        * causes the upgrade to fail.
         */
 
        if (fout->remoteVersion >= 90600)
@@ -6048,7 +6061,7 @@ getTables(Archive *fout, int *numTables)
                                                  "d.classid = c.tableoid AND d.objid = c.oid AND "
                                                  "d.objsubid = 0 AND "
                                                  "d.refclassid = c.tableoid AND d.deptype IN ('a', 'i')) "
-                                                 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
+                                                 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid AND c.relkind <> '%c') "
                                                  "LEFT JOIN pg_am am ON (c.relam = am.oid) "
                                                  "LEFT JOIN pg_init_privs pip ON "
                                                  "(c.oid = pip.objoid "
@@ -6071,6 +6084,7 @@ getTables(Archive *fout, int *numTables)
                                                  ispartition,
                                                  partbound,
                                                  RELKIND_SEQUENCE,
+                                                 RELKIND_PARTITIONED_TABLE,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
                                                  RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
@@ -6107,6 +6121,7 @@ getTables(Archive *fout, int *numTables)
                                                  "tc.relminmxid AS tminmxid, "
                                                  "c.relpersistence, c.relispopulated, "
                                                  "c.relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "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, "
@@ -6156,6 +6171,7 @@ getTables(Archive *fout, int *numTables)
                                                  "tc.relminmxid AS tminmxid, "
                                                  "c.relpersistence, c.relispopulated, "
                                                  "c.relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "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, "
@@ -6205,6 +6221,7 @@ getTables(Archive *fout, int *numTables)
                                                  "tc.relminmxid AS tminmxid, "
                                                  "c.relpersistence, c.relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "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, "
@@ -6254,6 +6271,7 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS tminmxid, "
                                                  "c.relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "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, "
@@ -6301,6 +6319,7 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS tminmxid, "
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "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, "
@@ -6347,6 +6366,7 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS tminmxid, "
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -6393,6 +6413,7 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS tminmxid, "
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
+                                                 "NULL AS amname, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -6438,6 +6459,7 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS tfrozenxid, 0 AS tminmxid,"
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, relpages, "
+                                                 "NULL AS amname, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -6658,8 +6680,8 @@ getTables(Archive *fout, int *numTables)
 
                /* Emit notice if join for owner failed */
                if (strlen(tblinfo[i].rolname) == 0)
-                       write_msg(NULL, "WARNING: owner of table \"%s\" appears to be invalid\n",
-                                         tblinfo[i].dobj.name);
+                       pg_log_warning("owner of table \"%s\" appears to be invalid",
+                                                  tblinfo[i].dobj.name);
        }
 
        if (dopt->lockWaitTimeout)
@@ -6700,8 +6722,8 @@ getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
 
                owning_tab = findTableByOid(seqinfo->owning_tab);
                if (owning_tab == NULL)
-                       exit_horribly(NULL, "failed sanity check, parent table with OID %u of sequence with OID %u not found\n",
-                                                 seqinfo->owning_tab, seqinfo->dobj.catId.oid);
+                       fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
+                                 seqinfo->owning_tab, seqinfo->dobj.catId.oid);
 
                /*
                 * Only dump identity sequences if we're going to dump the table that
@@ -6758,9 +6780,7 @@ getInherits(Archive *fout, int *numInherits)
 
        /*
         * Find all the inheritance information, excluding implicit inheritance
-        * via partitioning.  We handle that case using getPartitions(), because
-        * we want more information about partitions than just the parent-child
-        * relationship.
+        * via partitioning.
         */
        appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
 
@@ -6844,10 +6864,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                        !tbinfo->interesting)
                        continue;
 
-               if (g_verbose)
-                       write_msg(NULL, "reading indexes for table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("reading indexes for table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                /*
                 * The point of the messy-looking outer join is to find a constraint
@@ -7246,10 +7265,9 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
                        !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
                        continue;
 
-               if (g_verbose)
-                       write_msg(NULL, "reading foreign key constraints for table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("reading foreign key constraints for table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                resetPQExpBuffer(query);
                if (fout->remoteVersion >= 110000)
@@ -7466,8 +7484,8 @@ getRules(Archive *fout, int *numRules)
                ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
                ruleinfo[i].ruletable = findTableByOid(ruletableoid);
                if (ruleinfo[i].ruletable == NULL)
-                       exit_horribly(NULL, "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n",
-                                                 ruletableoid, ruleinfo[i].dobj.catId.oid);
+                       fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
+                                 ruletableoid, ruleinfo[i].dobj.catId.oid);
                ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
                ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
                ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
@@ -7549,10 +7567,9 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
                        !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
                        continue;
 
-               if (g_verbose)
-                       write_msg(NULL, "reading triggers for table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("reading triggers for table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                resetPQExpBuffer(query);
                if (fout->remoteVersion >= 90000)
@@ -7683,10 +7700,10 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
                                        if (OidIsValid(tginfo[j].tgconstrrelid))
                                        {
                                                if (PQgetisnull(res, j, i_tgconstrrelname))
-                                                       exit_horribly(NULL, "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n",
-                                                                                 tginfo[j].dobj.name,
-                                                                                 tbinfo->dobj.name,
-                                                                                 tginfo[j].tgconstrrelid);
+                                                       fatal("query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)",
+                                                                 tginfo[j].dobj.name,
+                                                                 tbinfo->dobj.name,
+                                                                 tginfo[j].tgconstrrelid);
                                                tginfo[j].tgconstrrelname = pg_strdup(PQgetvalue(res, j, i_tgconstrrelname));
                                        }
                                        else
@@ -8117,10 +8134,10 @@ getTransforms(Archive *fout, int *numTransforms)
 
        query = createPQExpBuffer();
 
-       appendPQExpBuffer(query, "SELECT tableoid, oid, "
-                                         "trftype, trflang, trffromsql::oid, trftosql::oid "
-                                         "FROM pg_transform "
-                                         "ORDER BY 3,4");
+       appendPQExpBufferStr(query, "SELECT tableoid, oid, "
+                                                "trftype, trflang, trffromsql::oid, trftosql::oid "
+                                                "FROM pg_transform "
+                                                "ORDER BY 3,4");
 
        res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -8207,6 +8224,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
        int                     i_attnotnull;
        int                     i_atthasdef;
        int                     i_attidentity;
+       int                     i_attgenerated;
        int                     i_attisdropped;
        int                     i_attlen;
        int                     i_attalign;
@@ -8237,55 +8255,61 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                 * we must read the attribute names in attribute number order! because
                 * we will use the attnum to index into the attnames array later.
                 */
-               if (g_verbose)
-                       write_msg(NULL, "finding the columns and types of table \"%s.%s\"\n",
-                                         tbinfo->dobj.namespace->dobj.name,
-                                         tbinfo->dobj.name);
+               pg_log_info("finding the columns and types of table \"%s.%s\"",
+                                       tbinfo->dobj.namespace->dobj.name,
+                                       tbinfo->dobj.name);
 
                resetPQExpBuffer(q);
 
-               appendPQExpBuffer(q,
-                                                 "SELECT\n"
-                                                 "a.attnum,\n"
-                                                 "a.attname,\n"
-                                                 "a.atttypmod,\n"
-                                                 "a.attstattarget,\n"
-                                                 "a.attstorage,\n"
-                                                 "t.typstorage,\n"
-                                                 "a.attnotnull,\n"
-                                                 "a.atthasdef,\n"
-                                                 "a.attisdropped,\n"
-                                                 "a.attlen,\n"
-                                                 "a.attalign,\n"
-                                                 "a.attislocal,\n"
-                                                 "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n");
+               appendPQExpBufferStr(q,
+                                                        "SELECT\n"
+                                                        "a.attnum,\n"
+                                                        "a.attname,\n"
+                                                        "a.atttypmod,\n"
+                                                        "a.attstattarget,\n"
+                                                        "a.attstorage,\n"
+                                                        "t.typstorage,\n"
+                                                        "a.attnotnull,\n"
+                                                        "a.atthasdef,\n"
+                                                        "a.attisdropped,\n"
+                                                        "a.attlen,\n"
+                                                        "a.attalign,\n"
+                                                        "a.attislocal,\n"
+                                                        "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n");
+
+               if (fout->remoteVersion >= 120000)
+                       appendPQExpBufferStr(q,
+                                                                "a.attgenerated,\n");
+               else
+                       appendPQExpBufferStr(q,
+                                                                "'' AS attgenerated,\n");
 
                if (fout->remoteVersion >= 110000)
-                       appendPQExpBuffer(q,
-                                                         "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
-                                                         "THEN a.attmissingval ELSE null END AS attmissingval,\n");
+                       appendPQExpBufferStr(q,
+                                                                "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
+                                                                "THEN a.attmissingval ELSE null END AS attmissingval,\n");
                else
-                       appendPQExpBuffer(q,
-                                                         "NULL AS attmissingval,\n");
+                       appendPQExpBufferStr(q,
+                                                                "NULL AS attmissingval,\n");
 
                if (fout->remoteVersion >= 100000)
-                       appendPQExpBuffer(q,
-                                                         "a.attidentity,\n");
+                       appendPQExpBufferStr(q,
+                                                                "a.attidentity,\n");
                else
-                       appendPQExpBuffer(q,
-                                                         "'' AS attidentity,\n");
+                       appendPQExpBufferStr(q,
+                                                                "'' AS attidentity,\n");
 
                if (fout->remoteVersion >= 90200)
-                       appendPQExpBuffer(q,
-                                                         "pg_catalog.array_to_string(ARRAY("
-                                                         "SELECT pg_catalog.quote_ident(option_name) || "
-                                                         "' ' || pg_catalog.quote_literal(option_value) "
-                                                         "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
-                                                         "ORDER BY option_name"
-                                                         "), E',\n    ') AS attfdwoptions,\n");
+                       appendPQExpBufferStr(q,
+                                                                "pg_catalog.array_to_string(ARRAY("
+                                                                "SELECT pg_catalog.quote_ident(option_name) || "
+                                                                "' ' || pg_catalog.quote_literal(option_value) "
+                                                                "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
+                                                                "ORDER BY option_name"
+                                                                "), E',\n    ') AS attfdwoptions,\n");
                else
-                       appendPQExpBuffer(q,
-                                                         "'' AS attfdwoptions,\n");
+                       appendPQExpBufferStr(q,
+                                                                "'' AS attfdwoptions,\n");
 
                if (fout->remoteVersion >= 90100)
                {
@@ -8294,20 +8318,20 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                         * collation is different from their type's default, we use a CASE
                         * here to suppress uninteresting attcollations cheaply.
                         */
-                       appendPQExpBuffer(q,
-                                                         "CASE WHEN a.attcollation <> t.typcollation "
-                                                         "THEN a.attcollation ELSE 0 END AS attcollation,\n");
+                       appendPQExpBufferStr(q,
+                                                                "CASE WHEN a.attcollation <> t.typcollation "
+                                                                "THEN a.attcollation ELSE 0 END AS attcollation,\n");
                }
                else
-                       appendPQExpBuffer(q,
-                                                         "0 AS attcollation,\n");
+                       appendPQExpBufferStr(q,
+                                                                "0 AS attcollation,\n");
 
                if (fout->remoteVersion >= 90000)
-                       appendPQExpBuffer(q,
-                                                         "array_to_string(a.attoptions, ', ') AS attoptions\n");
+                       appendPQExpBufferStr(q,
+                                                                "array_to_string(a.attoptions, ', ') AS attoptions\n");
                else
-                       appendPQExpBuffer(q,
-                                                         "'' AS attoptions\n");
+                       appendPQExpBufferStr(q,
+                                                                "'' AS attoptions\n");
 
                /* need left join here to not fail on dropped columns ... */
                appendPQExpBuffer(q,
@@ -8332,6 +8356,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                i_attnotnull = PQfnumber(res, "attnotnull");
                i_atthasdef = PQfnumber(res, "atthasdef");
                i_attidentity = PQfnumber(res, "attidentity");
+               i_attgenerated = PQfnumber(res, "attgenerated");
                i_attisdropped = PQfnumber(res, "attisdropped");
                i_attlen = PQfnumber(res, "attlen");
                i_attalign = PQfnumber(res, "attalign");
@@ -8349,6 +8374,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                tbinfo->attstorage = (char *) pg_malloc(ntups * sizeof(char));
                tbinfo->typstorage = (char *) pg_malloc(ntups * sizeof(char));
                tbinfo->attidentity = (char *) pg_malloc(ntups * sizeof(char));
+               tbinfo->attgenerated = (char *) pg_malloc(ntups * sizeof(char));
                tbinfo->attisdropped = (bool *) pg_malloc(ntups * sizeof(bool));
                tbinfo->attlen = (int *) pg_malloc(ntups * sizeof(int));
                tbinfo->attalign = (char *) pg_malloc(ntups * sizeof(char));
@@ -8365,9 +8391,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                for (j = 0; j < ntups; j++)
                {
                        if (j + 1 != atoi(PQgetvalue(res, j, i_attnum)))
-                               exit_horribly(NULL,
-                                                         "invalid column numbering in table \"%s\"\n",
-                                                         tbinfo->dobj.name);
+                               fatal("invalid column numbering in table \"%s\"",
+                                         tbinfo->dobj.name);
                        tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname));
                        tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname));
                        tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
@@ -8375,6 +8400,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                        tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
                        tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
                        tbinfo->attidentity[j] = *(PQgetvalue(res, j, i_attidentity));
+                       tbinfo->attgenerated[j] = *(PQgetvalue(res, j, i_attgenerated));
                        tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
                        tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
                        tbinfo->attlen[j] = atoi(PQgetvalue(res, j, i_attlen));
@@ -8402,10 +8428,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                        AttrDefInfo *attrdefs;
                        int                     numDefaults;
 
-                       if (g_verbose)
-                               write_msg(NULL, "finding default expressions of table \"%s.%s\"\n",
-                                                 tbinfo->dobj.namespace->dobj.name,
-                                                 tbinfo->dobj.name);
+                       pg_log_info("finding default expressions of table \"%s.%s\"",
+                                               tbinfo->dobj.namespace->dobj.name,
+                                               tbinfo->dobj.name);
 
                        printfPQExpBuffer(q, "SELECT tableoid, oid, adnum, "
                                                          "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc "
@@ -8425,9 +8450,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                                adnum = atoi(PQgetvalue(res, j, 2));
 
                                if (adnum <= 0 || adnum > ntups)
-                                       exit_horribly(NULL,
-                                                                 "invalid adnum value %d for table \"%s\"\n",
-                                                                 adnum, tbinfo->dobj.name);
+                                       fatal("invalid adnum value %d for table \"%s\"",
+                                                 adnum, tbinfo->dobj.name);
 
                                /*
                                 * dropped columns shouldn't have defaults, but just in case,
@@ -8491,10 +8515,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                        ConstraintInfo *constrs;
                        int                     numConstrs;
 
-                       if (g_verbose)
-                               write_msg(NULL, "finding check constraints for table \"%s.%s\"\n",
-                                                 tbinfo->dobj.namespace->dobj.name,
-                                                 tbinfo->dobj.name);
+                       pg_log_info("finding check constraints for table \"%s.%s\"",
+                                               tbinfo->dobj.namespace->dobj.name,
+                                               tbinfo->dobj.name);
 
                        resetPQExpBuffer(q);
                        if (fout->remoteVersion >= 90200)
@@ -8541,11 +8564,11 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                        numConstrs = PQntuples(res);
                        if (numConstrs != tbinfo->ncheck)
                        {
-                               write_msg(NULL, ngettext("expected %d check constraint on table \"%s\" but found %d\n",
-                                                                                "expected %d check constraints on table \"%s\" but found %d\n",
-                                                                                tbinfo->ncheck),
-                                                 tbinfo->ncheck, tbinfo->dobj.name, numConstrs);
-                               write_msg(NULL, "(The system catalogs might be corrupted.)\n");
+                               pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
+                                                                         "expected %d check constraints on table \"%s\" but found %d",
+                                                                         tbinfo->ncheck),
+                                                        tbinfo->ncheck, tbinfo->dobj.name, numConstrs);
+                               pg_log_error("(The system catalogs might be corrupted.)");
                                exit_nicely(1);
                        }
 
@@ -8614,9 +8637,12 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
  * Normally this is always true, but it's false for dropped columns, as well
  * as those that were inherited without any local definition.  (If we print
  * such a column it will mistakenly get pg_attribute.attislocal set to true.)
- * However, in binary_upgrade mode, we must print all such columns anyway and
- * fix the attislocal/attisdropped state later, so as to keep control of the
- * physical column order.
+ * For partitions, it's always true, because we want the partitions to be
+ * created independently and ATTACH PARTITION used afterwards.
+ *
+ * In binary_upgrade mode, we must print all columns and fix the attislocal/
+ * attisdropped state later, so as to keep control of the physical column
+ * order.
  *
  * This function exists because there are scattered nonobvious places that
  * must be kept in sync with this decision.
@@ -8626,7 +8652,9 @@ shouldPrintColumn(DumpOptions *dopt, TableInfo *tbinfo, int colno)
 {
        if (dopt->binary_upgrade)
                return true;
-       return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]);
+       if (tbinfo->attisdropped[colno])
+               return false;
+       return (tbinfo->attislocal[colno] || tbinfo->ispartition);
 }
 
 
@@ -9493,7 +9521,6 @@ dumpComment(Archive *fout, const char *type, const char *name,
                                                                  .description = "COMMENT",
                                                                  .section = SECTION_NONE,
                                                                  .createStmt = query->data,
-                                                                 .dropStmt = "",
                                                                  .deps = &dumpId,
                                                                  .nDeps = 1));
 
@@ -9563,7 +9590,6 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                                                                          .description = "COMMENT",
                                                                          .section = SECTION_NONE,
                                                                          .createStmt = query->data,
-                                                                         .dropStmt = "",
                                                                          .deps = &(tbinfo->dobj.dumpId),
                                                                          .nDeps = 1));
                }
@@ -9589,7 +9615,6 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                                                                          .description = "COMMENT",
                                                                          .section = SECTION_NONE,
                                                                          .createStmt = query->data,
-                                                                         .dropStmt = "",
                                                                          .deps = &(tbinfo->dobj.dumpId),
                                                                          .nDeps = 1));
                }
@@ -9870,11 +9895,8 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                                te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
                                                                  ARCHIVE_OPTS(.tag = dobj->name,
                                                                                           .description = "BLOBS",
-                                                                                          .owner = "",
                                                                                           .section = SECTION_DATA,
-                                                                                          .dumpFn = dumpBlobs,
-                                                                                          .createStmt = "",
-                                                                                          .dropStmt = ""));
+                                                                                          .dumpFn = dumpBlobs));
 
                                /*
                                 * Set the TocEntry's dataLength in case we are doing a
@@ -10079,7 +10101,6 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
                ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
                                         ARCHIVE_OPTS(.tag = extinfo->dobj.name,
                                                                  .description = "EXTENSION",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
                                                                  .createStmt = q->data,
                                                                  .dropStmt = delq->data));
@@ -10128,8 +10149,8 @@ dumpType(Archive *fout, TypeInfo *tyinfo)
        else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
                dumpUndefinedType(fout, tyinfo);
        else
-               write_msg(NULL, "WARNING: typtype of data type \"%s\" appears to be invalid\n",
-                                 tyinfo->dobj.name);
+               pg_log_warning("typtype of data type \"%s\" appears to be invalid",
+                                          tyinfo->dobj.name);
 }
 
 /*
@@ -11223,7 +11244,6 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
                                                                          .description = "COMMENT",
                                                                          .section = SECTION_NONE,
                                                                          .createStmt = query->data,
-                                                                         .dropStmt = "",
                                                                          .deps = &(tyinfo->dobj.dumpId),
                                                                          .nDeps = 1));
                }
@@ -11279,8 +11299,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
                                                                  .owner = stinfo->baseType->rolname,
                                                                  .description = "SHELL TYPE",
                                                                  .section = SECTION_PRE_DATA,
-                                                                 .createStmt = q->data,
-                                                                 .dropStmt = ""));
+                                                                 .createStmt = q->data));
 
        destroyPQExpBuffer(q);
 }
@@ -11484,7 +11503,7 @@ format_function_arguments_old(Archive *fout,
                                        argmode = "INOUT ";
                                        break;
                                default:
-                                       write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
+                                       pg_log_warning("bogus value in proargmodes array");
                                        argmode = "";
                                        break;
                        }
@@ -11856,7 +11875,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                if (!parsePGArray(proallargtypes, &allargtypes, &nitems) ||
                        nitems < finfo->nargs)
                {
-                       write_msg(NULL, "WARNING: could not parse proallargtypes array\n");
+                       pg_log_warning("could not parse proallargtypes array");
                        if (allargtypes)
                                free(allargtypes);
                        allargtypes = NULL;
@@ -11872,7 +11891,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                if (!parsePGArray(proargmodes, &argmodes, &nitems) ||
                        nitems != nallargs)
                {
-                       write_msg(NULL, "WARNING: could not parse proargmodes array\n");
+                       pg_log_warning("could not parse proargmodes array");
                        if (argmodes)
                                free(argmodes);
                        argmodes = NULL;
@@ -11886,7 +11905,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                if (!parsePGArray(proargnames, &argnames, &nitems) ||
                        nitems != nallargs)
                {
-                       write_msg(NULL, "WARNING: could not parse proargnames array\n");
+                       pg_log_warning("could not parse proargnames array");
                        if (argnames)
                                free(argnames);
                        argnames = NULL;
@@ -11897,7 +11916,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        {
                if (!parsePGArray(proconfig, &configitems, &nconfigitems))
                {
-                       write_msg(NULL, "WARNING: could not parse proconfig array\n");
+                       pg_log_warning("could not parse proconfig array");
                        if (configitems)
                                free(configitems);
                        configitems = NULL;
@@ -11977,8 +11996,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                else if (provolatile[0] == PROVOLATILE_STABLE)
                        appendPQExpBufferStr(q, " STABLE");
                else if (provolatile[0] != PROVOLATILE_VOLATILE)
-                       exit_horribly(NULL, "unrecognized provolatile value for function \"%s\"\n",
-                                                 finfo->dobj.name);
+                       fatal("unrecognized provolatile value for function \"%s\"",
+                                 finfo->dobj.name);
        }
 
        if (proisstrict[0] == 't')
@@ -12027,8 +12046,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                        appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
                else if (proparallel[0] != PROPARALLEL_UNSAFE)
-                       exit_horribly(NULL, "unrecognized proparallel value for function \"%s\"\n",
-                                                 finfo->dobj.name);
+                       fatal("unrecognized proparallel value for function \"%s\"",
+                                 finfo->dobj.name);
        }
 
        for (i = 0; i < nconfigitems; i++)
@@ -12160,8 +12179,8 @@ dumpCast(Archive *fout, CastInfo *cast)
        {
                funcInfo = findFuncByOid(cast->castfunc);
                if (funcInfo == NULL)
-                       exit_horribly(NULL, "could not find function definition for function with OID %u\n",
-                                                 cast->castfunc);
+                       fatal("could not find function definition for function with OID %u",
+                                 cast->castfunc);
        }
 
        defqry = createPQExpBuffer();
@@ -12199,10 +12218,10 @@ dumpCast(Archive *fout, CastInfo *cast)
                                free(fsig);
                        }
                        else
-                               write_msg(NULL, "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n");
+                               pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
                        break;
                default:
-                       write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n");
+                       pg_log_warning("bogus value in pg_cast.castmethod field");
        }
 
        if (cast->castcontext == 'a')
@@ -12225,7 +12244,6 @@ dumpCast(Archive *fout, CastInfo *cast)
                ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
                                         ARCHIVE_OPTS(.tag = labelq->data,
                                                                  .description = "CAST",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
                                                                  .createStmt = defqry->data,
                                                                  .dropStmt = delqry->data));
@@ -12270,15 +12288,15 @@ dumpTransform(Archive *fout, TransformInfo *transform)
        {
                fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
                if (fromsqlFuncInfo == NULL)
-                       exit_horribly(NULL, "could not find function definition for function with OID %u\n",
-                                                 transform->trffromsql);
+                       fatal("could not find function definition for function with OID %u",
+                                 transform->trffromsql);
        }
        if (OidIsValid(transform->trftosql))
        {
                tosqlFuncInfo = findFuncByOid(transform->trftosql);
                if (tosqlFuncInfo == NULL)
-                       exit_horribly(NULL, "could not find function definition for function with OID %u\n",
-                                                 transform->trftosql);
+                       fatal("could not find function definition for function with OID %u",
+                                 transform->trftosql);
        }
 
        defqry = createPQExpBuffer();
@@ -12296,7 +12314,7 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                                          transformType, lanname);
 
        if (!transform->trffromsql && !transform->trftosql)
-               write_msg(NULL, "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n");
+               pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
 
        if (transform->trffromsql)
        {
@@ -12313,13 +12331,13 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                        free(fsig);
                }
                else
-                       write_msg(NULL, "WARNING: bogus value in pg_transform.trffromsql field\n");
+                       pg_log_warning("bogus value in pg_transform.trffromsql field");
        }
 
        if (transform->trftosql)
        {
                if (transform->trffromsql)
-                       appendPQExpBuffer(defqry, ", ");
+                       appendPQExpBufferStr(defqry, ", ");
 
                if (tosqlFuncInfo)
                {
@@ -12334,10 +12352,10 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                        free(fsig);
                }
                else
-                       write_msg(NULL, "WARNING: bogus value in pg_transform.trftosql field\n");
+                       pg_log_warning("bogus value in pg_transform.trftosql field");
        }
 
-       appendPQExpBuffer(defqry, ");\n");
+       appendPQExpBufferStr(defqry, ");\n");
 
        appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
                                          transformType, lanname);
@@ -12353,7 +12371,6 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
                                         ARCHIVE_OPTS(.tag = labelq->data,
                                                                  .description = "TRANSFORM",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
                                                                  .createStmt = defqry->data,
                                                                  .dropStmt = delqry->data,
@@ -12651,8 +12668,8 @@ getFormattedOperatorName(Archive *fout, const char *oproid)
        oprInfo = findOprByOid(atooid(oproid));
        if (oprInfo == NULL)
        {
-               write_msg(NULL, "WARNING: could not find operator with OID %s\n",
-                                 oproid);
+               pg_log_warning("could not find operator with OID %s",
+                                          oproid);
                return NULL;
        }
 
@@ -12713,14 +12730,14 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
        switch (aminfo->amtype)
        {
                case AMTYPE_INDEX:
-                       appendPQExpBuffer(q, "TYPE INDEX ");
+                       appendPQExpBufferStr(q, "TYPE INDEX ");
                        break;
                case AMTYPE_TABLE:
-                       appendPQExpBuffer(q, "TYPE TABLE ");
+                       appendPQExpBufferStr(q, "TYPE TABLE ");
                        break;
                default:
-                       write_msg(NULL, "WARNING: invalid type \"%c\" of access method \"%s\"\n",
-                                         aminfo->amtype, qamname);
+                       pg_log_warning("invalid type \"%c\" of access method \"%s\"",
+                                                  aminfo->amtype, qamname);
                        destroyPQExpBuffer(q);
                        destroyPQExpBuffer(delq);
                        free(qamname);
@@ -12740,7 +12757,6 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
                ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
                                         ARCHIVE_OPTS(.tag = aminfo->dobj.name,
                                                                  .description = "ACCESS METHOD",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
                                                                  .createStmt = q->data,
                                                                  .dropStmt = delq->data));
@@ -13405,6 +13421,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        char       *qcollname;
        PGresult   *res;
        int                     i_collprovider;
+       int                     i_collisdeterministic;
        int                     i_collcollate;
        int                     i_collctype;
        const char *collprovider;
@@ -13422,28 +13439,35 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        qcollname = pg_strdup(fmtId(collinfo->dobj.name));
 
        /* Get collation-specific details */
+       appendPQExpBufferStr(query, "SELECT ");
+
        if (fout->remoteVersion >= 100000)
-               appendPQExpBuffer(query, "SELECT "
-                                                 "collprovider, "
-                                                 "collcollate, "
-                                                 "collctype, "
-                                                 "collversion "
-                                                 "FROM pg_catalog.pg_collation c "
-                                                 "WHERE c.oid = '%u'::pg_catalog.oid",
-                                                 collinfo->dobj.catId.oid);
+               appendPQExpBufferStr(query,
+                                                        "collprovider, "
+                                                        "collversion, ");
        else
-               appendPQExpBuffer(query, "SELECT "
-                                                 "'c' AS collprovider, "
-                                                 "collcollate, "
-                                                 "collctype, "
-                                                 "NULL AS collversion "
-                                                 "FROM pg_catalog.pg_collation c "
-                                                 "WHERE c.oid = '%u'::pg_catalog.oid",
-                                                 collinfo->dobj.catId.oid);
+               appendPQExpBufferStr(query,
+                                                        "'c' AS collprovider, "
+                                                        "NULL AS collversion, ");
+
+       if (fout->remoteVersion >= 120000)
+               appendPQExpBufferStr(query,
+                                                        "collisdeterministic, ");
+       else
+               appendPQExpBufferStr(query,
+                                                        "true AS collisdeterministic, ");
+
+       appendPQExpBuffer(query,
+                                         "collcollate, "
+                                         "collctype "
+                                         "FROM pg_catalog.pg_collation c "
+                                         "WHERE c.oid = '%u'::pg_catalog.oid",
+                                         collinfo->dobj.catId.oid);
 
        res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_collprovider = PQfnumber(res, "collprovider");
+       i_collisdeterministic = PQfnumber(res, "collisdeterministic");
        i_collcollate = PQfnumber(res, "collcollate");
        i_collctype = PQfnumber(res, "collctype");
 
@@ -13466,9 +13490,11 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
                /* to allow dumping pg_catalog; not accepted on input */
                appendPQExpBufferStr(q, "default");
        else
-               exit_horribly(NULL,
-                                         "unrecognized collation provider: %s\n",
-                                         collprovider);
+               fatal("unrecognized collation provider: %s",
+                         collprovider);
+
+       if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
+               appendPQExpBufferStr(q, ", deterministic = false");
 
        if (strcmp(collcollate, collctype) == 0)
        {
@@ -13645,7 +13671,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
                appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
 
        if (agginfo->aggfn.nargs == 0)
-               appendPQExpBuffer(&buf, "(*)");
+               appendPQExpBufferStr(&buf, "(*)");
        else
        {
                appendPQExpBufferChar(&buf, '(');
@@ -13936,8 +13962,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 
        if (!convertok)
        {
-               write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
-                                 aggsig);
+               pg_log_warning("aggregate function %s could not be dumped correctly for this database version; ignored",
+                                          aggsig);
 
                if (aggfullsig)
                        free(aggfullsig);
@@ -13991,8 +14017,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                        appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_WRITE");
                                        break;
                                default:
-                                       exit_horribly(NULL, "unrecognized aggfinalmodify value for aggregate \"%s\"\n",
-                                                                 agginfo->aggfn.dobj.name);
+                                       fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
+                                                 agginfo->aggfn.dobj.name);
                                        break;
                        }
                }
@@ -14047,8 +14073,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                        appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_WRITE");
                                        break;
                                default:
-                                       exit_horribly(NULL, "unrecognized aggmfinalmodify value for aggregate \"%s\"\n",
-                                                                 agginfo->aggfn.dobj.name);
+                                       fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
+                                                 agginfo->aggfn.dobj.name);
                                        break;
                        }
                }
@@ -14072,8 +14098,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                        appendPQExpBufferStr(details, ",\n    PARALLEL = restricted");
                else if (proparallel[0] != PROPARALLEL_UNSAFE)
-                       exit_horribly(NULL, "unrecognized proparallel value for function \"%s\"\n",
-                                                 agginfo->aggfn.dobj.name);
+                       fatal("unrecognized proparallel value for function \"%s\"",
+                                 agginfo->aggfn.dobj.name);
        }
 
        appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
@@ -14192,7 +14218,6 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
                                         ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
                                                                  .namespace = prsinfo->dobj.namespace->dobj.name,
                                                                  .description = "TEXT SEARCH PARSER",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
                                                                  .createStmt = q->data,
                                                                  .dropStmt = delq->data));
@@ -14331,7 +14356,6 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
                                         ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
                                                                  .namespace = tmplinfo->dobj.namespace->dobj.name,
                                                                  .description = "TEXT SEARCH TEMPLATE",
-                                                                 .owner = "",
                                                                  .section = SECTION_PRE_DATA,
                                                                  .createStmt = q->data,
                                                                  .dropStmt = delq->data));
@@ -14771,9 +14795,8 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                        break;
                default:
                        /* shouldn't get here */
-                       exit_horribly(NULL,
-                                                 "unrecognized object type in default privileges: %d\n",
-                                                 (int) daclinfo->defaclobjtype);
+                       fatal("unrecognized object type in default privileges: %d",
+                                 (int) daclinfo->defaclobjtype);
                        type = "";                      /* keep compiler quiet */
        }
 
@@ -14790,8 +14813,8 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                                                                 daclinfo->defaclrole,
                                                                 fout->remoteVersion,
                                                                 q))
-               exit_horribly(NULL, "could not parse default ACL list (%s)\n",
-                                         daclinfo->defaclacl);
+               fatal("could not parse default ACL list (%s)",
+                         daclinfo->defaclacl);
 
        if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
                ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
@@ -14801,8 +14824,7 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                                                                  .owner = daclinfo->defaclrole,
                                                                  .description = "DEFAULT ACL",
                                                                  .section = SECTION_POST_DATA,
-                                                                 .createStmt = q->data,
-                                                                 .dropStmt = ""));
+                                                                 .createStmt = q->data));
 
        destroyPQExpBuffer(tag);
        destroyPQExpBuffer(q);
@@ -14867,22 +14889,20 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
         */
        if (strlen(initacls) != 0 || strlen(initracls) != 0)
        {
-               appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
+               appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
                if (!buildACLCommands(name, subname, nspname, type,
                                                          initacls, initracls, owner,
                                                          "", fout->remoteVersion, sql))
-                       exit_horribly(NULL,
-                                                 "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n",
-                                                 initacls, initracls, name, type);
-               appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
+                       fatal("could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)",
+                                 initacls, initracls, name, type);
+               appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
        }
 
        if (!buildACLCommands(name, subname, nspname, type,
                                                  acls, racls, owner,
                                                  "", fout->remoteVersion, sql))
-               exit_horribly(NULL,
-                                         "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n",
-                                         acls, racls, name, type);
+               fatal("could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)",
+                         acls, racls, name, type);
 
        if (sql->len > 0)
        {
@@ -14900,7 +14920,6 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
                                                                  .description = "ACL",
                                                                  .section = SECTION_NONE,
                                                                  .createStmt = sql->data,
-                                                                 .dropStmt = "",
                                                                  .deps = &objDumpId,
                                                                  .nDeps = 1));
                destroyPQExpBuffer(tag);
@@ -14990,7 +15009,6 @@ dumpSecLabel(Archive *fout, const char *type, const char *name,
                                                                  .description = "SECURITY LABEL",
                                                                  .section = SECTION_NONE,
                                                                  .createStmt = query->data,
-                                                                 .dropStmt = "",
                                                                  .deps = &dumpId,
                                                                  .nDeps = 1));
                destroyPQExpBuffer(tag);
@@ -15074,7 +15092,6 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename)
                                                                  .description = "SECURITY LABEL",
                                                                  .section = SECTION_NONE,
                                                                  .createStmt = query->data,
-                                                                 .dropStmt = "",
                                                                  .deps = &(tbinfo->dobj.dumpId),
                                                                  .nDeps = 1));
        }
@@ -15383,18 +15400,18 @@ createViewAsClause(Archive *fout, TableInfo *tbinfo)
        if (PQntuples(res) != 1)
        {
                if (PQntuples(res) < 1)
-                       exit_horribly(NULL, "query to obtain definition of view \"%s\" returned no data\n",
-                                                 tbinfo->dobj.name);
+                       fatal("query to obtain definition of view \"%s\" returned no data",
+                                 tbinfo->dobj.name);
                else
-                       exit_horribly(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n",
-                                                 tbinfo->dobj.name);
+                       fatal("query to obtain definition of view \"%s\" returned more than one definition",
+                                 tbinfo->dobj.name);
        }
 
        len = PQgetlength(res, 0, 0);
 
        if (len == 0)
-               exit_horribly(NULL, "definition of view \"%s\" appears to be empty (length zero)\n",
-                                         tbinfo->dobj.name);
+               fatal("definition of view \"%s\" appears to be empty (length zero)",
+                         tbinfo->dobj.name);
 
        /* Strip off the trailing semicolon so that other things may follow. */
        Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
@@ -15475,9 +15492,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
 
        if (tbinfo->hasoids)
-               write_msg(NULL,
-                                 "WARNING: WITH OIDS is not supported anymore (table \"%s\")\n",
-                                 qrelname);
+               pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
+                                          qrelname);
 
        if (dopt->binary_upgrade)
                binary_upgrade_set_type_oids_by_rel_oid(fout, q,
@@ -15589,27 +15605,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                if (tbinfo->reloftype && !dopt->binary_upgrade)
                        appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
 
-               /*
-                * If the table is a partition, dump it as such; except in the case of
-                * a binary upgrade, we dump the table normally and attach it to the
-                * parent afterward.
-                */
-               if (tbinfo->ispartition && !dopt->binary_upgrade)
-               {
-                       TableInfo  *parentRel = tbinfo->parents[0];
-
-                       /*
-                        * With partitions, unlike inheritance, there can only be one
-                        * parent.
-                        */
-                       if (tbinfo->numParents != 1)
-                               exit_horribly(NULL, "invalid number of parents %d for table \"%s\"\n",
-                                                         tbinfo->numParents, tbinfo->dobj.name);
-
-                       appendPQExpBuffer(q, " PARTITION OF %s",
-                                                         fmtQualifiedDumpable(parentRel));
-               }
-
                if (tbinfo->relkind != RELKIND_MATVIEW)
                {
                        /* Dump the attributes */
@@ -15624,26 +15619,30 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                 */
                                if (shouldPrintColumn(dopt, tbinfo, j))
                                {
+                                       bool            print_default;
+                                       bool            print_notnull;
+
                                        /*
                                         * Default value --- suppress if to be printed separately.
                                         */
-                                       bool            has_default = (tbinfo->attrdefs[j] != NULL &&
-                                                                                          !tbinfo->attrdefs[j]->separate);
+                                       print_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.
+                                        * if partition, or in binary-upgrade case where that
+                                        * won't work.
                                         */
-                                       bool            has_notnull = (tbinfo->notnull[j] &&
-                                                                                          (!tbinfo->inhNotNull[j] ||
-                                                                                               dopt->binary_upgrade));
+                                       print_notnull = (tbinfo->notnull[j] &&
+                                                                        (!tbinfo->inhNotNull[j] ||
+                                                                         tbinfo->ispartition || dopt->binary_upgrade));
 
                                        /*
-                                        * Skip column if fully defined by reloftype or the
-                                        * partition parent.
+                                        * Skip column if fully defined by reloftype, except in
+                                        * binary upgrade
                                         */
-                                       if ((tbinfo->reloftype || tbinfo->ispartition) &&
-                                               !has_default && !has_notnull && !dopt->binary_upgrade)
+                                       if (tbinfo->reloftype && !print_default && !print_notnull &&
+                                               !dopt->binary_upgrade)
                                                continue;
 
                                        /* Format properly if not first attr */
@@ -15666,25 +15665,35 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                 * clean things up later.
                                                 */
                                                appendPQExpBufferStr(q, " INTEGER /* dummy */");
-                                               /* Skip all the rest, too */
+                                               /* and skip to the next column */
                                                continue;
                                        }
 
                                        /*
-                                        * Attribute type
-                                        *
-                                        * In binary-upgrade mode, we always include the type. If
-                                        * we aren't in binary-upgrade mode, then we skip the type
-                                        * when creating a typed table ('OF type_name') or a
-                                        * partition ('PARTITION OF'), since the type comes from
-                                        * the parent/partitioned table.
+                                        * Attribute type; print it except when creating a typed
+                                        * table ('OF type_name'), but in binary-upgrade mode,
+                                        * print it in that case too.
                                         */
-                                       if (dopt->binary_upgrade || (!tbinfo->reloftype && !tbinfo->ispartition))
+                                       if (dopt->binary_upgrade || !tbinfo->reloftype)
                                        {
                                                appendPQExpBuffer(q, " %s",
                                                                                  tbinfo->atttypnames[j]);
                                        }
 
+                                       if (print_default)
+                                       {
+                                               if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
+                                                       appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
+                                                                                         tbinfo->attrdefs[j]->adef_expr);
+                                               else
+                                                       appendPQExpBuffer(q, " DEFAULT %s",
+                                                                                         tbinfo->attrdefs[j]->adef_expr);
+                                       }
+
+
+                                       if (print_notnull)
+                                               appendPQExpBufferStr(q, " NOT NULL");
+
                                        /* Add collation if not default for the type */
                                        if (OidIsValid(tbinfo->attcollation[j]))
                                        {
@@ -15695,24 +15704,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                        appendPQExpBuffer(q, " COLLATE %s",
                                                                                          fmtQualifiedDumpable(coll));
                                        }
-
-                                       if (has_default)
-                                               appendPQExpBuffer(q, " DEFAULT %s",
-                                                                                 tbinfo->attrdefs[j]->adef_expr);
-
-                                       if (has_notnull)
-                                               appendPQExpBufferStr(q, " NOT NULL");
                                }
                        }
 
                        /*
                         * Add non-inherited CHECK constraints, if any.
+                        *
+                        * For partitions, we need to include check constraints even if
+                        * they're not defined locally, because the ALTER TABLE ATTACH
+                        * PARTITION that we'll emit later expects the constraint to be
+                        * there.  (No need to fix conislocal: ATTACH PARTITION does that)
                         */
                        for (j = 0; j < tbinfo->ncheck; j++)
                        {
                                ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
 
-                               if (constr->separate || !constr->conislocal)
+                               if (constr->separate ||
+                                       (!constr->conislocal && !tbinfo->ispartition))
                                        continue;
 
                                if (actual_atts == 0)
@@ -15729,25 +15737,20 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                        if (actual_atts)
                                appendPQExpBufferStr(q, "\n)");
-                       else if (!((tbinfo->reloftype || tbinfo->ispartition) &&
-                                          !dopt->binary_upgrade))
+                       else if (!(tbinfo->reloftype && !dopt->binary_upgrade))
                        {
                                /*
-                                * We must have a parenthesized attribute list, even though
-                                * empty, when not using the OF TYPE or PARTITION OF syntax.
+                                * No attributes? we must have a parenthesized attribute list,
+                                * even though empty, when not using the OF TYPE syntax.
                                 */
                                appendPQExpBufferStr(q, " (\n)");
                        }
 
-                       if (tbinfo->ispartition && !dopt->binary_upgrade)
-                       {
-                               appendPQExpBufferChar(q, '\n');
-                               appendPQExpBufferStr(q, tbinfo->partbound);
-                       }
-
-                       /* Emit the INHERITS clause, except if this is a partition. */
-                       if (numParents > 0 &&
-                               !tbinfo->ispartition &&
+                       /*
+                        * Emit the INHERITS clause (not for partitions), except in
+                        * binary-upgrade mode.
+                        */
+                       if (numParents > 0 && !tbinfo->ispartition &&
                                !dopt->binary_upgrade)
                        {
                                appendPQExpBufferStr(q, "\nINHERITS (");
@@ -15898,11 +15901,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                }
                        }
 
+                       /*
+                        * Add inherited CHECK constraints, if any.
+                        *
+                        * For partitions, they were already dumped, and conislocal
+                        * doesn't need fixing.
+                        */
                        for (k = 0; k < tbinfo->ncheck; k++)
                        {
                                ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
 
-                               if (constr->separate || constr->conislocal)
+                               if (constr->separate || constr->conislocal || tbinfo->ispartition)
                                        continue;
 
                                appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
@@ -15920,30 +15929,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                        }
 
-                       if (numParents > 0)
+                       if (numParents > 0 && !tbinfo->ispartition)
                        {
-                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance and partitioning 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];
 
-                                       /* In the partitioning case, we alter the parent */
-                                       if (tbinfo->ispartition)
-                                               appendPQExpBuffer(q,
-                                                                                 "ALTER TABLE ONLY %s ATTACH PARTITION ",
-                                                                                 fmtQualifiedDumpable(parentRel));
-                                       else
-                                               appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
-                                                                                 qualrelname);
-
-                                       /* Partition needs specifying the bounds */
-                                       if (tbinfo->ispartition)
-                                               appendPQExpBuffer(q, "%s %s;\n",
-                                                                                 qualrelname,
-                                                                                 tbinfo->partbound);
-                                       else
-                                               appendPQExpBuffer(q, "%s;\n",
-                                                                                 fmtQualifiedDumpable(parentRel));
+                                       appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
+                                                                         qualrelname,
+                                                                         fmtQualifiedDumpable(parentRel));
                                }
                        }
 
@@ -15956,6 +15951,27 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        }
                }
 
+               /*
+                * For partitioned tables, emit the ATTACH PARTITION clause.  Note
+                * that we always want to create partitions this way instead of using
+                * CREATE TABLE .. PARTITION OF, mainly to preserve a possible column
+                * layout discrepancy with the parent, but also to ensure it gets the
+                * correct tablespace setting if it differs from the parent's.
+                */
+               if (tbinfo->ispartition)
+               {
+                       /* With partitions there can only be one parent */
+                       if (tbinfo->numParents != 1)
+                               fatal("invalid number of parents %d for table \"%s\"",
+                                         tbinfo->numParents, tbinfo->dobj.name);
+
+                       /* Perform ALTER TABLE on the parent */
+                       appendPQExpBuffer(q,
+                                                         "ALTER TABLE ONLY %s ATTACH PARTITION %s %s;\n",
+                                                         fmtQualifiedDumpable(parents[0]),
+                                                         qualrelname, tbinfo->partbound);
+               }
+
                /*
                 * In binary_upgrade mode, arrange to restore the old relfrozenxid and
                 * relminmxid of all vacuumable relations.  (While vacuum.c processes
@@ -16154,7 +16170,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
        if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
        {
-               char *tableam = NULL;
+               char       *tableam = NULL;
 
                if (tbinfo->relkind == RELKIND_RELATION ||
                        tbinfo->relkind == RELKIND_MATVIEW)
@@ -16283,8 +16299,8 @@ getAttrName(int attrnum, TableInfo *tblInfo)
                case TableOidAttributeNumber:
                        return "tableoid";
        }
-       exit_horribly(NULL, "invalid column number %d for table \"%s\"\n",
-                                 attrnum, tblInfo->dobj.name);
+       fatal("invalid column number %d for table \"%s\"",
+                 attrnum, tblInfo->dobj.name);
        return NULL;                            /* keep compiler quiet */
 }
 
@@ -16442,10 +16458,8 @@ dumpIndexAttach(Archive *fout, IndexAttachInfo *attachinfo)
                                         ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                                                                  .namespace = attachinfo->dobj.namespace->dobj.name,
                                                                  .description = "INDEX ATTACH",
-                                                                 .owner = "",
                                                                  .section = SECTION_POST_DATA,
-                                                                 .createStmt = q->data,
-                                                                 .dropStmt = ""));
+                                                                 .createStmt = q->data));
 
                destroyPQExpBuffer(q);
        }
@@ -16547,8 +16561,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
 
                if (indxinfo == NULL)
-                       exit_horribly(NULL, "missing index for constraint \"%s\"\n",
-                                                 coninfo->dobj.name);
+                       fatal("missing index for constraint \"%s\"",
+                                 coninfo->dobj.name);
 
                if (dopt->binary_upgrade)
                        binary_upgrade_set_pg_class_oids(fout, q,
@@ -16583,7 +16597,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                        }
 
                        if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
-                               appendPQExpBuffer(q, ") INCLUDE (");
+                               appendPQExpBufferStr(q, ") INCLUDE (");
 
                        for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
                        {
@@ -16767,8 +16781,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
        }
        else
        {
-               exit_horribly(NULL, "unrecognized constraint type: %c\n",
-                                         coninfo->contype);
+               fatal("unrecognized constraint type: %c",
+                         coninfo->contype);
        }
 
        /* Dump Constraint Comments --- only works for table constraints */
@@ -16899,10 +16913,10 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
        if (PQntuples(res) != 1)
        {
-               write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
-                                                                "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
-                                                                PQntuples(res)),
-                                 tbinfo->dobj.name, PQntuples(res));
+               pg_log_error(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
+                                                         "query to get data of sequence \"%s\" returned %d rows (expected 1)",
+                                                         PQntuples(res)),
+                                        tbinfo->dobj.name, PQntuples(res));
                exit_nicely(1);
        }
 
@@ -16933,7 +16947,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        }
        else
        {
-               exit_horribly(NULL, "unrecognized sequence type: %s\n", seqtype);
+               fatal("unrecognized sequence type: %s", seqtype);
                default_minv = default_maxv = 0;        /* keep compiler quiet */
        }
 
@@ -16980,9 +16994,9 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                                  "ALTER COLUMN %s ADD GENERATED ",
                                                  fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
                if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
-                       appendPQExpBuffer(query, "ALWAYS");
+                       appendPQExpBufferStr(query, "ALWAYS");
                else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
-                       appendPQExpBuffer(query, "BY DEFAULT");
+                       appendPQExpBufferStr(query, "BY DEFAULT");
                appendPQExpBuffer(query, " AS IDENTITY (\n    SEQUENCE NAME %s\n",
                                                  fmtQualifiedDumpable(tbinfo));
        }
@@ -17054,8 +17068,8 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                TableInfo  *owning_tab = findTableByOid(tbinfo->owning_tab);
 
                if (owning_tab == NULL)
-                       exit_horribly(NULL, "failed sanity check, parent table with OID %u of sequence with OID %u not found\n",
-                                                 tbinfo->owning_tab, tbinfo->dobj.catId.oid);
+                       fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
+                                 tbinfo->owning_tab, tbinfo->dobj.catId.oid);
 
                if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
                {
@@ -17075,7 +17089,6 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                                                                  .description = "SEQUENCE OWNED BY",
                                                                                  .section = SECTION_PRE_DATA,
                                                                                  .createStmt = query->data,
-                                                                                 .dropStmt = "",
                                                                                  .deps = &(tbinfo->dobj.dumpId),
                                                                                  .nDeps = 1));
                }
@@ -17120,10 +17133,10 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
 
        if (PQntuples(res) != 1)
        {
-               write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
-                                                                "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
-                                                                PQntuples(res)),
-                                 tbinfo->dobj.name, PQntuples(res));
+               pg_log_error(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
+                                                         "query to get data of sequence \"%s\" returned %d rows (expected 1)",
+                                                         PQntuples(res)),
+                                        tbinfo->dobj.name, PQntuples(res));
                exit_nicely(1);
        }
 
@@ -17144,7 +17157,6 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
                                                                  .description = "SEQUENCE SET",
                                                                  .section = SECTION_DATA,
                                                                  .createStmt = query->data,
-                                                                 .dropStmt = "",
                                                                  .deps = &(tbinfo->dobj.dumpId),
                                                                  .nDeps = 1));
 
@@ -17217,7 +17229,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                        appendPQExpBufferStr(query, "INSTEAD OF");
                else
                {
-                       write_msg(NULL, "unexpected tgtype value: %d\n", tginfo->tgtype);
+                       pg_log_error("unexpected tgtype value: %d", tginfo->tgtype);
                        exit_nicely(1);
                }
 
@@ -17291,10 +17303,10 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                        if (p + tlen >= tgargs + lentgargs)
                        {
                                /* hm, not found before end of bytea value... */
-                               write_msg(NULL, "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n",
-                                                 tginfo->tgargs,
-                                                 tginfo->dobj.name,
-                                                 tbinfo->dobj.name);
+                               pg_log_error("invalid argument string (%s) for trigger \"%s\" on table \"%s\"",
+                                                        tginfo->tgargs,
+                                                        tginfo->dobj.name,
+                                                        tbinfo->dobj.name);
                                exit_nicely(1);
                        }
 
@@ -17520,8 +17532,8 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 
                if (PQntuples(res) != 1)
                {
-                       write_msg(NULL, "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n",
-                                         rinfo->dobj.name, tbinfo->dobj.name);
+                       pg_log_error("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
+                                                rinfo->dobj.name, tbinfo->dobj.name);
                        exit_nicely(1);
                }
 
@@ -17682,7 +17694,7 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
                if (ext == NULL)
                {
                        /* shouldn't happen */
-                       fprintf(stderr, "could not find referenced extension %u\n", extId);
+                       pg_log_warning("could not find referenced extension %u", extId);
                        continue;
                }
 
@@ -17894,20 +17906,57 @@ getDependencies(Archive *fout)
        DumpableObject *dobj,
                           *refdobj;
 
-       if (g_verbose)
-               write_msg(NULL, "reading dependency data\n");
+       pg_log_info("reading dependency data");
 
        query = createPQExpBuffer();
 
        /*
+        * Messy query to collect the dependency data we need.  Note that we
+        * ignore the sub-object column, so that dependencies of or on a column
+        * look the same as dependencies of or on a whole table.
+        *
         * PIN dependencies aren't interesting, and EXTENSION dependencies were
         * already processed by getExtensionMembership.
         */
        appendPQExpBufferStr(query, "SELECT "
                                                 "classid, objid, refclassid, refobjid, deptype "
                                                 "FROM pg_depend "
-                                                "WHERE deptype != 'p' AND deptype != 'e' "
-                                                "ORDER BY 1,2");
+                                                "WHERE deptype != 'p' AND deptype != 'e'\n");
+
+       /*
+        * Since we don't treat pg_amop entries as separate DumpableObjects, we
+        * have to translate their dependencies into dependencies of their parent
+        * opfamily.  Ignore internal dependencies though, as those will point to
+        * their parent opclass, which we needn't consider here (and if we did,
+        * it'd just result in circular dependencies).  Also, "loose" opfamily
+        * entries will have dependencies on their parent opfamily, which we
+        * should drop since they'd likewise become useless self-dependencies.
+        * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
+        *
+        * Skip this for pre-8.3 source servers: pg_opfamily doesn't exist there,
+        * and the (known) cases where it would matter to have these dependencies
+        * can't arise anyway.
+        */
+       if (fout->remoteVersion >= 80300)
+       {
+               appendPQExpBufferStr(query, "UNION ALL\n"
+                                                        "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
+                                                        "FROM pg_depend d, pg_amop o "
+                                                        "WHERE deptype NOT IN ('p', 'e', 'i') AND "
+                                                        "classid = 'pg_amop'::regclass AND objid = o.oid "
+                                                        "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
+
+               /* Likewise for pg_amproc entries */
+               appendPQExpBufferStr(query, "UNION ALL\n"
+                                                        "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
+                                                        "FROM pg_depend d, pg_amproc p "
+                                                        "WHERE deptype NOT IN ('p', 'e', 'i') AND "
+                                                        "classid = 'pg_amproc'::regclass AND objid = p.oid "
+                                                        "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
+       }
+
+       /* Sort the output for efficiency below */
+       appendPQExpBufferStr(query, "ORDER BY 1,2");
 
        res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -17950,8 +17999,8 @@ getDependencies(Archive *fout)
                if (dobj == NULL)
                {
 #ifdef NOT_USED
-                       fprintf(stderr, "no referencing object %u %u\n",
-                                       objId.tableoid, objId.oid);
+                       pg_log_warning("no referencing object %u %u",
+                                                  objId.tableoid, objId.oid);
 #endif
                        continue;
                }
@@ -17961,8 +18010,8 @@ getDependencies(Archive *fout)
                if (refdobj == NULL)
                {
 #ifdef NOT_USED
-                       fprintf(stderr, "no referenced object %u %u\n",
-                                       refobjId.tableoid, refobjId.oid);
+                       pg_log_warning("no referenced object %u %u",
+                                                  refobjId.tableoid, refobjId.oid);
 #endif
                        continue;
                }
@@ -18280,6 +18329,7 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
        int                     numatts = ti->numatts;
        char      **attnames = ti->attnames;
        bool       *attisdropped = ti->attisdropped;
+       char       *attgenerated = ti->attgenerated;
        bool            needComma;
        int                     i;
 
@@ -18289,6 +18339,8 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
        {
                if (attisdropped[i])
                        continue;
+               if (attgenerated[i])
+                       continue;
                if (needComma)
                        appendPQExpBufferStr(buffer, ", ");
                appendPQExpBufferStr(buffer, fmtId(attnames[i]));
@@ -18326,5 +18378,5 @@ appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
        res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
                                                                fout->std_strings);
        if (!res)
-               write_msg(NULL, "WARNING: could not parse reloptions array\n");
+               pg_log_warning("could not parse reloptions array");
 }