I intend to apply later today the attached patch in order to reduce some
code duplication in aclchk.c and clean a bit the API I just introduced
in the previous patch.  This reduces aclchk.c from 2377 lines to 2206.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
Index: src/backend/catalog/aclchk.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/aclchk.c,v
retrieving revision 1.121
diff -c -r1.121 aclchk.c
*** src/backend/catalog/aclchk.c        21 Nov 2005 12:49:30 -0000      1.121
--- src/backend/catalog/aclchk.c        21 Nov 2005 15:05:19 -0000
***************
*** 42,69 ****
  #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 AclMode string_to_privilege(const char *privname);
  static const char *privilege_to_string(AclMode privilege);
  
  
  #ifdef ACLDEBUG
--- 42,62 ----
  #include "utils/syscache.h"
  
  
! 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,
+                                                                               
AclMode whole_mask,
+                                                                               
AclObjectKind objkind, char *objname);
  
  
  #ifdef ACLDEBUG
***************
*** 160,172 ****
  void
  ExecuteGrantStmt(GrantStmt *stmt)
  {
!       List       *objects;
!       List       *grantees = NIL;
!       AclMode         privileges;
        ListCell   *cell;
!       bool            all_privs;
!       AclMode all_privileges = (AclMode) 0;
!       char    *errormsg = NULL;
  
        /*
         * Convert the PrivGrantee list into an Oid list.  Note that at this 
point
--- 153,174 ----
  void
  ExecuteGrantStmt(GrantStmt *stmt)
  {
!       InternalGrant istmt;
        ListCell   *cell;
!       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 */
!       /* grantees to be 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,194 ****
                PrivGrantee *grantee = (PrivGrantee *) lfirst(cell);
  
                if (grantee->rolname == NULL)
!                       grantees = lappend_oid(grantees, ACL_ID_PUBLIC);
                else
!                       grantees = lappend_oid(grantees,
!                                                                  
get_roleid_checked(grantee->rolname));
        }
  
        /*
!        * Convert stmt->privileges, a textual list, into an AclMode bitmask
!        * appropiate for the given object class.
         */
        switch (stmt->objtype)
        {
--- 182,196 ----
                PrivGrantee *grantee = (PrivGrantee *) lfirst(cell);
  
                if (grantee->rolname == NULL)
!                       istmt.grantees = lappend_oid(istmt.grantees, 
ACL_ID_PUBLIC);
                else
!                       istmt.grantees =
!                               lappend_oid(istmt.grantees,
!                                                       
get_roleid_checked(grantee->rolname));
        }
  
        /*
!        * Convert stmt->privileges, a textual list, into an AclMode bitmask.
         */
        switch (stmt->objtype)
        {
***************
*** 217,235 ****
                        errormsg = _("invalid privilege type %s for 
tablespace");
                        break;
                default:
                        elog(ERROR, "unrecognized GrantStmt.objtype: %d",
                                 (int) stmt->objtype);
        }
  
        if (stmt->privileges == NIL)
        {
!               all_privs = true;
!               privileges = all_privileges;
        }
        else
        {
!               all_privs = false;
!               privileges = ACL_NO_RIGHTS;
                foreach(cell, stmt->privileges)
                {
                        char       *privname = strVal(lfirst(cell));
--- 219,244 ----
                        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)
        {
!               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
        {
!               istmt.all_privs = false;
!               istmt.privileges = ACL_NO_RIGHTS;
                foreach(cell, stmt->privileges)
                {
                        char       *privname = strVal(lfirst(cell));
***************
*** 241,301 ****
                                                 errmsg(errormsg,
                                                                
privilege_to_string(priv))));
  
!                       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
   *
!  * "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.
   */
  void
! ExecGrantStmt_oids(bool is_grant, GrantObjectType objtype, List *objects,
!                                  bool all_privs, AclMode privileges, List 
*grantees,
!                                  bool grant_option, DropBehavior behavior)
  {
!       switch (objtype)
        {
                case ACL_OBJECT_RELATION:
!                       ExecGrant_Relation(is_grant, objects, all_privs, 
privileges,
!                                                          grantees, 
grant_option, behavior);
                        break;
                case ACL_OBJECT_DATABASE:
!                       ExecGrant_Database(is_grant, objects, all_privs, 
privileges,
!                                                          grantees, 
grant_option, behavior);
                        break;
                case ACL_OBJECT_FUNCTION:
!                       ExecGrant_Function(is_grant, objects, all_privs, 
privileges,
!                                                          grantees, 
grant_option, behavior);
                        break;
                case ACL_OBJECT_LANGUAGE:
!                       ExecGrant_Language(is_grant, objects, all_privs, 
privileges,
!                                                          grantees, 
grant_option, behavior);
                        break;
                case ACL_OBJECT_NAMESPACE:
!                       ExecGrant_Namespace(is_grant, objects, all_privs,
!                                                               privileges, 
grantees, grant_option,
!                                                               behavior);
                        break;
                case ACL_OBJECT_TABLESPACE:
!                       ExecGrant_Tablespace(is_grant, objects, all_privs,
!                                                                privileges, 
grantees, grant_option,
!                                                                behavior);
                        break;
                default:
                        elog(ERROR, "unrecognized GrantStmt.objtype: %d",
!                                (int) objtype);
        }
  }
  
--- 250,293 ----
                                                 errmsg(errormsg,
                                                                
privilege_to_string(priv))));
  
!                       istmt.privileges |= priv;
                }
        }
  
!       ExecGrantStmt_oids(&istmt);
  }
  
  /*
   * ExecGrantStmt_oids
   *
!  * "Internal" entrypoint for granting and revoking privileges.
   */
  void
! ExecGrantStmt_oids(InternalGrant *istmt)
  {
!       switch (istmt->objtype)
        {
                case ACL_OBJECT_RELATION:
!                       ExecGrant_Relation(istmt);
                        break;
                case ACL_OBJECT_DATABASE:
!                       ExecGrant_Database(istmt);
                        break;
                case ACL_OBJECT_FUNCTION:
!                       ExecGrant_Function(istmt);
                        break;
                case ACL_OBJECT_LANGUAGE:
!                       ExecGrant_Language(istmt);
                        break;
                case ACL_OBJECT_NAMESPACE:
!                       ExecGrant_Namespace(istmt);
                        break;
                case ACL_OBJECT_TABLESPACE:
!                       ExecGrant_Tablespace(istmt);
                        break;
                default:
                        elog(ERROR, "unrecognized GrantStmt.objtype: %d",
!                                (int) istmt->objtype);
        }
  }
  
***************
*** 443,462 ****
        return objects;
  }
  
  static void
! ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
!                                  AclMode privileges, List *grantees, bool 
grant_option,
!                                  DropBehavior behavior)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (all_privs && privileges == ACL_NO_RIGHTS)
!               privileges = ACL_ALL_RIGHTS_RELATION;
  
        relation = heap_open(RelationRelationId, RowExclusiveLock);
  
!       foreach (cell, objects)
        {
                Oid                     relOid = lfirst_oid(cell);
                Datum           aclDatum;
--- 435,513 ----
        return objects;
  }
  
+ /*
+  * 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,
+                                                AclMode whole_mask, 
AclObjectKind objkind,
+                                                char *objname)
+ {
+       AclMode this_privileges;
+ 
+       /*
+        * 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_class_aclmask(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;
+ }
+ 
  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)
        {
                Oid                     relOid = lfirst_oid(cell);
                Datum           aclDatum;
***************
*** 511,566 ****
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), 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_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")));
!               }
  
                /*
                 * Generate new ACL.
--- 562,581 ----
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, 
&avail_goptions);
  
                /*
!                * Restrict the privileges to what we can actually grant, and 
emit
!                * the standards-mandated warning and error messages.
                 */
!               this_privileges =
!                       restrict_and_check_grant(istmt->is_grant, 
avail_goptions,
!                                                                        
istmt->all_privs, istmt->privileges,
!                                                                        
relOid, grantorId,
!                                                                        
ACL_ALL_RIGHTS_RELATION, ACL_KIND_CLASS,
!                                                                        
NameStr(pg_class_tuple->relname));
  
                /*
                 * Generate new ACL.
***************
*** 570,578 ****
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               new_acl = merge_acl_with_grant(old_acl, is_grant,
!                                                                          
grant_option, behavior,
!                                                                          
grantees, this_privileges,
                                                                           
grantorId, ownerId);
  
                nnewmembers = aclmembers(new_acl, &newmembers);
--- 585,593 ----
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               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);
***************
*** 594,600 ****
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(RelationRelationId, relOid,
!                                                         ownerId, is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
--- 609,615 ----
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(RelationRelationId, relOid,
!                                                         ownerId, 
istmt->is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
***************
*** 610,628 ****
  }
  
  static void
! ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
!                                  AclMode privileges, List *grantees, bool 
grant_option,
!                                  DropBehavior behavior)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (all_privs && privileges == ACL_NO_RIGHTS)
!               privileges = ACL_ALL_RIGHTS_DATABASE;
  
        relation = heap_open(DatabaseRelationId, RowExclusiveLock);
  
!       foreach (cell, objects)
        {
                Oid                     datId = lfirst_oid(cell);
                Form_pg_database pg_database_tuple;
--- 625,641 ----
  }
  
  static void
! ExecGrant_Database(InternalGrant *istmt)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
!               istmt->privileges = ACL_ALL_RIGHTS_DATABASE;
  
        relation = heap_open(DatabaseRelationId, RowExclusiveLock);
  
!       foreach (cell, istmt->objects)
        {
                Oid                     datId = lfirst_oid(cell);
                Form_pg_database pg_database_tuple;
***************
*** 674,729 ****
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), 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.)
                 */
!               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")));
!               }
  
                /*
                 * Generate new ACL.
--- 687,706 ----
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, 
&avail_goptions);
  
                /*
!                * Restrict the privileges to what we can actually grant, and 
emit
!                * the standards-mandated warning and error messages.
                 */
!               this_privileges =
!                       restrict_and_check_grant(istmt->is_grant, 
avail_goptions,
!                                                                        
istmt->all_privs, istmt->privileges,
!                                                                        datId, 
grantorId, ACL_ALL_RIGHTS_DATABASE,
!                                                                        
ACL_KIND_DATABASE,
!                                                                        
NameStr(pg_database_tuple->datname));
  
                /*
                 * Generate new ACL.
***************
*** 733,741 ****
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               new_acl = merge_acl_with_grant(old_acl, is_grant,
!                                                                          
grant_option, behavior,
!                                                                          
grantees, this_privileges,
                                                                           
grantorId, ownerId);
  
                nnewmembers = aclmembers(new_acl, &newmembers);
--- 710,718 ----
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               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);
***************
*** 758,764 ****
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(DatabaseRelationId, 
HeapTupleGetOid(tuple),
!                                                         ownerId, is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
--- 735,741 ----
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(DatabaseRelationId, 
HeapTupleGetOid(tuple),
!                                                         ownerId, 
istmt->is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
***************
*** 774,792 ****
  }
  
  static void
! ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
!                                  AclMode privileges, List *grantees, bool 
grant_option,
!                                  DropBehavior behavior)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (all_privs && privileges == ACL_NO_RIGHTS)
!               privileges = ACL_ALL_RIGHTS_FUNCTION;
  
        relation = heap_open(ProcedureRelationId, RowExclusiveLock);
  
!       foreach (cell, objects)
        {
                Oid                     funcId = lfirst_oid(cell);
                Form_pg_proc pg_proc_tuple;
--- 751,767 ----
  }
  
  static void
! ExecGrant_Function(InternalGrant *istmt)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
!               istmt->privileges = ACL_ALL_RIGHTS_FUNCTION;
  
        relation = heap_open(ProcedureRelationId, RowExclusiveLock);
  
!       foreach (cell, istmt->objects)
        {
                Oid                     funcId = lfirst_oid(cell);
                Form_pg_proc pg_proc_tuple;
***************
*** 829,884 ****
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), 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_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")));
!               }
  
                /*
                 * Generate new ACL.
--- 804,824 ----
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, 
&avail_goptions);
  
                /*
!                * Restrict the privileges to what we can actually grant, and 
emit
!                * the standards-mandated warning and error messages.
                 */
!               this_privileges =
!                       restrict_and_check_grant(istmt->is_grant, 
avail_goptions,
!                                                                        
istmt->all_privs, istmt->privileges,
!                                                                        
funcId, grantorId,
!                                                                        
ACL_ALL_RIGHTS_FUNCTION,
!                                                                        
ACL_KIND_PROC,
!                                                                        
NameStr(pg_proc_tuple->proname));
  
                /*
                 * Generate new ACL.
***************
*** 888,896 ****
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               new_acl = merge_acl_with_grant(old_acl, is_grant,
!                                                                          
grant_option, behavior,
!                                                                          
grantees, this_privileges,
                                                                           
grantorId, ownerId);
  
                nnewmembers = aclmembers(new_acl, &newmembers);
--- 828,836 ----
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               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);
***************
*** 913,919 ****
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(ProcedureRelationId, funcId,      
!                                                         ownerId, is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
--- 853,859 ----
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(ProcedureRelationId, funcId,      
!                                                         ownerId, 
istmt->is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
***************
*** 929,949 ****
  }
  
  static void
! ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
!                                  AclMode privileges, List *grantees, bool 
grant_option,
!                                  DropBehavior behavior)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (all_privs && privileges == ACL_NO_RIGHTS)
!               privileges = ACL_ALL_RIGHTS_LANGUAGE;
  
        relation = heap_open(LanguageRelationId, RowExclusiveLock);
  
!       foreach (cell, objects)
        {
!               Oid                     langid = lfirst_oid(cell);
                Form_pg_language pg_language_tuple;
                Datum           aclDatum;
                bool            isNull;
--- 869,887 ----
  }
  
  static void
! ExecGrant_Language(InternalGrant *istmt)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
!               istmt->privileges = ACL_ALL_RIGHTS_LANGUAGE;
  
        relation = heap_open(LanguageRelationId, RowExclusiveLock);
  
!       foreach (cell, istmt->objects)
        {
!               Oid                     langId = lfirst_oid(cell);
                Form_pg_language pg_language_tuple;
                Datum           aclDatum;
                bool            isNull;
***************
*** 964,973 ****
                Oid                *newmembers;
  
                tuple = SearchSysCache(LANGOID,
!                                                          
ObjectIdGetDatum(langid),
                                                           0, 0, 0);
                if (!HeapTupleIsValid(tuple))
!                       elog(ERROR, "cache lookup failed for language %u", 
langid);
  
                pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple);
  
--- 902,911 ----
                Oid                *newmembers;
  
                tuple = SearchSysCache(LANGOID,
!                                                          
ObjectIdGetDatum(langId),
                                                           0, 0, 0);
                if (!HeapTupleIsValid(tuple))
!                       elog(ERROR, "cache lookup failed for language %u", 
langId);
  
                pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple);
  
***************
*** 994,1049 ****
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), 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_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")));
!               }
  
                /*
                 * Generate new ACL.
--- 932,952 ----
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, 
&avail_goptions);
  
                /*
!                * Restrict the privileges to what we can actually grant, and 
emit
!                * the standards-mandated warning and error messages.
                 */
!               this_privileges =
!                       restrict_and_check_grant(istmt->is_grant, 
avail_goptions,
!                                                                        
istmt->all_privs, istmt->privileges,
!                                                                        
langId, grantorId,
!                                                                        
ACL_ALL_RIGHTS_LANGUAGE,
!                                                                        
ACL_KIND_LANGUAGE,
!                                                                        
NameStr(pg_language_tuple->lanname));
  
                /*
                 * Generate new ACL.
***************
*** 1053,1061 ****
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               new_acl = merge_acl_with_grant(old_acl, is_grant,
!                                                                          
grant_option, behavior,
!                                                                          
grantees, this_privileges,
                                                                           
grantorId, ownerId);
  
                nnewmembers = aclmembers(new_acl, &newmembers);
--- 956,964 ----
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               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);
***************
*** 1078,1084 ****
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(LanguageRelationId, 
HeapTupleGetOid(tuple),
!                                                         ownerId, is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
--- 981,987 ----
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(LanguageRelationId, 
HeapTupleGetOid(tuple),
!                                                         ownerId, 
istmt->is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
***************
*** 1094,1112 ****
  }
  
  static void
! ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
!                                       AclMode privileges, List *grantees, 
bool grant_option,
!                                       DropBehavior behavior)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (all_privs && privileges == ACL_NO_RIGHTS)
!               privileges = ACL_ALL_RIGHTS_NAMESPACE;
  
        relation = heap_open(NamespaceRelationId, RowExclusiveLock);
  
!       foreach(cell, objects)
        {
                Oid                     nspid = lfirst_oid(cell);
                Form_pg_namespace pg_namespace_tuple;
--- 997,1013 ----
  }
  
  static void
! ExecGrant_Namespace(InternalGrant *istmt)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
!               istmt->privileges = ACL_ALL_RIGHTS_NAMESPACE;
  
        relation = heap_open(NamespaceRelationId, RowExclusiveLock);
  
!       foreach(cell, istmt->objects)
        {
                Oid                     nspid = lfirst_oid(cell);
                Form_pg_namespace pg_namespace_tuple;
***************
*** 1150,1205 ****
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), 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.)
!                */
!               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")));
!               }
  
                /*
                 * Generate new ACL.
--- 1051,1071 ----
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, 
&avail_goptions);
  
                /*
!                * Restrict the privileges to what we can actually grant, and 
emit
!                * the standards-mandated warning and error messages.
                 */
!               this_privileges =
!                       restrict_and_check_grant(istmt->is_grant, 
avail_goptions,
!                                                                        
istmt->all_privs, istmt->privileges,
!                                                                        nspid, 
grantorId,
!                                                                        
ACL_ALL_RIGHTS_NAMESPACE,
!                                                                        
ACL_KIND_NAMESPACE,
!                                                                        
NameStr(pg_namespace_tuple->nspname));
  
                /*
                 * Generate new ACL.
***************
*** 1209,1217 ****
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               new_acl = merge_acl_with_grant(old_acl, is_grant,
!                                                                          
grant_option, behavior,
!                                                                          
grantees, this_privileges,
                                                                           
grantorId, ownerId);
  
                nnewmembers = aclmembers(new_acl, &newmembers);
--- 1075,1083 ----
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               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);
***************
*** 1234,1240 ****
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(NamespaceRelationId, 
HeapTupleGetOid(tuple),
!                                                         ownerId, is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
--- 1100,1106 ----
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(NamespaceRelationId, 
HeapTupleGetOid(tuple),
!                                                         ownerId, 
istmt->is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
***************
*** 1250,1268 ****
  }
  
  static void
! ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
!                                        AclMode privileges, List *grantees, 
bool grant_option,
!                                        DropBehavior behavior)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (all_privs && privileges == ACL_NO_RIGHTS)
!               privileges = ACL_ALL_RIGHTS_TABLESPACE;
  
        relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
  
!       foreach(cell, objects)
        {
                Oid                     tblId = lfirst_oid(cell);
                Form_pg_tablespace pg_tablespace_tuple;
--- 1116,1132 ----
  }
  
  static void
! ExecGrant_Tablespace(InternalGrant *istmt)
  {
        Relation        relation;
        ListCell   *cell;
  
!       if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
!               istmt->privileges = ACL_ALL_RIGHTS_TABLESPACE;
  
        relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
  
!       foreach(cell, istmt->objects)
        {
                Oid                     tblId = lfirst_oid(cell);
                Form_pg_tablespace pg_tablespace_tuple;
***************
*** 1312,1367 ****
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), 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_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")));
!               }
  
                /*
                 * Generate new ACL.
--- 1176,1196 ----
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Determine ID to do the grant as, and available grant options 
*/
!               select_best_grantor(GetUserId(), istmt->privileges,
                                                        old_acl, ownerId,
                                                        &grantorId, 
&avail_goptions);
  
                /*
!                * Restrict the privileges to what we can actually grant, and 
emit
!                * the standards-mandated warning and error messages.
                 */
!               this_privileges =
!                       restrict_and_check_grant(istmt->is_grant, 
avail_goptions,
!                                                                        
istmt->all_privs, istmt->privileges,
!                                                                        tblId, 
grantorId,
!                                                                        
ACL_ALL_RIGHTS_TABLESPACE,
!                                                                        
ACL_KIND_TABLESPACE,
!                                                                        
NameStr(pg_tablespace_tuple->spcname));
  
                /*
                 * Generate new ACL.
***************
*** 1371,1379 ****
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               new_acl = merge_acl_with_grant(old_acl, is_grant,
!                                                                          
grant_option, behavior,
!                                                                          
grantees, this_privileges,
                                                                           
grantorId, ownerId);
  
                nnewmembers = aclmembers(new_acl, &newmembers);
--- 1200,1208 ----
                 */
                noldmembers = aclmembers(old_acl, &oldmembers);
  
!               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);
***************
*** 1396,1402 ****
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(TableSpaceRelationId, tblId,
!                                                         ownerId, is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
--- 1225,1231 ----
  
                /* Update the shared dependency ACL info */
                updateAclDependencies(TableSpaceRelationId, tblId,
!                                                         ownerId, 
istmt->is_grant,
                                                          noldmembers, 
oldmembers,
                                                          nnewmembers, 
newmembers);
  
Index: src/backend/catalog/pg_shdepend.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/pg_shdepend.c,v
retrieving revision 1.4
diff -c -r1.4 pg_shdepend.c
*** src/backend/catalog/pg_shdepend.c   21 Nov 2005 12:49:30 -0000      1.4
--- src/backend/catalog/pg_shdepend.c   21 Nov 2005 15:08:16 -0000
***************
*** 1122,1127 ****
--- 1122,1128 ----
                        {
                                ObjectAddress   obj;
                                GrantObjectType objtype;
+                               InternalGrant   istmt;
  
                                /* Shouldn't happen */
                                case SHARED_DEPENDENCY_PIN:
***************
*** 1132,1153 ****
                                        switch (sdepForm->classid)
                                        {
                                                case RelationRelationId:
!                                                       objtype = 
ACL_OBJECT_RELATION;
                                                        break;
                                                case DatabaseRelationId:
!                                                       objtype = 
ACL_OBJECT_DATABASE;
                                                        break;
                                                case ProcedureRelationId:
!                                                       objtype = 
ACL_OBJECT_FUNCTION;
                                                        break;
                                                case LanguageRelationId:
!                                                       objtype = 
ACL_OBJECT_LANGUAGE;
                                                        break;
                                                case NamespaceRelationId:
!                                                       objtype = 
ACL_OBJECT_NAMESPACE;
                                                        break;
                                                case TableSpaceRelationId:
!                                                       objtype = 
ACL_OBJECT_TABLESPACE;
                                                        break;
                                                default:
                                                        elog(ERROR, "unexpected 
object type %d",
--- 1133,1154 ----
                                        switch (sdepForm->classid)
                                        {
                                                case RelationRelationId:
!                                                       istmt.objtype = 
ACL_OBJECT_RELATION;
                                                        break;
                                                case DatabaseRelationId:
!                                                       istmt.objtype = 
ACL_OBJECT_DATABASE;
                                                        break;
                                                case ProcedureRelationId:
!                                                       istmt.objtype = 
ACL_OBJECT_FUNCTION;
                                                        break;
                                                case LanguageRelationId:
!                                                       istmt.objtype = 
ACL_OBJECT_LANGUAGE;
                                                        break;
                                                case NamespaceRelationId:
!                                                       istmt.objtype = 
ACL_OBJECT_NAMESPACE;
                                                        break;
                                                case TableSpaceRelationId:
!                                                       istmt.objtype = 
ACL_OBJECT_TABLESPACE;
                                                        break;
                                                default:
                                                        elog(ERROR, "unexpected 
object type %d",
***************
*** 1156,1166 ****
                                                        objtype = 
(GrantObjectType) 0;
                                                        break;
                                        }
  
!                                       ExecGrantStmt_oids(false, objtype,
!                                                                          
list_make1_oid(sdepForm->objid), true,
!                                                                          
ACL_NO_RIGHTS, list_make1_oid(roleid),
!                                                                          
false, DROP_CASCADE);
                                        break;
                                case SHARED_DEPENDENCY_OWNER:
                                        /*
--- 1157,1171 ----
                                                        objtype = 
(GrantObjectType) 0;
                                                        break;
                                        }
+                                       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: src/include/utils/acl.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/include/utils/acl.h,v
retrieving revision 1.89
diff -c -r1.89 acl.h
*** src/include/utils/acl.h     21 Nov 2005 12:49:33 -0000      1.89
--- src/include/utils/acl.h     21 Nov 2005 14:32:59 -0000
***************
*** 182,187 ****
--- 182,207 ----
  } 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,229 ****
   * 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 AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
                                 AclMode mask, AclMaskHow how);
--- 241,247 ----
   * prototypes for functions in aclchk.c
   */
  extern void ExecuteGrantStmt(GrantStmt *stmt);
! extern void ExecGrantStmt_oids(InternalGrant *istmt);
  
  extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
                                 AclMode mask, AclMaskHow how);
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to