diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index f5e6a3f061..9315e79c99 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -1211,7 +1211,7 @@ SetDefaultACL(InternalDefaultACL *iacls) myself.objectId = HeapTupleGetOid(tuple); myself.objectSubId = 0; - performDeletion(&myself, DROP_RESTRICT); + performDeletion(&myself, DROP_RESTRICT, 0); } } else diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 0b3d489ae0..db86262b4f 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -171,7 +171,8 @@ static void reportDependentObjects(const ObjectAddresses *targetObjects, DropBehavior behavior, int msglevel, const ObjectAddress *origObject); -static void deleteOneObject(const ObjectAddress *object, Relation depRel); +static void deleteOneObject(const ObjectAddress *object, + Relation depRel, int32 flags); static void doDeletion(const ObjectAddress *object); static void AcquireDeletionLock(const ObjectAddress *object); static void ReleaseDeletionLock(const ObjectAddress *object); @@ -205,10 +206,17 @@ static void getOpFamilyDescription(StringInfo buffer, Oid opfid); * that can participate in dependencies. Note that the next two routines * are variants on the same theme; if you change anything here you'll likely * need to fix them too. + * + * flags should include PERFORM_DELETION_INTERNAL when the drop operation is + * 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 + * because the user issued a DROP statement against it, that's not internal. */ void performDeletion(const ObjectAddress *object, - DropBehavior behavior) + DropBehavior behavior, int flags) { Relation depRel; ObjectAddresses *targetObjects; @@ -254,7 +262,7 @@ performDeletion(const ObjectAddress *object, { ObjectAddress *thisobj = targetObjects->refs + i; - deleteOneObject(thisobj, depRel); + deleteOneObject(thisobj, depRel, flags); } /* And clean up */ @@ -274,7 +282,7 @@ performDeletion(const ObjectAddress *object, */ void performMultipleDeletions(const ObjectAddresses *objects, - DropBehavior behavior) + DropBehavior behavior, int flags) { Relation depRel; ObjectAddresses *targetObjects; @@ -336,7 +344,7 @@ performMultipleDeletions(const ObjectAddresses *objects, { ObjectAddress *thisobj = targetObjects->refs + i; - deleteOneObject(thisobj, depRel); + deleteOneObject(thisobj, depRel, flags); } /* And clean up */ @@ -407,7 +415,14 @@ deleteWhatDependsOn(const ObjectAddress *object, if (thisextra->flags & DEPFLAG_ORIGINAL) continue; - deleteOneObject(thisobj, depRel); + /* + * Since this function is currently only used to clean out temporary + * schemas, we pass PERFORM_DELETION_INTERNAL here, indicating that + * the operation is an automatic system operation rather than a user + * action. If, in the future, this function is used for other + * purposes, we might need to revisit this. + */ + deleteOneObject(thisobj, depRel, PERFORM_DELETION_INTERNAL); } /* And clean up */ @@ -950,7 +965,7 @@ reportDependentObjects(const ObjectAddresses *targetObjects, * depRel is the already-open pg_depend relation. */ static void -deleteOneObject(const ObjectAddress *object, Relation depRel) +deleteOneObject(const ObjectAddress *object, Relation depRel, int flags) { ScanKeyData key[3]; int nkeys; diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 204236f550..aef410ae9b 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -1528,7 +1528,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) */ void RemoveAttrDefault(Oid relid, AttrNumber attnum, - DropBehavior behavior, bool complain) + DropBehavior behavior, bool complain, bool internal) { Relation attrdef_rel; ScanKeyData scankeys[2]; @@ -1559,7 +1559,8 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, object.objectId = HeapTupleGetOid(tuple); object.objectSubId = 0; - performDeletion(&object, behavior); + performDeletion(&object, behavior, + internal ? PERFORM_DELETION_INTERNAL : 0); found = true; } diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c index c3e55ab6a7..11cb9883a7 100644 --- a/src/backend/catalog/pg_shdepend.c +++ b/src/backend/catalog/pg_shdepend.c @@ -1240,7 +1240,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior) } /* the dependency mechanism does the actual work */ - performMultipleDeletions(deleteobjs, behavior); + performMultipleDeletions(deleteobjs, behavior, 0); heap_close(sdepRel, RowExclusiveLock); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 9408f259a6..349d13034e 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -1443,7 +1443,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, * The new relation is local to our transaction and we know nothing * depends on it, so DROP_RESTRICT should be OK. */ - performDeletion(&object, DROP_RESTRICT); + performDeletion(&object, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); /* performDeletion does CommandCounterIncrement at end */ diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index 9eeba041cf..298940c7c4 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -119,7 +119,7 @@ RemoveObjects(DropStmt *stmt) } /* Here we really delete them. */ - performMultipleDeletions(objects, stmt->behavior); + performMultipleDeletions(objects, stmt->behavior, 0); free_object_addresses(objects); } diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index a9ec904c35..4135e26857 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -1286,7 +1286,7 @@ RemoveUserMapping(DropUserMappingStmt *stmt) object.objectId = umId; object.objectSubId = 0; - performDeletion(&object, DROP_CASCADE); + performDeletion(&object, DROP_CASCADE, 0); } diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 5dca0222fd..5dc131a50e 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -1519,7 +1519,7 @@ dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, object.objectId = amopid; object.objectSubId = 0; - performDeletion(&object, DROP_RESTRICT); + performDeletion(&object, DROP_RESTRICT, 0); } } @@ -1559,7 +1559,7 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, object.objectId = amprocid; object.objectSubId = 0; - performDeletion(&object, DROP_RESTRICT); + performDeletion(&object, DROP_RESTRICT, 0); } } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index cb8ac67812..9172d99931 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -816,7 +816,7 @@ RemoveRelations(DropStmt *drop) add_exact_object_address(&obj, objects); } - performMultipleDeletions(objects, drop->behavior); + performMultipleDeletions(objects, drop->behavior, 0); free_object_addresses(objects); } @@ -4803,8 +4803,13 @@ ATExecColumnDefault(Relation rel, const char *colName, * Remove any old default for the column. We use RESTRICT here for * safety, but at present we do not expect anything to depend on the * default. + * + * We treat removing the existing default as an internal operation when + * it is preparatory to adding a new default, but as a user-initiated + * operation when the user asked for a drop. */ - RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false); + RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false, + newDefault == NULL ? false : true); if (newDefault) { @@ -5217,7 +5222,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, object.objectId = RelationGetRelid(rel); object.objectSubId = attnum; - performDeletion(&object, behavior); + performDeletion(&object, behavior, 0); /* * If we dropped the OID column, must adjust pg_class.relhasoids and tell @@ -6731,7 +6736,7 @@ ATExecDropConstraint(Relation rel, const char *constrName, conobj.objectId = HeapTupleGetOid(tuple); conobj.objectSubId = 0; - performDeletion(&conobj, behavior); + performDeletion(&conobj, behavior, 0); found = true; @@ -7453,7 +7458,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, * We use RESTRICT here for safety, but at present we do not expect * anything to depend on the default. */ - RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true); + RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true, + true); StoreAttrDefault(rel, attnum, defaultexpr); } @@ -7598,7 +7604,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) obj.classId = ConstraintRelationId; obj.objectId = lfirst_oid(oid_item); obj.objectSubId = 0; - performDeletion(&obj, DROP_RESTRICT); + performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); } foreach(oid_item, tab->changedIndexOids) @@ -7606,7 +7612,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) obj.classId = RelationRelationId; obj.objectId = lfirst_oid(oid_item); obj.objectSubId = 0; - performDeletion(&obj, DROP_RESTRICT); + performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); } /* @@ -9764,7 +9770,14 @@ PreCommit_on_commit_actions(void) object.classId = RelationRelationId; object.objectId = oc->relid; object.objectSubId = 0; - performDeletion(&object, DROP_CASCADE); + + /* + * Since this is an automatic drop, rather than one + * directly initiated by the user, we pass the + * PERFORM_DELETION_INTERNAL flag. + */ + performDeletion(&object, + DROP_CASCADE, PERFORM_DELETION_INTERNAL); /* * Note that table deletion will call diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 0043bf1fee..03918486a1 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -2318,7 +2318,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, conobj.objectId = HeapTupleGetOid(contup); conobj.objectSubId = 0; - performDeletion(&conobj, behavior); + performDeletion(&conobj, behavior, 0); found = true; } } diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index e84e21c62c..49c15c3261 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2044,7 +2044,7 @@ do_autovacuum(void) object.classId = RelationRelationId; object.objectId = relid; object.objectSubId = 0; - performDeletion(&object, DROP_CASCADE); + performDeletion(&object, DROP_CASCADE, PERFORM_DELETION_INTERNAL); } else { diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index afa572b3b1..a14ce442c1 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -307,7 +307,7 @@ inv_drop(Oid lobjId) object.classId = LargeObjectRelationId; object.objectId = lobjId; object.objectSubId = 0; - performDeletion(&object, DROP_CASCADE); + performDeletion(&object, DROP_CASCADE, 0); /* * Advance command counter so that tuple removal will be seen by later diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 087341e576..28e68c5ab5 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -152,11 +152,13 @@ typedef enum ObjectClass /* in dependency.c */ +#define PERFORM_DELETION_INTERNAL 0x0001 + extern void performDeletion(const ObjectAddress *object, - DropBehavior behavior); + DropBehavior behavior, int flags); extern void performMultipleDeletions(const ObjectAddresses *objects, - DropBehavior behavior); + DropBehavior behavior, int flags); extern void deleteWhatDependsOn(const ObjectAddress *object, bool showNotices); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 46bee44b5c..2055382096 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -107,7 +107,7 @@ extern void DeleteRelationTuple(Oid relid); extern void DeleteAttributeTuples(Oid relid); extern void RemoveAttributeById(Oid relid, AttrNumber attnum); extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, - DropBehavior behavior, bool complain); + DropBehavior behavior, bool complain, bool internal); extern void RemoveAttrDefaultById(Oid attrdefId); extern void RemoveStatistics(Oid relid, AttrNumber attnum);