diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 1b0f010702b72e662c2292b361db792b436a1a40..3914f46af7645b158a595e8b209d076b9808c596 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -212,7 +212,7 @@ static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
  * not the direct result of a user-initiated action.  For example, when a
  * temporary schema is cleaned out so that a new backend can use it, or when
  * a column default is dropped as an intermediate step while adding a new one,
- * that's an internal operation.  On the other hand, when the we drop something
+ * that's an internal operation.  On the other hand, when we drop something
  * because the user issued a DROP statement against it, that's not internal.
  */
 void
@@ -2083,6 +2083,7 @@ object_address_present_add_flags(const ObjectAddress *object,
 								 int flags,
 								 ObjectAddresses *addrs)
 {
+	bool		result = false;
 	int			i;
 
 	for (i = addrs->numrefs - 1; i >= 0; i--)
@@ -2097,22 +2098,48 @@ object_address_present_add_flags(const ObjectAddress *object,
 				ObjectAddressExtra *thisextra = addrs->extras + i;
 
 				thisextra->flags |= flags;
-				return true;
+				result = true;
 			}
-			if (thisobj->objectSubId == 0)
+			else if (thisobj->objectSubId == 0)
 			{
 				/*
 				 * We get here if we find a need to delete a column after
 				 * having already decided to drop its whole table.  Obviously
-				 * we no longer need to drop the column.  But don't plaster
-				 * its flags on the table.
+				 * we no longer need to drop the subobject, so report that we
+				 * found the subobject in the array.  But don't plaster its
+				 * flags on the whole object.
 				 */
-				return true;
+				result = true;
+			}
+			else if (object->objectSubId == 0)
+			{
+				/*
+				 * We get here if we find a need to delete a whole table after
+				 * having already decided to drop one of its columns.  We
+				 * can't report that the whole object is in the array, but we
+				 * should mark the subobject with the whole object's flags.
+				 *
+				 * It might seem attractive to physically delete the column's
+				 * array entry, or at least mark it as no longer needing
+				 * separate deletion.  But that could lead to, e.g., dropping
+				 * the column's datatype before we drop the table, which does
+				 * not seem like a good idea.  This is a very rare situation
+				 * in practice, so we just take the hit of doing a separate
+				 * DROP COLUMN action even though we know we're gonna delete
+				 * the table later.
+				 *
+				 * Because there could be other subobjects of this object in
+				 * the array, this case means we always have to loop through
+				 * the whole array; we cannot exit early on a match.
+				 */
+				ObjectAddressExtra *thisextra = addrs->extras + i;
+
+				thisextra->flags |= flags;
 			}
 		}
 	}
 
-	return false;
+	return result;
 }
 
 /*
@@ -2123,6 +2150,7 @@ stack_address_present_add_flags(const ObjectAddress *object,
 								int flags,
 								ObjectAddressStack *stack)
 {
+	bool		result = false;
 	ObjectAddressStack *stackptr;
 
 	for (stackptr = stack; stackptr; stackptr = stackptr->next)
@@ -2135,21 +2163,31 @@ stack_address_present_add_flags(const ObjectAddress *object,
 			if (object->objectSubId == thisobj->objectSubId)
 			{
 				stackptr->flags |= flags;
-				return true;
+				result = true;
+			}
+			else if (thisobj->objectSubId == 0)
+			{
+				/*
+				 * We're visiting a column with whole table already on stack.
+				 * As in object_address_present_add_flags(), we can skip
+				 * further processing of the subobject, but we don't want to
+				 * propagate flags for the subobject to the whole object.
+				 */
+				result = true;
+			}
+			else if (object->objectSubId == 0)
+			{
+				/*
+				 * We're visiting a table with column already on stack.  As in
+				 * object_address_present_add_flags(), we should propagate
+				 * flags for the whole object to each of its subobjects.
+				 */
+				stackptr->flags |= flags;
 			}
-
-			/*
-			 * 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;
+	return result;
 }
 
 /*