diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 04d7840..7148c48 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -76,6 +76,7 @@
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "miscadmin.h"
 #include "utils/tqual.h"
 
 
@@ -172,7 +173,8 @@ static void findDependentObjects(const ObjectAddress *object,
 					 ObjectAddressStack *stack,
 					 ObjectAddresses *targetObjects,
 					 const ObjectAddresses *pendingObjects,
-					 Relation *depRel);
+					 Relation *depRel,
+					 bool lockObjects);
 static void reportDependentObjects(const ObjectAddresses *targetObjects,
 					   DropBehavior behavior,
 					   int msglevel,
@@ -182,6 +184,7 @@ static void deleteOneObject(const ObjectAddress *object,
 static void doDeletion(const ObjectAddress *object, int flags);
 static void AcquireDeletionLock(const ObjectAddress *object, int flags);
 static void ReleaseDeletionLock(const ObjectAddress *object);
+static void ReleaseDeletionLockCompletely(const ObjectAddress *object);
 static bool find_expr_references_walker(Node *node,
 							find_expr_references_context *context);
 static void eliminate_duplicate_dependencies(ObjectAddresses *addrs);
@@ -296,7 +299,8 @@ performDeletion(const ObjectAddress *object,
 						 NULL,	/* empty stack */
 						 targetObjects,
 						 NULL,	/* no pendingObjects */
-						 &depRel);
+						 &depRel,
+						 true /* lock objects during the search */);
 
 	/*
 	 * Check if deletion is allowed, and report about cascaded deletes.
@@ -367,7 +371,8 @@ performMultipleDeletions(const ObjectAddresses *objects,
 							 NULL,		/* empty stack */
 							 targetObjects,
 							 objects,
-							 &depRel);
+							 &depRel,
+							 true /* lock objects during the search */);
 	}
 
 	/*
@@ -434,7 +439,9 @@ deleteWhatDependsOn(const ObjectAddress *object,
 						 NULL,	/* empty stack */
 						 targetObjects,
 						 NULL,	/* no pendingObjects */
-						 &depRel);
+						 &depRel,
+						 false /* without locking */);
+
 
 	/*
 	 * Check if deletion is allowed, and report about cascaded deletes.
@@ -464,8 +471,9 @@ deleteWhatDependsOn(const ObjectAddress *object,
 		 * purposes, we might need to revisit this.
 		 */
 		deleteOneObject(thisobj, &depRel, PERFORM_DELETION_INTERNAL);
+		ReleaseDeletionLockCompletely(thisobj);
 	}
 
 	/* And clean up */
 	free_object_addresses(targetObjects);
 
@@ -506,7 +514,8 @@ findDependentObjects(const ObjectAddress *object,
 					 ObjectAddressStack *stack,
 					 ObjectAddresses *targetObjects,
 					 const ObjectAddresses *pendingObjects,
-					 Relation *depRel)
+					 Relation *depRel,
+					 bool lockObjects)
 {
 	ScanKeyData key[3];
 	int			nkeys;
@@ -622,7 +631,8 @@ findDependentObjects(const ObjectAddress *object,
 					{
 						systable_endscan(scan);
 						/* need to release caller's lock; see notes below */
-						ReleaseDeletionLock(object);
+						if (lockObjects)
+							ReleaseDeletionLock(object);
 						return;
 					}
 
@@ -671,8 +681,11 @@ findDependentObjects(const ObjectAddress *object,
 				 * caller's lock to avoid deadlock against a concurrent
 				 * deletion of the owning object.)
 				 */
-				ReleaseDeletionLock(object);
-				AcquireDeletionLock(&otherObject, 0);
+				if (lockObjects)
+				{
+					ReleaseDeletionLock(object);
+					AcquireDeletionLock(&otherObject, 0);
+				}
 
 				/*
 				 * The owning object might have been deleted while we waited
@@ -683,7 +696,8 @@ findDependentObjects(const ObjectAddress *object,
 				if (!systable_recheck_tuple(scan, tup))
 				{
 					systable_endscan(scan);
-					ReleaseDeletionLock(&otherObject);
+					if (lockObjects)
+						ReleaseDeletionLock(&otherObject);
 					return;
 				}
 
@@ -703,7 +717,8 @@ findDependentObjects(const ObjectAddress *object,
 									 stack,
 									 targetObjects,
 									 pendingObjects,
-									 depRel);
+									 depRel,
+									 lockObjects);
 				/* And we're done here. */
 				systable_endscan(scan);
 				return;
@@ -764,10 +779,11 @@ findDependentObjects(const ObjectAddress *object,
 		otherObject.objectId = foundDep->objid;
 		otherObject.objectSubId = foundDep->objsubid;
 
 		/*
 		 * Must lock the dependent object before recursing to it.
 		 */
-		AcquireDeletionLock(&otherObject, 0);
+		if (lockObjects)
+			AcquireDeletionLock(&otherObject, 0);
 
 		/*
 		 * The dependent object might have been deleted while we waited to
@@ -779,7 +795,8 @@ findDependentObjects(const ObjectAddress *object,
 		if (!systable_recheck_tuple(scan, tup))
 		{
 			/* release the now-useless lock */
-			ReleaseDeletionLock(&otherObject);
+			if (lockObjects)
+				ReleaseDeletionLock(&otherObject);
 			/* and continue scanning for dependencies */
 			continue;
 		}
@@ -824,7 +841,8 @@ findDependentObjects(const ObjectAddress *object,
 							 &mystack,
 							 targetObjects,
 							 pendingObjects,
-							 depRel);
+							 depRel,
+							 lockObjects);
 	}
 
 	systable_endscan(scan);
@@ -1335,6 +1353,20 @@ ReleaseDeletionLock(const ObjectAddress *object)
 }
 
 /*
+ * ReleaseDeletionLock - release an object deletion lock
+ */
+static void
+ReleaseDeletionLockCompletely(const ObjectAddress *object)
+{
+	LOCKTAG		tag;
+	if (object->classId == RelationRelationId)
+		SET_LOCKTAG_RELATION(tag, MyDatabaseId, object->objectId);
+	else
+		SET_LOCKTAG_OBJECT(tag, MyDatabaseId, object->classId, object->objectId, 0);
+	LockReleaseCompletely(&tag, AccessExclusiveLock, false);
+}
+
+/*
  * recordDependencyOnExpr - find expression dependencies
  *
  * This is used to find the dependencies of rules, constraint expressions,
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -47,6 +47,7 @@
 #include "storage/standby.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
+#include "utils/rel.h"
 #include "utils/resowner_private.h"
 
 
@@ -1806,6 +1807,48 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
 				true);
 }
 
+void
+LockReleaseCompletely(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
+{
+	LOCKMETHODID lockmethodid = locktag->locktag_lockmethodid;
+	LockMethod	lockMethodTable;
+	LOCALLOCKTAG localtag;
+	LOCALLOCK  *locallock;
+	int num;
+
+	if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
+		elog(ERROR, "unrecognized lock method: %d", lockmethodid);
+	lockMethodTable = LockMethods[lockmethodid];
+	if (lockmode <= 0 || lockmode > lockMethodTable->numLockModes)
+		elog(ERROR, "unrecognized lock mode: %d", lockmode);
+
+#ifdef LOCK_DEBUG
+	if (LOCK_DEBUG_ENABLED(locktag))
+		elog(LOG, "LockReleaseCompletely: lock [%u,%u] %s",
+			 locktag->locktag_field1, locktag->locktag_field2,
+			 lockMethodTable->lockModeNames[lockmode]);
+#endif
+
+	/*
+	 * Find the LOCALLOCK entry for this lock and lockmode
+	 */
+	MemSet(&localtag, 0, sizeof(localtag));		/* must clear padding */
+	localtag.lock = *locktag;
+	localtag.mode = lockmode;
+
+	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
+										  (void *) &localtag,
+										  HASH_FIND, NULL);
+
+	num = 0;
+	if (!locallock) return;
+	num = locallock->nLocks;
+	if (num <= 0) return;
+
+	while (num--)
+		LockRelease(locktag, lockmode, sessionLock);
+}
+
 /*
  * LockRelease -- look up 'locktag' and release one 'lockmode' lock on it.
  *		Release a session lock if 'sessionLock' is true, else release a
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index efa75ec..0091d59 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -533,6 +533,8 @@ extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag,
 extern void AbortStrongLockAcquire(void);
 extern bool LockRelease(const LOCKTAG *locktag,
 			LOCKMODE lockmode, bool sessionLock);
+extern void LockReleaseCompletely(const LOCKTAG *locktag,
+			LOCKMODE lockmode, bool sessionLock);
 extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);
 extern void LockReleaseSession(LOCKMETHODID lockmethodid);
 extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks);
