OSDN Git Service

Fix pg_dumpall to do something sane when a pre-8.1 installation has
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 7 Apr 2006 21:26:29 +0000 (21:26 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 7 Apr 2006 21:26:29 +0000 (21:26 +0000)
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.

src/bin/pg_dump/pg_dumpall.c

index ccb2253..71edfde 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.73 2006/03/30 01:08:15 adunstan Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.74 2006/04/07 21:26:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -425,14 +425,16 @@ dumpRoles(PGconn *conn)
                                                  "rolcanlogin, rolconnlimit, rolpassword, "
                                                  "rolvaliduntil, "
                                                  "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
-                                                 "FROM pg_authid");
+                                                 "FROM pg_authid "
+                                                 "ORDER BY 1");
        else if (server_version >= 80100)
                printfPQExpBuffer(buf,
                                                  "SELECT rolname, rolsuper, rolinherit, "
                                                  "rolcreaterole, rolcreatedb, rolcatupdate, "
                                                  "rolcanlogin, rolconnlimit, rolpassword, "
                                                  "rolvaliduntil, null as rolcomment "
-                                                 "FROM pg_authid");
+                                                 "FROM pg_authid "
+                                                 "ORDER BY 1");
        else
                printfPQExpBuffer(buf,
                                                  "SELECT usename as rolname, "
@@ -459,7 +461,10 @@ dumpRoles(PGconn *conn)
                                                  "null::text as rolpassword, "
                                                  "null::abstime as rolvaliduntil, "
                                                  "null as rolcomment "
-                                                 "FROM pg_group");
+                                                 "FROM pg_group "
+                                                 "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
+                                                 " WHERE usename = groname) "
+                                                 "ORDER BY 1");
 
        res = executeQuery(conn, buf->data);
 
@@ -578,7 +583,8 @@ dumpRoleMembership(PGconn *conn)
                                           "FROM pg_auth_members a "
                                           "LEFT JOIN pg_authid ur on ur.oid = a.roleid "
                                           "LEFT JOIN pg_authid um on um.oid = a.member "
-                                          "LEFT JOIN pg_authid ug on ug.oid = a.grantor");
+                                          "LEFT JOIN pg_authid ug on ug.oid = a.grantor "
+                                          "ORDER BY 1,2,3");
 
        if (PQntuples(res) > 0)
                printf("--\n-- Role memberships\n--\n\n");
@@ -617,7 +623,8 @@ dumpGroups(PGconn *conn)
        PGresult   *res;
        int                     i;
 
-       res = executeQuery(conn, "SELECT groname, grolist FROM pg_group");
+       res = executeQuery(conn,
+                                          "SELECT groname, grolist FROM pg_group ORDER BY 1");
 
        if (PQntuples(res) > 0)
                printf("--\n-- Role memberships\n--\n\n");
@@ -625,34 +632,43 @@ dumpGroups(PGconn *conn)
        for (i = 0; i < PQntuples(res); i++)
        {
                char       *groname = PQgetvalue(res, i, 0);
-               char       *val;
-               char       *tok;
+               char       *grolist = PQgetvalue(res, i, 1);
+               PGresult   *res2;
+               int                     j;
 
-               val = strdup(PQgetvalue(res, i, 1));
-
-               tok = strtok(val, ",{}");
-               while (tok)
-               {
-                       PGresult   *res2;
-                       int                     j;
+               /*
+                * Array representation is {1,2,3} ... convert to (1,2,3)
+                */
+               if (strlen(grolist) < 3)
+                       continue;
 
-                       printfPQExpBuffer(buf,
-                                                "SELECT usename FROM pg_shadow WHERE usesysid = %s",
-                                                         tok);
+               grolist = strdup(grolist);
+               grolist[0] = '(';
+               grolist[strlen(grolist) - 1] = ')';
+               printfPQExpBuffer(buf,
+                                                 "SELECT usename FROM pg_shadow "
+                                                 "WHERE usesysid IN %s ORDER BY 1",
+                                                 grolist);
+               free(grolist);
 
-                       res2 = executeQuery(conn, buf->data);
+               res2 = executeQuery(conn, buf->data);
 
-                       for (j = 0; j < PQntuples(res2); j++)
-                       {
-                               printf("GRANT %s", fmtId(groname));
-                               printf(" TO %s;\n", fmtId(PQgetvalue(res2, j, 0)));
-                       }
+               for (j = 0; j < PQntuples(res2); j++)
+               {
+                       char       *usename = PQgetvalue(res2, j, 0);
 
-                       PQclear(res2);
+                       /*
+                        * Don't try to grant a role to itself; can happen if old
+                        * installation has identically named user and group.
+                        */
+                       if (strcmp(groname, usename) == 0)
+                               continue;
 
-                       tok = strtok(NULL, ",{}");
+                       printf("GRANT %s", fmtId(groname));
+                       printf(" TO %s;\n", fmtId(usename));
                }
-               free(val);
+
+               PQclear(res2);
        }
 
        PQclear(res);
@@ -676,18 +692,20 @@ dumpTablespaces(PGconn *conn)
         */
        if (server_version >= 80200)
                res = executeQuery(conn, "SELECT spcname, "
-                                          "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
-                                          "spclocation, spcacl, "
-                                          "pg_catalog.shobj_description(oid, 'pg_tablespace') "
-                                          "FROM pg_catalog.pg_tablespace "
-                                          "WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'");
+                                                  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
+                                                  "spclocation, spcacl, "
+                                                  "pg_catalog.shobj_description(oid, 'pg_tablespace') "
+                                                  "FROM pg_catalog.pg_tablespace "
+                                                  "WHERE spcname !~ '^pg_' "
+                                                  "ORDER BY 1");
        else 
                res = executeQuery(conn, "SELECT spcname, "
-                                          "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
-                                          "spclocation, spcacl, "
-                                          "null "
-                                          "FROM pg_catalog.pg_tablespace "
-                                          "WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'");
+                                                  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
+                                                  "spclocation, spcacl, "
+                                                  "null "
+                                                  "FROM pg_catalog.pg_tablespace "
+                                                  "WHERE spcname !~ '^pg_' "
+                                                  "ORDER BY 1");
 
        if (PQntuples(res) > 0)
                printf("--\n-- Tablespaces\n--\n\n");