pg_dump: minor performance improvements from eliminating sub-SELECTs.
authorTom Lane
Fri, 31 Dec 2021 16:39:26 +0000 (11:39 -0500)
committerTom Lane
Fri, 31 Dec 2021 16:39:26 +0000 (11:39 -0500)
Get rid of the "username_subquery" mechanism in favor of doing
local lookups of role names from role OIDs.  The PG backend isn't
terribly smart about scalar SubLinks in SELECT output lists,
so this offers a small performance improvement, at least in
installations with more than a couple of users.  In any case
the old method didn't make for particularly readable SQL code.

While at it, I removed the various custom warning messages about
failing to find an object's owner, in favor of just fatal'ing
in the local lookup function.  AFAIK there is no reason any
longer to treat that as anything but a catalog-corruption case,
and certainly no reason to make translators deal with a dozen
different messages where one would do.  (If it turns out that
fatal() is indeed a bad idea, we can back off to issuing
pg_log_warning() and returning an empty string, resulting in
the same behavior as before, except more consistent.)

Also drop an entirely unnecessary sub-SELECT to check on the
pg_depend status of a sequence relation: we already have a
LEFT JOIN to fetch the row of interest in the FROM clause.

Discussion: https://postgr.es/m/2460369.1640903318@sss.pgh.pa.us

src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index 7a5851e4c5b1275ca28d43a7d7da0705e46bee7d..ba19746ec30df5d7c22c15fee104b2c6b14e18db 100644 (file)
 #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);
    }
@@ -4232,7 +4233,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;
@@ -4267,10 +4268,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");
@@ -4301,7 +4301,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");
@@ -4320,7 +4320,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;
@@ -4337,10 +4337,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);
    }
@@ -4762,7 +4758,6 @@ getNamespaces(Archive *fout, int *numNamespaces)
    int         i_oid;
    int         i_nspname;
    int         i_nspowner;
-   int         i_rolname;
    int         i_nspacl;
    int         i_acldefault;
 
@@ -4774,11 +4769,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);
 
@@ -4790,12 +4783,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));
@@ -4805,8 +4799,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);
@@ -4855,10 +4850,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);
@@ -4981,7 +4972,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;
@@ -5007,15 +4998,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);
 
@@ -5029,7 +5019,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");
@@ -5051,7 +5041,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);
@@ -5119,10 +5109,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;
@@ -5153,7 +5139,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;
 
@@ -5164,11 +5150,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);
 
@@ -5181,7 +5166,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");
 
@@ -5194,16 +5179,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);
@@ -5232,7 +5213,7 @@ getCollations(Archive *fout, int *numCollations)
    int         i_oid;
    int         i_collname;
    int         i_collnamespace;
-   int         i_rolname;
+   int         i_collowner;
 
    query = createPQExpBuffer();
 
@@ -5243,9 +5224,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);
 
@@ -5258,7 +5238,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++)
    {
@@ -5269,7 +5249,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);
@@ -5301,7 +5281,7 @@ getConversions(Archive *fout, int *numConversions)
    int         i_oid;
    int         i_conname;
    int         i_connamespace;
-   int         i_rolname;
+   int         i_conowner;
 
    query = createPQExpBuffer();
 
@@ -5312,9 +5292,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);
 
@@ -5327,7 +5306,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++)
    {
@@ -5338,7 +5317,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);
@@ -5441,7 +5420,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
@@ -5450,9 +5429,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);
 
@@ -5465,7 +5443,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++)
    {
@@ -5476,14 +5454,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);
@@ -5512,7 +5486,7 @@ getOpfamilies(Archive *fout, int *numOpfamilies)
    int         i_oid;
    int         i_opfname;
    int         i_opfnamespace;
-   int         i_rolname;
+   int         i_opfowner;
 
    query = createPQExpBuffer();
 
@@ -5523,9 +5497,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);
 
@@ -5538,7 +5511,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++)
    {
@@ -5549,14 +5522,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);
@@ -5588,7 +5557,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;
 
@@ -5607,7 +5576,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 "
@@ -5620,7 +5589,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,
@@ -5636,15 +5604,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 "
@@ -5668,7 +5635,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");
 
@@ -5685,10 +5652,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));
@@ -5737,7 +5701,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;
@@ -5779,7 +5743,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 "
@@ -5800,7 +5764,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);
@@ -5822,7 +5785,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 "
@@ -5835,7 +5798,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)
@@ -5868,7 +5830,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");
@@ -5889,7 +5851,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));
@@ -5908,10 +5870,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);
@@ -5943,7 +5901,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;
@@ -5995,7 +5953,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, "
@@ -6013,8 +5971,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,
@@ -6070,12 +6027,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, ");
@@ -6163,7 +6115,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");
@@ -6225,7 +6177,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);
@@ -6333,11 +6285,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)
@@ -6781,7 +6728,7 @@ getExtendedStatistics(Archive *fout)
    int         i_oid;
    int         i_stxname;
    int         i_stxnamespace;
-   int         i_rolname;
+   int         i_stxowner;
    int         i_stattarget;
    int         i;
 
@@ -6793,14 +6740,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);
 
@@ -6810,7 +6755,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));
@@ -6824,7 +6769,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 */
@@ -7499,14 +7444,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);
 
@@ -7534,7 +7478,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));
@@ -7583,11 +7527,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);
 
@@ -7624,7 +7567,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);
@@ -8532,17 +8475,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);
 
@@ -8555,7 +8497,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");
 
@@ -8568,7 +8510,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;
@@ -8670,15 +8612,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);
 
@@ -8691,7 +8632,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++)
@@ -8703,7 +8644,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 */
@@ -8735,7 +8676,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;
@@ -8745,7 +8686,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, "
@@ -8756,8 +8697,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);
 
@@ -8769,7 +8709,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");
@@ -8788,7 +8728,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));
@@ -8826,7 +8766,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;
@@ -8837,7 +8777,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("
@@ -8846,8 +8786,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);
 
@@ -8859,7 +8798,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");
@@ -8879,7 +8818,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));
@@ -8943,7 +8882,7 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
     */
    appendPQExpBuffer(query,
                      "SELECT oid, tableoid, "
-                     "(%s defaclrole) AS defaclrole, "
+                     "defaclrole, "
                      "defaclnamespace, "
                      "defaclobjtype, "
                      "defaclacl, "
@@ -8951,8 +8890,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);
 
@@ -8989,7 +8927,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 */
@@ -9006,6 +8944,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
  *
index f011ace8a80f15ec3d95e705b89a1b6eb6f60f7e..f9deb321ac7578845836e66885e0ad5aed1009e7 100644 (file)
@@ -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;