I wrote: > ... So I'm thinking this recursive call should > just pass DEPFLAG_NORMAL in all cases:
On further reflection, it seems more in keeping with the coding elsewhere in this module to treat this as a distinct dependency type, instead of confusing it with a NORMAL dependency. There's no actual functional difference at the moment, but more info is better than less. Hence, proposed patch attached (which also improves some of the related comments). regards, tom lane
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,
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers