@@ -355,12 +355,7 @@ performMultipleDeletions(const ObjectAddresses *objects,
355
355
/* And clean up */
356
356
free_object_addresses (targetObjects );
357
357
358
- /*
359
- * We closed depRel earlier in deleteOneObject if doing a drop
360
- * concurrently
361
- */
362
- if ((flags & PERFORM_DELETION_CONCURRENTLY ) != PERFORM_DELETION_CONCURRENTLY )
363
- heap_close (depRel , RowExclusiveLock );
358
+ heap_close (depRel , RowExclusiveLock );
364
359
}
365
360
366
361
/*
@@ -1000,6 +995,7 @@ deleteOneObject(const ObjectAddress *object, Relation depRel, int flags)
1000
995
int nkeys ;
1001
996
SysScanDesc scan ;
1002
997
HeapTuple tup ;
998
+ Oid depRelOid = depRel -> rd_id ;
1003
999
1004
1000
/* DROP hook of the objects being removed */
1005
1001
if (object_access_hook )
@@ -1012,7 +1008,33 @@ deleteOneObject(const ObjectAddress *object, Relation depRel, int flags)
1012
1008
}
1013
1009
1014
1010
/*
1015
- * First remove any pg_depend records that link from this object to
1011
+ * Close depRel if we are doing a drop concurrently. The individual
1012
+ * deletion has to commit the transaction and we don't want dangling
1013
+ * references.
1014
+ */
1015
+ if (flags & PERFORM_DELETION_CONCURRENTLY )
1016
+ heap_close (depRel , RowExclusiveLock );
1017
+
1018
+ /*
1019
+ * Delete the object itself, in an object-type-dependent way.
1020
+ *
1021
+ * Do this before removing outgoing dependencies as deletions can be
1022
+ * happening in concurrent mode. That will only happen for a single object
1023
+ * at once and if so the object will be invalidated inside a separate
1024
+ * transaction and only dropped inside a transaction thats in-progress when
1025
+ * doDeletion returns. This way no observer can see dangling dependency
1026
+ * entries.
1027
+ */
1028
+ doDeletion (object , flags );
1029
+
1030
+ /*
1031
+ * Reopen depRel if we closed it before
1032
+ */
1033
+ if (flags & PERFORM_DELETION_CONCURRENTLY )
1034
+ depRel = heap_open (depRelOid , RowExclusiveLock );
1035
+
1036
+ /*
1037
+ * Then remove any pg_depend records that link from this object to
1016
1038
* others. (Any records linking to this object should be gone already.)
1017
1039
*
1018
1040
* When dropping a whole object (subId = 0), remove all pg_depend records
@@ -1054,17 +1076,6 @@ deleteOneObject(const ObjectAddress *object, Relation depRel, int flags)
1054
1076
deleteSharedDependencyRecordsFor (object -> classId , object -> objectId ,
1055
1077
object -> objectSubId );
1056
1078
1057
- /*
1058
- * Close depRel if we are doing a drop concurrently because it commits the
1059
- * transaction, so we don't want dangling references.
1060
- */
1061
- if ((flags & PERFORM_DELETION_CONCURRENTLY ) == PERFORM_DELETION_CONCURRENTLY )
1062
- heap_close (depRel , RowExclusiveLock );
1063
-
1064
- /*
1065
- * Now delete the object itself, in an object-type-dependent way.
1066
- */
1067
- doDeletion (object , flags );
1068
1079
1069
1080
/*
1070
1081
* Delete any comments or security labels associated with this object.
@@ -1247,7 +1258,7 @@ AcquireDeletionLock(const ObjectAddress *object, int flags)
1247
1258
{
1248
1259
if (object -> classId == RelationRelationId )
1249
1260
{
1250
- if (( flags & PERFORM_DELETION_CONCURRENTLY ) == PERFORM_DELETION_CONCURRENTLY )
1261
+ if (flags & PERFORM_DELETION_CONCURRENTLY )
1251
1262
LockRelationOid (object -> objectId , ShareUpdateExclusiveLock );
1252
1263
else
1253
1264
LockRelationOid (object -> objectId , AccessExclusiveLock );
0 commit comments