dependency-fix.patch
text/x-patch
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index c459c1e221383b47a6d4b21178b6b4d9e9b5f471..0e6165118556ca47b494ff2674f83016548a3fc8 100644 *** a/src/backend/catalog/dependency.c --- b/src/backend/catalog/dependency.c *************** typedef struct *** 98,103 **** --- 98,104 ---- #define DEPFLAG_AUTO 0x0004 /* reached via auto dependency */ #define DEPFLAG_INTERNAL 0x0008 /* reached via internal dependency */ #define DEPFLAG_EXTENSION 0x0010 /* reached via extension dependency */ + #define DEPFLAG_REVERSE 0x0020 /* reverse internal/extension link */ /* expansible list of ObjectAddresses */ *************** findDependentObjects(const ObjectAddress *** 513,524 **** /* * The target object might be internally dependent on some other object ! * (its "owner"). If so, and if we aren't recursing from the owning ! * object, we have to transform this deletion request into a deletion ! * request of the owning object. (We'll eventually recurse back to this ! * object, but the owning object has to be visited first so it will be ! * deleted after.) The way to find out about this is to scan the ! * pg_depend entries that show what this object depends on. */ ScanKeyInit(&key[0], Anum_pg_depend_classid, --- 514,526 ---- /* * The target object might be internally dependent on some other object ! * (its "owner"), or be a member of an extension (again considered its ! * owner). If so, and if we aren't recursing from the owning object, we ! * have to transform this deletion request into a deletion request of the ! * owning object. (We'll eventually recurse back to this object, but the ! * owning object has to be visited first so it will be deleted after.) ! * The way to find out about this is to scan the pg_depend entries that ! * show what this object depends on. */ ScanKeyInit(&key[0], Anum_pg_depend_classid, *************** findDependentObjects(const ObjectAddress *** 567,573 **** * 1. At the outermost recursion level, disallow the DROP. (We * just ereport here, rather than proceeding, since no other * dependencies are likely to be interesting.) However, if ! * the other object is listed in pendingObjects, just release * the caller's lock and return; we'll eventually complete the * DROP when we reach that entry in the pending list. */ --- 569,575 ---- * 1. At the outermost recursion level, disallow the DROP. (We * just ereport here, rather than proceeding, since no other * dependencies are likely to be interesting.) However, if ! * the owning object is listed in pendingObjects, just release * the caller's lock and return; we'll eventually complete the * DROP when we reach that entry in the pending list. */ *************** findDependentObjects(const ObjectAddress *** 607,625 **** /* * 3. When recursing from anyplace else, transform this ! * deletion request into a delete of the other object. * * First, release caller's lock on this object and get ! * deletion lock on the other object. (We must release * caller's lock to avoid deadlock against a concurrent ! * deletion of the other object.) */ ReleaseDeletionLock(object); AcquireDeletionLock(&otherObject); /* ! * The other object might have been deleted while we waited to ! * lock it; if so, neither it nor the current object are * interesting anymore. We test this by checking the * pg_depend entry (see notes below). */ --- 609,627 ---- /* * 3. When recursing from anyplace else, transform this ! * deletion request into a delete of the owning object. * * First, release caller's lock on this object and get ! * deletion lock on the owning object. (We must release * caller's lock to avoid deadlock against a concurrent ! * deletion of the owning object.) */ ReleaseDeletionLock(object); AcquireDeletionLock(&otherObject); /* ! * The owning object might have been deleted while we waited ! * to lock it; if so, neither it nor the current object are * interesting anymore. We test this by checking the * pg_depend entry (see notes below). */ *************** findDependentObjects(const ObjectAddress *** 631,643 **** } /* ! * Okay, recurse to the other object instead of proceeding. We ! * treat this exactly as if the original reference had linked ! * to that object instead of this one; hence, pass through the ! * same flags and stack. */ findDependentObjects(&otherObject, ! flags, stack, targetObjects, pendingObjects, --- 633,650 ---- } /* ! * Okay, recurse to the owning object instead of proceeding. ! * ! * We do not need to stack the current object; we want the ! * traversal order to be as if the original reference had ! * linked to the owning object instead of this one. ! * ! * The dependency type is a "reverse" dependency: we need to ! * delete the owning object if this one is to be deleted, but ! * this linkage is never a reason for an automatic deletion. */ findDependentObjects(&otherObject, ! DEPFLAG_REVERSE, stack, targetObjects, pendingObjects,