Avoid using unsafe search_path settings during dump and restore.
authorTom Lane <[email protected]>
Mon, 26 Feb 2018 15:18:21 +0000 (10:18 -0500)
committerTom Lane <[email protected]>
Mon, 26 Feb 2018 15:18:21 +0000 (10:18 -0500)
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object.  This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run.  That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.

This patch changes pg_dump so that it does not change the search_path
dynamically.  The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter.  Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.

Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.

Security: CVE-2018-1058

16 files changed:
src/backend/utils/adt/ruleutils.c
src/bin/pg_dump/dumputils.c
src/bin/pg_dump/dumputils.h
src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_archiver.h
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dumpall.c
src/bin/pg_dump/t/002_pg_dump.pl
src/test/modules/test_pg_dump/t/001_base.pl
src/test/regress/expected/collate.icu.utf8.out
src/test/regress/expected/collate.linux.utf8.out
src/test/regress/expected/collate.out
src/test/regress/expected/indexing.out
src/test/regress/expected/rules.out
src/test/regress/expected/triggers.out

index ba9fab4582fdd0601a982762c2e9e8718ea6e573..36974667892ce7dc3d794581ba683895903c1f6c 100644 (file)
 #define PRETTYINDENT_LIMIT             40      /* wrap limit */
 
 /* Pretty flags */
-#define PRETTYFLAG_PAREN               1
-#define PRETTYFLAG_INDENT              2
+#define PRETTYFLAG_PAREN               0x0001
+#define PRETTYFLAG_INDENT              0x0002
+#define PRETTYFLAG_SCHEMA              0x0004
 
 /* Default line length for pretty-print wrapping: 0 means wrap always */
 #define WRAP_COLUMN_DEFAULT            0
 
-/* macro to test if pretty action needed */
+/* macros to test if pretty action needed */
 #define PRETTY_PAREN(context)  ((context)->prettyFlags & PRETTYFLAG_PAREN)
 #define PRETTY_INDENT(context) ((context)->prettyFlags & PRETTYFLAG_INDENT)
+#define PRETTY_SCHEMA(context) ((context)->prettyFlags & PRETTYFLAG_SCHEMA)
 
 
 /* ----------
@@ -499,7 +501,7 @@ pg_get_ruledef_ext(PG_FUNCTION_ARGS)
        int                     prettyFlags;
        char       *res;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
 
        res = pg_get_ruledef_worker(ruleoid, prettyFlags);
 
@@ -620,7 +622,7 @@ pg_get_viewdef_ext(PG_FUNCTION_ARGS)
        int                     prettyFlags;
        char       *res;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
 
        res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
 
@@ -640,7 +642,7 @@ pg_get_viewdef_wrap(PG_FUNCTION_ARGS)
        char       *res;
 
        /* calling this implies we want pretty printing */
-       prettyFlags = PRETTYFLAG_PAREN | PRETTYFLAG_INDENT;
+       prettyFlags = PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA;
 
        res = pg_get_viewdef_worker(viewoid, prettyFlags, wrap);
 
@@ -686,7 +688,7 @@ pg_get_viewdef_name_ext(PG_FUNCTION_ARGS)
        Oid                     viewoid;
        char       *res;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
 
        /* Look up view name.  Can't lock it - we might not have privileges. */
        viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname));
@@ -922,8 +924,15 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
                        appendStringInfoString(&buf, " TRUNCATE");
                findx++;
        }
+
+       /*
+        * In non-pretty mode, always schema-qualify the target table name for
+        * safety.  In pretty mode, schema-qualify only if not visible.
+        */
        appendStringInfo(&buf, " ON %s ",
-                                        generate_relation_name(trigrec->tgrelid, NIL));
+                                        pretty ?
+                                        generate_relation_name(trigrec->tgrelid, NIL) :
+                                        generate_qualified_relation_name(trigrec->tgrelid));
 
        if (OidIsValid(trigrec->tgconstraint))
        {
@@ -1017,7 +1026,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
                context.windowClause = NIL;
                context.windowTList = NIL;
                context.varprefix = true;
-               context.prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+               context.prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
                context.wrapColumn = WRAP_COLUMN_DEFAULT;
                context.indentLevel = PRETTYINDENT_STD;
                context.special_exprkind = EXPR_KIND_NONE;
@@ -1104,7 +1113,7 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS)
        int                     prettyFlags;
        char       *res;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
 
        res = pg_get_indexdef_worker(indexrelid, colno, NULL, colno != 0, false,
                                                                 false, prettyFlags, true);
@@ -1132,7 +1141,8 @@ pg_get_indexdef_columns(Oid indexrelid, bool pretty)
 {
        int                     prettyFlags;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
+
        return pg_get_indexdef_worker(indexrelid, 0, NULL, true, false, false,
                                                                  prettyFlags, false);
 }
@@ -1264,7 +1274,9 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
                                                         quote_identifier(NameStr(idxrelrec->relname)),
                                                         idxrelrec->relkind == RELKIND_PARTITIONED_INDEX
                                                         && !inherits ? "ONLY " : "",
-                                                        generate_relation_name(indrelid, NIL),
+                                                        (prettyFlags & PRETTYFLAG_SCHEMA) ?
+                                                        generate_relation_name(indrelid, NIL) :
+                                                        generate_qualified_relation_name(indrelid),
                                                         quote_identifier(NameStr(amrec->amname)));
                else                                    /* currently, must be EXCLUDE constraint */
                        appendStringInfo(&buf, "EXCLUDE USING %s (",
@@ -1575,7 +1587,8 @@ pg_get_partkeydef_columns(Oid relid, bool pretty)
 {
        int                     prettyFlags;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
+
        return pg_get_partkeydef_worker(relid, prettyFlags, true, false);
 }
 
@@ -1803,7 +1816,7 @@ pg_get_constraintdef_ext(PG_FUNCTION_ARGS)
        int                     prettyFlags;
        char       *res;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
 
        res = pg_get_constraintdef_worker(constraintId, false, prettyFlags, true);
 
@@ -2258,7 +2271,7 @@ pg_get_expr_ext(PG_FUNCTION_ARGS)
        int                     prettyFlags;
        char       *relname;
 
-       prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
+       prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
 
        if (OidIsValid(relid))
        {
@@ -4709,7 +4722,10 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
        }
 
        /* The relation the rule is fired on */
-       appendStringInfo(buf, " TO %s", generate_relation_name(ev_class, NIL));
+       appendStringInfo(buf, " TO %s",
+                                        (prettyFlags & PRETTYFLAG_SCHEMA) ?
+                                        generate_relation_name(ev_class, NIL) :
+                                        generate_qualified_relation_name(ev_class));
 
        /* If the rule has an event qualification, add it */
        if (ev_qual == NULL)
index 7afddc315331da20dcbf19c309377fd4788d8f47..7f5bb1343e01617e52475e0a2c70cd662c041ab3 100644 (file)
@@ -32,6 +32,7 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
  *
  *     name: the object name, in the form to use in the commands (already quoted)
  *     subname: the sub-object name, if any (already quoted); NULL if none
+ *     nspname: the namespace the object is in (NULL if none); not pre-quoted
  *     type: the object type (as seen in GRANT command: must be one of
  *             TABLE, SEQUENCE, FUNCTION, PROCEDURE, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
  *             FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT)
@@ -52,7 +53,7 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
  * since this routine uses fmtId() internally.
  */
 bool
-buildACLCommands(const char *name, const char *subname,
+buildACLCommands(const char *name, const char *subname, const char *nspname,
                                 const char *type, const char *acls, const char *racls,
                                 const char *owner, const char *prefix, int remoteVersion,
                                 PQExpBuffer sql)
@@ -152,7 +153,10 @@ buildACLCommands(const char *name, const char *subname,
                appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix);
                if (subname)
                        appendPQExpBuffer(firstsql, "(%s)", subname);
-               appendPQExpBuffer(firstsql, " ON %s %s FROM PUBLIC;\n", type, name);
+               appendPQExpBuffer(firstsql, " ON %s ", type);
+               if (nspname && *nspname)
+                       appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+               appendPQExpBuffer(firstsql, "%s FROM PUBLIC;\n", name);
        }
        else
        {
@@ -170,8 +174,11 @@ buildACLCommands(const char *name, const char *subname,
                        {
                                if (privs->len > 0)
                                {
-                                       appendPQExpBuffer(firstsql, "%sREVOKE %s ON %s %s FROM ",
-                                                                         prefix, privs->data, type, name);
+                                       appendPQExpBuffer(firstsql, "%sREVOKE %s ON %s ",
+                                                                         prefix, privs->data, type);
+                                       if (nspname && *nspname)
+                                               appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+                                       appendPQExpBuffer(firstsql, "%s FROM ", name);
                                        if (grantee->len == 0)
                                                appendPQExpBufferStr(firstsql, "PUBLIC;\n");
                                        else if (strncmp(grantee->data, "group ",
@@ -185,8 +192,11 @@ buildACLCommands(const char *name, const char *subname,
                                if (privswgo->len > 0)
                                {
                                        appendPQExpBuffer(firstsql,
-                                                                         "%sREVOKE GRANT OPTION FOR %s ON %s %s FROM ",
-                                                                         prefix, privswgo->data, type, name);
+                                                                         "%sREVOKE GRANT OPTION FOR %s ON %s ",
+                                                                         prefix, privswgo->data, type);
+                                       if (nspname && *nspname)
+                                               appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+                                       appendPQExpBuffer(firstsql, "%s FROM ", name);
                                        if (grantee->len == 0)
                                                appendPQExpBufferStr(firstsql, "PUBLIC");
                                        else if (strncmp(grantee->data, "group ",
@@ -251,18 +261,33 @@ buildACLCommands(const char *name, const char *subname,
                                        appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix);
                                        if (subname)
                                                appendPQExpBuffer(firstsql, "(%s)", subname);
-                                       appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n",
-                                                                         type, name, fmtId(grantee->data));
+                                       appendPQExpBuffer(firstsql, " ON %s ", type);
+                                       if (nspname && *nspname)
+                                               appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+                                       appendPQExpBuffer(firstsql, "%s FROM %s;\n",
+                                                                         name, fmtId(grantee->data));
                                        if (privs->len > 0)
+                                       {
                                                appendPQExpBuffer(firstsql,
-                                                                                 "%sGRANT %s ON %s %s TO %s;\n",
-                                                                                 prefix, privs->data, type, name,
-                                                                                 fmtId(grantee->data));
+                                                                                 "%sGRANT %s ON %s ",
+                                                                                 prefix, privs->data, type);
+                                               if (nspname && *nspname)
+                                                       appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+                                               appendPQExpBuffer(firstsql,
+                                                                                 "%s TO %s;\n",
+                                                                                 name, fmtId(grantee->data));
+                                       }
                                        if (privswgo->len > 0)
+                                       {
                                                appendPQExpBuffer(firstsql,
-                                                                                 "%sGRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
-                                                                                 prefix, privswgo->data, type, name,
-                                                                                 fmtId(grantee->data));
+                                                                                 "%sGRANT %s ON %s ",
+                                                                                 prefix, privswgo->data, type);
+                                               if (nspname && *nspname)
+                                                       appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+                                               appendPQExpBuffer(firstsql,
+                                                                                 "%s TO %s WITH GRANT OPTION;\n",
+                                                                                 name, fmtId(grantee->data));
+                                       }
                                }
                        }
                        else
@@ -284,8 +309,11 @@ buildACLCommands(const char *name, const char *subname,
 
                                if (privs->len > 0)
                                {
-                                       appendPQExpBuffer(secondsql, "%sGRANT %s ON %s %s TO ",
-                                                                         prefix, privs->data, type, name);
+                                       appendPQExpBuffer(secondsql, "%sGRANT %s ON %s ",
+                                                                         prefix, privs->data, type);
+                                       if (nspname && *nspname)
+                                               appendPQExpBuffer(secondsql, "%s.", fmtId(nspname));
+                                       appendPQExpBuffer(secondsql, "%s TO ", name);
                                        if (grantee->len == 0)
                                                appendPQExpBufferStr(secondsql, "PUBLIC;\n");
                                        else if (strncmp(grantee->data, "group ",
@@ -297,8 +325,11 @@ buildACLCommands(const char *name, const char *subname,
                                }
                                if (privswgo->len > 0)
                                {
-                                       appendPQExpBuffer(secondsql, "%sGRANT %s ON %s %s TO ",
-                                                                         prefix, privswgo->data, type, name);
+                                       appendPQExpBuffer(secondsql, "%sGRANT %s ON %s ",
+                                                                         prefix, privswgo->data, type);
+                                       if (nspname && *nspname)
+                                               appendPQExpBuffer(secondsql, "%s.", fmtId(nspname));
+                                       appendPQExpBuffer(secondsql, "%s TO ", name);
                                        if (grantee->len == 0)
                                                appendPQExpBufferStr(secondsql, "PUBLIC");
                                        else if (strncmp(grantee->data, "group ",
@@ -328,8 +359,11 @@ buildACLCommands(const char *name, const char *subname,
                appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix);
                if (subname)
                        appendPQExpBuffer(firstsql, "(%s)", subname);
-               appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n",
-                                                 type, name, fmtId(owner));
+               appendPQExpBuffer(firstsql, " ON %s ", type);
+               if (nspname && *nspname)
+                       appendPQExpBuffer(firstsql, "%s.", fmtId(nspname));
+               appendPQExpBuffer(firstsql, "%s FROM %s;\n",
+                                                 name, fmtId(owner));
        }
 
        destroyPQExpBuffer(grantee);
@@ -388,7 +422,8 @@ buildDefaultACLCommands(const char *type, const char *nspname,
        if (strlen(initacls) != 0 || strlen(initracls) != 0)
        {
                appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
-               if (!buildACLCommands("", NULL, type, initacls, initracls, owner,
+               if (!buildACLCommands("", NULL, NULL, type,
+                                                         initacls, initracls, owner,
                                                          prefix->data, remoteVersion, sql))
                {
                        destroyPQExpBuffer(prefix);
@@ -397,7 +432,8 @@ buildDefaultACLCommands(const char *type, const char *nspname,
                appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
        }
 
-       if (!buildACLCommands("", NULL, type, acls, racls, owner,
+       if (!buildACLCommands("", NULL, NULL, type,
+                                                 acls, racls, owner,
                                                  prefix->data, remoteVersion, sql))
        {
                destroyPQExpBuffer(prefix);
@@ -641,26 +677,32 @@ AddAcl(PQExpBuffer aclbuf, const char *keyword, const char *subname)
  * buildShSecLabelQuery
  *
  * Build a query to retrieve security labels for a shared object.
+ * The object is identified by its OID plus the name of the catalog
+ * it can be found in (e.g., "pg_database" for database names).
+ * The query is appended to "sql".  (We don't execute it here so as to
+ * keep this file free of assumptions about how to deal with SQL errors.)
  */
 void
-buildShSecLabelQuery(PGconn *conn, const char *catalog_name, uint32 objectId,
+buildShSecLabelQuery(PGconn *conn, const char *catalog_name, Oid objectId,
                                         PQExpBuffer sql)
 {
        appendPQExpBuffer(sql,
                                          "SELECT provider, label FROM pg_catalog.pg_shseclabel "
-                                         "WHERE classoid = '%s'::pg_catalog.regclass AND "
-                                         "objoid = %u", catalog_name, objectId);
+                                         "WHERE classoid = 'pg_catalog.%s'::pg_catalog.regclass "
+                                         "AND objoid = '%u'", catalog_name, objectId);
 }
 
 /*
  * emitShSecLabels
  *
- * Format security label data retrieved by the query generated in
- * buildShSecLabelQuery.
+ * Construct SECURITY LABEL commands using the data retrieved by the query
+ * generated by buildShSecLabelQuery, and append them to "buffer".
+ * Here, the target object is identified by its type name (e.g. "DATABASE")
+ * and its name (not pre-quoted).
  */
 void
 emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer,
-                               const char *target, const char *objname)
+                               const char *objtype, const char *objname)
 {
        int                     i;
 
@@ -672,7 +714,7 @@ emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer,
                /* must use fmtId result before calling it again */
                appendPQExpBuffer(buffer,
                                                  "SECURITY LABEL FOR %s ON %s",
-                                                 fmtId(provider), target);
+                                                 fmtId(provider), objtype);
                appendPQExpBuffer(buffer,
                                                  " %s IS ",
                                                  fmtId(objname));
index 23a0645be8a9010c5ba21c0d98ecd5669dde2231..a9e26ae72a8d2f8ce96cf0c7987c6c0c4784f1b2 100644 (file)
@@ -36,7 +36,7 @@
 #endif
 
 
-extern bool buildACLCommands(const char *name, const char *subname,
+extern bool buildACLCommands(const char *name, const char *subname, const char *nspname,
                                 const char *type, const char *acls, const char *racls,
                                 const char *owner, const char *prefix, int remoteVersion,
                                 PQExpBuffer sql);
@@ -47,9 +47,9 @@ extern bool buildDefaultACLCommands(const char *type, const char *nspname,
                                                int remoteVersion,
                                                PQExpBuffer sql);
 extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name,
-                                        uint32 objectId, PQExpBuffer sql);
+                                        Oid objectId, PQExpBuffer sql);
 extern void emitShSecLabels(PGconn *conn, PGresult *res,
-                               PQExpBuffer buffer, const char *target, const char *objname);
+                               PQExpBuffer buffer, const char *objtype, const char *objname);
 
 extern void buildACLQueries(PQExpBuffer acl_subquery, PQExpBuffer racl_subquery,
                                PQExpBuffer init_acl_subquery, PQExpBuffer init_racl_subquery,
index 520cd095d3e0af985ad746516e6b1e2f60a5b11c..ceedd481fb4740b5674413728ef4875086d60f80 100644 (file)
@@ -197,6 +197,9 @@ typedef struct Archive
        /* info needed for string escaping */
        int                     encoding;               /* libpq code for client_encoding */
        bool            std_strings;    /* standard_conforming_strings */
+
+       /* other important stuff */
+       char       *searchpath;         /* search_path to set during restore */
        char       *use_role;           /* Issue SET ROLE to this */
 
        /* error handling */
index a4deb53e3a89e256c1c3f8bd4d4aa0f6c38b0bd7..fc233a608f395c3acedc2de0be25677465c1b07f 100644 (file)
@@ -70,6 +70,7 @@ static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
 static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
 static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
 static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
+static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te);
 static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH);
 static RestorePass _tocEntryRestorePass(TocEntry *te);
 static bool _tocEntryIsACL(TocEntry *te);
@@ -900,7 +901,9 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
                                                ahprintf(AH, "TRUNCATE TABLE %s%s;\n\n",
                                                                 (PQserverVersion(AH->connection) >= 80400 ?
                                                                  "ONLY " : ""),
-                                                                fmtId(te->tag));
+                                                                fmtQualifiedId(PQserverVersion(AH->connection),
+                                                                                               te->namespace,
+                                                                                               te->tag));
                                        }
 
                                        /*
@@ -987,10 +990,10 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te)
        /*
         * Disable them.
         */
-       _selectOutputSchema(AH, te->namespace);
-
        ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
-                        fmtId(te->tag));
+                        fmtQualifiedId(PQserverVersion(AH->connection),
+                                                       te->namespace,
+                                                       te->tag));
 }
 
 static void
@@ -1015,10 +1018,10 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te)
        /*
         * Enable them.
         */
-       _selectOutputSchema(AH, te->namespace);
-
        ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
-                        fmtId(te->tag));
+                        fmtQualifiedId(PQserverVersion(AH->connection),
+                                                       te->namespace,
+                                                       te->tag));
 }
 
 /*
@@ -2711,6 +2714,8 @@ ReadToc(ArchiveHandle *AH)
                        processEncodingEntry(AH, te);
                else if (strcmp(te->desc, "STDSTRINGS") == 0)
                        processStdStringsEntry(AH, te);
+               else if (strcmp(te->desc, "SEARCHPATH") == 0)
+                       processSearchPathEntry(AH, te);
        }
 }
 
@@ -2758,6 +2763,16 @@ processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
                                          te->defn);
 }
 
+static void
+processSearchPathEntry(ArchiveHandle *AH, TocEntry *te)
+{
+       /*
+        * te->defn should contain a command to set search_path.  We just copy it
+        * verbatim for use later.
+        */
+       AH->public.searchpath = pg_strdup(te->defn);
+}
+
 static void
 StrictNamesCheck(RestoreOptions *ropt)
 {
@@ -2814,9 +2829,10 @@ _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
        teReqs          res = REQ_SCHEMA | REQ_DATA;
        RestoreOptions *ropt = AH->public.ropt;
 
-       /* ENCODING and STDSTRINGS items are treated specially */
+       /* These items are treated specially */
        if (strcmp(te->desc, "ENCODING") == 0 ||
-               strcmp(te->desc, "STDSTRINGS") == 0)
+               strcmp(te->desc, "STDSTRINGS") == 0 ||
+               strcmp(te->desc, "SEARCHPATH") == 0)
                return REQ_SPECIAL;
 
        /*
@@ -3117,6 +3133,10 @@ _doSetFixedOutputState(ArchiveHandle *AH)
        if (ropt && ropt->use_role)
                ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
 
+       /* Select the dump-time search_path */
+       if (AH->public.searchpath)
+               ahprintf(AH, "%s", AH->public.searchpath);
+
        /* Make sure function checking is disabled */
        ahprintf(AH, "SET check_function_bodies = false;\n");
 
@@ -3321,6 +3341,15 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
 {
        PQExpBuffer qry;
 
+       /*
+        * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
+        * that search_path rather than switching to entry-specific paths.
+        * Otherwise, it's an old archive that will not restore correctly unless
+        * we set the search_path as it's expecting.
+        */
+       if (AH->public.searchpath)
+               return;
+
        if (!schemaName || *schemaName == '\0' ||
                (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
                return;                                 /* no need to do anything */
@@ -3453,8 +3482,10 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
                strcmp(type, "SUBSCRIPTION") == 0 ||
                strcmp(type, "USER MAPPING") == 0)
        {
-               /* We already know that search_path was set properly */
-               appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
+               appendPQExpBuffer(buf, "%s ", type);
+               if (te->namespace && *te->namespace)
+                       appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
+               appendPQExpBufferStr(buf, fmtId(te->tag));
                return;
        }
 
index becfee6e8191527c4995df57efcbc1187a3b0a5b..8dd19159989ccf5f4fbae700660ce88239e6ef5f 100644 (file)
@@ -92,10 +92,12 @@ typedef z_stream *z_streamp;
                                                                                                         * indicator */
 #define K_VERS_1_12 MAKE_ARCHIVE_VERSION(1, 12, 0)     /* add separate BLOB
                                                                                                         * entries */
+#define K_VERS_1_13 MAKE_ARCHIVE_VERSION(1, 13, 0)     /* change search_path
+                                                                                                        * behavior */
 
 /* Current archive version number (the format we can output) */
 #define K_VERS_MAJOR 1
-#define K_VERS_MINOR 12
+#define K_VERS_MINOR 13
 #define K_VERS_REV 0
 #define K_VERS_SELF MAKE_ARCHIVE_VERSION(K_VERS_MAJOR, K_VERS_MINOR, K_VERS_REV);
 
index f7a079f0b1d6fa3cb310be5b8eb3f2cac52638fe..8b67ec1aa1d60c0b60808ce2a4d3da9e46b8f151 100644 (file)
@@ -132,6 +132,15 @@ char               g_comment_end[10];
 
 static const CatalogId nilCatalogId = {0, 0};
 
+/*
+ * Macro for producing quoted, schema-qualified name of a dumpable object.
+ * Note implicit dependence on "fout"; we should get rid of that argument.
+ */
+#define fmtQualifiedDumpable(obj) \
+       fmtQualifiedId(fout->remoteVersion, \
+                                  (obj)->dobj.namespace->dobj.name, \
+                                  (obj)->dobj.name)
+
 static void help(const char *progname);
 static void setup_connection(Archive *AH,
                                 const char *dumpencoding, const char *dumpsnapshot,
@@ -149,13 +158,13 @@ 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 *target,
+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);
 static int     collectComments(Archive *fout, CommentItem **items);
-static void dumpSecLabel(Archive *fout, const char *target,
+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,
@@ -210,7 +219,7 @@ 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 *tag, const char *nspname, const char *owner,
+               const char *nspname, const char *owner,
                const char *acls, const char *racls,
                const char *initacls, const char *initracls);
 
@@ -239,10 +248,9 @@ static char *format_function_signature(Archive *fout,
                                                  FuncInfo *finfo, bool honor_quotes);
 static char *convertRegProcReference(Archive *fout,
                                                const char *proc);
-static char *convertOperatorReference(Archive *fout, const char *opr);
+static char *getFormattedOperatorName(Archive *fout, const char *oproid);
 static char *convertTSFunction(Archive *fout, Oid funcOid);
 static Oid     findLastBuiltinOid_V71(Archive *fout, const char *);
-static void selectSourceSchema(Archive *fout, const char *schemaName);
 static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
 static void getBlobs(Archive *fout);
 static void dumpBlob(Archive *fout, BlobInfo *binfo);
@@ -256,6 +264,7 @@ static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
                                   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,
@@ -267,7 +276,9 @@ static void binary_upgrade_set_pg_class_oids(Archive *fout,
                                                                 Oid pg_class_oid, bool is_index);
 static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                                                                DumpableObject *dobj,
-                                                               const char *objlabel);
+                                                               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);
@@ -844,9 +855,10 @@ main(int argc, char **argv)
         * order.
         */
 
-       /* First the special ENCODING and STDSTRINGS entries. */
+       /* First the special ENCODING, STDSTRINGS, and SEARCHPATH entries. */
        dumpEncoding(fout);
        dumpStdStrings(fout);
+       dumpSearchPath(fout);
 
        /* The database items are always next, unless we don't want them at all */
        if (dopt.outputCreateDB)
@@ -1733,14 +1745,6 @@ dumpTableData_copy(Archive *fout, void *dcontext)
                write_msg(NULL, "dumping contents of table \"%s.%s\"\n",
                                  tbinfo->dobj.namespace->dobj.name, classname);
 
-       /*
-        * Make sure we are in proper schema.  We will qualify the table name
-        * below anyway (in case its name conflicts with a pg_catalog table); but
-        * this ensures reproducible results in case the table contains regproc,
-        * regclass, etc columns.
-        */
-       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
        /*
         * Specify the column list explicitly so that we have no possibility of
         * retrieving data in the wrong column order.  (The default column
@@ -1752,9 +1756,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        if (oids && hasoids)
        {
                appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
-                                                 fmtQualifiedId(fout->remoteVersion,
-                                                                                tbinfo->dobj.namespace->dobj.name,
-                                                                                classname),
+                                                 fmtQualifiedDumpable(tbinfo),
                                                  column_list);
        }
        else if (tdinfo->filtercond)
@@ -1770,17 +1772,13 @@ dumpTableData_copy(Archive *fout, void *dcontext)
                else
                        appendPQExpBufferStr(q, "* ");
                appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
-                                                 fmtQualifiedId(fout->remoteVersion,
-                                                                                tbinfo->dobj.namespace->dobj.name,
-                                                                                classname),
+                                                 fmtQualifiedDumpable(tbinfo),
                                                  tdinfo->filtercond);
        }
        else
        {
                appendPQExpBuffer(q, "COPY %s %s TO stdout;",
-                                                 fmtQualifiedId(fout->remoteVersion,
-                                                                                tbinfo->dobj.namespace->dobj.name,
-                                                                                classname),
+                                                 fmtQualifiedDumpable(tbinfo),
                                                  column_list);
        }
        res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
@@ -1890,7 +1888,6 @@ dumpTableData_insert(Archive *fout, void *dcontext)
 {
        TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
        TableInfo  *tbinfo = tdinfo->tdtable;
-       const char *classname = tbinfo->dobj.name;
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer insertStmt = NULL;
@@ -1899,19 +1896,9 @@ dumpTableData_insert(Archive *fout, void *dcontext)
        int                     nfields;
        int                     field;
 
-       /*
-        * Make sure we are in proper schema.  We will qualify the table name
-        * below anyway (in case its name conflicts with a pg_catalog table); but
-        * this ensures reproducible results in case the table contains regproc,
-        * regclass, etc columns.
-        */
-       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
        appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                          "SELECT * FROM ONLY %s",
-                                         fmtQualifiedId(fout->remoteVersion,
-                                                                        tbinfo->dobj.namespace->dobj.name,
-                                                                        classname));
+                                         fmtQualifiedDumpable(tbinfo));
        if (tdinfo->filtercond)
                appendPQExpBuffer(q, " %s", tdinfo->filtercond);
 
@@ -1933,6 +1920,8 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                         */
                        if (insertStmt == NULL)
                        {
+                               TableInfo  *targettab;
+
                                insertStmt = createPQExpBuffer();
 
                                /*
@@ -1941,25 +1930,12 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                 * through the root table.
                                 */
                                if (dopt->load_via_partition_root && tbinfo->ispartition)
-                               {
-                                       TableInfo  *parentTbinfo;
-
-                                       parentTbinfo = getRootTableInfo(tbinfo);
-
-                                       /*
-                                        * When we loading data through the root, we will qualify
-                                        * the table name. This is needed because earlier
-                                        * search_path will be set for the partition table.
-                                        */
-                                       classname = (char *) fmtQualifiedId(fout->remoteVersion,
-                                                                                                               parentTbinfo->dobj.namespace->dobj.name,
-                                                                                                               parentTbinfo->dobj.name);
-                               }
+                                       targettab = getRootTableInfo(tbinfo);
                                else
-                                       classname = fmtId(tbinfo->dobj.name);
+                                       targettab = tbinfo;
 
                                appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
-                                                                 classname);
+                                                                 fmtQualifiedDumpable(targettab));
 
                                /* corner case for zero-column table */
                                if (nfields == 0)
@@ -2135,17 +2111,10 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                        TableInfo  *parentTbinfo;
 
                        parentTbinfo = getRootTableInfo(tbinfo);
-
-                       /*
-                        * When we load data through the root, we will qualify the table
-                        * name, because search_path is set for the partition.
-                        */
-                       copyFrom = fmtQualifiedId(fout->remoteVersion,
-                                                                         parentTbinfo->dobj.namespace->dobj.name,
-                                                                         parentTbinfo->dobj.name);
+                       copyFrom = fmtQualifiedDumpable(parentTbinfo);
                }
                else
-                       copyFrom = fmtId(tbinfo->dobj.name);
+                       copyFrom = fmtQualifiedDumpable(tbinfo);
 
                /* must use 2 steps here 'cause fmtId is nonreentrant */
                appendPQExpBuffer(copyBuf, "COPY %s ",
@@ -2200,7 +2169,7 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
        q = createPQExpBuffer();
 
        appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
-                                         fmtId(tbinfo->dobj.name));
+                                         fmtQualifiedDumpable(tbinfo));
 
        if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                ArchiveEntry(fout,
@@ -2328,9 +2297,6 @@ buildMatViewRefreshDependencies(Archive *fout)
        if (fout->remoteVersion < 90300)
                return;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        query = createPQExpBuffer();
 
        appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
@@ -2592,9 +2558,6 @@ dumpDatabase(Archive *fout)
        if (g_verbose)
                write_msg(NULL, "saving database definition\n");
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /* Fetch the database-level properties for this database */
        if (fout->remoteVersion >= 90600)
        {
@@ -2770,7 +2733,7 @@ dumpDatabase(Archive *fout)
                                 NULL,                  /* Dumper */
                                 NULL);                 /* Dumper Arg */
 
-       /* Compute correct tag for comments etc */
+       /* Compute correct tag for archive entry */
        appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
 
        /* Dump DB comment if any */
@@ -2805,7 +2768,7 @@ dumpDatabase(Archive *fout)
        }
        else
        {
-               dumpComment(fout, labelq->data, NULL, dba,
+               dumpComment(fout, "DATABASE", qdatname, NULL, dba,
                                        dbCatId, 0, dbDumpId);
        }
 
@@ -2837,7 +2800,7 @@ dumpDatabase(Archive *fout)
         * (pg_init_privs) on databases.
         */
        dumpACL(fout, dbCatId, dbDumpId, "DATABASE",
-                       qdatname, NULL, labelq->data, NULL,
+                       qdatname, NULL, NULL,
                        dba, datacl, rdatacl, "", "");
 
        /*
@@ -3125,6 +3088,69 @@ dumpStdStrings(Archive *AH)
        destroyPQExpBuffer(qry);
 }
 
+/*
+ * dumpSearchPath: record the active search_path in the archive
+ */
+static void
+dumpSearchPath(Archive *AH)
+{
+       PQExpBuffer qry = createPQExpBuffer();
+       PQExpBuffer path = createPQExpBuffer();
+       PGresult   *res;
+       char      **schemanames = NULL;
+       int                     nschemanames = 0;
+       int                     i;
+
+       /*
+        * We use the result of current_schemas(), not the search_path GUC,
+        * because that might contain wildcards such as "$user", which won't
+        * necessarily have the same value during restore.  Also, this way avoids
+        * listing schemas that may appear in search_path but not actually exist,
+        * which seems like a prudent exclusion.
+        */
+       res = ExecuteSqlQueryForSingleRow(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");
+
+       /*
+        * We use set_config(), not a simple "SET search_path" command, because
+        * the latter has less-clean behavior if the search path is empty.  While
+        * that's likely to get fixed at some point, it seems like a good idea to
+        * be as backwards-compatible as possible in what we put into archives.
+        */
+       for (i = 0; i < nschemanames; i++)
+       {
+               if (i > 0)
+                       appendPQExpBufferStr(path, ", ");
+               appendPQExpBufferStr(path, fmtId(schemanames[i]));
+       }
+
+       appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
+       appendStringLiteralAH(qry, path->data, AH);
+       appendPQExpBufferStr(qry, ", false);\n");
+
+       if (g_verbose)
+               write_msg(NULL, "saving search_path = %s\n", path->data);
+
+       ArchiveEntry(AH, nilCatalogId, createDumpId(),
+                                "SEARCHPATH", NULL, NULL, "",
+                                false, "SEARCHPATH", SECTION_PRE_DATA,
+                                qry->data, "", NULL,
+                                NULL, 0,
+                                NULL, NULL);
+
+       /* Also save it in AH->searchpath, in case we're doing plain text dump */
+       AH->searchpath = pg_strdup(qry->data);
+
+       if (schemanames)
+               free(schemanames);
+       PQclear(res);
+       destroyPQExpBuffer(qry);
+       destroyPQExpBuffer(path);
+}
+
 
 /*
  * getBlobs:
@@ -3151,9 +3177,6 @@ getBlobs(Archive *fout)
        if (g_verbose)
                write_msg(NULL, "reading large objects\n");
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /* Fetch BLOB OIDs, and owner/ACL data if >= 9.0 */
        if (fout->remoteVersion >= 90600)
        {
@@ -3300,26 +3323,22 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
                                         NULL, 0,
                                         NULL, NULL);
 
-       /* set up tag for comment and/or ACL */
-       resetPQExpBuffer(cquery);
-       appendPQExpBuffer(cquery, "LARGE OBJECT %s", binfo->dobj.name);
-
        /* Dump comment if any */
        if (binfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, cquery->data,
+               dumpComment(fout, "LARGE OBJECT", binfo->dobj.name,
                                        NULL, binfo->rolname,
                                        binfo->dobj.catId, 0, binfo->dobj.dumpId);
 
        /* Dump security label if any */
        if (binfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, cquery->data,
+               dumpSecLabel(fout, "LARGE OBJECT", binfo->dobj.name,
                                         NULL, binfo->rolname,
                                         binfo->dobj.catId, 0, binfo->dobj.dumpId);
 
        /* Dump ACL if any */
        if (binfo->blobacl && (binfo->dobj.dump & DUMP_COMPONENT_ACL))
                dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
-                               binfo->dobj.name, NULL, cquery->data,
+                               binfo->dobj.name, NULL,
                                NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
                                binfo->initblobacl, binfo->initrblobacl);
 
@@ -3346,9 +3365,6 @@ dumpBlobs(Archive *fout, void *arg)
        if (g_verbose)
                write_msg(NULL, "saving large objects\n");
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /*
         * Currently, we re-fetch all BLOB OIDs using a cursor.  Consider scanning
         * the already-in-memory dumpable objects instead...
@@ -3478,11 +3494,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
                                          tbinfo->dobj.namespace->dobj.name,
                                          tbinfo->dobj.name);
 
-               /*
-                * select table schema to ensure regproc name is qualified if needed
-                */
-               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
                resetPQExpBuffer(query);
 
                /* Get the policies for the table. */
@@ -3595,7 +3606,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
                query = createPQExpBuffer();
 
                appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
-                                                 fmtId(polinfo->dobj.name));
+                                                 fmtQualifiedDumpable(polinfo));
 
                if (polinfo->dobj.dump & DUMP_COMPONENT_POLICY)
                        ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
@@ -3634,7 +3645,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
 
        appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
 
-       appendPQExpBuffer(query, " ON %s%s%s", fmtId(tbinfo->dobj.name),
+       appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
                                          !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
 
        if (polinfo->polroles != NULL)
@@ -3649,7 +3660,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
        appendPQExpBuffer(query, ";\n");
 
        appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
-       appendPQExpBuffer(delqry, " ON %s;\n", fmtId(tbinfo->dobj.name));
+       appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
 
        tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
 
@@ -3698,9 +3709,6 @@ getPublications(Archive *fout)
 
        resetPQExpBuffer(query);
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /* Get the publications. */
        appendPQExpBuffer(query,
                                          "SELECT p.tableoid, p.oid, p.pubname, "
@@ -3763,7 +3771,7 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo)
 {
        PQExpBuffer delq;
        PQExpBuffer query;
-       PQExpBuffer labelq;
+       char       *qpubname;
        bool            first = true;
 
        if (!(pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
@@ -3771,15 +3779,14 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo)
 
        delq = createPQExpBuffer();
        query = createPQExpBuffer();
-       labelq = createPQExpBuffer();
+
+       qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
 
        appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
-                                         fmtId(pubinfo->dobj.name));
+                                         qpubname);
 
        appendPQExpBuffer(query, "CREATE PUBLICATION %s",
-                                         fmtId(pubinfo->dobj.name));
-
-       appendPQExpBuffer(labelq, "PUBLICATION %s", fmtId(pubinfo->dobj.name));
+                                         qpubname);
 
        if (pubinfo->puballtables)
                appendPQExpBufferStr(query, " FOR ALL TABLES");
@@ -3822,17 +3829,18 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo)
                                 NULL, NULL);
 
        if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "PUBLICATION", qpubname,
                                        NULL, pubinfo->rolname,
                                        pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
 
        if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "PUBLICATION", qpubname,
                                         NULL, pubinfo->rolname,
                                         pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
 
        destroyPQExpBuffer(delq);
        destroyPQExpBuffer(query);
+       free(qpubname);
 }
 
 /*
@@ -3857,9 +3865,6 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        for (i = 0; i < numTables; i++)
        {
                TableInfo  *tbinfo = &tblinfo[i];
@@ -3948,8 +3953,8 @@ dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
 
        appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
                                          fmtId(pubrinfo->pubname));
-       appendPQExpBuffer(query, " %s;",
-                                         fmtId(tbinfo->dobj.name));
+       appendPQExpBuffer(query, " %s;\n",
+                                         fmtQualifiedDumpable(tbinfo));
 
        /*
         * There is no point in creating drop query as drop query as the drop is
@@ -4011,9 +4016,6 @@ getSubscriptions(Archive *fout)
        if (dopt->no_subscriptions || fout->remoteVersion < 100000)
                return;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (!is_superuser(fout))
        {
                int                     n;
@@ -4099,8 +4101,8 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
 {
        PQExpBuffer delq;
        PQExpBuffer query;
-       PQExpBuffer labelq;
        PQExpBuffer publications;
+       char       *qsubname;
        char      **pubnames = NULL;
        int                     npubnames = 0;
        int                     i;
@@ -4110,13 +4112,14 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
 
        delq = createPQExpBuffer();
        query = createPQExpBuffer();
-       labelq = createPQExpBuffer();
+
+       qsubname = pg_strdup(fmtId(subinfo->dobj.name));
 
        appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
-                                         fmtId(subinfo->dobj.name));
+                                         qsubname);
 
        appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
-                                         fmtId(subinfo->dobj.name));
+                                         qsubname);
        appendStringLiteralAH(query, subinfo->subconninfo, fout);
 
        /* Build list of quoted publications and append them to query. */
@@ -4150,8 +4153,6 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
 
        appendPQExpBufferStr(query, ");\n");
 
-       appendPQExpBuffer(labelq, "SUBSCRIPTION %s", fmtId(subinfo->dobj.name));
-
        ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
                                 subinfo->dobj.name,
                                 NULL,
@@ -4163,12 +4164,12 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
                                 NULL, NULL);
 
        if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "SUBSCRIPTION", qsubname,
                                        NULL, subinfo->rolname,
                                        subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
 
        if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
                                         NULL, subinfo->rolname,
                                         subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
 
@@ -4178,6 +4179,7 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
 
        destroyPQExpBuffer(delq);
        destroyPQExpBuffer(query);
+       free(qsubname);
 }
 
 static void
@@ -4361,11 +4363,16 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
 /*
  * If the DumpableObject is a member of an extension, add a suitable
  * ALTER EXTENSION ADD command to the creation commands in upgrade_buffer.
+ *
+ * For somewhat historical reasons, objname should already be quoted,
+ * but not objnamespace (if any).
  */
 static void
 binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                                                                DumpableObject *dobj,
-                                                               const char *objlabel)
+                                                               const char *objtype,
+                                                               const char *objname,
+                                                               const char *objnamespace)
 {
        DumpableObject *extobj = NULL;
        int                     i;
@@ -4387,13 +4394,17 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                extobj = NULL;
        }
        if (extobj == NULL)
-               exit_horribly(NULL, "could not find parent extension for %s\n", objlabel);
+               exit_horribly(NULL, "could not find parent extension for %s %s\n",
+                                         objtype, objname);
 
        appendPQExpBufferStr(upgrade_buffer,
                                                 "\n-- For binary upgrade, handle extension membership the hard way\n");
-       appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s;\n",
+       appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
                                          fmtId(extobj->name),
-                                         objlabel);
+                                         objtype);
+       if (objnamespace && *objnamespace)
+               appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
+       appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
 }
 
 /*
@@ -4423,9 +4434,6 @@ getNamespaces(Archive *fout, int *numNamespaces)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /*
         * we fetch all namespaces including system ones, so that every object we
         * read in can be linked to a containing namespace.
@@ -4581,9 +4589,6 @@ getExtensions(Archive *fout, int *numExtensions)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
                                                 "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
                                                 "FROM pg_extension x "
@@ -4681,9 +4686,6 @@ getTypes(Archive *fout, int *numTypes)
         * be revisited if the backend ever allows renaming of array types.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 90600)
        {
                PQExpBuffer acl_subquery = createPQExpBuffer();
@@ -4913,9 +4915,6 @@ getOperators(Archive *fout, int *numOprs)
         * system-defined operators at dump-out time.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
                                          "oprnamespace, "
                                          "(%s oprowner) AS rolname, "
@@ -5006,9 +5005,6 @@ getCollations(Archive *fout, int *numCollations)
         * system-defined collations at dump-out time.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, collname, "
                                          "collnamespace, "
                                          "(%s collowner) AS rolname "
@@ -5082,9 +5078,6 @@ getConversions(Archive *fout, int *numConversions)
         * system-defined conversions at dump-out time.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
                                          "connamespace, "
                                          "(%s conowner) AS rolname "
@@ -5160,9 +5153,6 @@ getAccessMethods(Archive *fout, int *numAccessMethods)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /* Select all access methods from pg_am table */
        appendPQExpBuffer(query, "SELECT tableoid, oid, amname, amtype, "
                                          "amhandler::pg_catalog.regproc AS amhandler "
@@ -5233,9 +5223,6 @@ getOpclasses(Archive *fout, int *numOpclasses)
         * system-defined opclasses at dump-out time.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
                                          "opcnamespace, "
                                          "(%s opcowner) AS rolname "
@@ -5320,9 +5307,6 @@ getOpfamilies(Archive *fout, int *numOpfamilies)
         * system-defined opfamilies at dump-out time.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, opfname, "
                                          "opfnamespace, "
                                          "(%s opfowner) AS rolname "
@@ -5400,9 +5384,6 @@ getAggregates(Archive *fout, int *numAggs)
        int                     i_initaggacl;
        int                     i_initraggacl;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /*
         * Find all interesting aggregates.  See comment in getFuncs() for the
         * rationale behind the filtering logic.
@@ -5594,9 +5575,6 @@ getFuncs(Archive *fout, int *numFuncs)
        int                     i_initproacl;
        int                     i_initrproacl;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /*
         * Find all interesting functions.  This is a bit complicated:
         *
@@ -5853,9 +5831,6 @@ getTables(Archive *fout, int *numTables)
        int                     i_ispartition;
        int                     i_partbound;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /*
         * Find all the tables and table-like objects.
         *
@@ -6562,9 +6537,7 @@ getTables(Archive *fout, int *numTables)
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query,
                                                          "LOCK TABLE %s IN ACCESS SHARE MODE",
-                                                         fmtQualifiedId(fout->remoteVersion,
-                                                                                        tblinfo[i].dobj.namespace->dobj.name,
-                                                                                        tblinfo[i].dobj.name));
+                                                         fmtQualifiedDumpable(&tblinfo[i]));
                        ExecuteSqlStatement(fout, query->data);
                }
 
@@ -6656,9 +6629,6 @@ getInherits(Archive *fout, int *numInherits)
        int                     i_inhrelid;
        int                     i_inhparent;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        /*
         * Find all the inheritance information, excluding implicit inheritance
         * via partitioning.  We handle that case using getPartitions(), because
@@ -6750,9 +6720,6 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                                          tbinfo->dobj.namespace->dobj.name,
                                          tbinfo->dobj.name);
 
-               /* Make sure we are in proper schema so indexdef is right */
-               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
                /*
                 * The point of the messy-looking outer join is to find a constraint
                 * that is related by an internal dependency link to the index. If we
@@ -7046,9 +7013,6 @@ getExtendedStatistics(Archive *fout)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
                                          "stxnamespace, (%s stxowner) AS rolname "
                                          "FROM pg_catalog.pg_statistic_ext",
@@ -7128,12 +7092,6 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
                                          tbinfo->dobj.namespace->dobj.name,
                                          tbinfo->dobj.name);
 
-               /*
-                * select table schema to ensure constraint expr is qualified if
-                * needed
-                */
-               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
                resetPQExpBuffer(query);
                appendPQExpBuffer(query,
                                                  "SELECT tableoid, oid, conname, confrelid, "
@@ -7198,12 +7156,6 @@ getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
                                i_consrc;
        int                     ntups;
 
-       /*
-        * select appropriate schema to ensure names in constraint are properly
-        * qualified
-        */
-       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
-
        query = createPQExpBuffer();
 
        if (fout->remoteVersion >= 90100)
@@ -7298,9 +7250,6 @@ getRules(Archive *fout, int *numRules)
        int                     i_is_instead;
        int                     i_ev_enabled;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 80300)
        {
                appendPQExpBufferStr(query, "SELECT "
@@ -7436,11 +7385,6 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
                                          tbinfo->dobj.namespace->dobj.name,
                                          tbinfo->dobj.name);
 
-               /*
-                * select table schema to ensure regproc name is qualified if needed
-                */
-               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
                resetPQExpBuffer(query);
                if (fout->remoteVersion >= 90000)
                {
@@ -7624,9 +7568,6 @@ getEventTriggers(Archive *fout, int *numEventTriggers)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query,
                                          "SELECT e.tableoid, e.oid, evtname, evtenabled, "
                                          "evtevent, (%s evtowner) AS evtowner, "
@@ -7714,9 +7655,6 @@ getProcLangs(Archive *fout, int *numProcLangs)
        int                     i_initrlanacl;
        int                     i_lanowner;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 90600)
        {
                PQExpBuffer acl_subquery = createPQExpBuffer();
@@ -7889,9 +7827,6 @@ getCasts(Archive *fout, int *numCasts)
        int                     i_castcontext;
        int                     i_castmethod;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 80400)
        {
                appendPQExpBufferStr(query, "SELECT tableoid, oid, "
@@ -8013,9 +7948,6 @@ getTransforms(Archive *fout, int *numTransforms)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, "
                                          "trftype, trflang, trffromsql::oid, trftosql::oid "
                                          "FROM pg_transform "
@@ -8129,12 +8061,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                if (!tbinfo->interesting)
                        continue;
 
-               /*
-                * Make sure we are in proper schema for this table; this allows
-                * correct retrieval of formatted type names and default exprs
-                */
-               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
-
                /* find all the user attributes and their types */
 
                /*
@@ -8609,9 +8535,6 @@ getTSParsers(Archive *fout, int *numTSParsers)
         * system-defined objects at dump-out time.
         */
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
                                                 "prsstart::oid, prstoken::oid, "
                                                 "prsend::oid, prsheadline::oid, prslextype::oid "
@@ -8696,9 +8619,6 @@ getTSDictionaries(Archive *fout, int *numTSDicts)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, dictname, "
                                          "dictnamespace, (%s dictowner) AS rolname, "
                                          "dicttemplate, dictinitoption "
@@ -8782,9 +8702,6 @@ getTSTemplates(Archive *fout, int *numTSTemplates)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
                                                 "tmplnamespace, tmplinit::oid, tmpllexize::oid "
                                                 "FROM pg_ts_template");
@@ -8861,9 +8778,6 @@ getTSConfigurations(Archive *fout, int *numTSConfigs)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query, "SELECT tableoid, oid, cfgname, "
                                          "cfgnamespace, (%s cfgowner) AS rolname, cfgparser "
                                          "FROM pg_ts_config",
@@ -8947,9 +8861,6 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 90600)
        {
                PQExpBuffer acl_subquery = createPQExpBuffer();
@@ -9117,9 +9028,6 @@ getForeignServers(Archive *fout, int *numForeignServers)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 90600)
        {
                PQExpBuffer acl_subquery = createPQExpBuffer();
@@ -9266,9 +9174,6 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
 
        query = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 90600)
        {
                PQExpBuffer acl_subquery = createPQExpBuffer();
@@ -9369,13 +9274,18 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
  * dumpComment --
  *
  * This routine is used to dump any comments associated with the
- * object handed to this routine. The routine takes a constant character
- * string for the target part of the comment-creation command, plus
+ * object handed to this routine. The routine takes the object type
+ * and object name (ready to print, except for schema decoration), plus
  * the namespace and owner of the object (for labeling the ArchiveEntry),
  * plus catalog ID and subid which are the lookup key for pg_description,
  * plus the dump ID for the object (for setting a dependency).
  * If a matching pg_description entry is found, it is dumped.
  *
+ * Note: in some cases, such as comments for triggers and rules, the "type"
+ * string really looks like, e.g., "TRIGGER name ON".  This is a bit of a hack
+ * but it doesn't seem worth complicating the API for all callers to make
+ * it cleaner.
+ *
  * Note: although this routine takes a dumpId for dependency purposes,
  * that purpose is just to mark the dependency in the emitted dump file
  * for possible future use by pg_restore.  We do NOT use it for determining
@@ -9384,7 +9294,7 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
  * calling ArchiveEntry() for the specified object.
  */
 static void
-dumpComment(Archive *fout, const char *target,
+dumpComment(Archive *fout, const char *type, const char *name,
                        const char *namespace, const char *owner,
                        CatalogId catalogId, int subid, DumpId dumpId)
 {
@@ -9397,7 +9307,7 @@ dumpComment(Archive *fout, const char *target,
                return;
 
        /* Comments are schema not data ... except blob comments are data */
-       if (strncmp(target, "LARGE OBJECT ", 13) != 0)
+       if (strcmp(type, "LARGE OBJECT") != 0)
        {
                if (dopt->dataOnly)
                        return;
@@ -9426,24 +9336,31 @@ dumpComment(Archive *fout, const char *target,
        if (ncomments > 0)
        {
                PQExpBuffer query = createPQExpBuffer();
+               PQExpBuffer tag = createPQExpBuffer();
 
-               appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
+               appendPQExpBuffer(query, "COMMENT ON %s ", type);
+               if (namespace && *namespace)
+                       appendPQExpBuffer(query, "%s.", fmtId(namespace));
+               appendPQExpBuffer(query, "%s IS ", name);
                appendStringLiteralAH(query, comments->descr, fout);
                appendPQExpBufferStr(query, ";\n");
 
+               appendPQExpBuffer(tag, "%s %s", type, name);
+
                /*
                 * We mark comments as SECTION_NONE because they really belong in the
                 * same section as their parent, whether that is pre-data or
                 * post-data.
                 */
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                        target, namespace, NULL, owner,
+                                        tag->data, namespace, NULL, owner,
                                         false, "COMMENT", SECTION_NONE,
                                         query->data, "", NULL,
                                         &(dumpId), 1,
                                         NULL, NULL);
 
                destroyPQExpBuffer(query);
+               destroyPQExpBuffer(tag);
        }
 }
 
@@ -9461,7 +9378,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
        CommentItem *comments;
        int                     ncomments;
        PQExpBuffer query;
-       PQExpBuffer target;
+       PQExpBuffer tag;
 
        /* do nothing, if --no-comments is supplied */
        if (dopt->no_comments)
@@ -9482,7 +9399,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                return;
 
        query = createPQExpBuffer();
-       target = createPQExpBuffer();
+       tag = createPQExpBuffer();
 
        while (ncomments > 0)
        {
@@ -9491,17 +9408,18 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
 
                if (objsubid == 0)
                {
-                       resetPQExpBuffer(target);
-                       appendPQExpBuffer(target, "%s %s", reltypename,
+                       resetPQExpBuffer(tag);
+                       appendPQExpBuffer(tag, "%s %s", reltypename,
                                                          fmtId(tbinfo->dobj.name));
 
                        resetPQExpBuffer(query);
-                       appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
+                       appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
+                                                         fmtQualifiedDumpable(tbinfo));
                        appendStringLiteralAH(query, descr, fout);
                        appendPQExpBufferStr(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                                target->data,
+                                                tag->data,
                                                 tbinfo->dobj.namespace->dobj.name,
                                                 NULL, tbinfo->rolname,
                                                 false, "COMMENT", SECTION_NONE,
@@ -9511,18 +9429,21 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                }
                else if (objsubid > 0 && objsubid <= tbinfo->numatts)
                {
-                       resetPQExpBuffer(target);
-                       appendPQExpBuffer(target, "COLUMN %s.",
+                       resetPQExpBuffer(tag);
+                       appendPQExpBuffer(tag, "COLUMN %s.",
                                                          fmtId(tbinfo->dobj.name));
-                       appendPQExpBufferStr(target, fmtId(tbinfo->attnames[objsubid - 1]));
+                       appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
 
                        resetPQExpBuffer(query);
-                       appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
+                       appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
+                                                         fmtQualifiedDumpable(tbinfo));
+                       appendPQExpBuffer(query, "%s IS ",
+                                                         fmtId(tbinfo->attnames[objsubid - 1]));
                        appendStringLiteralAH(query, descr, fout);
                        appendPQExpBufferStr(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                                target->data,
+                                                tag->data,
                                                 tbinfo->dobj.namespace->dobj.name,
                                                 NULL, tbinfo->rolname,
                                                 false, "COMMENT", SECTION_NONE,
@@ -9536,7 +9457,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
        }
 
        destroyPQExpBuffer(query);
-       destroyPQExpBuffer(target);
+       destroyPQExpBuffer(tag);
 }
 
 /*
@@ -9643,11 +9564,6 @@ collectComments(Archive *fout, CommentItem **items)
        int                     i;
        CommentItem *comments;
 
-       /*
-        * Note we do NOT change source schema here; preserve the caller's
-        * setting, instead.
-        */
-
        query = createPQExpBuffer();
 
        appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
@@ -9842,7 +9758,6 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        char       *qnspname;
 
        /* Skip if not to be dumped */
@@ -9851,7 +9766,6 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
        qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
 
@@ -9859,10 +9773,9 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
        appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
 
-       appendPQExpBuffer(labelq, "SCHEMA %s", qnspname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &nspinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &nspinfo->dobj,
+                                                                               "SCHEMA", qnspname, NULL);
 
        if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
@@ -9876,18 +9789,18 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
        /* Dump Schema Comments and Security Labels */
        if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "SCHEMA", qnspname,
                                        NULL, nspinfo->rolname,
                                        nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
 
        if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "SCHEMA", qnspname,
                                         NULL, nspinfo->rolname,
                                         nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
 
        if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId, "SCHEMA",
-                               qnspname, NULL, labelq->data, NULL,
+                               qnspname, NULL, NULL,
                                nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
                                nspinfo->initnspacl, nspinfo->initrnspacl);
 
@@ -9895,7 +9808,6 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -9908,7 +9820,6 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        char       *qextname;
 
        /* Skip if not to be dumped */
@@ -9917,7 +9828,6 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
        qextname = pg_strdup(fmtId(extinfo->dobj.name));
 
@@ -10003,8 +9913,6 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
                appendPQExpBufferStr(q, ");\n");
        }
 
-       appendPQExpBuffer(labelq, "EXTENSION %s", qextname);
-
        if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
                                         extinfo->dobj.name,
@@ -10017,12 +9925,12 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 
        /* Dump Extension Comments and Security Labels */
        if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "EXTENSION", qextname,
                                        NULL, "",
                                        extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
 
        if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "EXTENSION", qextname,
                                         NULL, "",
                                         extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
 
@@ -10030,7 +9938,6 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -10074,18 +9981,15 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
        int                     num,
                                i;
        Oid                     enum_oid;
        char       *qtypname;
+       char       *qualtypname;
        char       *label;
 
-       /* Set proper schema search path */
-       selectSourceSchema(fout, "pg_catalog");
-
        if (fout->remoteVersion >= 90100)
                appendPQExpBuffer(query, "SELECT oid, enumlabel "
                                                  "FROM pg_catalog.pg_enum "
@@ -10104,16 +10008,13 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
        num = PQntuples(res);
 
        qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+       qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
 
        /*
-        * DROP must be fully qualified in case same name appears in pg_catalog.
         * CASCADE shouldn't be required here as for normal types since the I/O
         * functions are generic and do not get dropped.
         */
-       appendPQExpBuffer(delq, "DROP TYPE %s.",
-                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, "%s;\n",
-                                         qtypname);
+       appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
 
        if (dopt->binary_upgrade)
                binary_upgrade_set_type_oids_by_type_oid(fout, q,
@@ -10121,7 +10022,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                                                                                                 false);
 
        appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
-                                         qtypname);
+                                         qualtypname);
 
        if (!dopt->binary_upgrade)
        {
@@ -10151,19 +10052,16 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                        appendPQExpBuffer(q,
                                                          "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
                                                          enum_oid);
-                       appendPQExpBuffer(q, "ALTER TYPE %s.",
-                                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-                       appendPQExpBuffer(q, "%s ADD VALUE ",
-                                                         qtypname);
+                       appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
                        appendStringLiteralAH(q, label, fout);
                        appendPQExpBufferStr(q, ";\n\n");
                }
        }
 
-       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tyinfo->dobj,
+                                                                               "TYPE", qtypname,
+                                                                               tyinfo->dobj.namespace->dobj.name);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
@@ -10178,18 +10076,18 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
 
        /* Dump Type Comments and Security Labels */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TYPE", qtypname,
                                        tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                        tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "TYPE", qtypname,
                                         tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                         tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
-                               qtypname, NULL, labelq->data,
+                               qtypname, NULL,
                                tyinfo->dobj.namespace->dobj.name,
                                tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
                                tyinfo->inittypacl, tyinfo->initrtypacl);
@@ -10197,8 +10095,9 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qtypname);
+       free(qualtypname);
 }
 
 /*
@@ -10211,19 +10110,13 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
        Oid                     collationOid;
        char       *qtypname;
+       char       *qualtypname;
        char       *procname;
 
-       /*
-        * select appropriate schema to ensure names in CREATE are properly
-        * qualified
-        */
-       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
-
        appendPQExpBuffer(query,
                                          "SELECT pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
                                          "opc.opcname AS opcname, "
@@ -10242,16 +10135,13 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+       qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
 
        /*
-        * DROP must be fully qualified in case same name appears in pg_catalog.
         * CASCADE shouldn't be required here as for normal types since the I/O
         * functions are generic and do not get dropped.
         */
-       appendPQExpBuffer(delq, "DROP TYPE %s.",
-                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, "%s;\n",
-                                         qtypname);
+       appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
 
        if (dopt->binary_upgrade)
                binary_upgrade_set_type_oids_by_type_oid(fout, q,
@@ -10259,7 +10149,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                                                                                                 false);
 
        appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
-                                         qtypname);
+                                         qualtypname);
 
        appendPQExpBuffer(q, "\n    subtype = %s",
                                          PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
@@ -10270,7 +10160,6 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                char       *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
                char       *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
 
-               /* always schema-qualify, don't try to be smart */
                appendPQExpBuffer(q, ",\n    subtype_opclass = %s.",
                                                  fmtId(nspname));
                appendPQExpBufferStr(q, fmtId(opcname));
@@ -10282,12 +10171,8 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                CollInfo   *coll = findCollationByOid(collationOid);
 
                if (coll)
-               {
-                       /* always schema-qualify, don't try to be smart */
-                       appendPQExpBuffer(q, ",\n    collation = %s.",
-                                                         fmtId(coll->dobj.namespace->dobj.name));
-                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
-               }
+                       appendPQExpBuffer(q, ",\n    collation = %s",
+                                                         fmtQualifiedDumpable(coll));
        }
 
        procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
@@ -10300,10 +10185,10 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
 
        appendPQExpBufferStr(q, "\n);\n");
 
-       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tyinfo->dobj,
+                                                                               "TYPE", qtypname,
+                                                                               tyinfo->dobj.namespace->dobj.name);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
@@ -10318,18 +10203,18 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
 
        /* Dump Type Comments and Security Labels */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TYPE", qtypname,
                                        tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                        tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "TYPE", qtypname,
                                         tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                         tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
-                               qtypname, NULL, labelq->data,
+                               qtypname, NULL,
                                tyinfo->dobj.namespace->dobj.name,
                                tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
                                tyinfo->inittypacl, tyinfo->initrtypacl);
@@ -10337,8 +10222,9 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qtypname);
+       free(qualtypname);
 }
 
 /*
@@ -10356,18 +10242,13 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
        char       *qtypname;
+       char       *qualtypname;
 
        qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+       qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog.
-        */
-       appendPQExpBuffer(delq, "DROP TYPE %s.",
-                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, "%s;\n",
-                                         qtypname);
+       appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
 
        if (dopt->binary_upgrade)
                binary_upgrade_set_type_oids_by_type_oid(fout, q,
@@ -10375,12 +10256,12 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
                                                                                                 false);
 
        appendPQExpBuffer(q, "CREATE TYPE %s;\n",
-                                         qtypname);
-
-       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
+                                         qualtypname);
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tyinfo->dobj,
+                                                                               "TYPE", qtypname,
+                                                                               tyinfo->dobj.namespace->dobj.name);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
@@ -10395,25 +10276,26 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
 
        /* Dump Type Comments and Security Labels */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TYPE", qtypname,
                                        tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                        tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "TYPE", qtypname,
                                         tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                         tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
-                               qtypname, NULL, labelq->data,
+                               qtypname, NULL,
                                tyinfo->dobj.namespace->dobj.name,
                                tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
                                tyinfo->inittypacl, tyinfo->initrtypacl);
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       free(qtypname);
+       free(qualtypname);
 }
 
 /*
@@ -10426,10 +10308,10 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
        char       *qtypname;
+       char       *qualtypname;
        char       *typlen;
        char       *typinput;
        char       *typoutput;
@@ -10453,9 +10335,6 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        char       *typdefault;
        bool            typdefault_is_literal = false;
 
-       /* Set proper schema search path so regproc references list correctly */
-       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
-
        /* Fetch type-specific details */
        if (fout->remoteVersion >= 90100)
        {
@@ -10564,17 +10443,14 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
                typdefault = NULL;
 
        qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+       qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
 
        /*
-        * DROP must be fully qualified in case same name appears in pg_catalog.
         * The reason we include CASCADE is that the circular dependency between
         * the type and its I/O functions makes it impossible to drop the type any
         * other way.
         */
-       appendPQExpBuffer(delq, "DROP TYPE %s.",
-                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, "%s CASCADE;\n",
-                                         qtypname);
+       appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
 
        /*
         * We might already have a shell type, but setting pg_type_oid is
@@ -10588,7 +10464,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBuffer(q,
                                          "CREATE TYPE %s (\n"
                                          "    INTERNALLENGTH = %s",
-                                         qtypname,
+                                         qualtypname,
                                          (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
 
        /* regproc result is sufficiently quoted already */
@@ -10621,8 +10497,6 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        {
                char       *elemType;
 
-               /* reselect schema in case changed by function dump */
-               selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
                elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroAsOpaque);
                appendPQExpBuffer(q, ",\n    ELEMENT = %s", elemType);
                free(elemType);
@@ -10666,10 +10540,10 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 
        appendPQExpBufferStr(q, "\n);\n");
 
-       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tyinfo->dobj,
+                                                                               "TYPE", qtypname,
+                                                                               tyinfo->dobj.namespace->dobj.name);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
@@ -10684,18 +10558,18 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 
        /* Dump Type Comments and Security Labels */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TYPE", qtypname,
                                        tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                        tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "TYPE", qtypname,
                                         tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                         tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
-                               qtypname, NULL, labelq->data,
+                               qtypname, NULL,
                                tyinfo->dobj.namespace->dobj.name,
                                tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
                                tyinfo->inittypacl, tyinfo->initrtypacl);
@@ -10703,8 +10577,9 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qtypname);
+       free(qualtypname);
 }
 
 /*
@@ -10717,20 +10592,17 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
        int                     i;
        char       *qtypname;
+       char       *qualtypname;
        char       *typnotnull;
        char       *typdefn;
        char       *typdefault;
        Oid                     typcollation;
        bool            typdefault_is_literal = false;
 
-       /* Set proper schema search path so type references list correctly */
-       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
-
        /* Fetch domain specific details */
        if (fout->remoteVersion >= 90100)
        {
@@ -10778,10 +10650,11 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
                                                                                                 true); /* force array type */
 
        qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+       qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
 
        appendPQExpBuffer(q,
                                          "CREATE DOMAIN %s AS %s",
-                                         qtypname,
+                                         qualtypname,
                                          typdefn);
 
        /* Print collation only if different from base type's collation */
@@ -10791,12 +10664,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 
                coll = findCollationByOid(typcollation);
                if (coll)
-               {
-                       /* always schema-qualify, don't try to be smart */
-                       appendPQExpBuffer(q, " COLLATE %s.",
-                                                         fmtId(coll->dobj.namespace->dobj.name));
-                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
-               }
+                       appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
        }
 
        if (typnotnull[0] == 't')
@@ -10827,18 +10695,12 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 
        appendPQExpBufferStr(q, ";\n");
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP DOMAIN %s.",
-                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, "%s;\n",
-                                         qtypname);
-
-       appendPQExpBuffer(labelq, "DOMAIN %s", qtypname);
+       appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tyinfo->dobj,
+                                                                               "DOMAIN", qtypname,
+                                                                               tyinfo->dobj.namespace->dobj.name);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
@@ -10853,18 +10715,18 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 
        /* Dump Domain Comments and Security Labels */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "DOMAIN", qtypname,
                                        tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                        tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "DOMAIN", qtypname,
                                         tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                         tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
-                               qtypname, NULL, labelq->data,
+                               qtypname, NULL,
                                tyinfo->dobj.namespace->dobj.name,
                                tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
                                tyinfo->inittypacl, tyinfo->initrtypacl);
@@ -10873,26 +10735,25 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
        for (i = 0; i < tyinfo->nDomChecks; i++)
        {
                ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
-               PQExpBuffer labelq = createPQExpBuffer();
+               PQExpBuffer conprefix = createPQExpBuffer();
 
-               appendPQExpBuffer(labelq, "CONSTRAINT %s ",
+               appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
                                                  fmtId(domcheck->dobj.name));
-               appendPQExpBuffer(labelq, "ON DOMAIN %s",
-                                                 qtypname);
 
                if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-                       dumpComment(fout, labelq->data,
+                       dumpComment(fout, conprefix->data, qtypname,
                                                tyinfo->dobj.namespace->dobj.name,
                                                tyinfo->rolname,
                                                domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
 
-               destroyPQExpBuffer(labelq);
+               destroyPQExpBuffer(conprefix);
        }
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qtypname);
+       free(qualtypname);
 }
 
 /*
@@ -10907,10 +10768,10 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer dropped = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
        char       *qtypname;
+       char       *qualtypname;
        int                     ntups;
        int                     i_attname;
        int                     i_atttypdefn;
@@ -10921,9 +10782,6 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        int                     i;
        int                     actual_atts;
 
-       /* Set proper schema search path so type references list correctly */
-       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
-
        /* Fetch type specific details */
        if (fout->remoteVersion >= 90100)
        {
@@ -10983,9 +10841,10 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        }
 
        qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+       qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
 
        appendPQExpBuffer(q, "CREATE TYPE %s AS (",
-                                         qtypname);
+                                         qualtypname);
 
        actual_atts = 0;
        for (i = 0; i < ntups; i++)
@@ -11023,12 +10882,8 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 
                                coll = findCollationByOid(attcollation);
                                if (coll)
-                               {
-                                       /* always schema-qualify, don't try to be smart */
-                                       appendPQExpBuffer(q, " COLLATE %s.",
-                                                                         fmtId(coll->dobj.namespace->dobj.name));
-                                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
-                               }
+                                       appendPQExpBuffer(q, " COLLATE %s",
+                                                                         fmtQualifiedDumpable(coll));
                        }
                }
                else
@@ -11050,11 +10905,11 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                                                          "WHERE attname = ", attlen, attalign);
                        appendStringLiteralAH(dropped, attname, fout);
                        appendPQExpBufferStr(dropped, "\n  AND attrelid = ");
-                       appendStringLiteralAH(dropped, qtypname, fout);
+                       appendStringLiteralAH(dropped, qualtypname, fout);
                        appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
 
                        appendPQExpBuffer(dropped, "ALTER TYPE %s ",
-                                                         qtypname);
+                                                         qualtypname);
                        appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
                                                          fmtId(attname));
                }
@@ -11062,18 +10917,12 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBufferStr(q, "\n);\n");
        appendPQExpBufferStr(q, dropped->data);
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP TYPE %s.",
-                                         fmtId(tyinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, "%s;\n",
-                                         qtypname);
-
-       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
+       appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tyinfo->dobj,
+                                                                               "TYPE", qtypname,
+                                                                               tyinfo->dobj.namespace->dobj.name);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
@@ -11089,18 +10938,18 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 
        /* Dump Type Comments and Security Labels */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TYPE", qtypname,
                                        tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                        tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "TYPE", qtypname,
                                         tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                         tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
        if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
-                               qtypname, NULL, labelq->data,
+                               qtypname, NULL,
                                tyinfo->dobj.namespace->dobj.name,
                                tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
                                tyinfo->inittypacl, tyinfo->initrtypacl);
@@ -11109,8 +10958,9 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(dropped);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qtypname);
+       free(qualtypname);
 
        /* Dump any per-column comments */
        if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
@@ -11205,7 +11055,9 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
                        appendPQExpBufferStr(target, fmtId(attname));
 
                        resetPQExpBuffer(query);
-                       appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
+                       appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
+                                                         fmtQualifiedDumpable(tyinfo));
+                       appendPQExpBuffer(query, "%s IS ", fmtId(attname));
                        appendStringLiteralAH(query, descr, fout);
                        appendPQExpBufferStr(query, ";\n");
 
@@ -11261,7 +11113,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
                                                                                                 false);
 
        appendPQExpBuffer(q, "CREATE TYPE %s;\n",
-                                         fmtId(stinfo->dobj.name));
+                                         fmtQualifiedDumpable(stinfo));
 
        if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
@@ -11288,10 +11140,8 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer defqry;
        PQExpBuffer delqry;
-       PQExpBuffer labelq;
        bool            useParams;
        char       *qlanname;
-       char       *lanschema;
        FuncInfo   *funcInfo;
        FuncInfo   *inlineInfo = NULL;
        FuncInfo   *validatorInfo = NULL;
@@ -11337,20 +11187,9 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
        defqry = createPQExpBuffer();
        delqry = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
        qlanname = pg_strdup(fmtId(plang->dobj.name));
 
-       /*
-        * If dumping a HANDLER clause, treat the language as being in the handler
-        * function's schema; this avoids cluttering the HANDLER clause. Otherwise
-        * it doesn't really have a schema.
-        */
-       if (useParams)
-               lanschema = funcInfo->dobj.namespace->dobj.name;
-       else
-               lanschema = NULL;
-
        appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
                                          qlanname);
 
@@ -11360,25 +11199,13 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
                                                  plang->lanpltrusted ? "TRUSTED " : "",
                                                  qlanname);
                appendPQExpBuffer(defqry, " HANDLER %s",
-                                                 fmtId(funcInfo->dobj.name));
+                                                 fmtQualifiedDumpable(funcInfo));
                if (OidIsValid(plang->laninline))
-               {
-                       appendPQExpBufferStr(defqry, " INLINE ");
-                       /* Cope with possibility that inline is in different schema */
-                       if (inlineInfo->dobj.namespace != funcInfo->dobj.namespace)
-                               appendPQExpBuffer(defqry, "%s.",
-                                                                 fmtId(inlineInfo->dobj.namespace->dobj.name));
-                       appendPQExpBufferStr(defqry, fmtId(inlineInfo->dobj.name));
-               }
+                       appendPQExpBuffer(defqry, " INLINE %s",
+                                                         fmtQualifiedDumpable(inlineInfo));
                if (OidIsValid(plang->lanvalidator))
-               {
-                       appendPQExpBufferStr(defqry, " VALIDATOR ");
-                       /* Cope with possibility that validator is in different schema */
-                       if (validatorInfo->dobj.namespace != funcInfo->dobj.namespace)
-                               appendPQExpBuffer(defqry, "%s.",
-                                                                 fmtId(validatorInfo->dobj.namespace->dobj.name));
-                       appendPQExpBufferStr(defqry, fmtId(validatorInfo->dobj.name));
-               }
+                       appendPQExpBuffer(defqry, " VALIDATOR %s",
+                                                         fmtQualifiedDumpable(validatorInfo));
        }
        else
        {
@@ -11396,15 +11223,14 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
        }
        appendPQExpBufferStr(defqry, ";\n");
 
-       appendPQExpBuffer(labelq, "LANGUAGE %s", qlanname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(defqry, &plang->dobj, labelq->data);
+               binary_upgrade_extension_member(defqry, &plang->dobj,
+                                                                               "LANGUAGE", qlanname, NULL);
 
        if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
                                         plang->dobj.name,
-                                        lanschema, NULL, plang->lanowner,
+                                        NULL, NULL, plang->lanowner,
                                         false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
                                         defqry->data, delqry->data, NULL,
                                         NULL, 0,
@@ -11412,19 +11238,18 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
        /* Dump Proc Lang Comments and Security Labels */
        if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
-                                       lanschema, plang->lanowner,
+               dumpComment(fout, "LANGUAGE", qlanname,
+                                       NULL, plang->lanowner,
                                        plang->dobj.catId, 0, plang->dobj.dumpId);
 
        if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
-                                        lanschema, plang->lanowner,
+               dumpSecLabel(fout, "LANGUAGE", qlanname,
+                                        NULL, plang->lanowner,
                                         plang->dobj.catId, 0, plang->dobj.dumpId);
 
        if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE",
-                               qlanname, NULL, labelq->data,
-                               lanschema,
+                               qlanname, NULL, NULL,
                                plang->lanowner, plang->lanacl, plang->rlanacl,
                                plang->initlanacl, plang->initrlanacl);
 
@@ -11432,7 +11257,6 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
        destroyPQExpBuffer(defqry);
        destroyPQExpBuffer(delqry);
-       destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -11576,7 +11400,6 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delqry;
-       PQExpBuffer labelq;
        PQExpBuffer asPart;
        PGresult   *res;
        char       *funcsig;            /* identity signature */
@@ -11620,12 +11443,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delqry = createPQExpBuffer();
-       labelq = createPQExpBuffer();
        asPart = createPQExpBuffer();
 
-       /* Set proper schema search path so type references list correctly */
-       selectSourceSchema(fout, finfo->dobj.namespace->dobj.name);
-
        /* Fetch function-specific details */
        if (fout->remoteVersion >= 90600)
        {
@@ -11901,18 +11720,17 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 
        keyword = is_procedure ? "PROCEDURE" : "FUNCTION";
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
        appendPQExpBuffer(delqry, "DROP %s %s.%s;\n",
                                          keyword,
                                          fmtId(finfo->dobj.namespace->dobj.name),
                                          funcsig);
 
-       appendPQExpBuffer(q, "CREATE %s %s",
+       appendPQExpBuffer(q, "CREATE %s %s.%s",
                                          keyword,
+                                         fmtId(finfo->dobj.namespace->dobj.name),
                                          funcfullsig ? funcfullsig :
                                          funcsig);
+
        if (is_procedure)
                ;
        else if (funcresult)
@@ -12028,10 +11846,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 
        appendPQExpBuffer(q, "\n    %s;\n", asPart->data);
 
-       appendPQExpBuffer(labelq, "%s %s", keyword, funcsig);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &finfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &finfo->dobj,
+                                                                               keyword, funcsig,
+                                                                               finfo->dobj.namespace->dobj.name);
 
        if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
@@ -12046,18 +11864,18 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 
        /* Dump Function Comments and Security Labels */
        if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, keyword, funcsig,
                                        finfo->dobj.namespace->dobj.name, finfo->rolname,
                                        finfo->dobj.catId, 0, finfo->dobj.dumpId);
 
        if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, keyword, funcsig,
                                         finfo->dobj.namespace->dobj.name, finfo->rolname,
                                         finfo->dobj.catId, 0, finfo->dobj.dumpId);
 
        if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId, keyword,
-                               funcsig, NULL, labelq->data,
+                               funcsig, NULL,
                                finfo->dobj.namespace->dobj.name,
                                finfo->rolname, finfo->proacl, finfo->rproacl,
                                finfo->initproacl, finfo->initrproacl);
@@ -12067,7 +11885,6 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delqry);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(asPart);
        free(funcsig);
        if (funcfullsig)
@@ -12094,6 +11911,7 @@ dumpCast(Archive *fout, CastInfo *cast)
        PQExpBuffer defqry;
        PQExpBuffer delqry;
        PQExpBuffer labelq;
+       PQExpBuffer castargs;
        FuncInfo   *funcInfo = NULL;
        char       *sourceType;
        char       *targetType;
@@ -12111,15 +11929,10 @@ dumpCast(Archive *fout, CastInfo *cast)
                                                  cast->castfunc);
        }
 
-       /*
-        * Make sure we are in proper schema (needed for getFormattedTypeName).
-        * Casts don't have a schema of their own, so use pg_catalog.
-        */
-       selectSourceSchema(fout, "pg_catalog");
-
        defqry = createPQExpBuffer();
        delqry = createPQExpBuffer();
        labelq = createPQExpBuffer();
+       castargs = createPQExpBuffer();
 
        sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
        targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
@@ -12143,9 +11956,8 @@ dumpCast(Archive *fout, CastInfo *cast)
                                char       *fsig = format_function_signature(fout, funcInfo, true);
 
                                /*
-                                * Always qualify the function name, in case it is not in
-                                * pg_catalog schema (format_function_signature won't qualify
-                                * it).
+                                * Always qualify the function name (format_function_signature
+                                * won't qualify it).
                                 */
                                appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
                                                                  fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
@@ -12167,13 +11979,17 @@ dumpCast(Archive *fout, CastInfo *cast)
        appendPQExpBuffer(labelq, "CAST (%s AS %s)",
                                          sourceType, targetType);
 
+       appendPQExpBuffer(castargs, "(%s AS %s)",
+                                         sourceType, targetType);
+
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(defqry, &cast->dobj, labelq->data);
+               binary_upgrade_extension_member(defqry, &cast->dobj,
+                                                                               "CAST", castargs->data, NULL);
 
        if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
                                         labelq->data,
-                                        "pg_catalog", NULL, "",
+                                        NULL, NULL, "",
                                         false, "CAST", SECTION_PRE_DATA,
                                         defqry->data, delqry->data, NULL,
                                         NULL, 0,
@@ -12181,8 +11997,8 @@ dumpCast(Archive *fout, CastInfo *cast)
 
        /* Dump Cast Comments */
        if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
-                                       "pg_catalog", "",
+               dumpComment(fout, "CAST", castargs->data,
+                                       NULL, "",
                                        cast->dobj.catId, 0, cast->dobj.dumpId);
 
        free(sourceType);
@@ -12191,6 +12007,7 @@ dumpCast(Archive *fout, CastInfo *cast)
        destroyPQExpBuffer(defqry);
        destroyPQExpBuffer(delqry);
        destroyPQExpBuffer(labelq);
+       destroyPQExpBuffer(castargs);
 }
 
 /*
@@ -12203,6 +12020,7 @@ dumpTransform(Archive *fout, TransformInfo *transform)
        PQExpBuffer defqry;
        PQExpBuffer delqry;
        PQExpBuffer labelq;
+       PQExpBuffer transformargs;
        FuncInfo   *fromsqlFuncInfo = NULL;
        FuncInfo   *tosqlFuncInfo = NULL;
        char       *lanname;
@@ -12228,12 +12046,10 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                                                  transform->trftosql);
        }
 
-       /* Make sure we are in proper schema (needed for getFormattedTypeName) */
-       selectSourceSchema(fout, "pg_catalog");
-
        defqry = createPQExpBuffer();
        delqry = createPQExpBuffer();
        labelq = createPQExpBuffer();
+       transformargs = createPQExpBuffer();
 
        lanname = get_language_name(fout, transform->trflang);
        transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
@@ -12254,8 +12070,8 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                        char       *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
 
                        /*
-                        * Always qualify the function name, in case it is not in
-                        * pg_catalog schema (format_function_signature won't qualify it).
+                        * Always qualify the function name (format_function_signature
+                        * won't qualify it).
                         */
                        appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
                                                          fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
@@ -12275,8 +12091,8 @@ dumpTransform(Archive *fout, TransformInfo *transform)
                        char       *fsig = format_function_signature(fout, tosqlFuncInfo, true);
 
                        /*
-                        * Always qualify the function name, in case it is not in
-                        * pg_catalog schema (format_function_signature won't qualify it).
+                        * Always qualify the function name (format_function_signature
+                        * won't qualify it).
                         */
                        appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
                                                          fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
@@ -12291,13 +12107,17 @@ dumpTransform(Archive *fout, TransformInfo *transform)
        appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
                                          transformType, lanname);
 
+       appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
+                                         transformType, lanname);
+
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(defqry, &transform->dobj, labelq->data);
+               binary_upgrade_extension_member(defqry, &transform->dobj,
+                                                                               "TRANSFORM", transformargs->data, NULL);
 
        if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
                                         labelq->data,
-                                        "pg_catalog", NULL, "",
+                                        NULL, NULL, "",
                                         false, "TRANSFORM", SECTION_PRE_DATA,
                                         defqry->data, delqry->data, NULL,
                                         transform->dobj.dependencies, transform->dobj.nDeps,
@@ -12305,8 +12125,8 @@ dumpTransform(Archive *fout, TransformInfo *transform)
 
        /* Dump Transform Comments */
        if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
-                                       "pg_catalog", "",
+               dumpComment(fout, "TRANSFORM", transformargs->data,
+                                       NULL, "",
                                        transform->dobj.catId, 0, transform->dobj.dumpId);
 
        free(lanname);
@@ -12314,6 +12134,7 @@ dumpTransform(Archive *fout, TransformInfo *transform)
        destroyPQExpBuffer(defqry);
        destroyPQExpBuffer(delqry);
        destroyPQExpBuffer(labelq);
+       destroyPQExpBuffer(transformargs);
 }
 
 
@@ -12328,7 +12149,6 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        PQExpBuffer oprid;
        PQExpBuffer details;
        PGresult   *res;
@@ -12369,21 +12189,17 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
        oprid = createPQExpBuffer();
        details = createPQExpBuffer();
 
-       /* Make sure we are in proper schema so regoperator works correctly */
-       selectSourceSchema(fout, oprinfo->dobj.namespace->dobj.name);
-
        if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query, "SELECT oprkind, "
                                                  "oprcode::pg_catalog.regprocedure, "
                                                  "oprleft::pg_catalog.regtype, "
                                                  "oprright::pg_catalog.regtype, "
-                                                 "oprcom::pg_catalog.regoperator, "
-                                                 "oprnegate::pg_catalog.regoperator, "
+                                                 "oprcom, "
+                                                 "oprnegate, "
                                                  "oprrest::pg_catalog.regprocedure, "
                                                  "oprjoin::pg_catalog.regprocedure, "
                                                  "oprcanmerge, oprcanhash "
@@ -12397,8 +12213,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                                                  "oprcode::pg_catalog.regprocedure, "
                                                  "oprleft::pg_catalog.regtype, "
                                                  "oprright::pg_catalog.regtype, "
-                                                 "oprcom::pg_catalog.regoperator, "
-                                                 "oprnegate::pg_catalog.regoperator, "
+                                                 "oprcom, "
+                                                 "oprnegate, "
                                                  "oprrest::pg_catalog.regprocedure, "
                                                  "oprjoin::pg_catalog.regprocedure, "
                                                  "(oprlsortop != 0) AS oprcanmerge, "
@@ -12464,14 +12280,14 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        else
                appendPQExpBufferStr(oprid, ", NONE)");
 
-       oprref = convertOperatorReference(fout, oprcom);
+       oprref = getFormattedOperatorName(fout, oprcom);
        if (oprref)
        {
                appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", oprref);
                free(oprref);
        }
 
-       oprref = convertOperatorReference(fout, oprnegate);
+       oprref = getFormattedOperatorName(fout, oprnegate);
        if (oprref)
        {
                appendPQExpBuffer(details, ",\n    NEGATOR = %s", oprref);
@@ -12498,20 +12314,18 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                free(oprregproc);
        }
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
        appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
                                          fmtId(oprinfo->dobj.namespace->dobj.name),
                                          oprid->data);
 
-       appendPQExpBuffer(q, "CREATE OPERATOR %s (\n%s\n);\n",
+       appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
+                                         fmtId(oprinfo->dobj.namespace->dobj.name),
                                          oprinfo->dobj.name, details->data);
 
-       appendPQExpBuffer(labelq, "OPERATOR %s", oprid->data);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &oprinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &oprinfo->dobj,
+                                                                               "OPERATOR", oprid->data,
+                                                                               oprinfo->dobj.namespace->dobj.name);
 
        if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
@@ -12526,7 +12340,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 
        /* Dump Operator Comments */
        if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "OPERATOR", oprid->data,
                                        oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
                                        oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
 
@@ -12535,7 +12349,6 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(oprid);
        destroyPQExpBuffer(details);
 }
@@ -12577,49 +12390,39 @@ convertRegProcReference(Archive *fout, const char *proc)
 }
 
 /*
- * Convert an operator cross-reference obtained from pg_operator
+ * getFormattedOperatorName - retrieve the operator name for the
+ * given operator OID (presented in string form).
  *
- * Returns an allocated string of what to print, or NULL to print nothing.
+ * Returns an allocated string, or NULL if the given OID is invalid.
  * Caller is responsible for free'ing result string.
  *
- * The input is a REGOPERATOR display; we have to strip the argument-types
- * part, and add OPERATOR() decoration if the name is schema-qualified.
+ * What we produce has the format "OPERATOR(schema.oprname)".  This is only
+ * useful in commands where the operator's argument types can be inferred from
+ * context.  We always schema-qualify the name, though.  The predecessor to
+ * this code tried to skip the schema qualification if possible, but that led
+ * to wrong results in corner cases, such as if an operator and its negator
+ * are in different schemas.
  */
 static char *
-convertOperatorReference(Archive *fout, const char *opr)
+getFormattedOperatorName(Archive *fout, const char *oproid)
 {
-       char       *name;
-       char       *oname;
-       char       *ptr;
-       bool            inquote;
-       bool            sawdot;
+       OprInfo    *oprInfo;
 
        /* In all cases "0" means a null reference */
-       if (strcmp(opr, "0") == 0)
+       if (strcmp(oproid, "0") == 0)
                return NULL;
 
-       name = pg_strdup(opr);
-       /* find non-double-quoted left paren, and check for non-quoted dot */
-       inquote = false;
-       sawdot = false;
-       for (ptr = name; *ptr; ptr++)
+       oprInfo = findOprByOid(atooid(oproid));
+       if (oprInfo == NULL)
        {
-               if (*ptr == '"')
-                       inquote = !inquote;
-               else if (*ptr == '.' && !inquote)
-                       sawdot = true;
-               else if (*ptr == '(' && !inquote)
-               {
-                       *ptr = '\0';
-                       break;
-               }
+               write_msg(NULL, "WARNING: could not find operator with OID %s\n",
+                                 oproid);
+               return NULL;
        }
-       /* If not schema-qualified, don't need to add OPERATOR() */
-       if (!sawdot)
-               return name;
-       oname = psprintf("OPERATOR(%s)", name);
-       free(name);
-       return oname;
+
+       return psprintf("OPERATOR(%s.%s)",
+                                       fmtId(oprInfo->dobj.namespace->dobj.name),
+                                       oprInfo->dobj.name);
 }
 
 /*
@@ -12658,7 +12461,6 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        char       *qamname;
 
        /* Skip if not to be dumped */
@@ -12667,7 +12469,6 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
        qamname = pg_strdup(fmtId(aminfo->dobj.name));
 
@@ -12681,10 +12482,9 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
                default:
                        write_msg(NULL, "WARNING: invalid type \"%c\" of access method \"%s\"\n",
                                          aminfo->amtype, qamname);
-                       pg_free(qamname);
                        destroyPQExpBuffer(q);
                        destroyPQExpBuffer(delq);
-                       destroyPQExpBuffer(labelq);
+                       free(qamname);
                        return;
        }
 
@@ -12693,11 +12493,9 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
        appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
                                          qamname);
 
-       appendPQExpBuffer(labelq, "ACCESS METHOD %s",
-                                         qamname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &aminfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &aminfo->dobj,
+                                                                               "ACCESS METHOD", qamname, NULL);
 
        if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
@@ -12712,15 +12510,13 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
 
        /* Dump Access Method Comments */
        if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "ACCESS METHOD", qamname,
                                        NULL, "",
                                        aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
 
-       pg_free(qamname);
-
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       free(qamname);
 }
 
 /*
@@ -12734,7 +12530,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
+       PQExpBuffer nameusing;
        PGresult   *res;
        int                     ntups;
        int                     i_opcintype;
@@ -12779,10 +12575,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
-
-       /* Make sure we are in proper schema so regoperator works correctly */
-       selectSourceSchema(fout, opcinfo->dobj.namespace->dobj.name);
+       nameusing = createPQExpBuffer();
 
        /* Get additional fields from the pg_opclass row */
        if (fout->remoteVersion >= 80300)
@@ -12833,19 +12626,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        /* amname will still be needed after we PQclear res */
        amname = pg_strdup(PQgetvalue(res, 0, i_amname));
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
        appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
-                                         fmtId(opcinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s",
-                                         fmtId(opcinfo->dobj.name));
+                                         fmtQualifiedDumpable(opcinfo));
        appendPQExpBuffer(delq, " USING %s;\n",
                                          fmtId(amname));
 
        /* Build the fixed portion of the CREATE command */
        appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n    ",
-                                         fmtId(opcinfo->dobj.name));
+                                         fmtQualifiedDumpable(opcinfo));
        if (strcmp(opcdefault, "t") == 0)
                appendPQExpBufferStr(q, "DEFAULT ");
        appendPQExpBuffer(q, "FOR TYPE %s USING %s",
@@ -12854,8 +12642,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        if (strlen(opcfamilyname) > 0)
        {
                appendPQExpBufferStr(q, " FAMILY ");
-               if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
-                       appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
+               appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
                appendPQExpBufferStr(q, fmtId(opcfamilyname));
        }
        appendPQExpBufferStr(q, " AS\n    ");
@@ -12973,8 +12760,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                if (strlen(sortfamily) > 0)
                {
                        appendPQExpBufferStr(q, " FOR ORDER BY ");
-                       if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
-                               appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
+                       appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
                        appendPQExpBufferStr(q, fmtId(sortfamily));
                }
 
@@ -13068,13 +12854,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 
        appendPQExpBufferStr(q, ";\n");
 
-       appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
-                                         fmtId(opcinfo->dobj.name));
-       appendPQExpBuffer(labelq, " USING %s",
+       appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
+       appendPQExpBuffer(nameusing, " USING %s",
                                          fmtId(amname));
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &opcinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &opcinfo->dobj,
+                                                                               "OPERATOR CLASS", nameusing->data,
+                                                                               opcinfo->dobj.namespace->dobj.name);
 
        if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
@@ -13089,7 +12876,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 
        /* Dump Operator Class Comments */
        if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "OPERATOR CLASS", nameusing->data,
                                        opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
                                        opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
 
@@ -13099,7 +12886,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       destroyPQExpBuffer(nameusing);
 }
 
 /*
@@ -13116,7 +12903,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
+       PQExpBuffer nameusing;
        PGresult   *res;
        PGresult   *res_ops;
        PGresult   *res_procs;
@@ -13151,10 +12938,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
-
-       /* Make sure we are in proper schema so regoperator works correctly */
-       selectSourceSchema(fout, opfinfo->dobj.namespace->dobj.name);
+       nameusing = createPQExpBuffer();
 
        /*
         * Fetch only those opfamily members that are tied directly to the
@@ -13246,19 +13030,14 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        /* amname will still be needed after we PQclear res */
        amname = pg_strdup(PQgetvalue(res, 0, i_amname));
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
        appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
-                                         fmtId(opfinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s",
-                                         fmtId(opfinfo->dobj.name));
+                                         fmtQualifiedDumpable(opfinfo));
        appendPQExpBuffer(delq, " USING %s;\n",
                                          fmtId(amname));
 
        /* Build the fixed portion of the CREATE command */
        appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
-                                         fmtId(opfinfo->dobj.name));
+                                         fmtQualifiedDumpable(opfinfo));
        appendPQExpBuffer(q, " USING %s;\n",
                                          fmtId(amname));
 
@@ -13268,7 +13047,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
        {
                appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
-                                                 fmtId(opfinfo->dobj.name));
+                                                 fmtQualifiedDumpable(opfinfo));
                appendPQExpBuffer(q, " USING %s ADD\n    ",
                                                  fmtId(amname));
 
@@ -13302,8 +13081,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                        if (strlen(sortfamily) > 0)
                        {
                                appendPQExpBufferStr(q, " FOR ORDER BY ");
-                               if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0)
-                                       appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
+                               appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
                                appendPQExpBufferStr(q, fmtId(sortfamily));
                        }
 
@@ -13343,13 +13121,14 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                appendPQExpBufferStr(q, ";\n");
        }
 
-       appendPQExpBuffer(labelq, "OPERATOR FAMILY %s",
-                                         fmtId(opfinfo->dobj.name));
-       appendPQExpBuffer(labelq, " USING %s",
+       appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
+       appendPQExpBuffer(nameusing, " USING %s",
                                          fmtId(amname));
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &opfinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &opfinfo->dobj,
+                                                                               "OPERATOR FAMILY", nameusing->data,
+                                                                               opfinfo->dobj.namespace->dobj.name);
 
        if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
@@ -13364,7 +13143,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 
        /* Dump Operator Family Comments */
        if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
                                        opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
                                        opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
 
@@ -13374,7 +13153,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       destroyPQExpBuffer(nameusing);
 }
 
 /*
@@ -13388,7 +13167,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
+       char       *qcollname;
        PGresult   *res;
        int                     i_collprovider;
        int                     i_collcollate;
@@ -13404,10 +13183,8 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, collinfo->dobj.namespace->dobj.name);
+       qcollname = pg_strdup(fmtId(collinfo->dobj.name));
 
        /* Get collation-specific details */
        if (fout->remoteVersion >= 100000)
@@ -13439,16 +13216,11 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        collcollate = PQgetvalue(res, 0, i_collcollate);
        collctype = PQgetvalue(res, 0, i_collctype);
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP COLLATION %s",
-                                         fmtId(collinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s;\n",
-                                         fmtId(collinfo->dobj.name));
+       appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
+                                         fmtQualifiedDumpable(collinfo));
 
        appendPQExpBuffer(q, "CREATE COLLATION %s (",
-                                         fmtId(collinfo->dobj.name));
+                                         fmtQualifiedDumpable(collinfo));
 
        appendPQExpBufferStr(q, "provider = ");
        if (collprovider[0] == 'c')
@@ -13496,10 +13268,10 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
 
        appendPQExpBufferStr(q, ");\n");
 
-       appendPQExpBuffer(labelq, "COLLATION %s", fmtId(collinfo->dobj.name));
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &collinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &collinfo->dobj,
+                                                                               "COLLATION", qcollname,
+                                                                               collinfo->dobj.namespace->dobj.name);
 
        if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
@@ -13514,7 +13286,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
 
        /* Dump Collation Comments */
        if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "COLLATION", qcollname,
                                        collinfo->dobj.namespace->dobj.name, collinfo->rolname,
                                        collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
 
@@ -13523,7 +13295,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       free(qcollname);
 }
 
 /*
@@ -13537,7 +13309,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
+       char       *qconvname;
        PGresult   *res;
        int                     i_conforencoding;
        int                     i_contoencoding;
@@ -13555,10 +13327,8 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, convinfo->dobj.namespace->dobj.name);
+       qconvname = pg_strdup(fmtId(convinfo->dobj.name));
 
        /* Get conversion-specific details */
        appendPQExpBuffer(query, "SELECT "
@@ -13581,27 +13351,22 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        conproc = PQgetvalue(res, 0, i_conproc);
        condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP CONVERSION %s",
-                                         fmtId(convinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s;\n",
-                                         fmtId(convinfo->dobj.name));
+       appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
+                                         fmtQualifiedDumpable(convinfo));
 
        appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
                                          (condefault) ? "DEFAULT " : "",
-                                         fmtId(convinfo->dobj.name));
+                                         fmtQualifiedDumpable(convinfo));
        appendStringLiteralAH(q, conforencoding, fout);
        appendPQExpBufferStr(q, " TO ");
        appendStringLiteralAH(q, contoencoding, fout);
        /* regproc output is already sufficiently quoted */
        appendPQExpBuffer(q, " FROM %s;\n", conproc);
 
-       appendPQExpBuffer(labelq, "CONVERSION %s", fmtId(convinfo->dobj.name));
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &convinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &convinfo->dobj,
+                                                                               "CONVERSION", qconvname,
+                                                                               convinfo->dobj.namespace->dobj.name);
 
        if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
@@ -13616,7 +13381,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 
        /* Dump Conversion Comments */
        if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "CONVERSION", qconvname,
                                        convinfo->dobj.namespace->dobj.name, convinfo->rolname,
                                        convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
 
@@ -13625,7 +13390,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       free(qconvname);
 }
 
 /*
@@ -13679,7 +13444,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        PQExpBuffer query;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        PQExpBuffer details;
        char       *aggsig;                     /* identity signature */
        char       *aggfullsig = NULL;  /* full signature */
@@ -13739,12 +13503,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        query = createPQExpBuffer();
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
        details = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);
-
        /* Get aggregate-specific details */
        if (fout->remoteVersion >= 110000)
        {
@@ -13754,7 +13514,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
                                                  "aggfinalextra, aggmfinalextra, "
                                                  "aggfinalmodify, aggmfinalmodify, "
-                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "aggsortop, "
                                                  "aggkind, "
                                                  "aggtransspace, agginitval, "
                                                  "aggmtransspace, aggminitval, "
@@ -13775,7 +13535,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
                                                  "aggfinalextra, aggmfinalextra, "
                                                  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
-                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "aggsortop, "
                                                  "aggkind, "
                                                  "aggtransspace, agginitval, "
                                                  "aggmtransspace, aggminitval, "
@@ -13797,7 +13557,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
                                                  "aggfinalextra, aggmfinalextra, "
                                                  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
-                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "aggsortop, "
                                                  "aggkind, "
                                                  "aggtransspace, agginitval, "
                                                  "aggmtransspace, aggminitval, "
@@ -13819,7 +13579,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "0 AS aggmtranstype, false AS aggfinalextra, "
                                                  "false AS aggmfinalextra, "
                                                  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
-                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "aggsortop, "
                                                  "'n' AS aggkind, "
                                                  "0 AS aggtransspace, agginitval, "
                                                  "0 AS aggmtransspace, NULL AS aggminitval, "
@@ -13841,7 +13601,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "0 AS aggmtranstype, false AS aggfinalextra, "
                                                  "false AS aggmfinalextra, "
                                                  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
-                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "aggsortop, "
                                                  "'n' AS aggkind, "
                                                  "0 AS aggtransspace, agginitval, "
                                                  "0 AS aggmtransspace, NULL AS aggminitval, "
@@ -14061,7 +13821,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                }
        }
 
-       aggsortconvop = convertOperatorReference(fout, aggsortop);
+       aggsortconvop = getFormattedOperatorName(fout, aggsortop);
        if (aggsortconvop)
        {
                appendPQExpBuffer(details, ",\n    SORTOP = %s",
@@ -14083,20 +13843,18 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  agginfo->aggfn.dobj.name);
        }
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
        appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
                                          fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                                          aggsig);
 
-       appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
+       appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
+                                         fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                                          aggfullsig ? aggfullsig : aggsig, details->data);
 
-       appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &agginfo->aggfn.dobj, labelq->data);
+               binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
+                                                                               "AGGREGATE", aggsig,
+                                                                               agginfo->aggfn.dobj.namespace->dobj.name);
 
        if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
@@ -14112,13 +13870,13 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 
        /* Dump Aggregate Comments */
        if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "AGGREGATE", aggsig,
                                        agginfo->aggfn.dobj.namespace->dobj.name,
                                        agginfo->aggfn.rolname,
                                        agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
 
        if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
-               dumpSecLabel(fout, labelq->data,
+               dumpSecLabel(fout, "AGGREGATE", aggsig,
                                         agginfo->aggfn.dobj.namespace->dobj.name,
                                         agginfo->aggfn.rolname,
                                         agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
@@ -14134,8 +13892,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 
        if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
-                               "FUNCTION",
-                               aggsig, NULL, labelq->data,
+                               "FUNCTION", aggsig, NULL,
                                agginfo->aggfn.dobj.namespace->dobj.name,
                                agginfo->aggfn.rolname, agginfo->aggfn.proacl,
                                agginfo->aggfn.rproacl,
@@ -14151,7 +13908,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(details);
 }
 
@@ -14165,7 +13921,7 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
+       char       *qprsname;
 
        /* Skip if not to be dumped */
        if (!prsinfo->dobj.dump || dopt->dataOnly)
@@ -14173,13 +13929,11 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, prsinfo->dobj.namespace->dobj.name);
+       qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
 
        appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
-                                         fmtId(prsinfo->dobj.name));
+                                         fmtQualifiedDumpable(prsinfo));
 
        appendPQExpBuffer(q, "    START = %s,\n",
                                          convertTSFunction(fout, prsinfo->prsstart));
@@ -14193,19 +13947,13 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
        appendPQExpBuffer(q, "    LEXTYPES = %s );\n",
                                          convertTSFunction(fout, prsinfo->prslextype));
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s",
-                                         fmtId(prsinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s;\n",
-                                         fmtId(prsinfo->dobj.name));
-
-       appendPQExpBuffer(labelq, "TEXT SEARCH PARSER %s",
-                                         fmtId(prsinfo->dobj.name));
+       appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
+                                         fmtQualifiedDumpable(prsinfo));
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &prsinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &prsinfo->dobj,
+                                                                               "TEXT SEARCH PARSER", qprsname,
+                                                                               prsinfo->dobj.namespace->dobj.name);
 
        if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
@@ -14220,13 +13968,13 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 
        /* Dump Parser Comments */
        if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
                                        prsinfo->dobj.namespace->dobj.name, "",
                                        prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       free(qprsname);
 }
 
 /*
@@ -14239,8 +13987,8 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        PQExpBuffer query;
+       char       *qdictname;
        PGresult   *res;
        char       *nspname;
        char       *tmplname;
@@ -14251,11 +13999,11 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
        query = createPQExpBuffer();
 
+       qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
+
        /* Fetch name and namespace of the dictionary's template */
-       selectSourceSchema(fout, "pg_catalog");
        appendPQExpBuffer(query, "SELECT nspname, tmplname "
                                          "FROM pg_ts_template p, pg_namespace n "
                                          "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
@@ -14264,15 +14012,11 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
        nspname = PQgetvalue(res, 0, 0);
        tmplname = PQgetvalue(res, 0, 1);
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, dictinfo->dobj.namespace->dobj.name);
-
        appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
-                                         fmtId(dictinfo->dobj.name));
+                                         fmtQualifiedDumpable(dictinfo));
 
        appendPQExpBufferStr(q, "    TEMPLATE = ");
-       if (strcmp(nspname, dictinfo->dobj.namespace->dobj.name) != 0)
-               appendPQExpBuffer(q, "%s.", fmtId(nspname));
+       appendPQExpBuffer(q, "%s.", fmtId(nspname));
        appendPQExpBufferStr(q, fmtId(tmplname));
 
        PQclear(res);
@@ -14283,19 +14027,13 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 
        appendPQExpBufferStr(q, " );\n");
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s",
-                                         fmtId(dictinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s;\n",
-                                         fmtId(dictinfo->dobj.name));
-
-       appendPQExpBuffer(labelq, "TEXT SEARCH DICTIONARY %s",
-                                         fmtId(dictinfo->dobj.name));
+       appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
+                                         fmtQualifiedDumpable(dictinfo));
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &dictinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &dictinfo->dobj,
+                                                                               "TEXT SEARCH DICTIONARY", qdictname,
+                                                                               dictinfo->dobj.namespace->dobj.name);
 
        if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
@@ -14310,14 +14048,14 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 
        /* Dump Dictionary Comments */
        if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
                                        dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
                                        dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qdictname);
 }
 
 /*
@@ -14330,7 +14068,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
+       char       *qtmplname;
 
        /* Skip if not to be dumped */
        if (!tmplinfo->dobj.dump || dopt->dataOnly)
@@ -14338,13 +14076,11 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, tmplinfo->dobj.namespace->dobj.name);
+       qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
 
        appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
-                                         fmtId(tmplinfo->dobj.name));
+                                         fmtQualifiedDumpable(tmplinfo));
 
        if (tmplinfo->tmplinit != InvalidOid)
                appendPQExpBuffer(q, "    INIT = %s,\n",
@@ -14352,19 +14088,13 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
        appendPQExpBuffer(q, "    LEXIZE = %s );\n",
                                          convertTSFunction(fout, tmplinfo->tmpllexize));
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s",
-                                         fmtId(tmplinfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s;\n",
-                                         fmtId(tmplinfo->dobj.name));
-
-       appendPQExpBuffer(labelq, "TEXT SEARCH TEMPLATE %s",
-                                         fmtId(tmplinfo->dobj.name));
+       appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
+                                         fmtQualifiedDumpable(tmplinfo));
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &tmplinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &tmplinfo->dobj,
+                                                                               "TEXT SEARCH TEMPLATE", qtmplname,
+                                                                               tmplinfo->dobj.namespace->dobj.name);
 
        if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
@@ -14379,13 +14109,13 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 
        /* Dump Template Comments */
        if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
                                        tmplinfo->dobj.namespace->dobj.name, "",
                                        tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
+       free(qtmplname);
 }
 
 /*
@@ -14398,8 +14128,8 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        PQExpBuffer query;
+       char       *qcfgname;
        PGresult   *res;
        char       *nspname;
        char       *prsname;
@@ -14414,11 +14144,11 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
        query = createPQExpBuffer();
 
+       qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
+
        /* Fetch name and namespace of the config's parser */
-       selectSourceSchema(fout, "pg_catalog");
        appendPQExpBuffer(query, "SELECT nspname, prsname "
                                          "FROM pg_ts_parser p, pg_namespace n "
                                          "WHERE p.oid = '%u' AND n.oid = prsnamespace",
@@ -14427,15 +14157,10 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
        nspname = PQgetvalue(res, 0, 0);
        prsname = PQgetvalue(res, 0, 1);
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, cfginfo->dobj.namespace->dobj.name);
-
        appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
-                                         fmtId(cfginfo->dobj.name));
+                                         fmtQualifiedDumpable(cfginfo));
 
-       appendPQExpBufferStr(q, "    PARSER = ");
-       if (strcmp(nspname, cfginfo->dobj.namespace->dobj.name) != 0)
-               appendPQExpBuffer(q, "%s.", fmtId(nspname));
+       appendPQExpBuffer(q, "    PARSER = %s.", fmtId(nspname));
        appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
 
        PQclear(res);
@@ -14469,7 +14194,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
                        if (i > 0)
                                appendPQExpBufferStr(q, ";\n");
                        appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
-                                                         fmtId(cfginfo->dobj.name));
+                                                         fmtQualifiedDumpable(cfginfo));
                        /* tokenname needs quoting, dictname does NOT */
                        appendPQExpBuffer(q, "    ADD MAPPING FOR %s WITH %s",
                                                          fmtId(tokenname), dictname);
@@ -14483,19 +14208,13 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 
        PQclear(res);
 
-       /*
-        * DROP must be fully qualified in case same name appears in pg_catalog
-        */
-       appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s",
-                                         fmtId(cfginfo->dobj.namespace->dobj.name));
-       appendPQExpBuffer(delq, ".%s;\n",
-                                         fmtId(cfginfo->dobj.name));
-
-       appendPQExpBuffer(labelq, "TEXT SEARCH CONFIGURATION %s",
-                                         fmtId(cfginfo->dobj.name));
+       appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
+                                         fmtQualifiedDumpable(cfginfo));
 
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &cfginfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &cfginfo->dobj,
+                                                                               "TEXT SEARCH CONFIGURATION", qcfgname,
+                                                                               cfginfo->dobj.namespace->dobj.name);
 
        if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
@@ -14510,14 +14229,14 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 
        /* Dump Configuration Comments */
        if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
                                        cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
                                        cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
+       free(qcfgname);
 }
 
 /*
@@ -14530,7 +14249,6 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        char       *qfdwname;
 
        /* Skip if not to be dumped */
@@ -14539,7 +14257,6 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
 
        qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
 
@@ -14560,11 +14277,10 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
        appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
                                          qfdwname);
 
-       appendPQExpBuffer(labelq, "FOREIGN DATA WRAPPER %s",
-                                         qfdwname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &fdwinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &fdwinfo->dobj,
+                                                                               "FOREIGN DATA WRAPPER", qfdwname,
+                                                                               NULL);
 
        if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
@@ -14579,15 +14295,14 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 
        /* Dump Foreign Data Wrapper Comments */
        if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
                                        NULL, fdwinfo->rolname,
                                        fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
 
        /* Handle the ACL */
        if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
-                               "FOREIGN DATA WRAPPER",
-                               qfdwname, NULL, labelq->data,
+                               "FOREIGN DATA WRAPPER", qfdwname, NULL,
                                NULL, fdwinfo->rolname,
                                fdwinfo->fdwacl, fdwinfo->rfdwacl,
                                fdwinfo->initfdwacl, fdwinfo->initrfdwacl);
@@ -14596,7 +14311,6 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -14609,7 +14323,6 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q;
        PQExpBuffer delq;
-       PQExpBuffer labelq;
        PQExpBuffer query;
        PGresult   *res;
        char       *qsrvname;
@@ -14621,13 +14334,11 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
-       labelq = createPQExpBuffer();
        query = createPQExpBuffer();
 
        qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
 
        /* look up the foreign-data wrapper */
-       selectSourceSchema(fout, "pg_catalog");
        appendPQExpBuffer(query, "SELECT fdwname "
                                          "FROM pg_foreign_data_wrapper w "
                                          "WHERE w.oid = '%u'",
@@ -14658,10 +14369,9 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
        appendPQExpBuffer(delq, "DROP SERVER %s;\n",
                                          qsrvname);
 
-       appendPQExpBuffer(labelq, "SERVER %s", qsrvname);
-
        if (dopt->binary_upgrade)
-               binary_upgrade_extension_member(q, &srvinfo->dobj, labelq->data);
+               binary_upgrade_extension_member(q, &srvinfo->dobj,
+                                                                               "SERVER", qsrvname, NULL);
 
        if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
@@ -14676,15 +14386,14 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 
        /* Dump Foreign Server Comments */
        if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
-               dumpComment(fout, labelq->data,
+               dumpComment(fout, "SERVER", qsrvname,
                                        NULL, srvinfo->rolname,
                                        srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
 
        /* Handle the ACL */
        if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
                dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
-                               "FOREIGN SERVER",
-                               qsrvname, NULL, labelq->data,
+                               "FOREIGN SERVER", qsrvname, NULL,
                                NULL, srvinfo->rolname,
                                srvinfo->srvacl, srvinfo->rsrvacl,
                                srvinfo->initsrvacl, srvinfo->initrsrvacl);
@@ -14700,7 +14409,6 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
-       destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(query);
 }
 
@@ -14740,8 +14448,6 @@ dumpUserMappings(Archive *fout,
         * OPTIONS clause.  A possible alternative is to skip such mappings
         * altogether, but it's not clear that that's an improvement.
         */
-       selectSourceSchema(fout, "pg_catalog");
-
        appendPQExpBuffer(query,
                                          "SELECT usename, "
                                          "array_to_string(ARRAY("
@@ -14889,8 +14595,7 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
  *             FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
  * 'name' is the formatted name of the object.  Must be quoted etc. already.
  * 'subname' is the formatted name of the sub-object, if any.  Must be quoted.
- * 'tag' is the tag for the archive entry (should be the same tag as would be
- *             used for comments etc; for example "TABLE foo").
+ *             (Currently we assume that subname is only provided for table columns.)
  * 'nspname' is the namespace the object is in (NULL if none).
  * 'owner' is the owner, NULL if there is no owner (for languages).
  * 'acls' contains the ACL string of the object from the appropriate system
@@ -14912,7 +14617,7 @@ 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 *tag, const char *nspname, const char *owner,
+               const char *nspname, const char *owner,
                const char *acls, const char *racls,
                const char *initacls, const char *initracls)
 {
@@ -14940,7 +14645,8 @@ 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");
-               if (!buildACLCommands(name, subname, type, initacls, initracls, owner,
+               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",
@@ -14948,21 +14654,32 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
                appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
        }
 
-       if (!buildACLCommands(name, subname, type, acls, racls, owner,
+       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);
 
        if (sql->len > 0)
+       {
+               PQExpBuffer tag = createPQExpBuffer();
+
+               if (subname)
+                       appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
+               else
+                       appendPQExpBuffer(tag, "%s %s", type, name);
+
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                        tag, nspname,
+                                        tag->data, nspname,
                                         NULL,
                                         owner ? owner : "",
                                         false, "ACL", SECTION_NONE,
                                         sql->data, "", NULL,
                                         &(objDumpId), 1,
                                         NULL, NULL);
+               destroyPQExpBuffer(tag);
+       }
 
        destroyPQExpBuffer(sql);
 }
@@ -14971,8 +14688,8 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
  * dumpSecLabel
  *
  * This routine is used to dump any security labels associated with the
- * object handed to this routine. The routine takes a constant character
- * string for the target part of the security-label command, plus
+ * object handed to this routine. The routine takes the object type
+ * and object name (ready to print, except for schema decoration), plus
  * the namespace and owner of the object (for labeling the ArchiveEntry),
  * plus catalog ID and subid which are the lookup key for pg_seclabel,
  * plus the dump ID for the object (for setting a dependency).
@@ -14986,7 +14703,7 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
  * calling ArchiveEntry() for the specified object.
  */
 static void
-dumpSecLabel(Archive *fout, const char *target,
+dumpSecLabel(Archive *fout, const char *type, const char *name,
                         const char *namespace, const char *owner,
                         CatalogId catalogId, int subid, DumpId dumpId)
 {
@@ -15001,7 +14718,7 @@ dumpSecLabel(Archive *fout, const char *target,
                return;
 
        /* Security labels are schema not data ... except blob labels are data */
-       if (strncmp(target, "LARGE OBJECT ", 13) != 0)
+       if (strcmp(type, "LARGE OBJECT") != 0)
        {
                if (dopt->dataOnly)
                        return;
@@ -15027,21 +14744,29 @@ dumpSecLabel(Archive *fout, const char *target,
                        continue;
 
                appendPQExpBuffer(query,
-                                                 "SECURITY LABEL FOR %s ON %s IS ",
-                                                 fmtId(labels[i].provider), target);
+                                                 "SECURITY LABEL FOR %s ON %s ",
+                                                 fmtId(labels[i].provider), type);
+               if (namespace && *namespace)
+                       appendPQExpBuffer(query, "%s.", fmtId(namespace));
+               appendPQExpBuffer(query, "%s IS ", name);
                appendStringLiteralAH(query, labels[i].label, fout);
                appendPQExpBufferStr(query, ";\n");
        }
 
        if (query->len > 0)
        {
+               PQExpBuffer tag = createPQExpBuffer();
+
+               appendPQExpBuffer(tag, "%s %s", type, name);
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                        target, namespace, NULL, owner,
+                                        tag->data, namespace, NULL, owner,
                                         false, "SECURITY LABEL", SECTION_NONE,
                                         query->data, "", NULL,
                                         &(dumpId), 1,
                                         NULL, NULL);
+               destroyPQExpBuffer(tag);
        }
+
        destroyPQExpBuffer(query);
 }
 
@@ -15093,13 +14818,14 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename)
                if (objsubid == 0)
                {
                        appendPQExpBuffer(target, "%s %s", reltypename,
-                                                         fmtId(tbinfo->dobj.name));
+                                                         fmtQualifiedDumpable(tbinfo));
                }
                else
                {
                        colname = getAttrName(objsubid, tbinfo);
-                       /* first fmtId result must be consumed before calling it again */
-                       appendPQExpBuffer(target, "COLUMN %s", fmtId(tbinfo->dobj.name));
+                       /* first fmtXXX result must be consumed before calling again */
+                       appendPQExpBuffer(target, "COLUMN %s",
+                                                         fmtQualifiedDumpable(tbinfo));
                        appendPQExpBuffer(target, ".%s", fmtId(colname));
                }
                appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
@@ -15297,14 +15023,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
        {
                const char *objtype =
                (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
-               char       *acltag = psprintf("%s %s", objtype, namecopy);
 
                dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
-                               objtype, namecopy, NULL, acltag,
+                               objtype, namecopy, NULL,
                                tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                                tbinfo->relacl, tbinfo->rrelacl,
                                tbinfo->initrelacl, tbinfo->initrrelacl);
-               free(acltag);
        }
 
        /*
@@ -15386,17 +15110,14 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                        char       *initattacl = PQgetvalue(res, i, 3);
                        char       *initrattacl = PQgetvalue(res, i, 4);
                        char       *attnamecopy;
-                       char       *acltag;
 
                        attnamecopy = pg_strdup(fmtId(attname));
-                       acltag = psprintf("COLUMN %s.%s", namecopy, attnamecopy);
                        /* Column's GRANT type is always TABLE */
-                       dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
-                                       namecopy, attnamecopy, acltag,
+                       dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
+                                       "TABLE", namecopy, attnamecopy,
                                        tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                                        attacl, rattacl, initattacl, initrattacl);
                        free(attnamecopy);
-                       free(acltag);
                }
                PQclear(res);
                destroyPQExpBuffer(query);
@@ -15488,12 +15209,8 @@ createDummyViewAsClause(Archive *fout, TableInfo *tbinfo)
 
                        coll = findCollationByOid(tbinfo->attcollation[j]);
                        if (coll)
-                       {
-                               /* always schema-qualify, don't try to be smart */
-                               appendPQExpBuffer(result, " COLLATE %s.",
-                                                                 fmtId(coll->dobj.namespace->dobj.name));
-                               appendPQExpBufferStr(result, fmtId(coll->dobj.name));
-                       }
+                               appendPQExpBuffer(result, " COLLATE %s",
+                                                                 fmtQualifiedDumpable(coll));
                }
 
                appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
@@ -15512,7 +15229,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
        DumpOptions *dopt = fout->dopt;
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
-       PQExpBuffer labelq = createPQExpBuffer();
+       char       *qrelname;
+       char       *qualrelname;
        int                     numParents;
        TableInfo **parents;
        int                     actual_atts;    /* number of attrs in this CREATE statement */
@@ -15523,8 +15241,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
        int                     j,
                                k;
 
-       /* Make sure we are in proper schema */
-       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
+       qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
+       qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
 
        if (dopt->binary_upgrade)
                binary_upgrade_set_type_oids_by_rel_oid(fout, q,
@@ -15541,20 +15259,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                reltypename = "VIEW";
 
-               /*
-                * DROP must be fully qualified in case same name appears in
-                * pg_catalog
-                */
-               appendPQExpBuffer(delq, "DROP VIEW %s.",
-                                                 fmtId(tbinfo->dobj.namespace->dobj.name));
-               appendPQExpBuffer(delq, "%s;\n",
-                                                 fmtId(tbinfo->dobj.name));
+               appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
 
                if (dopt->binary_upgrade)
                        binary_upgrade_set_pg_class_oids(fout, q,
                                                                                         tbinfo->dobj.catId.oid, false);
 
-               appendPQExpBuffer(q, "CREATE VIEW %s", fmtId(tbinfo->dobj.name));
+               appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
+
                if (tbinfo->dummy_view)
                        result = createDummyViewAsClause(fout, tbinfo);
                else
@@ -15573,9 +15285,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
                        appendPQExpBuffer(q, "\n  WITH %s CHECK OPTION", tbinfo->checkoption);
                appendPQExpBufferStr(q, ";\n");
-
-               appendPQExpBuffer(labelq, "VIEW %s",
-                                                 fmtId(tbinfo->dobj.name));
        }
        else
        {
@@ -15627,17 +15336,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                numParents = tbinfo->numParents;
                parents = tbinfo->parents;
 
-               /*
-                * DROP must be fully qualified in case same name appears in
-                * pg_catalog
-                */
-               appendPQExpBuffer(delq, "DROP %s %s.", reltypename,
-                                                 fmtId(tbinfo->dobj.namespace->dobj.name));
-               appendPQExpBuffer(delq, "%s;\n",
-                                                 fmtId(tbinfo->dobj.name));
-
-               appendPQExpBuffer(labelq, "%s %s", reltypename,
-                                                 fmtId(tbinfo->dobj.name));
+               appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
 
                if (dopt->binary_upgrade)
                        binary_upgrade_set_pg_class_oids(fout, q,
@@ -15647,7 +15346,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                                                  "UNLOGGED " : "",
                                                  reltypename,
-                                                 fmtId(tbinfo->dobj.name));
+                                                 qualrelname);
 
                /*
                 * Attach to type, if reloftype; except in case of a binary upgrade,
@@ -15673,11 +15372,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                exit_horribly(NULL, "invalid number of parents %d for table \"%s\"\n",
                                                          tbinfo->numParents, tbinfo->dobj.name);
 
-                       appendPQExpBuffer(q, " PARTITION OF ");
-                       if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
-                               appendPQExpBuffer(q, "%s.",
-                                                                 fmtId(parentRel->dobj.namespace->dobj.name));
-                       appendPQExpBufferStr(q, fmtId(parentRel->dobj.name));
+                       appendPQExpBuffer(q, " PARTITION OF %s",
+                                                         fmtQualifiedDumpable(parentRel));
                }
 
                if (tbinfo->relkind != RELKIND_MATVIEW)
@@ -15762,12 +15458,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                                                coll = findCollationByOid(tbinfo->attcollation[j]);
                                                if (coll)
-                                               {
-                                                       /* always schema-qualify, don't try to be smart */
-                                                       appendPQExpBuffer(q, " COLLATE %s.",
-                                                                                         fmtId(coll->dobj.namespace->dobj.name));
-                                                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
-                                               }
+                                                       appendPQExpBuffer(q, " COLLATE %s",
+                                                                                         fmtQualifiedDumpable(coll));
                                        }
 
                                        if (has_default)
@@ -15831,10 +15523,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                                        if (k > 0)
                                                appendPQExpBufferStr(q, ", ");
-                                       if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
-                                               appendPQExpBuffer(q, "%s.",
-                                                                                 fmtId(parentRel->dobj.namespace->dobj.name));
-                                       appendPQExpBufferStr(q, fmtId(parentRel->dobj.name));
+                                       appendPQExpBufferStr(q, fmtQualifiedDumpable(parentRel));
                                }
                                appendPQExpBufferChar(q, ')');
                        }
@@ -15926,16 +15615,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                                          tbinfo->attalign[j]);
                                        appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                                        appendPQExpBufferStr(q, "\n  AND attrelid = ");
-                                       appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+                                       appendStringLiteralAH(q, qualrelname, fout);
                                        appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
 
                                        if (tbinfo->relkind == RELKIND_RELATION ||
                                                tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
                                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-                                                                                 fmtId(tbinfo->dobj.name));
+                                                                                 qualrelname);
                                        else
                                                appendPQExpBuffer(q, "ALTER FOREIGN TABLE ONLY %s ",
-                                                                                 fmtId(tbinfo->dobj.name));
+                                                                                 qualrelname);
                                        appendPQExpBuffer(q, "DROP COLUMN %s;\n",
                                                                          fmtId(tbinfo->attnames[j]));
                                }
@@ -15947,7 +15636,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                                                 "WHERE attname = ");
                                        appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                                        appendPQExpBufferStr(q, "\n  AND attrelid = ");
-                                       appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+                                       appendStringLiteralAH(q, qualrelname, fout);
                                        appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                                }
                        }
@@ -15961,7 +15650,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                                appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-                                                                 fmtId(tbinfo->dobj.name));
+                                                                 qualrelname);
                                appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
                                                                  fmtId(constr->dobj.name));
                                appendPQExpBuffer(q, "%s;\n", constr->condef);
@@ -15970,7 +15659,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                                         "WHERE contype = 'c' AND conname = ");
                                appendStringLiteralAH(q, constr->dobj.name, fout);
                                appendPQExpBufferStr(q, "\n  AND conrelid = ");
-                               appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+                               appendStringLiteralAH(q, qualrelname, fout);
                                appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                        }
 
@@ -15980,34 +15669,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                for (k = 0; k < numParents; k++)
                                {
                                        TableInfo  *parentRel = parents[k];
-                                       PQExpBuffer parentname = createPQExpBuffer();
-
-                                       /* Schema-qualify the parent table, if necessary */
-                                       if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
-                                               appendPQExpBuffer(parentname, "%s.",
-                                                                                 fmtId(parentRel->dobj.namespace->dobj.name));
-
-                                       appendPQExpBuffer(parentname, "%s",
-                                                                         fmtId(parentRel->dobj.name));
 
                                        /* In the partitioning case, we alter the parent */
                                        if (tbinfo->ispartition)
                                                appendPQExpBuffer(q,
                                                                                  "ALTER TABLE ONLY %s ATTACH PARTITION ",
-                                                                                 parentname->data);
+                                                                                 fmtQualifiedDumpable(parentRel));
                                        else
                                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
-                                                                                 fmtId(tbinfo->dobj.name));
+                                                                                 qualrelname);
 
                                        /* Partition needs specifying the bounds */
                                        if (tbinfo->ispartition)
                                                appendPQExpBuffer(q, "%s %s;\n",
-                                                                                 fmtId(tbinfo->dobj.name),
+                                                                                 qualrelname,
                                                                                  tbinfo->partbound);
                                        else
-                                               appendPQExpBuffer(q, "%s;\n", parentname->data);
-
-                                       destroyPQExpBuffer(parentname);
+                                               appendPQExpBuffer(q, "%s;\n",
+                                                                                 fmtQualifiedDumpable(parentRel));
                                }
                        }
 
@@ -16015,7 +15694,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        {
                                appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
-                                                                 fmtId(tbinfo->dobj.name),
+                                                                 qualrelname,
                                                                  tbinfo->reloftype);
                        }
                }
@@ -16036,7 +15715,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                          "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                                                          "WHERE oid = ",
                                                          tbinfo->frozenxid, tbinfo->minmxid);
-                       appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+                       appendStringLiteralAH(q, qualrelname, fout);
                        appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
 
                        if (tbinfo->toast_oid)
@@ -16068,7 +15747,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
                                                                 "SET relispopulated = 't'\n"
                                                                 "WHERE oid = ");
-                       appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+                       appendStringLiteralAH(q, qualrelname, fout);
                        appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                }
 
@@ -16091,7 +15770,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
                        {
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-                                                                 fmtId(tbinfo->dobj.name));
+                                                                 qualrelname);
                                appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
                                                                  fmtId(tbinfo->attnames[j]));
                        }
@@ -16104,7 +15783,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        if (tbinfo->attstattarget[j] >= 0)
                        {
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-                                                                 fmtId(tbinfo->dobj.name));
+                                                                 qualrelname);
                                appendPQExpBuffer(q, "ALTER COLUMN %s ",
                                                                  fmtId(tbinfo->attnames[j]));
                                appendPQExpBuffer(q, "SET STATISTICS %d;\n",
@@ -16141,7 +15820,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                if (storage != NULL)
                                {
                                        appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-