OSDN Git Service

Add GRANT ON SEQUENCE syntax to support sequence-only permissions.
authorBruce Momjian <bruce@momjian.us>
Sat, 21 Jan 2006 02:16:21 +0000 (02:16 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 21 Jan 2006 02:16:21 +0000 (02:16 +0000)
Continue to support GRANT ON [TABLE] for sequences for backward
compatibility;  issue warning for invalid sequence permissions.

[Backward compatibility warning message.]

Add USAGE permission for sequences that allows only currval() and
nextval(), not setval().

Mention object name in grant/revoke warnings because of possible
multi-object operations.

13 files changed:
doc/src/sgml/ref/grant.sgml
doc/src/sgml/ref/revoke.sgml
src/backend/catalog/aclchk.c
src/backend/catalog/pg_shdepend.c
src/backend/commands/sequence.c
src/backend/parser/gram.y
src/backend/utils/adt/acl.c
src/bin/pg_dump/dumputils.c
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_dump.c
src/include/nodes/parsenodes.h
src/include/utils/acl.h
src/test/regress/expected/privileges.out

index bb9571a..e5ea4bb 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.50 2005/10/20 19:18:01 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.51 2006/01/21 02:16:18 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -25,6 +25,11 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
     ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
     TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
 
+GRANT { { USAGE | SELECT | UPDATE }
+    [,...] | ALL [ PRIVILEGES ] }
+    ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...]
+    TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
 GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
     ON DATABASE <replaceable>dbname</replaceable> [, ...]
     TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
@@ -260,6 +265,10 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
        also met).  Essentially this allows the grantee to <quote>look up</>
        objects within the schema.
       </para>
+      <para>
+       For sequences, this privilege allows the use of the
+       <function>currval</function> and <function>nextval</function> functions.
+      </para>
      </listitem>
     </varlistentry>
 
@@ -511,7 +520,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable>
 
    <para>
     The <literal>RULE</literal> privilege, and privileges on
-    databases, tablespaces, schemas, languages, and sequences are
+    databases, tablespaces, schemas, and languages are
     <productname>PostgreSQL</productname> extensions.
    </para>
  </refsect1>
index 68c69f8..f09642a 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.35 2005/10/20 19:18:01 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.36 2006/01/21 02:16:18 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -28,6 +28,13 @@ REVOKE [ GRANT OPTION FOR ]
     [ CASCADE | RESTRICT ]
 
 REVOKE [ GRANT OPTION FOR ]
+    { { USAGE | SELECT | UPDATE }
+    [,...] | ALL [ PRIVILEGES ] }
+    ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...]
+    FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
+    [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
     { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
     ON DATABASE <replaceable>dbname</replaceable> [, ...]
     FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
index 643d31c..dbdf523 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.123 2005/12/01 02:03:00 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.124 2006/01/21 02:16:18 momjian Exp $
  *
  * NOTES
  *       See acl.h.
@@ -164,6 +164,9 @@ restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
                case ACL_KIND_CLASS:
                        whole_mask = ACL_ALL_RIGHTS_RELATION;
                        break;
+               case ACL_KIND_SEQUENCE:
+                       whole_mask = ACL_ALL_RIGHTS_SEQUENCE;
+                       break;
                case ACL_KIND_DATABASE:
                        whole_mask = ACL_ALL_RIGHTS_DATABASE;
                        break;
@@ -212,22 +215,22 @@ restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
                if (this_privileges == 0)
                        ereport(WARNING,
                                        (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                        errmsg("no privileges were granted")));
+                                        errmsg("no privileges were granted for \"%s\"", objname)));
                else if (!all_privs && this_privileges != privileges)
                        ereport(WARNING,
                                        (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                        errmsg("not all privileges were granted")));
+                                        errmsg("not all privileges were granted for \"%s\"", objname)));
        }
        else
        {
                if (this_privileges == 0)
                        ereport(WARNING,
                                        (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                        errmsg("no privileges could be revoked")));
+                                        errmsg("no privileges could be revoked for \"%s\"", objname)));
                else if (!all_privs && this_privileges != privileges)
                        ereport(WARNING,
                                        (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                        errmsg("not all privileges could be revoked")));
+                                        errmsg("not all privileges could be revoked for \"%s\"", objname)));
        }
 
        return this_privileges;
@@ -282,9 +285,18 @@ ExecuteGrantStmt(GrantStmt *stmt)
         */
        switch (stmt->objtype)
        {
+               /*
+                *      Because this might be a sequence, we test both relation
+                *      and sequence bits, and later do a more limited test
+                *      when we know the object type.
+                */
                case ACL_OBJECT_RELATION:
-                       all_privileges = ACL_ALL_RIGHTS_RELATION;
-                       errormsg = _("invalid privilege type %s for table");
+                       all_privileges = ACL_ALL_RIGHTS_RELATION | ACL_ALL_RIGHTS_SEQUENCE;
+                       errormsg = _("invalid privilege type %s for relation");
+                       break;
+               case ACL_OBJECT_SEQUENCE:
+                       all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
+                       errormsg = _("invalid privilege type %s for sequence");
                        break;
                case ACL_OBJECT_DATABASE:
                        all_privileges = ACL_ALL_RIGHTS_DATABASE;
@@ -327,6 +339,7 @@ ExecuteGrantStmt(GrantStmt *stmt)
        {
                istmt.all_privs = false;
                istmt.privileges = ACL_NO_RIGHTS;
+
                foreach(cell, stmt->privileges)
                {
                        char       *privname = strVal(lfirst(cell));
@@ -356,6 +369,7 @@ ExecGrantStmt_oids(InternalGrant *istmt)
        switch (istmt->objtype)
        {
                case ACL_OBJECT_RELATION:
+               case ACL_OBJECT_SEQUENCE:
                        ExecGrant_Relation(istmt);
                        break;
                case ACL_OBJECT_DATABASE:
@@ -395,6 +409,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
        switch (objtype)
        {
                case ACL_OBJECT_RELATION:
+               case ACL_OBJECT_SEQUENCE:
                        foreach(cell, objnames)
                        {
                                Oid                     relOid;
@@ -523,15 +538,15 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
        return objects;
 }
 
+/*
+ *     This processes both sequences and non-sequences.
+ */
 static void
 ExecGrant_Relation(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
-               istmt->privileges = ACL_ALL_RIGHTS_RELATION;
-
        relation = heap_open(RelationRelationId, RowExclusiveLock);
 
        foreach(cell, istmt->objects)
@@ -577,6 +592,69 @@ ExecGrant_Relation(InternalGrant *istmt)
                                         errmsg("\"%s\" is a composite type",
                                                        NameStr(pg_class_tuple->relname))));
 
+               /* Used GRANT SEQUENCE on a non-sequence? */
+               if (istmt->objtype == ACL_OBJECT_SEQUENCE &&
+                       pg_class_tuple->relkind != RELKIND_SEQUENCE)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                                        errmsg("\"%s\" is not a sequence",
+                                                       NameStr(pg_class_tuple->relname))));
+
+               /* Adjust the default permissions based on whether it is a sequence */
+               if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               {
+                       if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
+                               this_privileges = ACL_ALL_RIGHTS_SEQUENCE;
+                       else
+                               this_privileges = ACL_ALL_RIGHTS_RELATION;
+               }
+               else
+                       this_privileges = istmt->privileges;
+               
+               /*
+                *      The GRANT TABLE syntax can be used for sequences and
+                *      non-sequences, so we have to look at the relkind to
+                *      determine the supported permissions.  The OR of
+                *      table and sequence permissions were already checked.
+                */
+               if (istmt->objtype == ACL_OBJECT_RELATION)
+               {
+                       if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
+                       {
+                               /*
+                                *      For backward compatibility, throw just a warning
+                                *      for invalid sequence permissions when using the
+                                *      non-sequence GRANT syntax is used.
+                                */
+                               if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_SEQUENCE))
+                               {
+                                       /*
+                                        *      Mention the object name because the user needs to
+                                        *      know which operations succeeded.  This is required
+                                        *      because WARNING allows the command to continue.
+                                        */
+                                       ereport(WARNING,
+                                                       (errcode(ERRCODE_INVALID_GRANT_OPERATION),
+                                                        errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE",
+                                                                       NameStr(pg_class_tuple->relname))));
+                                       this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE;
+                               }
+                       }
+                       else
+                       {
+                               if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
+                                       /*
+                                        *      USAGE is the only permission supported by sequences
+                                        *      but not by non-sequences.  Don't mention the object
+                                        *      name because we didn't in the combined TABLE |
+                                        *      SEQUENCE check.
+                                        */
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_INVALID_GRANT_OPERATION),
+                                                        errmsg("invalid privilege type USAGE for table")));
+                       }
+               }
+
                /*
                 * Get owner ID and working copy of existing ACL. If there's no ACL,
                 * substitute the proper default.
@@ -585,12 +663,14 @@ ExecGrant_Relation(InternalGrant *istmt)
                aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
                                                                   &isNull);
                if (isNull)
-                       old_acl = acldefault(ACL_OBJECT_RELATION, ownerId);
+                       old_acl = acldefault(pg_class_tuple->relkind == RELKIND_SEQUENCE ?
+                                                                ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
+                                                                ownerId);
                else
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), istmt->privileges,
+               select_best_grantor(GetUserId(), this_privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
@@ -600,8 +680,10 @@ ExecGrant_Relation(InternalGrant *istmt)
                 */
                this_privileges =
                        restrict_and_check_grant(istmt->is_grant, avail_goptions,
-                                                                        istmt->all_privs, istmt->privileges,
-                                                                        relOid, grantorId, ACL_KIND_CLASS,
+                                                                        istmt->all_privs, this_privileges,
+                                                                        relOid, grantorId,
+                                                                        pg_class_tuple->relkind == RELKIND_SEQUENCE
+                                                                               ? ACL_KIND_SEQUENCE : ACL_KIND_CLASS,
                                                                         NameStr(pg_class_tuple->relname));
 
                /*
@@ -1336,6 +1418,8 @@ static const char *const no_priv_msg[MAX_ACL_KIND] =
 {
        /* ACL_KIND_CLASS */
        gettext_noop("permission denied for relation %s"),
+       /* ACL_KIND_SEQUENCE */
+       gettext_noop("permission denied for sequence %s"),
        /* ACL_KIND_DATABASE */
        gettext_noop("permission denied for database %s"),
        /* ACL_KIND_PROC */
@@ -1360,6 +1444,8 @@ static const char *const not_owner_msg[MAX_ACL_KIND] =
 {
        /* ACL_KIND_CLASS */
        gettext_noop("must be owner of relation %s"),
+       /* ACL_KIND_SEQUENCE */
+       gettext_noop("must be owner of sequence %s"),
        /* ACL_KIND_DATABASE */
        gettext_noop("must be owner of database %s"),
        /* ACL_KIND_PROC */
@@ -1439,6 +1525,7 @@ pg_aclmask(AclObjectKind objkind, Oid table_oid, Oid roleid,
        switch (objkind)
        {
                case ACL_KIND_CLASS:
+               case ACL_KIND_SEQUENCE:
                        return pg_class_aclmask(table_oid, roleid, mask, how);
                case ACL_KIND_DATABASE:
                        return pg_database_aclmask(table_oid, roleid, mask, how);
@@ -1500,9 +1587,9 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
         *
         * As of 7.4 we have some updatable system views; those shouldn't be
         * protected in this way.  Assume the view rules can take care of
-        * themselves.
+        * themselves.  ACL_USAGE is if we ever have system sequences.
         */
-       if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
+       if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE)) &&
                IsSystemClass(classForm) &&
                classForm->relkind != RELKIND_VIEW &&
                !has_rolcatupdate(roleid) &&
@@ -1511,7 +1598,7 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
 #ifdef ACLDEBUG
                elog(DEBUG2, "permission denied for system catalog update");
 #endif
-               mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE);
+               mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE);
        }
 
        /*
@@ -1536,7 +1623,9 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
        if (isNull)
        {
                /* No ACL, so build default ACL */
-               acl = acldefault(ACL_OBJECT_RELATION, ownerId);
+               acl = acldefault(classForm->relkind == RELKIND_SEQUENCE ?
+                                                       ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
+                                                ownerId);
                aclDatum = (Datum) 0;
        }
        else
index faa64c2..e57a228 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.6 2005/12/01 02:03:00 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.7 2006/01/21 02:16:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1133,8 +1133,25 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
                                        switch (sdepForm->classid)
                                        {
                                                case RelationRelationId:
-                                                       istmt.objtype = ACL_OBJECT_RELATION;
+                                               {
+                                                       /* is it a sequence or non-sequence? */
+                                                       Form_pg_class pg_class_tuple;
+                                                       HeapTuple       tuple;
+
+                                                       tuple = SearchSysCache(RELOID,
+                                                               ObjectIdGetDatum(sdepForm->objid),
+                                                               0, 0, 0);
+                                                       if (!HeapTupleIsValid(tuple))
+                                                               elog(ERROR, "cache lookup failed for relation %u",
+                                                                                       sdepForm->objid);
+                                                       pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
+                                                       if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
+                                                               istmt.objtype = ACL_OBJECT_SEQUENCE;
+                                                       else
+                                                               istmt.objtype = ACL_OBJECT_RELATION;
+                                                       ReleaseSysCache(tuple);
                                                        break;
+                                               }
                                                case DatabaseRelationId:
                                                        istmt.objtype = ACL_OBJECT_DATABASE;
                                                        break;
index 9c1efe8..53244cb 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.126 2005/11/22 18:17:09 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.127 2006/01/21 02:16:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -422,7 +422,8 @@ nextval_internal(Oid relid)
        /* open and AccessShareLock sequence */
        init_sequence(relid, &elm, &seqrel);
 
-       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
+       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK &&
+               pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
                ereport(ERROR,
                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                 errmsg("permission denied for sequence %s",
@@ -613,7 +614,8 @@ currval_oid(PG_FUNCTION_ARGS)
        /* open and AccessShareLock sequence */
        init_sequence(relid, &elm, &seqrel);
 
-       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
+       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
+               pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
                ereport(ERROR,
                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                 errmsg("permission denied for sequence %s",
@@ -657,7 +659,8 @@ lastval(PG_FUNCTION_ARGS)
        /* nextval() must have already been called for this sequence */
        Assert(last_used_seq->increment != 0);
 
-       if (pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
+       if (pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
+               pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
                ereport(ERROR,
                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                 errmsg("permission denied for sequence %s",
index ceb7143..41b22d8 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.521 2005/12/29 04:53:18 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.522 2006/01/21 02:16:19 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -3322,6 +3322,13 @@ privilege_target:
                                        n->objs = $2;
                                        $$ = n;
                                }
+                       | SEQUENCE qualified_name_list
+                               {
+                                       PrivTarget *n = makeNode(PrivTarget);
+                                       n->objtype = ACL_OBJECT_SEQUENCE;
+                                       n->objs = $2;
+                                       $$ = n;
+                               }
                        | FUNCTION function_with_argtypes_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
index 9282c41..2232e04 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.129 2005/11/18 02:38:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.130 2006/01/21 02:16:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -545,6 +545,10 @@ acldefault(GrantObjectType objtype, Oid ownerId)
                        world_default = ACL_NO_RIGHTS;
                        owner_default = ACL_ALL_RIGHTS_RELATION;
                        break;
+               case ACL_OBJECT_SEQUENCE:
+                       world_default = ACL_NO_RIGHTS;
+                       owner_default = ACL_ALL_RIGHTS_SEQUENCE;
+                       break;
                case ACL_OBJECT_DATABASE:
                        world_default = ACL_CREATE_TEMP;        /* not NO_RIGHTS! */
                        owner_default = ACL_ALL_RIGHTS_DATABASE;
index a4d1fa4..7bdce3b 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.24 2006/01/11 21:24:30 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.25 2006/01/21 02:16:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,8 +22,7 @@
 #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,
+                        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);
@@ -326,7 +325,7 @@ parsePGArray(const char *atext, char ***itemarray, int *nitems)
  *
  *     name: the object name, in the form to use in the commands (already quoted)
  *     type: the object type (as seen in GRANT command: must be one of
- *             TABLE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
+ *             TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
  *     acls: the ACL string fetched from the database
  *     owner: username of object owner (will be passed through fmtId); can be
  *             NULL or empty string to indicate "no owner known"
@@ -515,8 +514,7 @@ buildACLCommands(const char *name, const char *type,
  */
 static bool
 parseAclItem(const char *item, const char *type, const char *name,
-                        int remoteVersion,
-                        PQExpBuffer grantee, PQExpBuffer grantor,
+                        int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
                         PQExpBuffer privs, PQExpBuffer privswgo)
 {
        char       *buf;
@@ -547,6 +545,7 @@ parseAclItem(const char *item, const char *type, const char *name,
 
        /* privilege codes */
 #define CONVERT_PRIV(code, keywd) \
+do { \
        if ((pos = strchr(eqpos + 1, code))) \
        { \
                if (*(pos + 1) == '*') \
@@ -561,29 +560,38 @@ parseAclItem(const char *item, const char *type, const char *name,
                } \
        } \
        else \
-               all_with_go = all_without_go = false
+               all_with_go = all_without_go = false; \
+} while (0)
 
        resetPQExpBuffer(privs);
        resetPQExpBuffer(privswgo);
 
-       if (strcmp(type, "TABLE") == 0)
+       if (strcmp(type, "TABLE") == 0 || strcmp(type, "SEQUENCE") == 0)
        {
-               CONVERT_PRIV('a', "INSERT");
                CONVERT_PRIV('r', "SELECT");
-               CONVERT_PRIV('R', "RULE");
-
-               if (remoteVersion >= 70200)
+               
+               if (strcmp(type, "SEQUENCE") == 0)
+                       /* sequence only */
+                       CONVERT_PRIV('U', "USAGE");
+               else
                {
-                       CONVERT_PRIV('w', "UPDATE");
-                       CONVERT_PRIV('d', "DELETE");
-                       CONVERT_PRIV('x', "REFERENCES");
-                       CONVERT_PRIV('t', "TRIGGER");
+                       /* table only */
+                       CONVERT_PRIV('a', "INSERT");
+                       CONVERT_PRIV('R', "RULE");
+                       if (remoteVersion >= 70200)
+                       {
+                               CONVERT_PRIV('d', "DELETE");
+                               CONVERT_PRIV('x', "REFERENCES");
+                               CONVERT_PRIV('t', "TRIGGER");
+                       }
                }
+
+               /* UPDATE */
+               if (remoteVersion >= 70200 || strcmp(type, "SEQUENCE") == 0)
+                       CONVERT_PRIV('w', "UPDATE");
                else
-               {
                        /* 7.0 and 7.1 have a simpler worldview */
                        CONVERT_PRIV('w', "UPDATE,DELETE");
-               }
        }
        else if (strcmp(type, "FUNCTION") == 0)
                CONVERT_PRIV('X', "EXECUTE");
index a450185..4a31162 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.118 2005/11/22 18:17:28 momjian Exp $
+ *             $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.119 2006/01/21 02:16:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1889,7 +1889,8 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
                        if (strcmp(ropt->schemaNames, te->namespace) != 0)
                                return 0;
                }
-               if ((strcmp(te->desc, "TABLE") == 0) || (strcmp(te->desc, "TABLE DATA") == 0))
+               if (strcmp(te->desc, "TABLE") == 0 ||
+                       strcmp(te->desc, "TABLE DATA") == 0)
                {
                        if (!ropt->selTable)
                                return 0;
@@ -2276,8 +2277,7 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
        const char *type = te->desc;
 
        /* Use ALTER TABLE for views and sequences */
-       if (strcmp(type, "VIEW") == 0 ||
-               strcmp(type, "SEQUENCE") == 0)
+       if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0)
                type = "TABLE";
 
        /* objects named by a schema and name */
index 1ae6730..3dffc9b 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.426 2006/01/09 21:16:17 tgl Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.427 2006/01/21 02:16:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -6788,7 +6788,8 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
 
                /* Handle the ACL here */
                namecopy = strdup(fmtId(tbinfo->dobj.name));
-               dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
+               dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
+                               (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE",
                                namecopy, tbinfo->dobj.name,
                                tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                                tbinfo->relacl);
index ba39652..e738ec2 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/include/nodes/parsenodes.h,v 1.298 2005/12/07 15:20:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.299 2006/01/21 02:16:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -884,7 +884,8 @@ typedef struct AlterDomainStmt
  */
 typedef enum GrantObjectType
 {
-       ACL_OBJECT_RELATION,            /* table, view, sequence */
+       ACL_OBJECT_RELATION,            /* table, view */
+       ACL_OBJECT_SEQUENCE,            /* sequence */
        ACL_OBJECT_DATABASE,            /* database */
        ACL_OBJECT_FUNCTION,            /* function */
        ACL_OBJECT_LANGUAGE,            /* procedural language */
index 8e6cb95..4967970 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/include/utils/acl.h,v 1.91 2005/12/01 02:03:01 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.92 2006/01/21 02:16:21 momjian Exp $
  *
  * NOTES
  *       An ACL array is simply an array of AclItems, representing the union
@@ -143,6 +143,7 @@ typedef ArrayType Acl;
  * Bitmasks defining "all rights" for each supported object type
  */
 #define ACL_ALL_RIGHTS_RELATION                (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
+#define ACL_ALL_RIGHTS_SEQUENCE                (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
 #define ACL_ALL_RIGHTS_DATABASE                (ACL_CREATE|ACL_CREATE_TEMP)
 #define ACL_ALL_RIGHTS_FUNCTION                (ACL_EXECUTE)
 #define ACL_ALL_RIGHTS_LANGUAGE                (ACL_USAGE)
@@ -169,6 +170,7 @@ typedef enum
 typedef enum AclObjectKind
 {
        ACL_KIND_CLASS,                         /* pg_class */
+       ACL_KIND_SEQUENCE,                      /* pg_sequence */
        ACL_KIND_DATABASE,                      /* pg_database */
        ACL_KIND_PROC,                          /* pg_proc */
        ACL_KIND_OPER,                          /* pg_operator */
index 354f5b2..a18116a 100644 (file)
@@ -90,7 +90,7 @@ ERROR:  permission denied for relation atest2
 COPY atest2 FROM stdin; -- fail
 ERROR:  permission denied for relation atest2
 GRANT ALL ON atest1 TO PUBLIC; -- fail
-WARNING:  no privileges were granted
+WARNING:  no privileges were granted for "atest1"
 -- checks in subquery, both ok
 SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
  a | b 
@@ -227,7 +227,7 @@ ERROR:  language "c" is not trusted
 HINT:  Only superusers may use untrusted languages.
 SET SESSION AUTHORIZATION regressuser1;
 GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
-WARNING:  no privileges were granted
+WARNING:  no privileges were granted for "sql"
 CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
 CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
 REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
@@ -551,7 +551,7 @@ GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
 SET SESSION AUTHORIZATION regressuser2;
 GRANT SELECT ON atest4 TO regressuser3;
 GRANT UPDATE ON atest4 TO regressuser3; -- fail
-WARNING:  no privileges were granted
+WARNING:  no privileges were granted for "atest4"
 SET SESSION AUTHORIZATION regressuser1;
 REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
 SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true