diff --git a/contrib/earthdistance/expected/earthdistance.out b/contrib/earthdistance/expected/earthdistance.out
index 8a3fc749c1cf4708b552f7e252fa14c68fe4d43d..e9382a39a46dfd9fab7d7cc30730037d9bf597b5 100644
--- a/contrib/earthdistance/expected/earthdistance.out
+++ b/contrib/earthdistance/expected/earthdistance.out
@@ -1,6 +1,14 @@
 --
---  Test earth distance functions
+--  Test earthdistance extension
 --
+-- In this file we also do some testing of extension create/drop scenarios.
+-- That's really exercising the core database's dependency logic, so ideally
+-- we'd do it in the core regression tests, but we can't for lack of suitable
+-- guaranteed-available extensions.  earthdistance is a good test case because
+-- it has a dependency on the cube extension.
+--
+CREATE EXTENSION earthdistance;  -- fail, must install cube first
+ERROR:  required extension "cube" is not installed
 CREATE EXTENSION cube;
 CREATE EXTENSION earthdistance;
 --
@@ -945,3 +953,325 @@ SELECT abs(cube_distance(ll_to_earth(-30,-90), '(0)'::cube) / earth() - 1) <
  t
 (1 row)
 
+--
+-- Now we are going to test extension create/drop scenarios.
+--
+-- list what's installed
+\dT
+                                              List of data types
+ Schema | Name  |                                         Description                                         
+--------+-------+---------------------------------------------------------------------------------------------
+ public | cube  | multi-dimensional cube '(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)'
+ public | earth | 
+(2 rows)
+
+\df
+                                         List of functions
+ Schema |       Name        | Result data type |           Argument data types            |  Type  
+--------+-------------------+------------------+------------------------------------------+--------
+ public | cube              | cube             | cube, double precision                   | normal
+ public | cube              | cube             | cube, double precision, double precision | normal
+ public | cube              | cube             | double precision                         | normal
+ public | cube              | cube             | double precision, double precision       | normal
+ public | cube              | cube             | double precision[]                       | normal
+ public | cube              | cube             | double precision[], double precision[]   | normal
+ public | cube_cmp          | integer          | cube, cube                               | normal
+ public | cube_contained    | boolean          | cube, cube                               | normal
+ public | cube_contains     | boolean          | cube, cube                               | normal
+ public | cube_dim          | integer          | cube                                     | normal
+ public | cube_distance     | double precision | cube, cube                               | normal
+ public | cube_enlarge      | cube             | cube, double precision, integer          | normal
+ public | cube_eq           | boolean          | cube, cube                               | normal
+ public | cube_ge           | boolean          | cube, cube                               | normal
+ public | cube_gt           | boolean          | cube, cube                               | normal
+ public | cube_in           | cube             | cstring                                  | normal
+ public | cube_inter        | cube             | cube, cube                               | normal
+ public | cube_is_point     | boolean          | cube                                     | normal
+ public | cube_le           | boolean          | cube, cube                               | normal
+ public | cube_ll_coord     | double precision | cube, integer                            | normal
+ public | cube_lt           | boolean          | cube, cube                               | normal
+ public | cube_ne           | boolean          | cube, cube                               | normal
+ public | cube_out          | cstring          | cube                                     | normal
+ public | cube_overlap      | boolean          | cube, cube                               | normal
+ public | cube_size         | double precision | cube                                     | normal
+ public | cube_subset       | cube             | cube, integer[]                          | normal
+ public | cube_union        | cube             | cube, cube                               | normal
+ public | cube_ur_coord     | double precision | cube, integer                            | normal
+ public | earth             | double precision |                                          | normal
+ public | earth_box         | cube             | earth, double precision                  | normal
+ public | earth_distance    | double precision | earth, earth                             | normal
+ public | g_cube_compress   | internal         | internal                                 | normal
+ public | g_cube_consistent | boolean          | internal, cube, integer, oid, internal   | normal
+ public | g_cube_decompress | internal         | internal                                 | normal
+ public | g_cube_penalty    | internal         | internal, internal, internal             | normal
+ public | g_cube_picksplit  | internal         | internal, internal                       | normal
+ public | g_cube_same       | internal         | cube, cube, internal                     | normal
+ public | g_cube_union      | cube             | internal, internal                       | normal
+ public | gc_to_sec         | double precision | double precision                         | normal
+ public | geo_distance      | double precision | point, point                             | normal
+ public | latitude          | double precision | earth                                    | normal
+ public | ll_to_earth       | earth            | double precision, double precision       | normal
+ public | longitude         | double precision | earth                                    | normal
+ public | sec_to_gc         | double precision | double precision                         | normal
+(44 rows)
+
+\do
+                                      List of operators
+ Schema | Name | Left arg type | Right arg type |   Result type    |       Description        
+--------+------+---------------+----------------+------------------+--------------------------
+ public | &&   | cube          | cube           | boolean          | overlaps
+ public | <    | cube          | cube           | boolean          | lower than
+ public | <=   | cube          | cube           | boolean          | lower than or equal to
+ public | <>   | cube          | cube           | boolean          | different
+ public | <@   | cube          | cube           | boolean          | contained in
+ public | <@>  | point         | point          | double precision | 
+ public | =    | cube          | cube           | boolean          | same as
+ public | >    | cube          | cube           | boolean          | greater than
+ public | >=   | cube          | cube           | boolean          | greater than or equal to
+ public | @    | cube          | cube           | boolean          | contains
+ public | @>   | cube          | cube           | boolean          | contains
+ public | ~    | cube          | cube           | boolean          | contained in
+(12 rows)
+
+drop extension cube;  -- fail, earthdistance requires it
+ERROR:  cannot drop extension cube because other objects depend on it
+DETAIL:  extension earthdistance depends on extension cube
+HINT:  Use DROP ... CASCADE to drop the dependent objects too.
+drop extension earthdistance;
+drop type cube;  -- fail, extension cube requires it
+ERROR:  cannot drop type cube because extension cube requires it
+HINT:  You can drop extension cube instead.
+-- list what's installed
+\dT
+                                             List of data types
+ Schema | Name |                                         Description                                         
+--------+------+---------------------------------------------------------------------------------------------
+ public | cube | multi-dimensional cube '(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)'
+(1 row)
+
+\df
+                                         List of functions
+ Schema |       Name        | Result data type |           Argument data types            |  Type  
+--------+-------------------+------------------+------------------------------------------+--------
+ public | cube              | cube             | cube, double precision                   | normal
+ public | cube              | cube             | cube, double precision, double precision | normal
+ public | cube              | cube             | double precision                         | normal
+ public | cube              | cube             | double precision, double precision       | normal
+ public | cube              | cube             | double precision[]                       | normal
+ public | cube              | cube             | double precision[], double precision[]   | normal
+ public | cube_cmp          | integer          | cube, cube                               | normal
+ public | cube_contained    | boolean          | cube, cube                               | normal
+ public | cube_contains     | boolean          | cube, cube                               | normal
+ public | cube_dim          | integer          | cube                                     | normal
+ public | cube_distance     | double precision | cube, cube                               | normal
+ public | cube_enlarge      | cube             | cube, double precision, integer          | normal
+ public | cube_eq           | boolean          | cube, cube                               | normal
+ public | cube_ge           | boolean          | cube, cube                               | normal
+ public | cube_gt           | boolean          | cube, cube                               | normal
+ public | cube_in           | cube             | cstring                                  | normal
+ public | cube_inter        | cube             | cube, cube                               | normal
+ public | cube_is_point     | boolean          | cube                                     | normal
+ public | cube_le           | boolean          | cube, cube                               | normal
+ public | cube_ll_coord     | double precision | cube, integer                            | normal
+ public | cube_lt           | boolean          | cube, cube                               | normal
+ public | cube_ne           | boolean          | cube, cube                               | normal
+ public | cube_out          | cstring          | cube                                     | normal
+ public | cube_overlap      | boolean          | cube, cube                               | normal
+ public | cube_size         | double precision | cube                                     | normal
+ public | cube_subset       | cube             | cube, integer[]                          | normal
+ public | cube_union        | cube             | cube, cube                               | normal
+ public | cube_ur_coord     | double precision | cube, integer                            | normal
+ public | g_cube_compress   | internal         | internal                                 | normal
+ public | g_cube_consistent | boolean          | internal, cube, integer, oid, internal   | normal
+ public | g_cube_decompress | internal         | internal                                 | normal
+ public | g_cube_penalty    | internal         | internal, internal, internal             | normal
+ public | g_cube_picksplit  | internal         | internal, internal                       | normal
+ public | g_cube_same       | internal         | cube, cube, internal                     | normal
+ public | g_cube_union      | cube             | internal, internal                       | normal
+(35 rows)
+
+\do
+                                    List of operators
+ Schema | Name | Left arg type | Right arg type | Result type |       Description        
+--------+------+---------------+----------------+-------------+--------------------------
+ public | &&   | cube          | cube           | boolean     | overlaps
+ public | <    | cube          | cube           | boolean     | lower than
+ public | <=   | cube          | cube           | boolean     | lower than or equal to
+ public | <>   | cube          | cube           | boolean     | different
+ public | <@   | cube          | cube           | boolean     | contained in
+ public | =    | cube          | cube           | boolean     | same as
+ public | >    | cube          | cube           | boolean     | greater than
+ public | >=   | cube          | cube           | boolean     | greater than or equal to
+ public | @    | cube          | cube           | boolean     | contains
+ public | @>   | cube          | cube           | boolean     | contains
+ public | ~    | cube          | cube           | boolean     | contained in
+(11 rows)
+
+create table foo (f1 cube, f2 int);
+drop extension cube;  -- fail, foo.f1 requires it
+ERROR:  cannot drop extension cube because other objects depend on it
+DETAIL:  table foo column f1 depends on type cube
+HINT:  Use DROP ... CASCADE to drop the dependent objects too.
+drop table foo;
+drop extension cube;
+-- list what's installed
+\dT
+     List of data types
+ Schema | Name | Description 
+--------+------+-------------
+(0 rows)
+
+\df
+                       List of functions
+ Schema | Name | Result data type | Argument data types | Type 
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\do
+                             List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description 
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+create schema c;
+create extension cube with schema c;
+-- list what's installed
+\dT public.*
+     List of data types
+ Schema | Name | Description 
+--------+------+-------------
+(0 rows)
+
+\df public.*
+                       List of functions
+ Schema | Name | Result data type | Argument data types | Type 
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\do public.*
+                             List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description 
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+\dT c.*
+                                              List of data types
+ Schema |  Name  |                                         Description                                         
+--------+--------+---------------------------------------------------------------------------------------------
+ c      | c.cube | multi-dimensional cube '(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)'
+(1 row)
+
+\df c.*
+                                          List of functions
+ Schema |       Name        | Result data type |            Argument data types             |  Type  
+--------+-------------------+------------------+--------------------------------------------+--------
+ c      | cube              | c.cube           | c.cube, double precision                   | normal
+ c      | cube              | c.cube           | c.cube, double precision, double precision | normal
+ c      | cube              | c.cube           | double precision                           | normal
+ c      | cube              | c.cube           | double precision, double precision         | normal
+ c      | cube              | c.cube           | double precision[]                         | normal
+ c      | cube              | c.cube           | double precision[], double precision[]     | normal
+ c      | cube_cmp          | integer          | c.cube, c.cube                             | normal
+ c      | cube_contained    | boolean          | c.cube, c.cube                             | normal
+ c      | cube_contains     | boolean          | c.cube, c.cube                             | normal
+ c      | cube_dim          | integer          | c.cube                                     | normal
+ c      | cube_distance     | double precision | c.cube, c.cube                             | normal
+ c      | cube_enlarge      | c.cube           | c.cube, double precision, integer          | normal
+ c      | cube_eq           | boolean          | c.cube, c.cube                             | normal
+ c      | cube_ge           | boolean          | c.cube, c.cube                             | normal
+ c      | cube_gt           | boolean          | c.cube, c.cube                             | normal
+ c      | cube_in           | c.cube           | cstring                                    | normal
+ c      | cube_inter        | c.cube           | c.cube, c.cube                             | normal
+ c      | cube_is_point     | boolean          | c.cube                                     | normal
+ c      | cube_le           | boolean          | c.cube, c.cube                             | normal
+ c      | cube_ll_coord     | double precision | c.cube, integer                            | normal
+ c      | cube_lt           | boolean          | c.cube, c.cube                             | normal
+ c      | cube_ne           | boolean          | c.cube, c.cube                             | normal
+ c      | cube_out          | cstring          | c.cube                                     | normal
+ c      | cube_overlap      | boolean          | c.cube, c.cube                             | normal
+ c      | cube_size         | double precision | c.cube                                     | normal
+ c      | cube_subset       | c.cube           | c.cube, integer[]                          | normal
+ c      | cube_union        | c.cube           | c.cube, c.cube                             | normal
+ c      | cube_ur_coord     | double precision | c.cube, integer                            | normal
+ c      | g_cube_compress   | internal         | internal                                   | normal
+ c      | g_cube_consistent | boolean          | internal, c.cube, integer, oid, internal   | normal
+ c      | g_cube_decompress | internal         | internal                                   | normal
+ c      | g_cube_penalty    | internal         | internal, internal, internal               | normal
+ c      | g_cube_picksplit  | internal         | internal, internal                         | normal
+ c      | g_cube_same       | internal         | c.cube, c.cube, internal                   | normal
+ c      | g_cube_union      | c.cube           | internal, internal                         | normal
+(35 rows)
+
+\do c.*
+                                    List of operators
+ Schema | Name | Left arg type | Right arg type | Result type |       Description        
+--------+------+---------------+----------------+-------------+--------------------------
+ c      | &&   | c.cube        | c.cube         | boolean     | overlaps
+ c      | <    | c.cube        | c.cube         | boolean     | lower than
+ c      | <=   | c.cube        | c.cube         | boolean     | lower than or equal to
+ c      | <>   | c.cube        | c.cube         | boolean     | different
+ c      | <@   | c.cube        | c.cube         | boolean     | contained in
+ c      | =    | c.cube        | c.cube         | boolean     | same as
+ c      | >    | c.cube        | c.cube         | boolean     | greater than
+ c      | >=   | c.cube        | c.cube         | boolean     | greater than or equal to
+ c      | @    | c.cube        | c.cube         | boolean     | contains
+ c      | @>   | c.cube        | c.cube         | boolean     | contains
+ c      | ~    | c.cube        | c.cube         | boolean     | contained in
+(11 rows)
+
+create table foo (f1 c.cube, f2 int);
+drop extension cube;  -- fail, foo.f1 requires it
+ERROR:  cannot drop extension cube because other objects depend on it
+DETAIL:  table foo column f1 depends on type c.cube
+HINT:  Use DROP ... CASCADE to drop the dependent objects too.
+drop schema c;  -- fail, cube requires it
+ERROR:  cannot drop schema c because other objects depend on it
+DETAIL:  extension cube depends on schema c
+table foo column f1 depends on type c.cube
+HINT:  Use DROP ... CASCADE to drop the dependent objects too.
+drop extension cube cascade;
+NOTICE:  drop cascades to table foo column f1
+\d foo
+      Table "public.foo"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ f2     | integer | 
+
+-- list what's installed
+\dT public.*
+     List of data types
+ Schema | Name | Description 
+--------+------+-------------
+(0 rows)
+
+\df public.*
+                       List of functions
+ Schema | Name | Result data type | Argument data types | Type 
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\do public.*
+                             List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description 
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+\dT c.*
+     List of data types
+ Schema | Name | Description 
+--------+------+-------------
+(0 rows)
+
+\df c.*
+                       List of functions
+ Schema | Name | Result data type | Argument data types | Type 
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\do c.*
+                             List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description 
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+drop schema c;
diff --git a/contrib/earthdistance/sql/earthdistance.sql b/contrib/earthdistance/sql/earthdistance.sql
index e494c350ce9d67d5937c2a766c2e06de46ccb0c5..23746f6fe915164806bd3015f2def6eab32d3c35 100644
--- a/contrib/earthdistance/sql/earthdistance.sql
+++ b/contrib/earthdistance/sql/earthdistance.sql
@@ -1,7 +1,14 @@
 --
---  Test earth distance functions
+--  Test earthdistance extension
+--
+-- In this file we also do some testing of extension create/drop scenarios.
+-- That's really exercising the core database's dependency logic, so ideally
+-- we'd do it in the core regression tests, but we can't for lack of suitable
+-- guaranteed-available extensions.  earthdistance is a good test case because
+-- it has a dependency on the cube extension.
 --
 
+CREATE EXTENSION earthdistance;  -- fail, must install cube first
 CREATE EXTENSION cube;
 CREATE EXTENSION earthdistance;
 
@@ -291,3 +298,68 @@ SELECT is_point(ll_to_earth(-30,-90));
 SELECT cube_dim(ll_to_earth(-30,-90)) <= 3;
 SELECT abs(cube_distance(ll_to_earth(-30,-90), '(0)'::cube) / earth() - 1) <
        '10e-12'::float8;
+
+--
+-- Now we are going to test extension create/drop scenarios.
+--
+
+-- list what's installed
+\dT
+\df
+\do
+
+drop extension cube;  -- fail, earthdistance requires it
+
+drop extension earthdistance;
+
+drop type cube;  -- fail, extension cube requires it
+
+-- list what's installed
+\dT
+\df
+\do
+
+create table foo (f1 cube, f2 int);
+
+drop extension cube;  -- fail, foo.f1 requires it
+
+drop table foo;
+
+drop extension cube;
+
+-- list what's installed
+\dT
+\df
+\do
+
+create schema c;
+
+create extension cube with schema c;
+
+-- list what's installed
+\dT public.*
+\df public.*
+\do public.*
+\dT c.*
+\df c.*
+\do c.*
+
+create table foo (f1 c.cube, f2 int);
+
+drop extension cube;  -- fail, foo.f1 requires it
+
+drop schema c;  -- fail, cube requires it
+
+drop extension cube cascade;
+
+\d foo
+
+-- list what's installed
+\dT public.*
+\df public.*
+\do public.*
+\dT c.*
+\df c.*
+\do c.*
+
+drop schema c;
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c459c1e221383b47a6d4b21178b6b4d9e9b5f471..0526555ac3baeefc672135e8e5332cb90d5ddb28 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -98,6 +98,7 @@ typedef struct
 #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 */
@@ -190,6 +191,9 @@ static void add_exact_object_address_extra(const ObjectAddress *object,
 static bool object_address_present_add_flags(const ObjectAddress *object,
 								 int flags,
 								 ObjectAddresses *addrs);
+static bool stack_address_present_add_flags(const ObjectAddress *object,
+								int flags,
+								ObjectAddressStack *stack);
 static void getRelationDescription(StringInfo buffer, Oid relid);
 static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
 
@@ -459,7 +463,6 @@ findDependentObjects(const ObjectAddress *object,
 	ObjectAddress otherObject;
 	ObjectAddressStack mystack;
 	ObjectAddressExtra extra;
-	ObjectAddressStack *stackptr;
 
 	/*
 	 * If the target object is already being visited in an outer recursion
@@ -477,27 +480,8 @@ findDependentObjects(const ObjectAddress *object,
 	 * auto dependency, too, if we had to.	However there are no known cases
 	 * where that would be necessary.
 	 */
-	for (stackptr = stack; stackptr; stackptr = stackptr->next)
-	{
-		if (object->classId == stackptr->object->classId &&
-			object->objectId == stackptr->object->objectId)
-		{
-			if (object->objectSubId == stackptr->object->objectSubId)
-			{
-				stackptr->flags |= flags;
-				return;
-			}
-
-			/*
-			 * Could visit column with whole table already on stack; this is
-			 * the same case noted in object_address_present_add_flags().
-			 * (It's not clear this can really happen, but we might as well
-			 * check.)
-			 */
-			if (stackptr->object->objectSubId == 0)
-				return;
-		}
-	}
+	if (stack_address_present_add_flags(object, flags, stack))
+		return;
 
 	/*
 	 * It's also possible that the target object has already been completely
@@ -513,12 +497,13 @@ findDependentObjects(const ObjectAddress *object,
 
 	/*
 	 * 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.
+	 * (its "owner"), and/or be a member of an extension (also 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,
@@ -567,7 +552,7 @@ findDependentObjects(const ObjectAddress *object,
 				 * 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 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.
 				 */
@@ -595,31 +580,31 @@ findDependentObjects(const ObjectAddress *object,
 
 				/*
 				 * 2. When recursing from the other end of this dependency,
-				 * it's okay to continue with the deletion. This holds when
+				 * it's okay to continue with the deletion.  This holds when
 				 * recursing from a whole object that includes the nominal
-				 * other end as a component, too.
+				 * other end as a component, too.  Since there can be more
+				 * than one "owning" object, we have to allow matches that
+				 * are more than one level down in the stack.
 				 */
-				if (stack->object->classId == otherObject.classId &&
-					stack->object->objectId == otherObject.objectId &&
-					(stack->object->objectSubId == otherObject.objectSubId ||
-					 stack->object->objectSubId == 0))
+				if (stack_address_present_add_flags(&otherObject, 0, stack))
 					break;
 
 				/*
-				 * 3. When recursing from anyplace else, transform this
-				 * deletion request into a delete of the other object.
+				 * 3. Not all the owning objects have been visited, so
+				 * transform this deletion request into a delete of this
+				 * owning object.
 				 *
 				 * First, release caller's lock on this object and get
-				 * deletion lock on the other object.  (We must release
+				 * deletion lock on the owning object.  (We must release
 				 * caller's lock to avoid deadlock against a concurrent
-				 * deletion of the other object.)
+				 * deletion of the owning 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
+				 * 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).
 				 */
@@ -631,13 +616,18 @@ findDependentObjects(const ObjectAddress *object,
 				}
 
 				/*
-				 * 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.
+				 * 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,
-									 flags,
+									 DEPFLAG_REVERSE,
 									 stack,
 									 targetObjects,
 									 pendingObjects,
@@ -2016,6 +2006,43 @@ object_address_present_add_flags(const ObjectAddress *object,
 	return false;
 }
 
+/*
+ * Similar to above, except we search an ObjectAddressStack.
+ */
+static bool
+stack_address_present_add_flags(const ObjectAddress *object,
+								int flags,
+								ObjectAddressStack *stack)
+{
+	ObjectAddressStack *stackptr;
+
+	for (stackptr = stack; stackptr; stackptr = stackptr->next)
+	{
+		const ObjectAddress *thisobj = stackptr->object;
+
+		if (object->classId == thisobj->classId &&
+			object->objectId == thisobj->objectId)
+		{
+			if (object->objectSubId == thisobj->objectSubId)
+			{
+				stackptr->flags |= flags;
+				return true;
+			}
+
+			/*
+			 * Could visit column with whole table already on stack; this is
+			 * the same case noted in object_address_present_add_flags(), and
+			 * as in that case, we don't propagate flags for the component to
+			 * the whole object.
+			 */
+			if (thisobj->objectSubId == 0)
+				return true;
+		}
+	}
+
+	return false;
+}
+
 /*
  * Record multiple dependencies from an ObjectAddresses array, after first
  * removing any duplicates.