diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 9ab05f74cc2..0b8dcde46ea 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -1008,10 +1008,12 @@ dumpRoleMembership(PGconn *conn) PGresult *res; int i; - printfPQExpBuffer(buf, "SELECT ur.rolname AS roleid, " + printfPQExpBuffer(buf, "SELECT ur.rolname AS role, " "um.rolname AS member, " "a.admin_option, " - "ug.rolname AS grantor " + "ug.rolname AS grantor, " + "a.roleid AS roleid, " + "a.member AS memberid " "FROM pg_auth_members a " "LEFT JOIN %s ur on ur.oid = a.roleid " "LEFT JOIN %s um on um.oid = a.member " @@ -1025,13 +1027,33 @@ dumpRoleMembership(PGconn *conn) for (i = 0; i < PQntuples(res); i++) { - char *roleid = PQgetvalue(res, i, 0); + char *role = PQgetvalue(res, i, 0); char *member = PQgetvalue(res, i, 1); - char *option = PQgetvalue(res, i, 2); + char *admin_option = PQgetvalue(res, i, 2); - fprintf(OPF, "GRANT %s", fmtId(roleid)); + /* + * Due to race conditions, the role and/or member could have been + * dropped. If we find such cases, print a warning and skip the + * entry. + */ + if (PQgetisnull(res, i, 0)) + { + /* translator: %s represents a numeric role OID */ + pg_log_warning("found orphaned pg_auth_members entry for role %s", + PQgetvalue(res, i, 4)); + continue; + } + if (PQgetisnull(res, i, 1)) + { + /* translator: %s represents a numeric role OID */ + pg_log_warning("found orphaned pg_auth_members entry for role %s", + PQgetvalue(res, i, 5)); + continue; + } + + fprintf(OPF, "GRANT %s", fmtId(role)); fprintf(OPF, " TO %s", fmtId(member)); - if (*option == 't') + if (*admin_option == 't') fprintf(OPF, " WITH ADMIN OPTION"); /*