diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 690a24e3f3..643d31c199 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -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.
@@ -42,28 +42,22 @@
 #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.
+		 * 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_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")));
-		}
+		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.
+		 * 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_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")));
-		}
+		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
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 703f613916..faa64c22fc 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -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;
 					}
+					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(false, objtype,
-									   list_make1_oid(sdepForm->objid), true,
-									   ACL_NO_RIGHTS, list_make1_oid(roleid),
-									   false, DROP_CASCADE);
+					ExecGrantStmt_oids(&istmt);
 					break;
 				case SHARED_DEPENDENCY_OWNER:
 
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 04c5631214..8e6cb95d25 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -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
@@ -181,6 +181,26 @@ typedef enum AclObjectKind
 	MAX_ACL_KIND				/* MUST BE LAST */
 } 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
  */
@@ -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);