diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 5151d7bbceab564f0e25a19421440ed57195cef0..f61add142aaa2e36d4b10bb811b5fd58e9f5d400 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.164 2010/03/06 23:10:42 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.165 2010/04/05 01:09:52 tgl Exp $
  *
  * NOTES
  *	  See acl.h.
@@ -1142,7 +1142,16 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		isNew = true;
 	}
 
-	if (old_acl == NULL)
+	if (old_acl != NULL)
+	{
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.  Collect data before
+		 * merge_acl_with_grant throws away old_acl.
+		 */
+		noldmembers = aclmembers(old_acl, &oldmembers);
+	}
+	else
 	{
 		/*
 		 * If we are creating a global entry, start with the hard-wired
@@ -1154,14 +1163,11 @@ SetDefaultACL(InternalDefaultACL *iacls)
 			old_acl = acldefault(iacls->objtype, iacls->roleid);
 		else
 			old_acl = make_empty_acl();
-	}
 
-	/*
-	 * We need the members of both old and new ACLs so we can correct the
-	 * shared dependency information.  Collect data before
-	 * merge_acl_with_grant throws away old_acl.
-	 */
-	noldmembers = aclmembers(old_acl, &oldmembers);
+		/* There are no old member roles according to the catalogs */
+		noldmembers = 0;
+		oldmembers = NULL;
+	}
 
 	/*
 	 * Generate new ACL.  Grantor of rights is always the same as the target
@@ -1236,7 +1242,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
 	nnewmembers = aclmembers(new_acl, &newmembers);
 
 	updateAclDependencies(DefaultAclRelationId, HeapTupleGetOid(newtuple), 0,
-						  iacls->roleid, iacls->is_grant,
+						  iacls->roleid,
 						  noldmembers, oldmembers,
 						  nnewmembers, newmembers);
 
@@ -1526,9 +1532,18 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	aclDatum = SysCacheGetAttr(ATTNUM, attr_tuple, Anum_pg_attribute_attacl,
 							   &isNull);
 	if (isNull)
+	{
 		old_acl = acldefault(ACL_OBJECT_COLUMN, ownerId);
+		/* There are no old member roles according to the catalogs */
+		noldmembers = 0;
+		oldmembers = NULL;
+	}
 	else
+	{
 		old_acl = DatumGetAclPCopy(aclDatum);
+		/* Get the roles mentioned in the existing ACL */
+		noldmembers = aclmembers(old_acl, &oldmembers);
+	}
 
 	/*
 	 * In select_best_grantor we should consider existing table-level ACL bits
@@ -1563,18 +1578,17 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 
 	/*
 	 * Generate new ACL.
-	 *
-	 * We need the members of both old and new ACLs so we can correct the
-	 * shared dependency information.
 	 */
-	noldmembers = aclmembers(old_acl, &oldmembers);
-
 	new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
 								   istmt->grant_option,
 								   istmt->behavior, istmt->grantees,
 								   col_privileges, grantorId,
 								   ownerId);
 
+	/*
+	 * We need the members of both old and new ACLs so we can correct the
+	 * shared dependency information.
+	 */
 	nnewmembers = aclmembers(new_acl, &newmembers);
 
 	/* finished building new ACL value, now insert it */
@@ -1613,7 +1627,7 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(RelationRelationId, relOid, attnum,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 	}
@@ -1648,6 +1662,8 @@ ExecGrant_Relation(InternalGrant *istmt)
 		bool		have_col_privileges;
 		Acl		   *old_acl;
 		Acl		   *old_rel_acl;
+		int			noldmembers;
+		Oid		   *oldmembers;
 		Oid			ownerId;
 		HeapTuple	tuple;
 		ListCell   *cell_colprivs;
@@ -1770,11 +1786,20 @@ ExecGrant_Relation(InternalGrant *istmt)
 		aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
 								   &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(pg_class_tuple->relkind == RELKIND_SEQUENCE ?
 								 ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
 								 ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Need an extra copy of original rel ACL for column handling */
 		old_rel_acl = aclcopy(old_acl);
@@ -1791,9 +1816,7 @@ ExecGrant_Relation(InternalGrant *istmt)
 			Datum		values[Natts_pg_class];
 			bool		nulls[Natts_pg_class];
 			bool		replaces[Natts_pg_class];
-			int			noldmembers;
 			int			nnewmembers;
-			Oid		   *oldmembers;
 			Oid		   *newmembers;
 
 			/* Determine ID to do the grant as, and available grant options */
@@ -1816,12 +1839,7 @@ ExecGrant_Relation(InternalGrant *istmt)
 
 			/*
 			 * Generate new ACL.
-			 *
-			 * We need the members of both old and new ACLs so we can correct
-			 * the shared dependency information.
 			 */
-			noldmembers = aclmembers(old_acl, &oldmembers);
-
 			new_acl = merge_acl_with_grant(old_acl,
 										   istmt->is_grant,
 										   istmt->grant_option,
@@ -1831,6 +1849,10 @@ ExecGrant_Relation(InternalGrant *istmt)
 										   grantorId,
 										   ownerId);
 
+			/*
+			 * We need the members of both old and new ACLs so we can correct
+			 * the shared dependency information.
+			 */
 			nnewmembers = aclmembers(new_acl, &newmembers);
 
 			/* finished building new ACL value, now insert it */
@@ -1851,7 +1873,7 @@ ExecGrant_Relation(InternalGrant *istmt)
 
 			/* Update the shared dependency ACL info */
 			updateAclDependencies(RelationRelationId, relOid, 0,
-								  ownerId, istmt->is_grant,
+								  ownerId,
 								  noldmembers, oldmembers,
 								  nnewmembers, newmembers);
 
@@ -1980,9 +2002,18 @@ ExecGrant_Database(InternalGrant *istmt)
 		aclDatum = heap_getattr(tuple, Anum_pg_database_datacl,
 								RelationGetDescr(relation), &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_DATABASE, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2002,17 +2033,16 @@ ExecGrant_Database(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2033,7 +2063,7 @@ ExecGrant_Database(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple), 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2097,9 +2127,18 @@ ExecGrant_Fdw(InternalGrant *istmt)
 								   Anum_pg_foreign_data_wrapper_fdwacl,
 								   &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_FDW, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2119,17 +2158,16 @@ ExecGrant_Fdw(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2151,7 +2189,7 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(ForeignDataWrapperRelationId,
 							  HeapTupleGetOid(tuple), 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2214,9 +2252,18 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 								   Anum_pg_foreign_server_srvacl,
 								   &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_FOREIGN_SERVER, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2236,17 +2283,16 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2268,7 +2314,7 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(ForeignServerRelationId,
 							  HeapTupleGetOid(tuple), 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2330,9 +2376,18 @@ ExecGrant_Function(InternalGrant *istmt)
 		aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
 								   &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_FUNCTION, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2352,17 +2407,16 @@ ExecGrant_Function(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2383,7 +2437,7 @@ ExecGrant_Function(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(ProcedureRelationId, funcId, 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2452,9 +2506,18 @@ ExecGrant_Language(InternalGrant *istmt)
 		aclDatum = SysCacheGetAttr(LANGNAME, tuple, Anum_pg_language_lanacl,
 								   &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2474,17 +2537,16 @@ ExecGrant_Language(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2505,7 +2567,7 @@ ExecGrant_Language(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple), 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2582,9 +2644,18 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 								Anum_pg_largeobject_metadata_lomacl,
 								RelationGetDescr(relation), &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_LARGEOBJECT, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2604,17 +2675,16 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2637,7 +2707,7 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(LargeObjectRelationId,
 							  HeapTupleGetOid(tuple), 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2700,9 +2770,18 @@ ExecGrant_Namespace(InternalGrant *istmt)
 								   Anum_pg_namespace_nspacl,
 								   &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2722,17 +2801,16 @@ ExecGrant_Namespace(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2753,7 +2831,7 @@ ExecGrant_Namespace(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple), 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
@@ -2816,9 +2894,18 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		aclDatum = heap_getattr(tuple, Anum_pg_tablespace_spcacl,
 								RelationGetDescr(relation), &isNull);
 		if (isNull)
+		{
 			old_acl = acldefault(ACL_OBJECT_TABLESPACE, ownerId);
+			/* There are no old member roles according to the catalogs */
+			noldmembers = 0;
+			oldmembers = NULL;
+		}
 		else
+		{
 			old_acl = DatumGetAclPCopy(aclDatum);
+			/* Get the roles mentioned in the existing ACL */
+			noldmembers = aclmembers(old_acl, &oldmembers);
+		}
 
 		/* Determine ID to do the grant as, and available grant options */
 		select_best_grantor(GetUserId(), istmt->privileges,
@@ -2838,17 +2925,16 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 
 		/*
 		 * Generate new ACL.
-		 *
-		 * We need the members of both old and new ACLs so we can correct the
-		 * shared dependency information.
 		 */
-		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);
 
+		/*
+		 * We need the members of both old and new ACLs so we can correct the
+		 * shared dependency information.
+		 */
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
@@ -2869,7 +2955,7 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(TableSpaceRelationId, tblId, 0,
-							  ownerId, istmt->is_grant,
+							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 39aec680c086926ba232082a07ad58e83cf8536a..47e0c9b9cf5df0eb69a8ffa863a888f5fb991c4a 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.372 2010/02/26 02:00:36 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.373 2010/04/05 01:09:52 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1160,7 +1160,7 @@ heap_create_with_catalog(const char *relname,
 
 			nnewmembers = aclmembers(relacl, &newmembers);
 			updateAclDependencies(RelationRelationId, relid, 0,
-								  ownerid, true,
+								  ownerid,
 								  0, NULL,
 								  nnewmembers, newmembers);
 		}
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index f97641d55556377cb28f1861c0f034160063c48c..64b8872706354a1cf912b83e6e942810e8bd2335 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.173 2010/03/19 22:54:40 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.174 2010/04/05 01:09:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -609,7 +609,7 @@ ProcedureCreate(const char *procedureName,
 
 		nnewmembers = aclmembers(proacl, &newmembers);
 		updateAclDependencies(ProcedureRelationId, retval, 0,
-							  proowner, true,
+							  proowner,
 							  0, NULL,
 							  nnewmembers, newmembers);
 	}
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index df65e1086ee57a65c05587c4b0f62d1e0a1e01fa..c7a5e86c58340f768115c0d51f8fa0478272dcde 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.40 2010/02/26 02:00:37 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.41 2010/04/05 01:09:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -54,8 +54,7 @@ typedef enum
 	REMOTE_OBJECT
 } objectType;
 
-static int getOidListDiff(Oid *list1, int nlist1, Oid *list2, int nlist2,
-			   Oid **diff);
+static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2);
 static Oid	classIdGetDbId(Oid classId);
 static void shdepChangeDep(Relation sdepRel,
 			   Oid classid, Oid objid, int32 objsubid,
@@ -328,57 +327,53 @@ changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
  * getOidListDiff
  *		Helper for updateAclDependencies.
  *
- * Takes two Oid arrays and returns elements from the first not found in the
- * second.	We assume both arrays are sorted and de-duped, and that the
- * second array does not contain any values not found in the first.
- *
- * NOTE: Both input arrays are pfreed.
+ * Takes two Oid arrays and removes elements that are common to both arrays,
+ * leaving just those that are in one input but not the other.
+ * We assume both arrays have been sorted and de-duped.
  */
-static int
-getOidListDiff(Oid *list1, int nlist1, Oid *list2, int nlist2, Oid **diff)
+static void
+getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2)
 {
-	Oid		   *result;
-	int			i,
-				j,
-				k = 0;
-
-	AssertArg(nlist1 >= nlist2 && nlist2 >= 0);
+	int			in1,
+				in2,
+				out1,
+				out2;
 
-	result = palloc(sizeof(Oid) * (nlist1 - nlist2));
-	*diff = result;
-
-	for (i = 0, j = 0; i < nlist1 && j < nlist2;)
+	in1 = in2 = out1 = out2 = 0;
+	while (in1 < *nlist1 && in2 < *nlist2)
 	{
-		if (list1[i] == list2[j])
+		if (list1[in1] == list2[in2])
 		{
-			i++;
-			j++;
+			/* skip over duplicates */
+			in1++;
+			in2++;
 		}
-		else if (list1[i] < list2[j])
+		else if (list1[in1] < list2[in2])
 		{
-			result[k++] = list1[i];
-			i++;
+			/* list1[in1] is not in list2 */
+			list1[out1++] = list1[in1++];
 		}
 		else
 		{
-			/* can't happen */
-			elog(WARNING, "invalid element %u in shorter list", list2[j]);
-			j++;
+			/* list2[in2] is not in list1 */
+			list2[out2++] = list2[in2++];
 		}
 	}
 
-	for (; i < nlist1; i++)
-		result[k++] = list1[i];
-
-	/* We should have copied the exact number of elements */
-	AssertState(k == (nlist1 - nlist2));
+	/* any remaining list1 entries are not in list2 */
+	while (in1 < *nlist1)
+	{
+		list1[out1++] = list1[in1++];
+	}
 
-	if (list1)
-		pfree(list1);
-	if (list2)
-		pfree(list2);
+	/* any remaining list2 entries are not in list1 */
+	while (in2 < *nlist2)
+	{
+		list2[out2++] = list2[in2++];
+	}
 
-	return k;
+	*nlist1 = out1;
+	*nlist2 = out2;
 }
 
 /*
@@ -387,52 +382,50 @@ getOidListDiff(Oid *list1, int nlist1, Oid *list2, int nlist2, Oid **diff)
  *
  * classId, objectId, objsubId: identify the object whose ACL this is
  * ownerId: role owning the object
- * isGrant: are we adding or removing ACL entries?
  * noldmembers, oldmembers: array of roleids appearing in old ACL
  * nnewmembers, newmembers: array of roleids appearing in new ACL
  *
- * We calculate the difference between the new and old lists of roles,
- * and then insert (if it's a grant) or delete (if it's a revoke) from
- * pg_shdepend as appropiate.
+ * We calculate the differences between the new and old lists of roles,
+ * and then insert or delete from pg_shdepend as appropiate.
  *
- * Note that we can't insert blindly at grant, because we would end up with
- * duplicate registered dependencies.  We could check for existence of the
- * tuple before inserting, but that seems to be more expensive than what we are
- * doing now.  On the other hand, we can't just delete the tuples blindly at
- * revoke, because the user may still have other privileges.
+ * Note that we can't just insert all referenced roles blindly during GRANT,
+ * because we would end up with duplicate registered dependencies.  We could
+ * check for existence of the tuples before inserting, but that seems to be
+ * more expensive than what we are doing here.  Likewise we can't just delete
+ * blindly during REVOKE, because the user may still have other privileges.
+ * It is also possible that REVOKE actually adds dependencies, due to
+ * instantiation of a formerly implicit default ACL (although at present,
+ * all such dependencies should be for the owning role, which we ignore here).
  *
- * NOTE: Both input arrays must be sorted and de-duped.  They are pfreed
- * before return.
+ * NOTE: Both input arrays must be sorted and de-duped.  (Typically they
+ * are extracted from an ACL array by aclmembers(), which takes care of
+ * both requirements.)  The arrays are pfreed before return.
  */
 void
 updateAclDependencies(Oid classId, Oid objectId, int32 objsubId,
-					  Oid ownerId, bool isGrant,
+					  Oid ownerId,
 					  int noldmembers, Oid *oldmembers,
 					  int nnewmembers, Oid *newmembers)
 {
 	Relation	sdepRel;
-	Oid		   *diff;
-	int			ndiff,
-				i;
+	int			i;
 
 	/*
-	 * Calculate the differences between the old and new lists.
+	 * Remove entries that are common to both lists; those represent
+	 * existing dependencies we don't need to change.
+	 *
+	 * OK to overwrite the inputs since we'll pfree them anyway.
 	 */
-	if (isGrant)
-		ndiff = getOidListDiff(newmembers, nnewmembers,
-							   oldmembers, noldmembers, &diff);
-	else
-		ndiff = getOidListDiff(oldmembers, noldmembers,
-							   newmembers, nnewmembers, &diff);
+	getOidListDiff(oldmembers, &noldmembers, newmembers, &nnewmembers);
 
-	if (ndiff > 0)
+	if (noldmembers > 0 || nnewmembers > 0)
 	{
 		sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
 
-		/* Add or drop the respective dependency */
-		for (i = 0; i < ndiff; i++)
+		/* Add new dependencies that weren't already present */
+		for (i = 0; i < nnewmembers; i++)
 		{
-			Oid			roleid = diff[i];
+			Oid			roleid = newmembers[i];
 
 			/*
 			 * Skip the owner: he has an OWNER shdep entry instead. (This is
@@ -442,25 +435,41 @@ updateAclDependencies(Oid classId, Oid objectId, int32 objsubId,
 			if (roleid == ownerId)
 				continue;
 
+			/* Skip pinned roles; they don't need dependency entries */
+			if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
+				continue;
+
+			shdepAddDependency(sdepRel, classId, objectId, objsubId,
+							   AuthIdRelationId, roleid,
+							   SHARED_DEPENDENCY_ACL);
+		}
+
+		/* Drop no-longer-used old dependencies */
+		for (i = 0; i < noldmembers; i++)
+		{
+			Oid			roleid = oldmembers[i];
+
+			/* Skip the owner, same as above */
+			if (roleid == ownerId)
+				continue;
+
 			/* Skip pinned roles */
 			if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
 				continue;
 
-			if (isGrant)
-				shdepAddDependency(sdepRel, classId, objectId, objsubId,
-								   AuthIdRelationId, roleid,
-								   SHARED_DEPENDENCY_ACL);
-			else
-				shdepDropDependency(sdepRel, classId, objectId, objsubId,
-									false,		/* exact match on objsubId */
-									AuthIdRelationId, roleid,
-									SHARED_DEPENDENCY_ACL);
+			shdepDropDependency(sdepRel, classId, objectId, objsubId,
+								false,		/* exact match on objsubId */
+								AuthIdRelationId, roleid,
+								SHARED_DEPENDENCY_ACL);
 		}
 
 		heap_close(sdepRel, RowExclusiveLock);
 	}
 
-	pfree(diff);
+	if (oldmembers)
+		pfree(oldmembers);
+	if (newmembers)
+		pfree(newmembers);
 }
 
 /*
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 6d39ecee507f434ae11ec262535d9435cdbfbabb..d8a0e0aa639e60b4901cc3cf532c81981704f196 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.44 2010/01/02 16:58:01 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.45 2010/04/05 01:09:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -232,7 +232,7 @@ extern void changeDependencyOnOwner(Oid classId, Oid objectId,
 						Oid newOwnerId);
 
 extern void updateAclDependencies(Oid classId, Oid objectId, int32 objectSubId,
-					  Oid ownerId, bool isGrant,
+					  Oid ownerId,
 					  int noldmembers, Oid *oldmembers,
 					  int nnewmembers, Oid *newmembers);