OSDN Git Service

Refactor some bits in aclchk.c in order to reduce code duplication.
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 1 Dec 2005 02:03:01 +0000 (02:03 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 1 Dec 2005 02:03:01 +0000 (02:03 +0000)
src/backend/catalog/aclchk.c
src/backend/catalog/pg_shdepend.c
src/include/utils/acl.h

index 690a24e..643d31c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.122 2005/11/22 18:17:07 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.123 2005/12/01 02:03:00 alvherre Exp $
  *
  * NOTES
  *       See acl.h.
 #include "utils/syscache.h"
 
 
-static void ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior);
-static void ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior);
-static void ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior);
-static void ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior);
-static void ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
-                                       AclMode privileges, List *grantees, bool grant_option,
-                                       DropBehavior behavior);
-static void ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
-                                        AclMode privileges, List *grantees, bool grant_option,
-                                        DropBehavior behavior);
-static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
+static void ExecGrant_Relation(InternalGrant *grantStmt);
+static void ExecGrant_Database(InternalGrant *grantStmt);
+static void ExecGrant_Function(InternalGrant *grantStmt);
+static void ExecGrant_Language(InternalGrant *grantStmt);
+static void ExecGrant_Namespace(InternalGrant *grantStmt);
+static void ExecGrant_Tablespace(InternalGrant *grantStmt);
 
+static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
 static AclMode string_to_privilege(const char *privname);
 static const char *privilege_to_string(AclMode privilege);
+static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
+                                                                               bool all_privs, AclMode privileges,
+                                                                               Oid objectId, Oid grantorId,
+                                                                               AclObjectKind objkind, char *objname);
+static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, Oid roleid,
+                  AclMode mask, AclMaskHow how);
 
 
 #ifdef ACLDEBUG
@@ -153,6 +147,91 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
        return new_acl;
 }
 
+/*
+ * Restrict the privileges to what we can actually grant, and emit
+ * the standards-mandated warning and error messages.
+ */
+static AclMode
+restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
+                                                AclMode privileges, Oid objectId, Oid grantorId,
+                                                AclObjectKind objkind, char *objname)
+{
+       AclMode this_privileges;
+       AclMode whole_mask;
+
+       switch (objkind)
+       {
+               case ACL_KIND_CLASS:
+                       whole_mask = ACL_ALL_RIGHTS_RELATION;
+                       break;
+               case ACL_KIND_DATABASE:
+                       whole_mask = ACL_ALL_RIGHTS_DATABASE;
+                       break;
+               case ACL_KIND_PROC:
+                       whole_mask = ACL_ALL_RIGHTS_FUNCTION;
+                       break;
+               case ACL_KIND_LANGUAGE:
+                       whole_mask = ACL_ALL_RIGHTS_LANGUAGE;
+                       break;
+               case ACL_KIND_NAMESPACE:
+                       whole_mask = ACL_ALL_RIGHTS_NAMESPACE;
+                       break;
+               case ACL_KIND_TABLESPACE:
+                       whole_mask = ACL_ALL_RIGHTS_TABLESPACE;
+                       break;
+               default:
+                       elog(ERROR, "unrecognized object kind: %d", objkind);
+                       /* not reached, but keep compiler quiet */
+                       return ACL_NO_RIGHTS;
+       }
+
+       /*
+        * If we found no grant options, consider whether to issue a hard
+        * error.  Per spec, having any privilege at all on the object will
+        * get you by here.
+        */
+       if (avail_goptions == ACL_NO_RIGHTS)
+       {
+               if (pg_aclmask(objkind, objectId, grantorId,
+                                          whole_mask | ACL_GRANT_OPTION_FOR(whole_mask),
+                                          ACLMASK_ANY) == ACL_NO_RIGHTS)
+                       aclcheck_error(ACLCHECK_NO_PRIV, objkind, objname);
+       }
+
+       /*
+        * Restrict the operation to what we can actually grant or revoke, and
+        * issue a warning if appropriate.      (For REVOKE this isn't quite what
+        * the spec says to do: the spec seems to want a warning only if no
+        * privilege bits actually change in the ACL. In practice that
+        * behavior seems much too noisy, as well as inconsistent with the
+        * GRANT case.)
+        */
+       this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
+       if (is_grant)
+       {
+               if (this_privileges == 0)
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
+                                        errmsg("no privileges were granted")));
+               else if (!all_privs && this_privileges != privileges)
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
+                                        errmsg("not all privileges were granted")));
+       }
+       else
+       {
+               if (this_privileges == 0)
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
+                                        errmsg("no privileges could be revoked")));
+               else if (!all_privs && this_privileges != privileges)
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
+                                        errmsg("not all privileges could be revoked")));
+       }
+
+       return this_privileges;
+}
 
 /*
  * Called to execute the utility commands GRANT and REVOKE
@@ -160,13 +239,24 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
 void
 ExecuteGrantStmt(GrantStmt *stmt)
 {
-       List       *objects;
-       List       *grantees = NIL;
-       AclMode         privileges;
+       InternalGrant istmt;
        ListCell   *cell;
-       bool            all_privs;
-       AclMode         all_privileges = (AclMode) 0;
-       char       *errormsg = NULL;
+       char       *errormsg;
+       AclMode         all_privileges;
+
+       /*
+        * Turn the regular GrantStmt into the InternalGrant form.
+        */
+       istmt.is_grant = stmt->is_grant;
+       istmt.objtype = stmt->objtype;
+       istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
+       /* all_privs to be filled below */
+       /* privileges to be filled below */
+       istmt.grantees = NIL;
+       /* filled below */
+       istmt.grant_option = stmt->grant_option;
+       istmt.behavior = stmt->behavior;
+
 
        /*
         * Convert the PrivGrantee list into an Oid list.  Note that at this point
@@ -180,15 +270,15 @@ ExecuteGrantStmt(GrantStmt *stmt)
                PrivGrantee *grantee = (PrivGrantee *) lfirst(cell);
 
                if (grantee->rolname == NULL)
-                       grantees = lappend_oid(grantees, ACL_ID_PUBLIC);
+                       istmt.grantees = lappend_oid(istmt.grantees, ACL_ID_PUBLIC);
                else
-                       grantees = lappend_oid(grantees,
-                                                                  get_roleid_checked(grantee->rolname));
+                       istmt.grantees =
+                               lappend_oid(istmt.grantees,
+                                                       get_roleid_checked(grantee->rolname));
        }
 
        /*
-        * Convert stmt->privileges, a textual list, into an AclMode bitmask
-        * appropiate for the given object class.
+        * Convert stmt->privileges, a textual list, into an AclMode bitmask.
         */
        switch (stmt->objtype)
        {
@@ -217,19 +307,26 @@ ExecuteGrantStmt(GrantStmt *stmt)
                        errormsg = _("invalid privilege type %s for tablespace");
                        break;
                default:
+                       /* keep compiler quiet */
+                       all_privileges = ACL_NO_RIGHTS;
+                       errormsg = NULL;
                        elog(ERROR, "unrecognized GrantStmt.objtype: %d",
                                 (int) stmt->objtype);
        }
 
        if (stmt->privileges == NIL)
        {
-               all_privs = true;
-               privileges = all_privileges;
+               istmt.all_privs = true;
+               /*
+                * will be turned into ACL_ALL_RIGHTS_* by the internal routines
+                * depending on the object type
+                */
+               istmt.privileges = ACL_NO_RIGHTS;
        }
        else
        {
-               all_privs = false;
-               privileges = ACL_NO_RIGHTS;
+               istmt.all_privs = false;
+               istmt.privileges = ACL_NO_RIGHTS;
                foreach(cell, stmt->privileges)
                {
                        char       *privname = strVal(lfirst(cell));
@@ -241,61 +338,44 @@ ExecuteGrantStmt(GrantStmt *stmt)
                                                 errmsg(errormsg,
                                                                privilege_to_string(priv))));
 
-                       privileges |= priv;
+                       istmt.privileges |= priv;
                }
        }
 
-       /* Turn the list of object names into an Oid list */
-       objects = objectNamesToOids(stmt->objtype, stmt->objects);
-
-       ExecGrantStmt_oids(stmt->is_grant, stmt->objtype, objects, all_privs,
-                                          privileges, grantees, stmt->grant_option,
-                                          stmt->behavior);
+       ExecGrantStmt_oids(&istmt);
 }
 
 /*
  * ExecGrantStmt_oids
  *
- * "Internal" entrypoint for granting and revoking privileges. The arguments
- * it receives are lists of Oids or have been otherwise converted from text
- * format to internal format.
+ * "Internal" entrypoint for granting and revoking privileges.
  */
 void
-ExecGrantStmt_oids(bool is_grant, GrantObjectType objtype, List *objects,
-                                  bool all_privs, AclMode privileges, List *grantees,
-                                  bool grant_option, DropBehavior behavior)
+ExecGrantStmt_oids(InternalGrant *istmt)
 {
-       switch (objtype)
+       switch (istmt->objtype)
        {
                case ACL_OBJECT_RELATION:
-                       ExecGrant_Relation(is_grant, objects, all_privs, privileges,
-                                                          grantees, grant_option, behavior);
+                       ExecGrant_Relation(istmt);
                        break;
                case ACL_OBJECT_DATABASE:
-                       ExecGrant_Database(is_grant, objects, all_privs, privileges,
-                                                          grantees, grant_option, behavior);
+                       ExecGrant_Database(istmt);
                        break;
                case ACL_OBJECT_FUNCTION:
-                       ExecGrant_Function(is_grant, objects, all_privs, privileges,
-                                                          grantees, grant_option, behavior);
+                       ExecGrant_Function(istmt);
                        break;
                case ACL_OBJECT_LANGUAGE:
-                       ExecGrant_Language(is_grant, objects, all_privs, privileges,
-                                                          grantees, grant_option, behavior);
+                       ExecGrant_Language(istmt);
                        break;
                case ACL_OBJECT_NAMESPACE:
-                       ExecGrant_Namespace(is_grant, objects, all_privs,
-                                                               privileges, grantees, grant_option,
-                                                               behavior);
+                       ExecGrant_Namespace(istmt);
                        break;
                case ACL_OBJECT_TABLESPACE:
-                       ExecGrant_Tablespace(is_grant, objects, all_privs,
-                                                                privileges, grantees, grant_option,
-                                                                behavior);
+                       ExecGrant_Tablespace(istmt);
                        break;
                default:
                        elog(ERROR, "unrecognized GrantStmt.objtype: %d",
-                                (int) objtype);
+                                (int) istmt->objtype);
        }
 }
 
@@ -444,19 +524,17 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
 }
 
 static void
-ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior)
+ExecGrant_Relation(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (all_privs && privileges == ACL_NO_RIGHTS)
-               privileges = ACL_ALL_RIGHTS_RELATION;
+       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               istmt->privileges = ACL_ALL_RIGHTS_RELATION;
 
        relation = heap_open(RelationRelationId, RowExclusiveLock);
 
-       foreach(cell, objects)
+       foreach(cell, istmt->objects)
        {
                Oid                     relOid = lfirst_oid(cell);
                Datum           aclDatum;
@@ -512,56 +590,19 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), privileges,
+               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
                /*
-                * If we found no grant options, consider whether to issue a hard
-                * error.  Per spec, having any privilege at all on the object will
-                * get you by here.
+                * Restrict the privileges to what we can actually grant, and emit
+                * the standards-mandated warning and error messages.
                 */
-               if (avail_goptions == ACL_NO_RIGHTS)
-               {
-                       if (pg_class_aclmask(relOid,
-                                                                grantorId,
-                                                                ACL_ALL_RIGHTS_RELATION | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_RELATION),
-                                                                ACLMASK_ANY) == ACL_NO_RIGHTS)
-                               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
-                                                          NameStr(pg_class_tuple->relname));
-               }
-
-               /*
-                * Restrict the operation to what we can actually grant or revoke, and
-                * issue a warning if appropriate.      (For REVOKE this isn't quite what
-                * the spec says to do: the spec seems to want a warning only if no
-                * privilege bits actually change in the ACL. In practice that
-                * behavior seems much too noisy, as well as inconsistent with the
-                * GRANT case.)
-                */
-               this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
-               if (is_grant)
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("no privileges were granted")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("not all privileges were granted")));
-               }
-               else
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("no privileges could be revoked")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("not all privileges could be revoked")));
-               }
+               this_privileges =
+                       restrict_and_check_grant(istmt->is_grant, avail_goptions,
+                                                                        istmt->all_privs, istmt->privileges,
+                                                                        relOid, grantorId, ACL_KIND_CLASS,
+                                                                        NameStr(pg_class_tuple->relname));
 
                /*
                 * Generate new ACL.
@@ -571,9 +612,9 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
 
-               new_acl = merge_acl_with_grant(old_acl, is_grant,
-                                                                          grant_option, behavior,
-                                                                          grantees, this_privileges,
+               new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
+                                                                          istmt->grant_option, istmt->behavior,
+                                                                          istmt->grantees, this_privileges,
                                                                           grantorId, ownerId);
 
                nnewmembers = aclmembers(new_acl, &newmembers);
@@ -595,7 +636,7 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
 
                /* Update the shared dependency ACL info */
                updateAclDependencies(RelationRelationId, relOid,
-                                                         ownerId, is_grant,
+                                                         ownerId, istmt->is_grant,
                                                          noldmembers, oldmembers,
                                                          nnewmembers, newmembers);
 
@@ -611,19 +652,17 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
 }
 
 static void
-ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior)
+ExecGrant_Database(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (all_privs && privileges == ACL_NO_RIGHTS)
-               privileges = ACL_ALL_RIGHTS_DATABASE;
+       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               istmt->privileges = ACL_ALL_RIGHTS_DATABASE;
 
        relation = heap_open(DatabaseRelationId, RowExclusiveLock);
 
-       foreach(cell, objects)
+       foreach(cell, istmt->objects)
        {
                Oid                     datId = lfirst_oid(cell);
                Form_pg_database pg_database_tuple;
@@ -675,56 +714,19 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), privileges,
+               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
                /*
-                * If we found no grant options, consider whether to issue a hard
-                * error.  Per spec, having any privilege at all on the object will
-                * get you by here.
-                */
-               if (avail_goptions == ACL_NO_RIGHTS)
-               {
-                       if (pg_database_aclmask(HeapTupleGetOid(tuple),
-                                                                       grantorId,
-                                                                       ACL_ALL_RIGHTS_DATABASE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_DATABASE),
-                                                                       ACLMASK_ANY) == ACL_NO_RIGHTS)
-                               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_DATABASE,
-                                                          NameStr(pg_database_tuple->datname));
-               }
-
-               /*
-                * Restrict the operation to what we can actually grant or revoke, and
-                * issue a warning if appropriate.      (For REVOKE this isn't quite what
-                * the spec says to do: the spec seems to want a warning only if no
-                * privilege bits actually change in the ACL. In practice that
-                * behavior seems much too noisy, as well as inconsistent with the
-                * GRANT case.)
+                * Restrict the privileges to what we can actually grant, and emit
+                * the standards-mandated warning and error messages.
                 */
-               this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
-               if (is_grant)
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("no privileges were granted")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("not all privileges were granted")));
-               }
-               else
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("no privileges could be revoked")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("not all privileges could be revoked")));
-               }
+               this_privileges =
+                       restrict_and_check_grant(istmt->is_grant, avail_goptions,
+                                                                        istmt->all_privs, istmt->privileges,
+                                                                        datId, grantorId, ACL_KIND_DATABASE,
+                                                                        NameStr(pg_database_tuple->datname));
 
                /*
                 * Generate new ACL.
@@ -734,9 +736,9 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
 
-               new_acl = merge_acl_with_grant(old_acl, is_grant,
-                                                                          grant_option, behavior,
-                                                                          grantees, this_privileges,
+               new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
+                                                                          istmt->grant_option, istmt->behavior,
+                                                                          istmt->grantees, this_privileges,
                                                                           grantorId, ownerId);
 
                nnewmembers = aclmembers(new_acl, &newmembers);
@@ -759,7 +761,7 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
 
                /* Update the shared dependency ACL info */
                updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple),
-                                                         ownerId, is_grant,
+                                                         ownerId, istmt->is_grant,
                                                          noldmembers, oldmembers,
                                                          nnewmembers, newmembers);
 
@@ -775,19 +777,17 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
 }
 
 static void
-ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior)
+ExecGrant_Function(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (all_privs && privileges == ACL_NO_RIGHTS)
-               privileges = ACL_ALL_RIGHTS_FUNCTION;
+       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               istmt->privileges = ACL_ALL_RIGHTS_FUNCTION;
 
        relation = heap_open(ProcedureRelationId, RowExclusiveLock);
 
-       foreach(cell, objects)
+       foreach(cell, istmt->objects)
        {
                Oid                     funcId = lfirst_oid(cell);
                Form_pg_proc pg_proc_tuple;
@@ -830,56 +830,19 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), privileges,
+               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
                /*
-                * If we found no grant options, consider whether to issue a hard
-                * error.  Per spec, having any privilege at all on the object will
-                * get you by here.
+                * Restrict the privileges to what we can actually grant, and emit
+                * the standards-mandated warning and error messages.
                 */
-               if (avail_goptions == ACL_NO_RIGHTS)
-               {
-                       if (pg_proc_aclmask(funcId,
-                                                               grantorId,
-                                                               ACL_ALL_RIGHTS_FUNCTION | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_FUNCTION),
-                                                               ACLMASK_ANY) == ACL_NO_RIGHTS)
-                               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_PROC,
-                                                          NameStr(pg_proc_tuple->proname));
-               }
-
-               /*
-                * Restrict the operation to what we can actually grant or revoke, and
-                * issue a warning if appropriate.      (For REVOKE this isn't quite what
-                * the spec says to do: the spec seems to want a warning only if no
-                * privilege bits actually change in the ACL. In practice that
-                * behavior seems much too noisy, as well as inconsistent with the
-                * GRANT case.)
-                */
-               this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
-               if (is_grant)
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("no privileges were granted")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("not all privileges were granted")));
-               }
-               else
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("no privileges could be revoked")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("not all privileges could be revoked")));
-               }
+               this_privileges =
+                       restrict_and_check_grant(istmt->is_grant, avail_goptions,
+                                                                        istmt->all_privs, istmt->privileges,
+                                                                        funcId, grantorId, ACL_KIND_PROC,
+                                                                        NameStr(pg_proc_tuple->proname));
 
                /*
                 * Generate new ACL.
@@ -889,9 +852,9 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
 
-               new_acl = merge_acl_with_grant(old_acl, is_grant,
-                                                                          grant_option, behavior,
-                                                                          grantees, this_privileges,
+               new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
+                                                                          istmt->grant_option, istmt->behavior,
+                                                                          istmt->grantees, this_privileges,
                                                                           grantorId, ownerId);
 
                nnewmembers = aclmembers(new_acl, &newmembers);
@@ -914,7 +877,7 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
 
                /* Update the shared dependency ACL info */
                updateAclDependencies(ProcedureRelationId, funcId,
-                                                         ownerId, is_grant,
+                                                         ownerId, istmt->is_grant,
                                                          noldmembers, oldmembers,
                                                          nnewmembers, newmembers);
 
@@ -930,21 +893,19 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
 }
 
 static void
-ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
-                                  AclMode privileges, List *grantees, bool grant_option,
-                                  DropBehavior behavior)
+ExecGrant_Language(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (all_privs && privileges == ACL_NO_RIGHTS)
-               privileges = ACL_ALL_RIGHTS_LANGUAGE;
+       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               istmt->privileges = ACL_ALL_RIGHTS_LANGUAGE;
 
        relation = heap_open(LanguageRelationId, RowExclusiveLock);
 
-       foreach(cell, objects)
+       foreach(cell, istmt->objects)
        {
-               Oid                     langid = lfirst_oid(cell);
+               Oid                     langId = lfirst_oid(cell);
                Form_pg_language pg_language_tuple;
                Datum           aclDatum;
                bool            isNull;
@@ -965,10 +926,10 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
                Oid                *newmembers;
 
                tuple = SearchSysCache(LANGOID,
-                                                          ObjectIdGetDatum(langid),
+                                                          ObjectIdGetDatum(langId),
                                                           0, 0, 0);
                if (!HeapTupleIsValid(tuple))
-                       elog(ERROR, "cache lookup failed for language %u", langid);
+                       elog(ERROR, "cache lookup failed for language %u", langId);
 
                pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple);
 
@@ -995,56 +956,19 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), privileges,
+               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
                /*
-                * If we found no grant options, consider whether to issue a hard
-                * error.  Per spec, having any privilege at all on the object will
-                * get you by here.
+                * Restrict the privileges to what we can actually grant, and emit
+                * the standards-mandated warning and error messages.
                 */
-               if (avail_goptions == ACL_NO_RIGHTS)
-               {
-                       if (pg_language_aclmask(HeapTupleGetOid(tuple),
-                                                                       grantorId,
-                                                                       ACL_ALL_RIGHTS_LANGUAGE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_LANGUAGE),
-                                                                       ACLMASK_ANY) == ACL_NO_RIGHTS)
-                               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_LANGUAGE,
-                                                          NameStr(pg_language_tuple->lanname));
-               }
-
-               /*
-                * Restrict the operation to what we can actually grant or revoke, and
-                * issue a warning if appropriate.      (For REVOKE this isn't quite what
-                * the spec says to do: the spec seems to want a warning only if no
-                * privilege bits actually change in the ACL. In practice that
-                * behavior seems much too noisy, as well as inconsistent with the
-                * GRANT case.)
-                */
-               this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
-               if (is_grant)
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("no privileges were granted")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("not all privileges were granted")));
-               }
-               else
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("no privileges could be revoked")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("not all privileges could be revoked")));
-               }
+               this_privileges =
+                       restrict_and_check_grant(istmt->is_grant, avail_goptions,
+                                                                        istmt->all_privs, istmt->privileges,
+                                                                        langId, grantorId, ACL_KIND_LANGUAGE,
+                                                                        NameStr(pg_language_tuple->lanname));
 
                /*
                 * Generate new ACL.
@@ -1054,9 +978,9 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
 
-               new_acl = merge_acl_with_grant(old_acl, is_grant,
-                                                                          grant_option, behavior,
-                                                                          grantees, this_privileges,
+               new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
+                                                                          istmt->grant_option, istmt->behavior,
+                                                                          istmt->grantees, this_privileges,
                                                                           grantorId, ownerId);
 
                nnewmembers = aclmembers(new_acl, &newmembers);
@@ -1079,7 +1003,7 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
 
                /* Update the shared dependency ACL info */
                updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple),
-                                                         ownerId, is_grant,
+                                                         ownerId, istmt->is_grant,
                                                          noldmembers, oldmembers,
                                                          nnewmembers, newmembers);
 
@@ -1095,19 +1019,17 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
 }
 
 static void
-ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
-                                       AclMode privileges, List *grantees, bool grant_option,
-                                       DropBehavior behavior)
+ExecGrant_Namespace(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (all_privs && privileges == ACL_NO_RIGHTS)
-               privileges = ACL_ALL_RIGHTS_NAMESPACE;
+       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               istmt->privileges = ACL_ALL_RIGHTS_NAMESPACE;
 
        relation = heap_open(NamespaceRelationId, RowExclusiveLock);
 
-       foreach(cell, objects)
+       foreach(cell, istmt->objects)
        {
                Oid                     nspid = lfirst_oid(cell);
                Form_pg_namespace pg_namespace_tuple;
@@ -1151,56 +1073,19 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), privileges,
+               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
                /*
-                * If we found no grant options, consider whether to issue a hard
-                * error.  Per spec, having any privilege at all on the object will
-                * get you by here.
-                */
-               if (avail_goptions == ACL_NO_RIGHTS)
-               {
-                       if (pg_namespace_aclmask(HeapTupleGetOid(tuple),
-                                                                        grantorId,
-                                                                        ACL_ALL_RIGHTS_NAMESPACE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_NAMESPACE),
-                                                                        ACLMASK_ANY) == ACL_NO_RIGHTS)
-                               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_NAMESPACE,
-                                                          NameStr(pg_namespace_tuple->nspname));
-               }
-
-               /*
-                * Restrict the operation to what we can actually grant or revoke, and
-                * issue a warning if appropriate.      (For REVOKE this isn't quite what
-                * the spec says to do: the spec seems to want a warning only if no
-                * privilege bits actually change in the ACL. In practice that
-                * behavior seems much too noisy, as well as inconsistent with the
-                * GRANT case.)
+                * Restrict the privileges to what we can actually grant, and emit
+                * the standards-mandated warning and error messages.
                 */
-               this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
-               if (is_grant)
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("no privileges were granted")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("not all privileges were granted")));
-               }
-               else
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("no privileges could be revoked")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("not all privileges could be revoked")));
-               }
+               this_privileges =
+                       restrict_and_check_grant(istmt->is_grant, avail_goptions,
+                                                                        istmt->all_privs, istmt->privileges,
+                                                                        nspid, grantorId, ACL_KIND_NAMESPACE,
+                                                                        NameStr(pg_namespace_tuple->nspname));
 
                /*
                 * Generate new ACL.
@@ -1210,9 +1095,9 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
 
-               new_acl = merge_acl_with_grant(old_acl, is_grant,
-                                                                          grant_option, behavior,
-                                                                          grantees, this_privileges,
+               new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
+                                                                          istmt->grant_option, istmt->behavior,
+                                                                          istmt->grantees, this_privileges,
                                                                           grantorId, ownerId);
 
                nnewmembers = aclmembers(new_acl, &newmembers);
@@ -1235,7 +1120,7 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
 
                /* Update the shared dependency ACL info */
                updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple),
-                                                         ownerId, is_grant,
+                                                         ownerId, istmt->is_grant,
                                                          noldmembers, oldmembers,
                                                          nnewmembers, newmembers);
 
@@ -1251,19 +1136,17 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
 }
 
 static void
-ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
-                                        AclMode privileges, List *grantees, bool grant_option,
-                                        DropBehavior behavior)
+ExecGrant_Tablespace(InternalGrant *istmt)
 {
        Relation        relation;
        ListCell   *cell;
 
-       if (all_privs && privileges == ACL_NO_RIGHTS)
-               privileges = ACL_ALL_RIGHTS_TABLESPACE;
+       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+               istmt->privileges = ACL_ALL_RIGHTS_TABLESPACE;
 
        relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
 
-       foreach(cell, objects)
+       foreach(cell, istmt->objects)
        {
                Oid                     tblId = lfirst_oid(cell);
                Form_pg_tablespace pg_tablespace_tuple;
@@ -1313,56 +1196,19 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
                        old_acl = DatumGetAclPCopy(aclDatum);
 
                /* Determine ID to do the grant as, and available grant options */
-               select_best_grantor(GetUserId(), privileges,
+               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, &avail_goptions);
 
                /*
-                * If we found no grant options, consider whether to issue a hard
-                * error.  Per spec, having any privilege at all on the object will
-                * get you by here.
+                * Restrict the privileges to what we can actually grant, and emit
+                * the standards-mandated warning and error messages.
                 */
-               if (avail_goptions == ACL_NO_RIGHTS)
-               {
-                       if (pg_tablespace_aclmask(HeapTupleGetOid(tuple),
-                                                                         grantorId,
-                                                                         ACL_ALL_RIGHTS_TABLESPACE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_TABLESPACE),
-                                                                         ACLMASK_ANY) == ACL_NO_RIGHTS)
-                               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE,
-                                                          NameStr(pg_tablespace_tuple->spcname));
-               }
-
-               /*
-                * Restrict the operation to what we can actually grant or revoke, and
-                * issue a warning if appropriate.      (For REVOKE this isn't quite what
-                * the spec says to do: the spec seems to want a warning only if no
-                * privilege bits actually change in the ACL. In practice that
-                * behavior seems much too noisy, as well as inconsistent with the
-                * GRANT case.)
-                */
-               this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
-               if (is_grant)
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("no privileges were granted")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
-                                                errmsg("not all privileges were granted")));
-               }
-               else
-               {
-                       if (this_privileges == 0)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("no privileges could be revoked")));
-                       else if (!all_privs && this_privileges != privileges)
-                               ereport(WARNING,
-                                               (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
-                                                errmsg("not all privileges could be revoked")));
-               }
+               this_privileges =
+                       restrict_and_check_grant(istmt->is_grant, avail_goptions,
+                                                                        istmt->all_privs, istmt->privileges,
+                                                                        tblId, grantorId, ACL_KIND_TABLESPACE,
+                                                                        NameStr(pg_tablespace_tuple->spcname));
 
                /*
                 * Generate new ACL.
@@ -1372,9 +1218,9 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
 
-               new_acl = merge_acl_with_grant(old_acl, is_grant,
-                                                                          grant_option, behavior,
-                                                                          grantees, this_privileges,
+               new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
+                                                                          istmt->grant_option, istmt->behavior,
+                                                                          istmt->grantees, this_privileges,
                                                                           grantorId, ownerId);
 
                nnewmembers = aclmembers(new_acl, &newmembers);
@@ -1397,7 +1243,7 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
 
                /* Update the shared dependency ACL info */
                updateAclDependencies(TableSpaceRelationId, tblId,
-                                                         ownerId, is_grant,
+                                                         ownerId, istmt->is_grant,
                                                          noldmembers, oldmembers,
                                                          nnewmembers, newmembers);
 
@@ -1583,6 +1429,34 @@ has_rolcatupdate(Oid roleid)
        return rolcatupdate;
 }
 
+/*
+ * Relay for the various pg_*_mask routines depending on object kind
+ */
+static AclMode
+pg_aclmask(AclObjectKind objkind, Oid table_oid, Oid roleid,
+                  AclMode mask, AclMaskHow how)
+{
+       switch (objkind)
+       {
+               case ACL_KIND_CLASS:
+                       return pg_class_aclmask(table_oid, roleid, mask, how);
+               case ACL_KIND_DATABASE:
+                       return pg_database_aclmask(table_oid, roleid, mask, how);
+               case ACL_KIND_PROC:
+                       return pg_proc_aclmask(table_oid, roleid, mask, how);
+               case ACL_KIND_LANGUAGE:
+                       return pg_language_aclmask(table_oid, roleid, mask, how);
+               case ACL_KIND_NAMESPACE:
+                       return pg_namespace_aclmask(table_oid, roleid, mask, how);
+               case ACL_KIND_TABLESPACE:
+                       return pg_tablespace_aclmask(table_oid, roleid, mask, how);
+               default:
+                       elog(ERROR, "unrecognized objkind: %d",
+                                (int) objkind);
+                       /* not reached, but keep compiler quiet */
+                       return ACL_NO_RIGHTS;
+       }
+}
 
 /*
  * Exported routine for examining a user's privileges for a table
index 703f613..faa64c2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.5 2005/11/22 18:17:08 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.6 2005/12/01 02:03:00 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1122,6 +1122,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
                        {
                                        ObjectAddress obj;
                                        GrantObjectType objtype;
+                                       InternalGrant istmt;
 
                                        /* Shouldn't happen */
                                case SHARED_DEPENDENCY_PIN:
@@ -1132,22 +1133,22 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
                                        switch (sdepForm->classid)
                                        {
                                                case RelationRelationId:
-                                                       objtype = ACL_OBJECT_RELATION;
+                                                       istmt.objtype = ACL_OBJECT_RELATION;
                                                        break;
                                                case DatabaseRelationId:
-                                                       objtype = ACL_OBJECT_DATABASE;
+                                                       istmt.objtype = ACL_OBJECT_DATABASE;
                                                        break;
                                                case ProcedureRelationId:
-                                                       objtype = ACL_OBJECT_FUNCTION;
+                                                       istmt.objtype = ACL_OBJECT_FUNCTION;
                                                        break;
                                                case LanguageRelationId:
-                                                       objtype = ACL_OBJECT_LANGUAGE;
+                                                       istmt.objtype = ACL_OBJECT_LANGUAGE;
                                                        break;
                                                case NamespaceRelationId:
-                                                       objtype = ACL_OBJECT_NAMESPACE;
+                                                       istmt.objtype = ACL_OBJECT_NAMESPACE;
                                                        break;
                                                case TableSpaceRelationId:
-                                                       objtype = ACL_OBJECT_TABLESPACE;
+                                                       istmt.objtype = ACL_OBJECT_TABLESPACE;
                                                        break;
                                                default:
                                                        elog(ERROR, "unexpected object type %d",
@@ -1156,11 +1157,15 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
                                                        objtype = (GrantObjectType) 0;
                                                        break;
                                        }
-
-                                       ExecGrantStmt_oids(false, objtype,
-                                                                          list_make1_oid(sdepForm->objid), true,
-                                                                          ACL_NO_RIGHTS, list_make1_oid(roleid),
-                                                                          false, DROP_CASCADE);
+                                       istmt.is_grant = false;
+                                       istmt.objects = list_make1_oid(sdepForm->objid);
+                                       istmt.all_privs = true;
+                                       istmt.privileges = ACL_NO_RIGHTS;
+                                       istmt.grantees = list_make1_oid(roleid);
+                                       istmt.grant_option = false;
+                                       istmt.behavior = DROP_CASCADE;
+
+                                       ExecGrantStmt_oids(&istmt);
                                        break;
                                case SHARED_DEPENDENCY_OWNER:
 
index 04c5631..8e6cb95 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.90 2005/11/22 18:17:31 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.91 2005/12/01 02:03:01 alvherre Exp $
  *
  * NOTES
  *       An ACL array is simply an array of AclItems, representing the union
@@ -182,6 +182,26 @@ typedef enum AclObjectKind
 } AclObjectKind;
 
 /*
+ * The information about one Grant/Revoke statement, in internal format: object
+ * and grantees names have been turned into Oids, the privilege list is an
+ * AclMode bitmask.  If 'privileges' is ACL_NO_RIGHTS (the 0 value) and
+ * all_privs is true, it will be internally turned into the right kind of
+ * ACL_ALL_RIGHTS_*, depending on the object type (NB - this will modify the
+ * InternalGrant struct!)
+ */
+typedef struct
+{
+       bool    is_grant;
+       GrantObjectType objtype;
+       List   *objects;
+       bool    all_privs;
+       AclMode privileges;
+       List   *grantees;
+       bool    grant_option;
+       DropBehavior behavior;
+} InternalGrant;
+
+/*
  * routines used internally
  */
 extern Acl *acldefault(GrantObjectType objtype, Oid ownerId);
@@ -221,9 +241,7 @@ extern Datum hash_aclitem(PG_FUNCTION_ARGS);
  * prototypes for functions in aclchk.c
  */
 extern void ExecuteGrantStmt(GrantStmt *stmt);
-extern void ExecGrantStmt_oids(bool is_grant, GrantObjectType objtype,
-                                  List *objects, bool all_privs, AclMode privileges,
-                                  List *grantees, bool grant_option, DropBehavior behavior);
+extern void ExecGrantStmt_oids(InternalGrant *istmt);
 
 extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
                                 AclMode mask, AclMaskHow how);