diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c459c1e221383b47a6d4b21178b6b4d9e9b5f471..0e6165118556ca47b494ff2674f83016548a3fc8 100644
*** a/src/backend/catalog/dependency.c
--- b/src/backend/catalog/dependency.c
*************** typedef struct
*** 98,103 ****
--- 98,104 ----
  #define DEPFLAG_AUTO		0x0004		/* reached via auto dependency */
  #define DEPFLAG_INTERNAL	0x0008		/* reached via internal dependency */
  #define DEPFLAG_EXTENSION	0x0010		/* reached via extension dependency */
+ #define DEPFLAG_REVERSE		0x0020		/* reverse internal/extension link */
  
  
  /* expansible list of ObjectAddresses */
*************** findDependentObjects(const ObjectAddress
*** 513,524 ****
  
  	/*
  	 * The target object might be internally dependent on some other object
! 	 * (its "owner").  If so, and if we aren't recursing from the owning
! 	 * object, we have to transform this deletion request into a deletion
! 	 * request of the owning object.  (We'll eventually recurse back to this
! 	 * object, but the owning object has to be visited first so it will be
! 	 * deleted after.)	The way to find out about this is to scan the
! 	 * pg_depend entries that show what this object depends on.
  	 */
  	ScanKeyInit(&key[0],
  				Anum_pg_depend_classid,
--- 514,526 ----
  
  	/*
  	 * The target object might be internally dependent on some other object
! 	 * (its "owner"), or be a member of an extension (again considered its
! 	 * owner).  If so, and if we aren't recursing from the owning object, we
! 	 * have to transform this deletion request into a deletion request of the
! 	 * owning object.  (We'll eventually recurse back to this object, but the
! 	 * owning object has to be visited first so it will be deleted after.)
! 	 * The way to find out about this is to scan the pg_depend entries that
! 	 * show what this object depends on.
  	 */
  	ScanKeyInit(&key[0],
  				Anum_pg_depend_classid,
*************** findDependentObjects(const ObjectAddress
*** 567,573 ****
  				 * 1. At the outermost recursion level, disallow the DROP. (We
  				 * just ereport here, rather than proceeding, since no other
  				 * dependencies are likely to be interesting.)	However, if
! 				 * the other object is listed in pendingObjects, just release
  				 * the caller's lock and return; we'll eventually complete the
  				 * DROP when we reach that entry in the pending list.
  				 */
--- 569,575 ----
  				 * 1. At the outermost recursion level, disallow the DROP. (We
  				 * just ereport here, rather than proceeding, since no other
  				 * dependencies are likely to be interesting.)	However, if
! 				 * the owning object is listed in pendingObjects, just release
  				 * the caller's lock and return; we'll eventually complete the
  				 * DROP when we reach that entry in the pending list.
  				 */
*************** findDependentObjects(const ObjectAddress
*** 607,625 ****
  
  				/*
  				 * 3. When recursing from anyplace else, transform this
! 				 * deletion request into a delete of the other object.
  				 *
  				 * First, release caller's lock on this object and get
! 				 * deletion lock on the other object.  (We must release
  				 * caller's lock to avoid deadlock against a concurrent
! 				 * deletion of the other object.)
  				 */
  				ReleaseDeletionLock(object);
  				AcquireDeletionLock(&otherObject);
  
  				/*
! 				 * The other object might have been deleted while we waited to
! 				 * lock it; if so, neither it nor the current object are
  				 * interesting anymore.  We test this by checking the
  				 * pg_depend entry (see notes below).
  				 */
--- 609,627 ----
  
  				/*
  				 * 3. When recursing from anyplace else, transform this
! 				 * deletion request into a delete of the owning object.
  				 *
  				 * First, release caller's lock on this object and get
! 				 * deletion lock on the owning object.  (We must release
  				 * caller's lock to avoid deadlock against a concurrent
! 				 * deletion of the owning object.)
  				 */
  				ReleaseDeletionLock(object);
  				AcquireDeletionLock(&otherObject);
  
  				/*
! 				 * The owning object might have been deleted while we waited
! 				 * to lock it; if so, neither it nor the current object are
  				 * interesting anymore.  We test this by checking the
  				 * pg_depend entry (see notes below).
  				 */
*************** findDependentObjects(const ObjectAddress
*** 631,643 ****
  				}
  
  				/*
! 				 * Okay, recurse to the other object instead of proceeding. We
! 				 * treat this exactly as if the original reference had linked
! 				 * to that object instead of this one; hence, pass through the
! 				 * same flags and stack.
  				 */
  				findDependentObjects(&otherObject,
! 									 flags,
  									 stack,
  									 targetObjects,
  									 pendingObjects,
--- 633,650 ----
  				}
  
  				/*
! 				 * Okay, recurse to the owning object instead of proceeding.
! 				 *
! 				 * We do not need to stack the current object; we want the
! 				 * traversal order to be as if the original reference had
! 				 * linked to the owning object instead of this one.
! 				 *
! 				 * The dependency type is a "reverse" dependency: we need to
! 				 * delete the owning object if this one is to be deleted, but
! 				 * this linkage is never a reason for an automatic deletion.
  				 */
  				findDependentObjects(&otherObject,
! 									 DEPFLAG_REVERSE,
  									 stack,
  									 targetObjects,
  									 pendingObjects,
