Skip to content

Commit 74bdf96

Browse files
committed
Fix pg_dumpall to do something sane when a pre-8.1 installation has
identically named user and group: we merge these into a single entity with LOGIN permission. Also, add ORDER BY commands to ensure consistent dump ordering, for ease of comparing outputs from different installations.
1 parent 39ec43a commit 74bdf96

File tree

1 file changed

+55
-37
lines changed

1 file changed

+55
-37
lines changed

src/bin/pg_dump/pg_dumpall.c

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1994, Regents of the University of California
77
*
88
*
9-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.73 2006/03/30 01:08:15 adunstan Exp $
9+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.74 2006/04/07 21:26:29 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -425,14 +425,16 @@ dumpRoles(PGconn *conn)
425425
"rolcanlogin, rolconnlimit, rolpassword, "
426426
"rolvaliduntil, "
427427
"pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
428-
"FROM pg_authid");
428+
"FROM pg_authid "
429+
"ORDER BY 1");
429430
else if (server_version >= 80100)
430431
printfPQExpBuffer(buf,
431432
"SELECT rolname, rolsuper, rolinherit, "
432433
"rolcreaterole, rolcreatedb, rolcatupdate, "
433434
"rolcanlogin, rolconnlimit, rolpassword, "
434435
"rolvaliduntil, null as rolcomment "
435-
"FROM pg_authid");
436+
"FROM pg_authid "
437+
"ORDER BY 1");
436438
else
437439
printfPQExpBuffer(buf,
438440
"SELECT usename as rolname, "
@@ -459,7 +461,10 @@ dumpRoles(PGconn *conn)
459461
"null::text as rolpassword, "
460462
"null::abstime as rolvaliduntil, "
461463
"null as rolcomment "
462-
"FROM pg_group");
464+
"FROM pg_group "
465+
"WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
466+
" WHERE usename = groname) "
467+
"ORDER BY 1");
463468

464469
res = executeQuery(conn, buf->data);
465470

@@ -578,7 +583,8 @@ dumpRoleMembership(PGconn *conn)
578583
"FROM pg_auth_members a "
579584
"LEFT JOIN pg_authid ur on ur.oid = a.roleid "
580585
"LEFT JOIN pg_authid um on um.oid = a.member "
581-
"LEFT JOIN pg_authid ug on ug.oid = a.grantor");
586+
"LEFT JOIN pg_authid ug on ug.oid = a.grantor "
587+
"ORDER BY 1,2,3");
582588

583589
if (PQntuples(res) > 0)
584590
printf("--\n-- Role memberships\n--\n\n");
@@ -617,42 +623,52 @@ dumpGroups(PGconn *conn)
617623
PGresult *res;
618624
int i;
619625

620-
res = executeQuery(conn, "SELECT groname, grolist FROM pg_group");
626+
res = executeQuery(conn,
627+
"SELECT groname, grolist FROM pg_group ORDER BY 1");
621628

622629
if (PQntuples(res) > 0)
623630
printf("--\n-- Role memberships\n--\n\n");
624631

625632
for (i = 0; i < PQntuples(res); i++)
626633
{
627634
char *groname = PQgetvalue(res, i, 0);
628-
char *val;
629-
char *tok;
635+
char *grolist = PQgetvalue(res, i, 1);
636+
PGresult *res2;
637+
int j;
630638

631-
val = strdup(PQgetvalue(res, i, 1));
632-
633-
tok = strtok(val, ",{}");
634-
while (tok)
635-
{
636-
PGresult *res2;
637-
int j;
639+
/*
640+
* Array representation is {1,2,3} ... convert to (1,2,3)
641+
*/
642+
if (strlen(grolist) < 3)
643+
continue;
638644

639-
printfPQExpBuffer(buf,
640-
"SELECT usename FROM pg_shadow WHERE usesysid = %s",
641-
tok);
645+
grolist = strdup(grolist);
646+
grolist[0] = '(';
647+
grolist[strlen(grolist) - 1] = ')';
648+
printfPQExpBuffer(buf,
649+
"SELECT usename FROM pg_shadow "
650+
"WHERE usesysid IN %s ORDER BY 1",
651+
grolist);
652+
free(grolist);
642653

643-
res2 = executeQuery(conn, buf->data);
654+
res2 = executeQuery(conn, buf->data);
644655

645-
for (j = 0; j < PQntuples(res2); j++)
646-
{
647-
printf("GRANT %s", fmtId(groname));
648-
printf(" TO %s;\n", fmtId(PQgetvalue(res2, j, 0)));
649-
}
656+
for (j = 0; j < PQntuples(res2); j++)
657+
{
658+
char *usename = PQgetvalue(res2, j, 0);
650659

651-
PQclear(res2);
660+
/*
661+
* Don't try to grant a role to itself; can happen if old
662+
* installation has identically named user and group.
663+
*/
664+
if (strcmp(groname, usename) == 0)
665+
continue;
652666

653-
tok = strtok(NULL, ",{}");
667+
printf("GRANT %s", fmtId(groname));
668+
printf(" TO %s;\n", fmtId(usename));
654669
}
655-
free(val);
670+
671+
PQclear(res2);
656672
}
657673

658674
PQclear(res);
@@ -676,18 +692,20 @@ dumpTablespaces(PGconn *conn)
676692
*/
677693
if (server_version >= 80200)
678694
res = executeQuery(conn, "SELECT spcname, "
679-
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
680-
"spclocation, spcacl, "
681-
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
682-
"FROM pg_catalog.pg_tablespace "
683-
"WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'");
695+
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
696+
"spclocation, spcacl, "
697+
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
698+
"FROM pg_catalog.pg_tablespace "
699+
"WHERE spcname !~ '^pg_' "
700+
"ORDER BY 1");
684701
else
685702
res = executeQuery(conn, "SELECT spcname, "
686-
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
687-
"spclocation, spcacl, "
688-
"null "
689-
"FROM pg_catalog.pg_tablespace "
690-
"WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'");
703+
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
704+
"spclocation, spcacl, "
705+
"null "
706+
"FROM pg_catalog.pg_tablespace "
707+
"WHERE spcname !~ '^pg_' "
708+
"ORDER BY 1");
691709

692710
if (PQntuples(res) > 0)
693711
printf("--\n-- Tablespaces\n--\n\n");

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy