Treat procedural languages as owned by the bootstrap superuser, rather
authorTom Lane
Sat, 3 Dec 2005 21:06:18 +0000 (21:06 +0000)
committerTom Lane
Sat, 3 Dec 2005 21:06:18 +0000 (21:06 +0000)
than owned by nobody.  This results in cleaner display of language ACLs,
since the backend's aclchk.c uses the same convention.  AFAICS there is
no practical difference but it's nice to avoid emitting SET SESSION
AUTHORIZATION; also this will make it easier to transition pg_dump to
some future version in which we may include an explicit ownership column
in pg_language.  Per gripe from David Begley.

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

index 26f6c96f88ea6e62fb4aac0c00b780357b597dd3..9502b1f16a27965fba7d524471f68ffdcc150ea0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.22 2005/12/02 22:06:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.23 2005/12/03 21:06:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -328,7 +328,8 @@ parsePGArray(const char *atext, char ***itemarray, int *nitems)
  * type: the object type (as seen in GRANT command: must be one of
  *     TABLE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
  * acls: the ACL string fetched from the database
- * owner: username of object owner (will be passed through fmtId), or NULL
+ * owner: username of object owner (will be passed through fmtId); can be
+ *     NULL or empty string to indicate "no owner known"
  * remoteVersion: version of database
  *
  * Returns TRUE if okay, FALSE if could not parse the acl string.
@@ -357,6 +358,10 @@ buildACLCommands(const char *name, const char *type,
    if (strlen(acls) == 0)
        return true;            /* object has default permissions */
 
+   /* treat empty-string owner same as NULL */
+   if (owner && *owner == '\0')
+       owner = NULL;
+
    if (!parsePGArray(acls, &aclitems, &naclitems))
    {
        if (aclitems)
index ab21b13ee4453ce43e1069737e84abfaa9a16505..fc2633f27bc2860f6853ef9baeb13bc03d168a91 100644 (file)
@@ -12,7 +12,7 @@
  * by PostgreSQL
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.423 2005/11/22 18:17:28 momjian Exp $
+ *   $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.424 2005/12/03 21:06:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3493,14 +3493,36 @@ getProcLangs(int *numProcLangs)
    int         i_lanname;
    int         i_lanpltrusted;
    int         i_lanplcallfoid;
-   int         i_lanvalidator = -1;
-   int         i_lanacl = -1;
+   int         i_lanvalidator;
+   int         i_lanacl;
+   int         i_lanowner;
 
    /* Make sure we are in proper schema */
    selectSourceSchema("pg_catalog");
 
-   if (g_fout->remoteVersion >= 70100)
+   if (g_fout->remoteVersion >= 80100)
    {
+       /* Languages are owned by the bootstrap superuser, OID 10 */
+       appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
+                         "(%s '10') as lanowner "
+                         "FROM pg_language "
+                         "WHERE lanispl "
+                         "ORDER BY oid",
+                         username_subquery);
+   }
+   else if (g_fout->remoteVersion >= 70400)
+   {
+       /* Languages are owned by the bootstrap superuser, sysid 1 */
+       appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
+                         "(%s '1') as lanowner "
+                         "FROM pg_language "
+                         "WHERE lanispl "
+                         "ORDER BY oid",
+                         username_subquery);
+   }
+   else if (g_fout->remoteVersion >= 70100)
+   {
+       /* No clear notion of an owner at all before 7.4 ... */
        appendPQExpBuffer(query, "SELECT tableoid, oid, * FROM pg_language "
                          "WHERE lanispl "
                          "ORDER BY oid");
@@ -3528,11 +3550,10 @@ getProcLangs(int *numProcLangs)
    i_lanname = PQfnumber(res, "lanname");
    i_lanpltrusted = PQfnumber(res, "lanpltrusted");
    i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
-   if (g_fout->remoteVersion >= 70300)
-   {
-       i_lanvalidator = PQfnumber(res, "lanvalidator");
-       i_lanacl = PQfnumber(res, "lanacl");
-   }
+   /* these may fail and return -1: */
+   i_lanvalidator = PQfnumber(res, "lanvalidator");
+   i_lanacl = PQfnumber(res, "lanacl");
+   i_lanowner = PQfnumber(res, "lanowner");
 
    for (i = 0; i < ntups; i++)
    {
@@ -3544,24 +3565,28 @@ getProcLangs(int *numProcLangs)
        planginfo[i].dobj.name = strdup(PQgetvalue(res, i, i_lanname));
        planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
        planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
-       if (g_fout->remoteVersion >= 70300)
-       {
+       if (i_lanvalidator >= 0)
            planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
-           planginfo[i].lanacl = strdup(PQgetvalue(res, i, i_lanacl));
-       }
        else
-       {
-           FuncInfo   *funcInfo;
-
            planginfo[i].lanvalidator = InvalidOid;
+       if (i_lanacl >= 0)
+           planginfo[i].lanacl = strdup(PQgetvalue(res, i, i_lanacl));
+       else
            planginfo[i].lanacl = strdup("{=U}");
+       if (i_lanowner >= 0)
+           planginfo[i].lanowner = strdup(PQgetvalue(res, i, i_lanowner));
+       else
+           planginfo[i].lanowner = strdup("");
 
+       if (g_fout->remoteVersion < 70300)
+       {
            /*
             * We need to make a dependency to ensure the function will be
             * dumped first.  (In 7.3 and later the regular dependency
             * mechanism will handle this for us.)
             */
-           funcInfo = findFuncByOid(planginfo[i].lanplcallfoid);
+           FuncInfo   *funcInfo = findFuncByOid(planginfo[i].lanplcallfoid);
+
            if (funcInfo)
                addObjectDependency(&planginfo[i].dobj,
                                    funcInfo->dobj.dumpId);
@@ -5171,7 +5196,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
    ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
                 plang->dobj.name,
-                lanschema, NULL, "",
+                lanschema, NULL, plang->lanowner,
                 false, "PROCEDURAL LANGUAGE",
                 defqry->data, delqry->data, NULL,
                 plang->dobj.dependencies, plang->dobj.nDeps,
@@ -5188,7 +5213,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
        dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE",
                qlanname, plang->dobj.name,
                lanschema,
-               NULL, plang->lanacl);
+               plang->lanowner, plang->lanacl);
 
    free(qlanname);
 
@@ -6689,7 +6714,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
  *
  * '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.
+ * '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).
index a3d694d04feddaeed9b749f8768e86272f26a7c2..8e8e48f4db8083432636b6712d2891ccf2062154 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.122 2005/10/15 02:49:39 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.123 2005/12/03 21:06:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -297,6 +297,7 @@ typedef struct _procLangInfo
    Oid         lanplcallfoid;
    Oid         lanvalidator;
    char       *lanacl;
+   char       *lanowner;       /* name of owner, or empty string */
 } ProcLangInfo;
 
 typedef struct _castInfo