Thread: Patch for gripe about pg_dump -C not dumping database privileges

Patch for gripe about pg_dump -C not dumping database privileges

From
Tom Lane
Date:
Attached is a proposed patch for bug #2085.  It's pretty grotty because
it introduces a new TOC tag type into the pg_dump format, which makes it
incompatible with existing pg_restores; so I think we probably couldn't
back-patch this, it'd have to be treated as a new feature for 8.2.
I don't see any other way to do it, though, because we want pg_restore
to emit the information under different conditions than those under
which it emits regular object ACLs (namely, only if -C mode).

Comments, better ideas?  Should we just leave well enough alone?
IMHO #2085 is a definition disagreement, not an outright bug.

            regards, tom lane


*** src/bin/pg_dump/pg_backup_archiver.c.orig    Tue Nov 22 16:06:41 2005
--- src/bin/pg_dump/pg_backup_archiver.c    Fri Dec  2 17:01:46 2005
***************
*** 1877,1882 ****
--- 1877,1885 ----

      if (!ropt->create && strcmp(te->desc, "DATABASE") == 0)
          return 0;
+     if ((!ropt->create || ropt->aclsSkip) &&
+         strcmp(te->desc, "DATABASE ACL") == 0)
+         return 0;

      /* Check if tablename only is wanted */
      if (ropt->selTypes)
*** src/bin/pg_dump/pg_dump.c.orig    Tue Nov 22 16:06:41 2005
--- src/bin/pg_dump/pg_dump.c    Fri Dec  2 16:54:48 2005
***************
*** 1168,1179 ****
--- 1168,1181 ----
                  i_oid,
                  i_dba,
                  i_encoding,
+                 i_datacl,
                  i_tablespace;
      CatalogId    dbCatId;
      DumpId        dbDumpId;
      const char *datname,
                 *dba,
                 *encoding,
+                *datacl,
                 *tablespace;

      datname = PQdb(g_conn);
***************
*** 1190,1206 ****
--- 1192,1222 ----
          appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                            "(%s datdba) as dba, "
                            "pg_encoding_to_char(encoding) as encoding, "
+                           "datacl, "
                            "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace "
                            "FROM pg_database "
                            "WHERE datname = ",
                            username_subquery);
          appendStringLiteral(dbQry, datname, true);
      }
+     else if (g_fout->remoteVersion >= 70300)
+     {
+         appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
+                           "(%s datdba) as dba, "
+                           "pg_encoding_to_char(encoding) as encoding, "
+                           "datacl, "
+                           "NULL as tablespace "
+                           "FROM pg_database "
+                           "WHERE datname = ",
+                           username_subquery);
+         appendStringLiteral(dbQry, datname, true);
+     }
      else if (g_fout->remoteVersion >= 70100)
      {
          appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                            "(%s datdba) as dba, "
                            "pg_encoding_to_char(encoding) as encoding, "
+                           "NULL as datacl, "
                            "NULL as tablespace "
                            "FROM pg_database "
                            "WHERE datname = ",
***************
*** 1214,1219 ****
--- 1230,1236 ----
                            "oid, "
                            "(%s datdba) as dba, "
                            "pg_encoding_to_char(encoding) as encoding, "
+                           "NULL as datacl, "
                            "NULL as tablespace "
                            "FROM pg_database "
                            "WHERE datname = ",
***************
*** 1244,1255 ****
--- 1261,1274 ----
      i_oid = PQfnumber(res, "oid");
      i_dba = PQfnumber(res, "dba");
      i_encoding = PQfnumber(res, "encoding");
+     i_datacl = PQfnumber(res, "datacl");
      i_tablespace = PQfnumber(res, "tablespace");

      dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
      dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
      dba = PQgetvalue(res, 0, i_dba);
      encoding = PQgetvalue(res, 0, i_encoding);
+     datacl = PQgetvalue(res, 0, i_datacl);
      tablespace = PQgetvalue(res, 0, i_tablespace);

      appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
***************
*** 1292,1297 ****
--- 1311,1320 ----
      dumpComment(AH, dbQry->data, NULL, "",
                  dbCatId, 0, dbDumpId);

+     dumpACL(AH, dbCatId, dbDumpId, "DATABASE",
+             fmtId(datname), datname, NULL,
+             dba, datacl);
+
      PQclear(res);

      destroyPQExpBuffer(dbQry);
***************
*** 6689,6695 ****
   *
   * 'objCatId' is the catalog ID of the underlying object.
   * 'objDumpId' is the dump ID of the underlying object.
!  * 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA.
   * 'name' is the formatted name of the object.    Must be quoted etc. already.
   * 'tag' is the tag for the archive entry (typ. unquoted name of object).
   * 'nspname' is the namespace the object is in (NULL if none).
--- 6712,6718 ----
   *
   * 'objCatId' is the catalog ID of the underlying object.
   * 'objDumpId' is the dump ID of the underlying object.
!  * 'type' must be TABLE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE.
   * 'name' is the formatted name of the object.    Must be quoted etc. already.
   * 'tag' is the tag for the archive entry (typ. unquoted name of object).
   * 'nspname' is the namespace the object is in (NULL if none).
***************
*** 6705,6710 ****
--- 6728,6734 ----
          const char *acls)
  {
      PQExpBuffer sql;
+     const char *acltag;

      /* Do nothing if ACL dump is not enabled */
      if (dataOnly || aclsSkip)
***************
*** 6720,6732 ****
      }

      if (sql->len > 0)
          ArchiveEntry(fout, nilCatalogId, createDumpId(),
                       tag, nspname,
                       NULL,
                       owner ? owner : "",
!                      false, "ACL", sql->data, "", NULL,
                       &(objDumpId), 1,
                       NULL, NULL);

      destroyPQExpBuffer(sql);
  }
--- 6744,6763 ----
      }

      if (sql->len > 0)
+     {
+         if (strcmp(type, "DATABASE") == 0)
+             acltag = "DATABASE ACL";
+         else
+             acltag = "ACL";
+
          ArchiveEntry(fout, nilCatalogId, createDumpId(),
                       tag, nspname,
                       NULL,
                       owner ? owner : "",
!                      false, acltag, sql->data, "", NULL,
                       &(objDumpId), 1,
                       NULL, NULL);
+     }

      destroyPQExpBuffer(sql);
  }