diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index 7e97b83927f3e1561e2f3a7d6d897221f5983264..bb735ac02060083eb9f886a2ac7fbdfe2b6bcd29 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -370,7 +370,10 @@ RemovePolicyById(Oid policy_id)
 		elog(ERROR, "could not find tuple for policy %u", policy_id);
 
 	/*
-	 * Open and exclusive-lock the relation the policy belong to.
+	 * Open and exclusive-lock the relation the policy belongs to.  (We need
+	 * exclusive lock to lock out queries that might otherwise depend on the
+	 * set of policies the rel has; furthermore we've got to hold the lock
+	 * till commit.)
 	 */
 	relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
 
@@ -390,7 +393,6 @@ RemovePolicyById(Oid policy_id)
 	simple_heap_delete(pg_policy_rel, &tuple->t_self);
 
 	systable_endscan(sscan);
-	heap_close(rel, AccessExclusiveLock);
 
 	/*
 	 * Note that, unlike some of the other flags in pg_class, relrowsecurity
@@ -400,9 +402,10 @@ RemovePolicyById(Oid policy_id)
 	 * policy is created and all records are filtered (except for queries from
 	 * the owner).
 	 */
-
 	CacheInvalidateRelcache(rel);
 
+	heap_close(rel, NoLock);
+
 	/* Clean up */
 	heap_close(pg_policy_rel, RowExclusiveLock);
 }
@@ -657,7 +660,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
 
 	/* Clean up. */
 	systable_endscan(sscan);
-	relation_close(rel, AccessExclusiveLock);
+
+	relation_close(rel, NoLock);
+
 	heap_close(pg_policy_rel, RowExclusiveLock);
 
 	return(noperm || num_roles > 0);
@@ -734,7 +739,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
 										RangeVarCallbackForPolicy,
 										(void *) stmt);
 
-	/* Open target_table to build quals. No lock is necessary. */
+	/* Open target_table to build quals. No additional lock is necessary. */
 	target_table = relation_open(table_id, NoLock);
 
 	/* Add for the regular security quals */