aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/dumputils.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-01-22 20:16:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-01-22 20:16:10 +0000
commit3cb5d6580a335e0b7fcf25da7fcebee3a776edb4 (patch)
tree53580564c946729c7f352b0dc26c7ee389a9d3a6 /src/bin/pg_dump/dumputils.c
parentbf136cf6e376ae1a636341e5c8471c55299f9122 (diff)
downloadpostgresql-3cb5d6580a335e0b7fcf25da7fcebee3a776edb4.tar.gz
postgresql-3cb5d6580a335e0b7fcf25da7fcebee3a776edb4.zip
Support column-level privileges, as required by SQL standard.
Stephen Frost, with help from KaiGai Kohei and others
Diffstat (limited to 'src/bin/pg_dump/dumputils.c')
-rw-r--r--src/bin/pg_dump/dumputils.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 819bb4d2e61..85b3373c535 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.43 2009/01/01 17:23:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.44 2009/01/22 20:16:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,11 +23,13 @@
#define supports_grant_options(version) ((version) >= 70400)
-static bool parseAclItem(const char *item, const char *type, const char *name,
- int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
+static bool parseAclItem(const char *item, const char *type,
+ const char *name, const char *subname, int remoteVersion,
+ PQExpBuffer grantee, PQExpBuffer grantor,
PQExpBuffer privs, PQExpBuffer privswgo);
static char *copyAclUserName(PQExpBuffer output, char *input);
-static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
+static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
+ const char *subname);
/*
@@ -384,6 +386,7 @@ parsePGArray(const char *atext, char ***itemarray, int *nitems)
* Build GRANT/REVOKE command(s) for an object.
*
* name: the object name, in the form to use in the commands (already quoted)
+ * subname: the sub-object name, if any (already quoted); NULL if none
* type: the object type (as seen in GRANT command: must be one of
* TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
* acls: the ACL string fetched from the database
@@ -394,12 +397,12 @@ parsePGArray(const char *atext, char ***itemarray, int *nitems)
* Returns TRUE if okay, FALSE if could not parse the acl string.
* The resulting commands (if any) are appended to the contents of 'sql'.
*
- * Note: beware of passing fmtId() result as 'name', since this routine
- * uses fmtId() internally.
+ * Note: beware of passing a fmtId() result directly as 'name' or 'subname',
+ * since this routine uses fmtId() internally.
*/
bool
-buildACLCommands(const char *name, const char *type,
- const char *acls, const char *owner,
+buildACLCommands(const char *name, const char *subname,
+ const char *type, const char *acls, const char *owner,
int remoteVersion,
PQExpBuffer sql)
{
@@ -448,8 +451,10 @@ buildACLCommands(const char *name, const char *type,
* wire-in knowledge about the default public privileges for different
* kinds of objects.
*/
- appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM PUBLIC;\n",
- type, name);
+ appendPQExpBuffer(firstsql, "REVOKE ALL");
+ if (subname)
+ appendPQExpBuffer(firstsql, "(%s)", subname);
+ appendPQExpBuffer(firstsql, " ON %s %s FROM PUBLIC;\n", type, name);
/*
* We still need some hacking though to cover the case where new default
@@ -468,7 +473,7 @@ buildACLCommands(const char *name, const char *type,
/* Scan individual ACL items */
for (i = 0; i < naclitems; i++)
{
- if (!parseAclItem(aclitems[i], type, name, remoteVersion,
+ if (!parseAclItem(aclitems[i], type, name, subname, remoteVersion,
grantee, grantor, privs, privswgo))
return false;
@@ -491,15 +496,19 @@ buildACLCommands(const char *name, const char *type,
? strcmp(privswgo->data, "ALL") != 0
: strcmp(privs->data, "ALL") != 0)
{
- appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM %s;\n",
- type, name,
- fmtId(grantee->data));
+ appendPQExpBuffer(firstsql, "REVOKE ALL");
+ if (subname)
+ appendPQExpBuffer(firstsql, "(%s)", subname);
+ appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n",
+ type, name, fmtId(grantee->data));
if (privs->len > 0)
- appendPQExpBuffer(firstsql, "GRANT %s ON %s %s TO %s;\n",
+ appendPQExpBuffer(firstsql,
+ "GRANT %s ON %s %s TO %s;\n",
privs->data, type, name,
fmtId(grantee->data));
if (privswgo->len > 0)
- appendPQExpBuffer(firstsql, "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
+ appendPQExpBuffer(firstsql,
+ "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
privswgo->data, type, name,
fmtId(grantee->data));
}
@@ -553,8 +562,13 @@ buildACLCommands(const char *name, const char *type,
* If we didn't find any owner privs, the owner must have revoked 'em all
*/
if (!found_owner_privs && owner)
- appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM %s;\n",
+ {
+ appendPQExpBuffer(firstsql, "REVOKE ALL");
+ if (subname)
+ appendPQExpBuffer(firstsql, "(%s)", subname);
+ appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n",
type, name, fmtId(owner));
+ }
destroyPQExpBuffer(grantee);
destroyPQExpBuffer(grantor);
@@ -587,8 +601,9 @@ buildACLCommands(const char *name, const char *type,
* appropriate.
*/
static bool
-parseAclItem(const char *item, const char *type, const char *name,
- int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
+parseAclItem(const char *item, const char *type,
+ const char *name, const char *subname, int remoteVersion,
+ PQExpBuffer grantee, PQExpBuffer grantor,
PQExpBuffer privs, PQExpBuffer privswgo)
{
char *buf;
@@ -626,12 +641,12 @@ do { \
{ \
if (*(pos + 1) == '*') \
{ \
- AddAcl(privswgo, keywd); \
+ AddAcl(privswgo, keywd, subname); \
all_without_go = false; \
} \
else \
{ \
- AddAcl(privs, keywd); \
+ AddAcl(privs, keywd, subname); \
all_with_go = false; \
} \
} \
@@ -654,13 +669,18 @@ do { \
/* table only */
CONVERT_PRIV('a', "INSERT");
if (remoteVersion >= 70200)
- {
- CONVERT_PRIV('d', "DELETE");
CONVERT_PRIV('x', "REFERENCES");
- CONVERT_PRIV('t', "TRIGGER");
+ /* rest are not applicable to columns */
+ if (subname == NULL)
+ {
+ if (remoteVersion >= 70200)
+ {
+ CONVERT_PRIV('d', "DELETE");
+ CONVERT_PRIV('t', "TRIGGER");
+ }
+ if (remoteVersion >= 80400)
+ CONVERT_PRIV('D', "TRUNCATE");
}
- if (remoteVersion >= 80400)
- CONVERT_PRIV('D', "TRUNCATE");
}
/* UPDATE */
@@ -700,11 +720,15 @@ do { \
{
resetPQExpBuffer(privs);
printfPQExpBuffer(privswgo, "ALL");
+ if (subname)
+ appendPQExpBuffer(privswgo, "(%s)", subname);
}
else if (all_without_go)
{
resetPQExpBuffer(privswgo);
printfPQExpBuffer(privs, "ALL");
+ if (subname)
+ appendPQExpBuffer(privs, "(%s)", subname);
}
free(buf);
@@ -757,11 +781,13 @@ copyAclUserName(PQExpBuffer output, char *input)
* Append a privilege keyword to a keyword list, inserting comma if needed.
*/
static void
-AddAcl(PQExpBuffer aclbuf, const char *keyword)
+AddAcl(PQExpBuffer aclbuf, const char *keyword, const char *subname)
{
if (aclbuf->len > 0)
appendPQExpBufferChar(aclbuf, ',');
appendPQExpBuffer(aclbuf, "%s", keyword);
+ if (subname)
+ appendPQExpBuffer(aclbuf, "(%s)", subname);
}