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);
 /*
  * 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)
 
 /*
  * ReleaseDeletionLock - release an object deletion lock
+ *
+ * Companion to AcquireDeletionLock.
  */
-static void
+void
 ReleaseDeletionLock(const ObjectAddress *object)
 {
    if (object->classId == RelationRelationId)
 
                                            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))
                        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;
                        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;
 
 #define PERFORM_DELETION_INTERNAL          0x0001
 #define PERFORM_DELETION_CONCURRENTLY      0x0002
 
+extern void AcquireDeletionLock(const ObjectAddress *object, int flags);
+
+extern void ReleaseDeletionLock(const ObjectAddress *object);
+
 extern void performDeletion(const ObjectAddress *object,
                DropBehavior behavior, int flags);