From e4a9229d5512852c7cb73988644ae39894e8ff1d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 3 Dec 2005 21:06:18 +0000 Subject: [PATCH] Treat procedural languages as owned by the bootstrap superuser, rather 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 | 9 +++-- src/bin/pg_dump/pg_dump.c | 65 +++++++++++++++++++++++++------------ src/bin/pg_dump/pg_dump.h | 3 +- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 26f6c96f88..9502b1f16a 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -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) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index ab21b13ee4..fc2633f27b 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -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). diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index a3d694d04f..8e8e48f4db 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -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 -- GitLab