aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/dependency.c15
-rw-r--r--src/backend/catalog/pg_shdepend.c24
-rw-r--r--src/backend/commands/subscriptioncmds.c1
-rw-r--r--src/include/catalog/dependency.h4
4 files changed, 36 insertions, 8 deletions
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index d07bb4496e3..038469c9a3a 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -199,8 +199,6 @@ static void reportDependentObjects(const ObjectAddresses *targetObjects,
static void deleteOneObject(const ObjectAddress *object,
Relation *depRel, int32 flags);
static void doDeletion(const ObjectAddress *object, int flags);
-static void AcquireDeletionLock(const ObjectAddress *object, int flags);
-static void ReleaseDeletionLock(const ObjectAddress *object);
static bool find_expr_references_walker(Node *node,
find_expr_references_context *context);
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs);
@@ -1526,11 +1524,14 @@ doDeletion(const ObjectAddress *object, int flags)
/*
* AcquireDeletionLock - acquire a suitable lock for deleting an object
*
+ * Accepts the same flags as performDeletion (though currently only
+ * PERFORM_DELETION_CONCURRENTLY does anything).
+ *
* We use LockRelation for relations, LockDatabaseObject for everything
- * else. Note that dependency.c is not concerned with deleting any kind of
- * shared-across-databases object, so we have no need for LockSharedObject.
+ * else. Shared-across-databases objects are not currently supported
+ * because no caller cares, but could be modified to use LockSharedObject.
*/
-static void
+void
AcquireDeletionLock(const ObjectAddress *object, int flags)
{
if (object->classId == RelationRelationId)
@@ -1556,8 +1557,10 @@ AcquireDeletionLock(const ObjectAddress *object, int flags)
/*
* ReleaseDeletionLock - release an object deletion lock
+ *
+ * Companion to AcquireDeletionLock.
*/
-static void
+void
ReleaseDeletionLock(const ObjectAddress *object)
{
if (object->classId == RelationRelationId)
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index fb7f8ddefc9..e6fef9782df 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -1325,7 +1325,10 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
sdepForm->objid);
break;
case SHARED_DEPENDENCY_POLICY:
- /* If unable to remove role from policy, remove policy. */
+ /*
+ * Try to remove role from policy; if unable to, remove
+ * policy.
+ */
if (!RemoveRoleFromObjectPolicy(roleid,
sdepForm->classid,
sdepForm->objid))
@@ -1333,6 +1336,18 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
obj.classId = sdepForm->classid;
obj.objectId = sdepForm->objid;
obj.objectSubId = sdepForm->objsubid;
+ /*
+ * Acquire lock on object, then verify this dependency
+ * is still relevant. If not, the object might have
+ * been dropped or the policy modified. Ignore the
+ * object in that case.
+ */
+ AcquireDeletionLock(&obj, 0);
+ if (!systable_recheck_tuple(scan, tuple))
+ {
+ ReleaseDeletionLock(&obj);
+ break;
+ }
add_exact_object_address(&obj, deleteobjs);
}
break;
@@ -1343,6 +1358,13 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
obj.classId = sdepForm->classid;
obj.objectId = sdepForm->objid;
obj.objectSubId = sdepForm->objsubid;
+ /* as above */
+ AcquireDeletionLock(&obj, 0);
+ if (!systable_recheck_tuple(scan, tuple))
+ {
+ ReleaseDeletionLock(&obj);
+ break;
+ }
add_exact_object_address(&obj, deleteobjs);
}
break;
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 2e67a5889e5..aa88092f3a4 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -928,7 +928,6 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
if (slotname)
PreventInTransactionBlock(isTopLevel, "DROP SUBSCRIPTION");
-
ObjectAddressSet(myself, SubscriptionRelationId, subid);
EventTriggerSQLDropAddObject(&myself, true, true);
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 9a11acfadea..7b1796ed094 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -142,6 +142,10 @@ typedef enum ObjectClass
/* in dependency.c */
+extern void AcquireDeletionLock(const ObjectAddress *object, int flags);
+
+extern void ReleaseDeletionLock(const ObjectAddress *object);
+
extern void performDeletion(const ObjectAddress *object,
DropBehavior behavior, int flags);