More pg_dump performance hacking

Поиск
Список
Период
Сортировка
От Tom Lane
Тема More pg_dump performance hacking
Дата
Msg-id 2460369.1640903318@sss.pgh.pa.us
обсуждение исходный текст
Список pgsql-hackers
Attached are a couple of patches for loose ends that I didn't
get to when I was working on pg_dump before the last CF.

0001 removes all the "username_subquery" subqueries in favor
of doing local username lookups.  On the regression database
with no extra roles, it seems to be more or less a wash ...
but if I create 100 roles, then the patch seems to save five
or ten percent compared to HEAD.

I also got rid of the rather-pointless-IMO checks for pg_authid
join failures, in favor of having the lookup subroutine just
fatal() if it doesn't find a match.  I don't think we need to
burden translators with all those strings for cases that shouldn't
happen.  Note that a lot of object types weren't checking
for this condition anyway, making it even more pointless.

0002 is a very small patch that gets rid of an extra subquery
for identity-sequence checking, realizing that the LEFT JOIN
in the FROM clause will have picked up that row already,
if it exists.  This again saves a few percent for
"pg_dump -s regression", though the effects would depend a lot
on how many sequences you have.

These don't seem complicated enough to require real review,
so I plan to just push them, unless there are objections.

            regards, tom lane

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 94f1f32558..76226de485 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -66,6 +66,12 @@
 #include "pg_dump.h"
 #include "storage/block.h"

+typedef struct
+{
+    Oid            roleoid;        /* role's OID */
+    const char *rolename;        /* role's name */
+} RoleNameItem;
+
 typedef struct
 {
     const char *descr;            /* comment for an object */
@@ -93,9 +99,6 @@ typedef enum OidOptions
 /* global decls */
 static bool dosync = true;        /* Issue fsync() to make dump durable on disk. */

-/* subquery used to convert user ID (eg, datdba) to user name */
-static const char *username_subquery;
-
 static Oid    g_last_builtin_oid; /* value of the last builtin oid */

 /* The specified names/patterns should to match at least one entity */
@@ -130,6 +133,10 @@ static const CatalogId nilCatalogId = {0, 0};
 static bool have_extra_float_digits = false;
 static int    extra_float_digits;

+/* sorted table of role names */
+static RoleNameItem *rolenames = NULL;
+static int    nrolenames = 0;
+
 /* sorted table of comments */
 static CommentItem *comments = NULL;
 static int    ncomments = 0;
@@ -174,6 +181,8 @@ static void expand_table_name_patterns(Archive *fout,
 static NamespaceInfo *findNamespace(Oid nsoid);
 static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo);
 static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo);
+static const char *getRoleName(const char *roleoid_str);
+static void collectRoleNames(Archive *fout);
 static void getAdditionalACLs(Archive *fout);
 static void dumpCommentExtended(Archive *fout, const char *type,
                                 const char *name, const char *namespace,
@@ -744,9 +753,6 @@ main(int argc, char **argv)
     if (fout->isStandby)
         dopt.no_unlogged_table_data = true;

-    /* Select the appropriate subquery to convert user IDs to names */
-    username_subquery = "SELECT rolname FROM pg_catalog.pg_roles WHERE oid =";
-
     /*
      * Find the last built-in OID, if needed (prior to 8.1)
      *
@@ -814,6 +820,11 @@ main(int argc, char **argv)
     if (dopt.include_everything && !dopt.schemaOnly && !dopt.dontOutputBlobs)
         dopt.outputBlobs = true;

+    /*
+     * Collect role names so we can map object owner OIDs to names.
+     */
+    collectRoleNames(fout);
+
     /*
      * Now scan the database and create DumpableObject structs for all the
      * objects we intend to dump.
@@ -2737,7 +2748,7 @@ dumpDatabase(Archive *fout)
     int            i_tableoid,
                 i_oid,
                 i_datname,
-                i_dba,
+                i_datdba,
                 i_encoding,
                 i_collate,
                 i_ctype,
@@ -2771,7 +2782,7 @@ dumpDatabase(Archive *fout)
     if (fout->remoteVersion >= 90300)
     {
         appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, "
-                          "(%s datdba) AS dba, "
+                          "datdba, "
                           "pg_encoding_to_char(encoding) AS encoding, "
                           "datcollate, datctype, datfrozenxid, datminmxid, "
                           "datacl, acldefault('d', datdba) AS acldefault, "
@@ -2780,13 +2791,12 @@ dumpDatabase(Archive *fout)
                           "shobj_description(oid, 'pg_database') AS description "

                           "FROM pg_database "
-                          "WHERE datname = current_database()",
-                          username_subquery);
+                          "WHERE datname = current_database()");
     }
     else
     {
         appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, "
-                          "(%s datdba) AS dba, "
+                          "datdba, "
                           "pg_encoding_to_char(encoding) AS encoding, "
                           "datcollate, datctype, datfrozenxid, 0 AS datminmxid, "
                           "datacl, acldefault('d', datdba) AS acldefault, "
@@ -2795,8 +2805,7 @@ dumpDatabase(Archive *fout)
                           "shobj_description(oid, 'pg_database') AS description "

                           "FROM pg_database "
-                          "WHERE datname = current_database()",
-                          username_subquery);
+                          "WHERE datname = current_database()");
     }

     res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
@@ -2804,7 +2813,7 @@ dumpDatabase(Archive *fout)
     i_tableoid = PQfnumber(res, "tableoid");
     i_oid = PQfnumber(res, "oid");
     i_datname = PQfnumber(res, "datname");
-    i_dba = PQfnumber(res, "dba");
+    i_datdba = PQfnumber(res, "datdba");
     i_encoding = PQfnumber(res, "encoding");
     i_collate = PQfnumber(res, "datcollate");
     i_ctype = PQfnumber(res, "datctype");
@@ -2819,7 +2828,7 @@ dumpDatabase(Archive *fout)
     dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
     dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
     datname = PQgetvalue(res, 0, i_datname);
-    dba = PQgetvalue(res, 0, i_dba);
+    dba = getRoleName(PQgetvalue(res, 0, i_datdba));
     encoding = PQgetvalue(res, 0, i_encoding);
     collate = PQgetvalue(res, 0, i_collate);
     ctype = PQgetvalue(res, 0, i_ctype);
@@ -3264,15 +3273,14 @@ getBlobs(Archive *fout)

     /* Fetch BLOB OIDs, and owner/ACL data */
     appendPQExpBuffer(blobQry,
-                      "SELECT oid, (%s lomowner) AS rolname, lomacl, "
+                      "SELECT oid, lomowner, lomacl, "
                       "acldefault('L', lomowner) AS acldefault "
-                      "FROM pg_largeobject_metadata",
-                      username_subquery);
+                      "FROM pg_largeobject_metadata");

     res = ExecuteSqlQuery(fout, blobQry->data, PGRES_TUPLES_OK);

     i_oid = PQfnumber(res, "oid");
-    i_lomowner = PQfnumber(res, "rolname");
+    i_lomowner = PQfnumber(res, "lomowner");
     i_lomacl = PQfnumber(res, "lomacl");
     i_acldefault = PQfnumber(res, "acldefault");

@@ -3295,7 +3303,7 @@ getBlobs(Archive *fout)
         binfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         binfo[i].dacl.privtype = 0;
         binfo[i].dacl.initprivs = NULL;
-        binfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_lomowner));
+        binfo[i].rolname = getRoleName(PQgetvalue(res, i, i_lomowner));

         /* Blobs have data */
         binfo[i].dobj.components |= DUMP_COMPONENT_DATA;
@@ -3743,7 +3751,7 @@ getPublications(Archive *fout, int *numPublications)
     int            i_tableoid;
     int            i_oid;
     int            i_pubname;
-    int            i_rolname;
+    int            i_pubowner;
     int            i_puballtables;
     int            i_pubinsert;
     int            i_pubupdate;
@@ -3767,24 +3775,21 @@ getPublications(Archive *fout, int *numPublications)
     if (fout->remoteVersion >= 130000)
         appendPQExpBuffer(query,
                           "SELECT p.tableoid, p.oid, p.pubname, "
-                          "(%s p.pubowner) AS rolname, "
+                          "p.pubowner, "
                           "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
-                          "FROM pg_publication p",
-                          username_subquery);
+                          "FROM pg_publication p");
     else if (fout->remoteVersion >= 110000)
         appendPQExpBuffer(query,
                           "SELECT p.tableoid, p.oid, p.pubname, "
-                          "(%s p.pubowner) AS rolname, "
+                          "p.pubowner, "
                           "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
-                          "FROM pg_publication p",
-                          username_subquery);
+                          "FROM pg_publication p");
     else
         appendPQExpBuffer(query,
                           "SELECT p.tableoid, p.oid, p.pubname, "
-                          "(%s p.pubowner) AS rolname, "
+                          "p.pubowner, "
                           "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS
pubviaroot" 
-                          "FROM pg_publication p",
-                          username_subquery);
+                          "FROM pg_publication p");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -3793,7 +3798,7 @@ getPublications(Archive *fout, int *numPublications)
     i_tableoid = PQfnumber(res, "tableoid");
     i_oid = PQfnumber(res, "oid");
     i_pubname = PQfnumber(res, "pubname");
-    i_rolname = PQfnumber(res, "rolname");
+    i_pubowner = PQfnumber(res, "pubowner");
     i_puballtables = PQfnumber(res, "puballtables");
     i_pubinsert = PQfnumber(res, "pubinsert");
     i_pubupdate = PQfnumber(res, "pubupdate");
@@ -3811,7 +3816,7 @@ getPublications(Archive *fout, int *numPublications)
         pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
         AssignDumpId(&pubinfo[i].dobj);
         pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
-        pubinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
         pubinfo[i].puballtables =
             (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
         pubinfo[i].pubinsert =
@@ -3825,10 +3830,6 @@ getPublications(Archive *fout, int *numPublications)
         pubinfo[i].pubviaroot =
             (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);

-        if (strlen(pubinfo[i].rolname) == 0)
-            pg_log_warning("owner of publication \"%s\" appears to be invalid",
-                           pubinfo[i].dobj.name);
-
         /* Decide whether we want to dump it */
         selectDumpableObject(&(pubinfo[i].dobj), fout);
     }
@@ -4215,7 +4216,7 @@ getSubscriptions(Archive *fout)
     int            i_tableoid;
     int            i_oid;
     int            i_subname;
-    int            i_rolname;
+    int            i_subowner;
     int            i_substream;
     int            i_subtwophasestate;
     int            i_subconninfo;
@@ -4250,10 +4251,9 @@ getSubscriptions(Archive *fout)
     /* Get the subscriptions in current database. */
     appendPQExpBuffer(query,
                       "SELECT s.tableoid, s.oid, s.subname,\n"
-                      " (%s s.subowner) AS rolname,\n"
+                      " s.subowner,\n"
                       " s.subconninfo, s.subslotname, s.subsynccommit,\n"
-                      " s.subpublications,\n",
-                      username_subquery);
+                      " s.subpublications,\n");

     if (fout->remoteVersion >= 140000)
         appendPQExpBufferStr(query, " s.subbinary,\n");
@@ -4284,7 +4284,7 @@ getSubscriptions(Archive *fout)
     i_tableoid = PQfnumber(res, "tableoid");
     i_oid = PQfnumber(res, "oid");
     i_subname = PQfnumber(res, "subname");
-    i_rolname = PQfnumber(res, "rolname");
+    i_subowner = PQfnumber(res, "subowner");
     i_subconninfo = PQfnumber(res, "subconninfo");
     i_subslotname = PQfnumber(res, "subslotname");
     i_subsynccommit = PQfnumber(res, "subsynccommit");
@@ -4303,7 +4303,7 @@ getSubscriptions(Archive *fout)
         subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
         AssignDumpId(&subinfo[i].dobj);
         subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
-        subinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
         subinfo[i].subconninfo = pg_strdup(PQgetvalue(res, i, i_subconninfo));
         if (PQgetisnull(res, i, i_subslotname))
             subinfo[i].subslotname = NULL;
@@ -4320,10 +4320,6 @@ getSubscriptions(Archive *fout)
         subinfo[i].subtwophasestate =
             pg_strdup(PQgetvalue(res, i, i_subtwophasestate));

-        if (strlen(subinfo[i].rolname) == 0)
-            pg_log_warning("owner of subscription \"%s\" appears to be invalid",
-                           subinfo[i].dobj.name);
-
         /* Decide whether we want to dump it */
         selectDumpableObject(&(subinfo[i].dobj), fout);
     }
@@ -4740,7 +4736,6 @@ getNamespaces(Archive *fout, int *numNamespaces)
     int            i_oid;
     int            i_nspname;
     int            i_nspowner;
-    int            i_rolname;
     int            i_nspacl;
     int            i_acldefault;

@@ -4752,11 +4747,9 @@ getNamespaces(Archive *fout, int *numNamespaces)
      */
     appendPQExpBuffer(query, "SELECT n.tableoid, n.oid, n.nspname, "
                       "n.nspowner, "
-                      "(%s nspowner) AS rolname, "
                       "n.nspacl, "
                       "acldefault('n', n.nspowner) AS acldefault "
-                      "FROM pg_namespace n",
-                      username_subquery);
+                      "FROM pg_namespace n");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -4768,12 +4761,13 @@ getNamespaces(Archive *fout, int *numNamespaces)
     i_oid = PQfnumber(res, "oid");
     i_nspname = PQfnumber(res, "nspname");
     i_nspowner = PQfnumber(res, "nspowner");
-    i_rolname = PQfnumber(res, "rolname");
     i_nspacl = PQfnumber(res, "nspacl");
     i_acldefault = PQfnumber(res, "acldefault");

     for (i = 0; i < ntups; i++)
     {
+        const char *nspowner;
+
         nsinfo[i].dobj.objType = DO_NAMESPACE;
         nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
         nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
@@ -4783,8 +4777,9 @@ getNamespaces(Archive *fout, int *numNamespaces)
         nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         nsinfo[i].dacl.privtype = 0;
         nsinfo[i].dacl.initprivs = NULL;
-        nsinfo[i].nspowner = atooid(PQgetvalue(res, i, i_nspowner));
-        nsinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        nspowner = PQgetvalue(res, i, i_nspowner);
+        nsinfo[i].nspowner = atooid(nspowner);
+        nsinfo[i].rolname = getRoleName(nspowner);

         /* Decide whether to dump this namespace */
         selectDumpableNamespace(&nsinfo[i], fout);
@@ -4833,10 +4828,6 @@ getNamespaces(Archive *fout, int *numNamespaces)
             destroyPQExpBuffer(aclarray);
             destroyPQExpBuffer(aclitem);
         }
-
-        if (strlen(nsinfo[i].rolname) == 0)
-            pg_log_warning("owner of schema \"%s\" appears to be invalid",
-                           nsinfo[i].dobj.name);
     }

     PQclear(res);
@@ -4959,7 +4950,7 @@ getTypes(Archive *fout, int *numTypes)
     int            i_typnamespace;
     int            i_typacl;
     int            i_acldefault;
-    int            i_rolname;
+    int            i_typowner;
     int            i_typelem;
     int            i_typrelid;
     int            i_typrelkind;
@@ -4985,15 +4976,14 @@ getTypes(Archive *fout, int *numTypes)
     appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
                       "typnamespace, typacl, "
                       "acldefault('T', typowner) AS acldefault, "
-                      "(%s typowner) AS rolname, "
+                      "typowner, "
                       "typelem, typrelid, "
                       "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                       "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
                       "typtype, typisdefined, "
                       "typname[0] = '_' AND typelem != 0 AND "
                       "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
-                      "FROM pg_type",
-                      username_subquery);
+                      "FROM pg_type");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -5007,7 +4997,7 @@ getTypes(Archive *fout, int *numTypes)
     i_typnamespace = PQfnumber(res, "typnamespace");
     i_typacl = PQfnumber(res, "typacl");
     i_acldefault = PQfnumber(res, "acldefault");
-    i_rolname = PQfnumber(res, "rolname");
+    i_typowner = PQfnumber(res, "typowner");
     i_typelem = PQfnumber(res, "typelem");
     i_typrelid = PQfnumber(res, "typrelid");
     i_typrelkind = PQfnumber(res, "typrelkind");
@@ -5029,7 +5019,7 @@ getTypes(Archive *fout, int *numTypes)
         tyinfo[i].dacl.privtype = 0;
         tyinfo[i].dacl.initprivs = NULL;
         tyinfo[i].ftypname = NULL;    /* may get filled later */
-        tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
         tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
         tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
         tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
@@ -5097,10 +5087,6 @@ getTypes(Archive *fout, int *numTypes)
              */
             stinfo->dobj.dump = DUMP_COMPONENT_NONE;
         }
-
-        if (strlen(tyinfo[i].rolname) == 0)
-            pg_log_warning("owner of data type \"%s\" appears to be invalid",
-                           tyinfo[i].dobj.name);
     }

     *numTypes = ntups;
@@ -5131,7 +5117,7 @@ getOperators(Archive *fout, int *numOprs)
     int            i_oid;
     int            i_oprname;
     int            i_oprnamespace;
-    int            i_rolname;
+    int            i_oprowner;
     int            i_oprkind;
     int            i_oprcode;

@@ -5142,11 +5128,10 @@ getOperators(Archive *fout, int *numOprs)

     appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
                       "oprnamespace, "
-                      "(%s oprowner) AS rolname, "
+                      "oprowner, "
                       "oprkind, "
                       "oprcode::oid AS oprcode "
-                      "FROM pg_operator",
-                      username_subquery);
+                      "FROM pg_operator");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -5159,7 +5144,7 @@ getOperators(Archive *fout, int *numOprs)
     i_oid = PQfnumber(res, "oid");
     i_oprname = PQfnumber(res, "oprname");
     i_oprnamespace = PQfnumber(res, "oprnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_oprowner = PQfnumber(res, "oprowner");
     i_oprkind = PQfnumber(res, "oprkind");
     i_oprcode = PQfnumber(res, "oprcode");

@@ -5172,16 +5157,12 @@ getOperators(Archive *fout, int *numOprs)
         oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
         oprinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
-        oprinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
         oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
         oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));

         /* Decide whether we want to dump it */
         selectDumpableObject(&(oprinfo[i].dobj), fout);
-
-        if (strlen(oprinfo[i].rolname) == 0)
-            pg_log_warning("owner of operator \"%s\" appears to be invalid",
-                           oprinfo[i].dobj.name);
     }

     PQclear(res);
@@ -5210,7 +5191,7 @@ getCollations(Archive *fout, int *numCollations)
     int            i_oid;
     int            i_collname;
     int            i_collnamespace;
-    int            i_rolname;
+    int            i_collowner;

     query = createPQExpBuffer();

@@ -5221,9 +5202,8 @@ getCollations(Archive *fout, int *numCollations)

     appendPQExpBuffer(query, "SELECT tableoid, oid, collname, "
                       "collnamespace, "
-                      "(%s collowner) AS rolname "
-                      "FROM pg_collation",
-                      username_subquery);
+                      "collowner "
+                      "FROM pg_collation");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -5236,7 +5216,7 @@ getCollations(Archive *fout, int *numCollations)
     i_oid = PQfnumber(res, "oid");
     i_collname = PQfnumber(res, "collname");
     i_collnamespace = PQfnumber(res, "collnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_collowner = PQfnumber(res, "collowner");

     for (i = 0; i < ntups; i++)
     {
@@ -5247,7 +5227,7 @@ getCollations(Archive *fout, int *numCollations)
         collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
         collinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
-        collinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));

         /* Decide whether we want to dump it */
         selectDumpableObject(&(collinfo[i].dobj), fout);
@@ -5279,7 +5259,7 @@ getConversions(Archive *fout, int *numConversions)
     int            i_oid;
     int            i_conname;
     int            i_connamespace;
-    int            i_rolname;
+    int            i_conowner;

     query = createPQExpBuffer();

@@ -5290,9 +5270,8 @@ getConversions(Archive *fout, int *numConversions)

     appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
                       "connamespace, "
-                      "(%s conowner) AS rolname "
-                      "FROM pg_conversion",
-                      username_subquery);
+                      "conowner "
+                      "FROM pg_conversion");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -5305,7 +5284,7 @@ getConversions(Archive *fout, int *numConversions)
     i_oid = PQfnumber(res, "oid");
     i_conname = PQfnumber(res, "conname");
     i_connamespace = PQfnumber(res, "connamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_conowner = PQfnumber(res, "conowner");

     for (i = 0; i < ntups; i++)
     {
@@ -5316,7 +5295,7 @@ getConversions(Archive *fout, int *numConversions)
         convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
         convinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
-        convinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));

         /* Decide whether we want to dump it */
         selectDumpableObject(&(convinfo[i].dobj), fout);
@@ -5419,7 +5398,7 @@ getOpclasses(Archive *fout, int *numOpclasses)
     int            i_oid;
     int            i_opcname;
     int            i_opcnamespace;
-    int            i_rolname;
+    int            i_opcowner;

     /*
      * find all opclasses, including builtin opclasses; we filter out
@@ -5428,9 +5407,8 @@ getOpclasses(Archive *fout, int *numOpclasses)

     appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
                       "opcnamespace, "
-                      "(%s opcowner) AS rolname "
-                      "FROM pg_opclass",
-                      username_subquery);
+                      "opcowner "
+                      "FROM pg_opclass");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -5443,7 +5421,7 @@ getOpclasses(Archive *fout, int *numOpclasses)
     i_oid = PQfnumber(res, "oid");
     i_opcname = PQfnumber(res, "opcname");
     i_opcnamespace = PQfnumber(res, "opcnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_opcowner = PQfnumber(res, "opcowner");

     for (i = 0; i < ntups; i++)
     {
@@ -5454,14 +5432,10 @@ getOpclasses(Archive *fout, int *numOpclasses)
         opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
         opcinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
-        opcinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));

         /* Decide whether we want to dump it */
         selectDumpableObject(&(opcinfo[i].dobj), fout);
-
-        if (strlen(opcinfo[i].rolname) == 0)
-            pg_log_warning("owner of operator class \"%s\" appears to be invalid",
-                           opcinfo[i].dobj.name);
     }

     PQclear(res);
@@ -5490,7 +5464,7 @@ getOpfamilies(Archive *fout, int *numOpfamilies)
     int            i_oid;
     int            i_opfname;
     int            i_opfnamespace;
-    int            i_rolname;
+    int            i_opfowner;

     query = createPQExpBuffer();

@@ -5501,9 +5475,8 @@ getOpfamilies(Archive *fout, int *numOpfamilies)

     appendPQExpBuffer(query, "SELECT tableoid, oid, opfname, "
                       "opfnamespace, "
-                      "(%s opfowner) AS rolname "
-                      "FROM pg_opfamily",
-                      username_subquery);
+                      "opfowner "
+                      "FROM pg_opfamily");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -5516,7 +5489,7 @@ getOpfamilies(Archive *fout, int *numOpfamilies)
     i_oid = PQfnumber(res, "oid");
     i_opfname = PQfnumber(res, "opfname");
     i_opfnamespace = PQfnumber(res, "opfnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_opfowner = PQfnumber(res, "opfowner");

     for (i = 0; i < ntups; i++)
     {
@@ -5527,14 +5500,10 @@ getOpfamilies(Archive *fout, int *numOpfamilies)
         opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
         opfinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
-        opfinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));

         /* Decide whether we want to dump it */
         selectDumpableObject(&(opfinfo[i].dobj), fout);
-
-        if (strlen(opfinfo[i].rolname) == 0)
-            pg_log_warning("owner of operator family \"%s\" appears to be invalid",
-                           opfinfo[i].dobj.name);
     }

     PQclear(res);
@@ -5566,7 +5535,7 @@ getAggregates(Archive *fout, int *numAggs)
     int            i_aggnamespace;
     int            i_pronargs;
     int            i_proargtypes;
-    int            i_rolname;
+    int            i_proowner;
     int            i_aggacl;
     int            i_acldefault;

@@ -5585,7 +5554,7 @@ getAggregates(Archive *fout, int *numAggs)
                           "p.proname AS aggname, "
                           "p.pronamespace AS aggnamespace, "
                           "p.pronargs, p.proargtypes, "
-                          "(%s p.proowner) AS rolname, "
+                          "p.proowner, "
                           "p.proacl AS aggacl, "
                           "acldefault('f', p.proowner) AS acldefault "
                           "FROM pg_proc p "
@@ -5598,7 +5567,6 @@ getAggregates(Archive *fout, int *numAggs)
                           "(SELECT oid FROM pg_namespace "
                           "WHERE nspname = 'pg_catalog') OR "
                           "p.proacl IS DISTINCT FROM pip.initprivs",
-                          username_subquery,
                           agg_check);
         if (dopt->binary_upgrade)
             appendPQExpBufferStr(query,
@@ -5614,15 +5582,14 @@ getAggregates(Archive *fout, int *numAggs)
         appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
                           "pronamespace AS aggnamespace, "
                           "pronargs, proargtypes, "
-                          "(%s proowner) AS rolname, "
+                          "proowner, "
                           "proacl AS aggacl, "
                           "acldefault('f', proowner) AS acldefault "
                           "FROM pg_proc p "
                           "WHERE proisagg AND ("
                           "pronamespace != "
                           "(SELECT oid FROM pg_namespace "
-                          "WHERE nspname = 'pg_catalog')",
-                          username_subquery);
+                          "WHERE nspname = 'pg_catalog')");
         if (dopt->binary_upgrade)
             appendPQExpBufferStr(query,
                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
@@ -5646,7 +5613,7 @@ getAggregates(Archive *fout, int *numAggs)
     i_aggnamespace = PQfnumber(res, "aggnamespace");
     i_pronargs = PQfnumber(res, "pronargs");
     i_proargtypes = PQfnumber(res, "proargtypes");
-    i_rolname = PQfnumber(res, "rolname");
+    i_proowner = PQfnumber(res, "proowner");
     i_aggacl = PQfnumber(res, "aggacl");
     i_acldefault = PQfnumber(res, "acldefault");

@@ -5663,10 +5630,7 @@ getAggregates(Archive *fout, int *numAggs)
         agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         agginfo[i].aggfn.dacl.privtype = 0;
         agginfo[i].aggfn.dacl.initprivs = NULL;
-        agginfo[i].aggfn.rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
-        if (strlen(agginfo[i].aggfn.rolname) == 0)
-            pg_log_warning("owner of aggregate function \"%s\" appears to be invalid",
-                           agginfo[i].aggfn.dobj.name);
+        agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
         agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
         agginfo[i].aggfn.prorettype = InvalidOid;    /* not saved */
         agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
@@ -5715,7 +5679,7 @@ getFuncs(Archive *fout, int *numFuncs)
     int            i_oid;
     int            i_proname;
     int            i_pronamespace;
-    int            i_rolname;
+    int            i_proowner;
     int            i_prolang;
     int            i_pronargs;
     int            i_proargtypes;
@@ -5757,7 +5721,7 @@ getFuncs(Archive *fout, int *numFuncs)
                           "p.proacl, "
                           "acldefault('f', p.proowner) AS acldefault, "
                           "p.pronamespace, "
-                          "(%s p.proowner) AS rolname "
+                          "p.proowner "
                           "FROM pg_proc p "
                           "LEFT JOIN pg_init_privs pip ON "
                           "(p.oid = pip.objoid "
@@ -5778,7 +5742,6 @@ getFuncs(Archive *fout, int *numFuncs)
                           "\n  WHERE pg_transform.oid > %u AND "
                           "\n  (p.oid = pg_transform.trffromsql"
                           "\n  OR p.oid = pg_transform.trftosql))",
-                          username_subquery,
                           not_agg_check,
                           g_last_builtin_oid,
                           g_last_builtin_oid);
@@ -5800,7 +5763,7 @@ getFuncs(Archive *fout, int *numFuncs)
                           "pronargs, proargtypes, prorettype, proacl, "
                           "acldefault('f', proowner) AS acldefault, "
                           "pronamespace, "
-                          "(%s proowner) AS rolname "
+                          "proowner "
                           "FROM pg_proc p "
                           "WHERE NOT proisagg"
                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
@@ -5813,7 +5776,6 @@ getFuncs(Archive *fout, int *numFuncs)
                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                           "\n  WHERE pg_cast.oid > '%u'::oid"
                           "\n  AND p.oid = pg_cast.castfunc)",
-                          username_subquery,
                           g_last_builtin_oid);

         if (fout->remoteVersion >= 90500)
@@ -5846,7 +5808,7 @@ getFuncs(Archive *fout, int *numFuncs)
     i_oid = PQfnumber(res, "oid");
     i_proname = PQfnumber(res, "proname");
     i_pronamespace = PQfnumber(res, "pronamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_proowner = PQfnumber(res, "proowner");
     i_prolang = PQfnumber(res, "prolang");
     i_pronargs = PQfnumber(res, "pronargs");
     i_proargtypes = PQfnumber(res, "proargtypes");
@@ -5867,7 +5829,7 @@ getFuncs(Archive *fout, int *numFuncs)
         finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         finfo[i].dacl.privtype = 0;
         finfo[i].dacl.initprivs = NULL;
-        finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
         finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
         finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
         finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
@@ -5886,10 +5848,6 @@ getFuncs(Archive *fout, int *numFuncs)
         /* Mark whether function has an ACL */
         if (!PQgetisnull(res, i, i_proacl))
             finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
-
-        if (strlen(finfo[i].rolname) == 0)
-            pg_log_warning("owner of function \"%s\" appears to be invalid",
-                           finfo[i].dobj.name);
     }

     PQclear(res);
@@ -5921,7 +5879,7 @@ getTables(Archive *fout, int *numTables)
     int            i_relnamespace;
     int            i_relkind;
     int            i_reltype;
-    int            i_rolname;
+    int            i_relowner;
     int            i_relchecks;
     int            i_relhasindex;
     int            i_relhasrules;
@@ -5973,7 +5931,7 @@ getTables(Archive *fout, int *numTables)
     appendPQExpBuffer(query,
                       "SELECT c.tableoid, c.oid, c.relname, "
                       "c.relnamespace, c.relkind, c.reltype, "
-                      "(%s c.relowner) AS rolname, "
+                      "c.relowner, "
                       "c.relchecks, "
                       "c.relhasindex, c.relhasrules, c.relpages, "
                       "c.relhastriggers, "
@@ -5991,8 +5949,7 @@ getTables(Archive *fout, int *numTables)
                       "tc.reloptions AS toast_reloptions, "
                       "d.refobjid AS owning_tab, "
                       "d.refobjsubid AS owning_col, "
-                      "tsp.spcname AS reltablespace, ",
-                      username_subquery);
+                      "tsp.spcname AS reltablespace, ");

     if (fout->remoteVersion >= 120000)
         appendPQExpBufferStr(query,
@@ -6141,7 +6098,7 @@ getTables(Archive *fout, int *numTables)
     i_relnamespace = PQfnumber(res, "relnamespace");
     i_relkind = PQfnumber(res, "relkind");
     i_reltype = PQfnumber(res, "reltype");
-    i_rolname = PQfnumber(res, "rolname");
+    i_relowner = PQfnumber(res, "relowner");
     i_relchecks = PQfnumber(res, "relchecks");
     i_relhasindex = PQfnumber(res, "relhasindex");
     i_relhasrules = PQfnumber(res, "relhasrules");
@@ -6203,7 +6160,7 @@ getTables(Archive *fout, int *numTables)
         tblinfo[i].dacl.initprivs = NULL;
         tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
         tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
-        tblinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
         tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
         tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
         tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
@@ -6311,11 +6268,6 @@ getTables(Archive *fout, int *numTables)
                               fmtQualifiedDumpable(&tblinfo[i]));
             ExecuteSqlStatement(fout, query->data);
         }
-
-        /* Emit notice if join for owner failed */
-        if (strlen(tblinfo[i].rolname) == 0)
-            pg_log_warning("owner of table \"%s\" appears to be invalid",
-                           tblinfo[i].dobj.name);
     }

     if (dopt->lockWaitTimeout)
@@ -6759,7 +6711,7 @@ getExtendedStatistics(Archive *fout)
     int            i_oid;
     int            i_stxname;
     int            i_stxnamespace;
-    int            i_rolname;
+    int            i_stxowner;
     int            i_stattarget;
     int            i;

@@ -6771,14 +6723,12 @@ getExtendedStatistics(Archive *fout)

     if (fout->remoteVersion < 130000)
         appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
-                          "stxnamespace, (%s stxowner) AS rolname, (-1) AS stxstattarget "
-                          "FROM pg_catalog.pg_statistic_ext",
-                          username_subquery);
+                          "stxnamespace, stxowner, (-1) AS stxstattarget "
+                          "FROM pg_catalog.pg_statistic_ext");
     else
         appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
-                          "stxnamespace, (%s stxowner) AS rolname, stxstattarget "
-                          "FROM pg_catalog.pg_statistic_ext",
-                          username_subquery);
+                          "stxnamespace, stxowner, stxstattarget "
+                          "FROM pg_catalog.pg_statistic_ext");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -6788,7 +6738,7 @@ getExtendedStatistics(Archive *fout)
     i_oid = PQfnumber(res, "oid");
     i_stxname = PQfnumber(res, "stxname");
     i_stxnamespace = PQfnumber(res, "stxnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_stxowner = PQfnumber(res, "stxowner");
     i_stattarget = PQfnumber(res, "stxstattarget");

     statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
@@ -6802,7 +6752,7 @@ getExtendedStatistics(Archive *fout)
         statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
         statsextinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
-        statsextinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
         statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));

         /* Decide whether we want to dump it */
@@ -7477,14 +7427,13 @@ getEventTriggers(Archive *fout, int *numEventTriggers)

     appendPQExpBuffer(query,
                       "SELECT e.tableoid, e.oid, evtname, evtenabled, "
-                      "evtevent, (%s evtowner) AS evtowner, "
+                      "evtevent, evtowner, "
                       "array_to_string(array("
                       "select quote_literal(x) "
                       " from unnest(evttags) as t(x)), ', ') as evttags, "
                       "e.evtfoid::regproc as evtfname "
                       "FROM pg_event_trigger e "
-                      "ORDER BY e.oid",
-                      username_subquery);
+                      "ORDER BY e.oid");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -7512,7 +7461,7 @@ getEventTriggers(Archive *fout, int *numEventTriggers)
         evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
         evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
         evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
-        evtinfo[i].evtowner = pg_strdup(PQgetvalue(res, i, i_evtowner));
+        evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
         evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
         evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
         evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
@@ -7561,11 +7510,10 @@ getProcLangs(Archive *fout, int *numProcLangs)
                       "laninline, lanvalidator, "
                       "lanacl, "
                       "acldefault('l', lanowner) AS acldefault, "
-                      "(%s lanowner) AS lanowner "
+                      "lanowner "
                       "FROM pg_language "
                       "WHERE lanispl "
-                      "ORDER BY oid",
-                      username_subquery);
+                      "ORDER BY oid");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -7602,7 +7550,7 @@ getProcLangs(Archive *fout, int *numProcLangs)
         planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
         planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
         planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
-        planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner));
+        planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));

         /* Decide whether we want to dump it */
         selectDumpableProcLang(&(planginfo[i]), fout);
@@ -8510,17 +8458,16 @@ getTSDictionaries(Archive *fout, int *numTSDicts)
     int            i_oid;
     int            i_dictname;
     int            i_dictnamespace;
-    int            i_rolname;
+    int            i_dictowner;
     int            i_dicttemplate;
     int            i_dictinitoption;

     query = createPQExpBuffer();

     appendPQExpBuffer(query, "SELECT tableoid, oid, dictname, "
-                      "dictnamespace, (%s dictowner) AS rolname, "
+                      "dictnamespace, dictowner, "
                       "dicttemplate, dictinitoption "
-                      "FROM pg_ts_dict",
-                      username_subquery);
+                      "FROM pg_ts_dict");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -8533,7 +8480,7 @@ getTSDictionaries(Archive *fout, int *numTSDicts)
     i_oid = PQfnumber(res, "oid");
     i_dictname = PQfnumber(res, "dictname");
     i_dictnamespace = PQfnumber(res, "dictnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_dictowner = PQfnumber(res, "dictowner");
     i_dictinitoption = PQfnumber(res, "dictinitoption");
     i_dicttemplate = PQfnumber(res, "dicttemplate");

@@ -8546,7 +8493,7 @@ getTSDictionaries(Archive *fout, int *numTSDicts)
         dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
         dictinfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
-        dictinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
         dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
         if (PQgetisnull(res, i, i_dictinitoption))
             dictinfo[i].dictinitoption = NULL;
@@ -8648,15 +8595,14 @@ getTSConfigurations(Archive *fout, int *numTSConfigs)
     int            i_oid;
     int            i_cfgname;
     int            i_cfgnamespace;
-    int            i_rolname;
+    int            i_cfgowner;
     int            i_cfgparser;

     query = createPQExpBuffer();

     appendPQExpBuffer(query, "SELECT tableoid, oid, cfgname, "
-                      "cfgnamespace, (%s cfgowner) AS rolname, cfgparser "
-                      "FROM pg_ts_config",
-                      username_subquery);
+                      "cfgnamespace, cfgowner, cfgparser "
+                      "FROM pg_ts_config");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -8669,7 +8615,7 @@ getTSConfigurations(Archive *fout, int *numTSConfigs)
     i_oid = PQfnumber(res, "oid");
     i_cfgname = PQfnumber(res, "cfgname");
     i_cfgnamespace = PQfnumber(res, "cfgnamespace");
-    i_rolname = PQfnumber(res, "rolname");
+    i_cfgowner = PQfnumber(res, "cfgowner");
     i_cfgparser = PQfnumber(res, "cfgparser");

     for (i = 0; i < ntups; i++)
@@ -8681,7 +8627,7 @@ getTSConfigurations(Archive *fout, int *numTSConfigs)
         cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
         cfginfo[i].dobj.namespace =
             findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
-        cfginfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
         cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));

         /* Decide whether we want to dump it */
@@ -8713,7 +8659,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
     int            i_tableoid;
     int            i_oid;
     int            i_fdwname;
-    int            i_rolname;
+    int            i_fdwowner;
     int            i_fdwhandler;
     int            i_fdwvalidator;
     int            i_fdwacl;
@@ -8723,7 +8669,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
     query = createPQExpBuffer();

     appendPQExpBuffer(query, "SELECT tableoid, oid, fdwname, "
-                      "(%s fdwowner) AS rolname, "
+                      "fdwowner, "
                       "fdwhandler::pg_catalog.regproc, "
                       "fdwvalidator::pg_catalog.regproc, "
                       "fdwacl, "
@@ -8734,8 +8680,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
                       "FROM pg_options_to_table(fdwoptions) "
                       "ORDER BY option_name"
                       "), E',\n    ') AS fdwoptions "
-                      "FROM pg_foreign_data_wrapper",
-                      username_subquery);
+                      "FROM pg_foreign_data_wrapper");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -8747,7 +8692,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
     i_tableoid = PQfnumber(res, "tableoid");
     i_oid = PQfnumber(res, "oid");
     i_fdwname = PQfnumber(res, "fdwname");
-    i_rolname = PQfnumber(res, "rolname");
+    i_fdwowner = PQfnumber(res, "fdwowner");
     i_fdwhandler = PQfnumber(res, "fdwhandler");
     i_fdwvalidator = PQfnumber(res, "fdwvalidator");
     i_fdwacl = PQfnumber(res, "fdwacl");
@@ -8766,7 +8711,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
         fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         fdwinfo[i].dacl.privtype = 0;
         fdwinfo[i].dacl.initprivs = NULL;
-        fdwinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
         fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
         fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
         fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
@@ -8804,7 +8749,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
     int            i_tableoid;
     int            i_oid;
     int            i_srvname;
-    int            i_rolname;
+    int            i_srvowner;
     int            i_srvfdw;
     int            i_srvtype;
     int            i_srvversion;
@@ -8815,7 +8760,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
     query = createPQExpBuffer();

     appendPQExpBuffer(query, "SELECT tableoid, oid, srvname, "
-                      "(%s srvowner) AS rolname, "
+                      "srvowner, "
                       "srvfdw, srvtype, srvversion, srvacl, "
                       "acldefault('S', srvowner) AS acldefault, "
                       "array_to_string(ARRAY("
@@ -8824,8 +8769,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
                       "FROM pg_options_to_table(srvoptions) "
                       "ORDER BY option_name"
                       "), E',\n    ') AS srvoptions "
-                      "FROM pg_foreign_server",
-                      username_subquery);
+                      "FROM pg_foreign_server");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -8837,7 +8781,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
     i_tableoid = PQfnumber(res, "tableoid");
     i_oid = PQfnumber(res, "oid");
     i_srvname = PQfnumber(res, "srvname");
-    i_rolname = PQfnumber(res, "rolname");
+    i_srvowner = PQfnumber(res, "srvowner");
     i_srvfdw = PQfnumber(res, "srvfdw");
     i_srvtype = PQfnumber(res, "srvtype");
     i_srvversion = PQfnumber(res, "srvversion");
@@ -8857,7 +8801,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
         srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         srvinfo[i].dacl.privtype = 0;
         srvinfo[i].dacl.initprivs = NULL;
-        srvinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+        srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
         srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
         srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
         srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
@@ -8921,7 +8865,7 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
      */
     appendPQExpBuffer(query,
                       "SELECT oid, tableoid, "
-                      "(%s defaclrole) AS defaclrole, "
+                      "defaclrole, "
                       "defaclnamespace, "
                       "defaclobjtype, "
                       "defaclacl, "
@@ -8929,8 +8873,7 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
                       "acldefault(CASE WHEN defaclobjtype = 'S' "
                       "THEN 's'::\"char\" ELSE defaclobjtype END, "
                       "defaclrole) ELSE '{}' END AS acldefault "
-                      "FROM pg_default_acl",
-                      username_subquery);
+                      "FROM pg_default_acl");

     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

@@ -8967,7 +8910,7 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
         daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
         daclinfo[i].dacl.privtype = 0;
         daclinfo[i].dacl.initprivs = NULL;
-        daclinfo[i].defaclrole = pg_strdup(PQgetvalue(res, i, i_defaclrole));
+        daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
         daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));

         /* Default ACLs are ACLs, of course */
@@ -8984,6 +8927,71 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
     return daclinfo;
 }

+/*
+ * getRoleName -- look up the name of a role, given its OID
+ *
+ * In current usage, we don't expect failures, so error out for a bad OID.
+ */
+static const char *
+getRoleName(const char *roleoid_str)
+{
+    Oid            roleoid = atooid(roleoid_str);
+
+    /*
+     * Do binary search to find the appropriate item.
+     */
+    if (nrolenames > 0)
+    {
+        RoleNameItem *low = &rolenames[0];
+        RoleNameItem *high = &rolenames[nrolenames - 1];
+
+        while (low <= high)
+        {
+            RoleNameItem *middle = low + (high - low) / 2;
+
+            if (roleoid < middle->roleoid)
+                high = middle - 1;
+            else if (roleoid > middle->roleoid)
+                low = middle + 1;
+            else
+                return middle->rolename;    /* found a match */
+        }
+    }
+
+    fatal("role with OID %u does not exist", roleoid);
+    return NULL;                /* keep compiler quiet */
+}
+
+/*
+ * collectRoleNames --
+ *
+ * Construct a table of all known roles.
+ * The table is sorted by OID for speed in lookup.
+ */
+static void
+collectRoleNames(Archive *fout)
+{
+    PGresult   *res;
+    const char *query;
+    int            i;
+
+    query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
+
+    res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
+
+    nrolenames = PQntuples(res);
+
+    rolenames = (RoleNameItem *) pg_malloc(nrolenames * sizeof(RoleNameItem));
+
+    for (i = 0; i < nrolenames; i++)
+    {
+        rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
+        rolenames[i].rolename = pg_strdup(PQgetvalue(res, i, 1));
+    }
+
+    PQclear(res);
+}
+
 /*
  * getAdditionalACLs
  *
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index f011ace8a8..f9deb321ac 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -171,8 +171,8 @@ typedef struct _namespaceInfo
     DumpableObject dobj;
     DumpableAcl dacl;
     bool        create;            /* CREATE SCHEMA, or just set owner? */
-    Oid            nspowner;
-    char       *rolname;        /* name of owner, or empty string */
+    Oid            nspowner;        /* OID of owner */
+    const char *rolname;        /* name of owner */
 } NamespaceInfo;

 typedef struct _extensionInfo
@@ -196,7 +196,7 @@ typedef struct _typeInfo
      * schema-qualified too.
      */
     char       *ftypname;
-    char       *rolname;        /* name of owner, or empty string */
+    const char *rolname;
     Oid            typelem;
     Oid            typrelid;
     char        typrelkind;        /* 'r', 'v', 'c', etc */
@@ -222,7 +222,7 @@ typedef struct _funcInfo
 {
     DumpableObject dobj;
     DumpableAcl dacl;
-    char       *rolname;        /* name of owner, or empty string */
+    const char *rolname;
     Oid            lang;
     int            nargs;
     Oid           *argtypes;
@@ -239,7 +239,7 @@ typedef struct _aggInfo
 typedef struct _oprInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
     char        oprkind;
     Oid            oprcode;
 } OprInfo;
@@ -254,25 +254,25 @@ typedef struct _accessMethodInfo
 typedef struct _opclassInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
 } OpclassInfo;

 typedef struct _opfamilyInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
 } OpfamilyInfo;

 typedef struct _collInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
 } CollInfo;

 typedef struct _convInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
 } ConvInfo;

 typedef struct _tableInfo
@@ -282,7 +282,7 @@ typedef struct _tableInfo
      */
     DumpableObject dobj;
     DumpableAcl dacl;
-    char       *rolname;        /* name of owner, or empty string */
+    const char *rolname;
     char        relkind;
     char        relpersistence; /* relation persistence */
     bool        relispopulated; /* relation is populated */
@@ -415,7 +415,7 @@ typedef struct _indexAttachInfo
 typedef struct _statsExtInfo
 {
     DumpableObject dobj;
-    char       *rolname;        /* name of owner, or empty string */
+    const char *rolname;
     int            stattarget;        /* statistics target */
 } StatsExtInfo;

@@ -454,7 +454,7 @@ typedef struct _evttriggerInfo
     DumpableObject dobj;
     char       *evtname;
     char       *evtevent;
-    char       *evtowner;
+    const char *evtowner;
     char       *evttags;
     char       *evtfname;
     char        evtenabled;
@@ -491,7 +491,7 @@ typedef struct _procLangInfo
     Oid            lanplcallfoid;
     Oid            laninline;
     Oid            lanvalidator;
-    char       *lanowner;        /* name of owner, or empty string */
+    const char *lanowner;
 } ProcLangInfo;

 typedef struct _castInfo
@@ -533,7 +533,7 @@ typedef struct _prsInfo
 typedef struct _dictInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
     Oid            dicttemplate;
     char       *dictinitoption;
 } TSDictInfo;
@@ -548,7 +548,7 @@ typedef struct _tmplInfo
 typedef struct _cfgInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
     Oid            cfgparser;
 } TSConfigInfo;

@@ -556,7 +556,7 @@ typedef struct _fdwInfo
 {
     DumpableObject dobj;
     DumpableAcl dacl;
-    char       *rolname;
+    const char *rolname;
     char       *fdwhandler;
     char       *fdwvalidator;
     char       *fdwoptions;
@@ -566,7 +566,7 @@ typedef struct _foreignServerInfo
 {
     DumpableObject dobj;
     DumpableAcl dacl;
-    char       *rolname;
+    const char *rolname;
     Oid            srvfdw;
     char       *srvtype;
     char       *srvversion;
@@ -577,7 +577,7 @@ typedef struct _defaultACLInfo
 {
     DumpableObject dobj;
     DumpableAcl dacl;
-    char       *defaclrole;
+    const char *defaclrole;
     char        defaclobjtype;
 } DefaultACLInfo;

@@ -585,7 +585,7 @@ typedef struct _blobInfo
 {
     DumpableObject dobj;
     DumpableAcl dacl;
-    char       *rolname;
+    const char *rolname;
 } BlobInfo;

 /*
@@ -612,7 +612,7 @@ typedef struct _policyInfo
 typedef struct _PublicationInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
     bool        puballtables;
     bool        pubinsert;
     bool        pubupdate;
@@ -649,7 +649,7 @@ typedef struct _PublicationSchemaInfo
 typedef struct _SubscriptionInfo
 {
     DumpableObject dobj;
-    char       *rolname;
+    const char *rolname;
     char       *subconninfo;
     char       *subslotname;
     char       *subbinary;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 76226de485..bdb7129ef5 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -6005,12 +6005,7 @@ getTables(Archive *fout, int *numTables)
 
     if (fout->remoteVersion >= 90600)
         appendPQExpBufferStr(query,
-                             "c.relkind = " CppAsString2(RELKIND_SEQUENCE)
-                             " AND EXISTS (SELECT 1 FROM pg_depend "
-                             "WHERE classid = 'pg_class'::regclass AND "
-                             "objid = c.oid AND objsubid = 0 AND "
-                             "refclassid = 'pg_class'::regclass AND "
-                             "deptype = 'i') AS is_identity_sequence, ");
+                             "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
     else
         appendPQExpBufferStr(query,
                              "false AS is_identity_sequence, ");

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Justin Pryzby
Дата:
Сообщение: Re: Column Filtering in Logical Replication
Следующее
От: Alvaro Herrera
Дата:
Сообщение: Re: Column Filtering in Logical Replication