Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gUnGB-0006fj-H8 for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Dec 2018 06:35:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gUnG9-0003v1-Vz for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Dec 2018 06:35:41 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gUnG9-0003uf-DW for pgsql-hackers@lists.postgresql.org; Thu, 06 Dec 2018 06:35:41 +0000 Received: from mail.postgrespro.ru ([93.174.131.138]) by makus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gUnG2-00023V-QJ for pgsql-hackers@postgresql.org; Thu, 06 Dec 2018 06:35:39 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id 5025221CFEDD; Thu, 6 Dec 2018 09:35:31 +0300 (MSK) X-Virus-Scanned: Debian amavisd-new at postgrespro.ru X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=x tagged_above=-99 required=4 WHITELISTED tests=[] autolearn=unavailable Received: from [192.168.0.103] (unknown [5.79.143.247]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.postgrespro.ru (Postfix) with ESMTPSA id E997C21CFEDC; Thu, 6 Dec 2018 09:35:30 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1544078131; bh=2QCdq+SDSJHeN4vDvr22Jqlx3Cq2yMNUHaZznpxxxKA=; h=Subject:To:Cc:References:From:Date:In-Reply-To; b=JgXQ5GRr+f3hDOYCOUC4zjpRh5cTIJtcWkImJ6vOXbvHV+8F/tbewcFgkimqbXqcY 3G4QlXZv5JvcXQcYSfsO3CtEYe26XkJpgxFfJh4q95Xte8SizawTyoko/ZndCucVDw GRwBbovlXR9zlTrmMU3hpfST2Lm4EAWo8Qaxs4I4= Subject: Re: Fixing findDependentObjects()'s dependency on scan order (regressions in DROP diagnostic messages) To: Peter Geoghegan , Peter Eisentraut Cc: Alvaro Herrera , PostgreSQL Hackers References: <0a89eb40-ea89-9037-aad0-3b65c67cdcbd@postgrespro.ru> From: Andrey Lepikhov Organization: Postgres Professional Message-ID: <65ced322-84d2-777a-2fac-5f482c175431@postgrespro.ru> Date: Thu, 6 Dec 2018 11:35:29 +0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------2F243136085225DBA429D7A2" Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------2F243136085225DBA429D7A2 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 14.11.2018 11:28, Peter Geoghegan wrote: > We're already relying on the scan order being in reverse chronological > order, so we might as well formalize the dependency. I don't think > that it's possible to sort the pg_depend entries as a way of fixing > the breakage while avoiding storing this extra information -- what is > there to sort on that's there already? You'd have to infer a whole > bunch of things about the object types associated with pg_depend > entries to do that, and teach dependency.c about its callers. That > seems pretty brittle to me. This solution changes pg_depend relation for solve a problem, which exists only in regression tests. Very rarely it can be in the partitioning cases. Or is it not? I think this decision is some excessive. May be you consider another approach: 1. Order of dependencies in 'DROP ... CASCADE' case is a problem of test tools, not DBMS. And here we can use 'verbose terse'. 2. Print all dependencies in findDependentObjects() on a drop error (see attachment as a prototype). -- Andrey Lepikhov Postgres Professional https://postgrespro.com The Russian Postgres Company --------------2F243136085225DBA429D7A2 Content-Type: text/x-patch; name="0001-Print-All-dependencies-on-error.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Print-All-dependencies-on-error.patch" From e6056363889a00699fcb6ef6ef8ce9bc3e007d7e Mon Sep 17 00:00:00 2001 From: "Andrey V. Lepikhov" Date: Thu, 6 Dec 2018 11:09:17 +0500 Subject: [PATCH] Print All dependencies on error --- src/backend/catalog/dependency.c | 59 ++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 7dfa3278a5..e84143af2a 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -595,7 +595,9 @@ findDependentObjects(const ObjectAddress *object, */ if (stack == NULL) { - char *otherObjDesc; + char *emsg = NULL; + int emsgbufsize = 1024; + char *depObjDesc; if (pendingObjects && object_address_present(&otherObject, pendingObjects)) @@ -605,14 +607,57 @@ findDependentObjects(const ObjectAddress *object, ReleaseDeletionLock(object); return; } - otherObjDesc = getObjectDescription(&otherObject); + + do + { + ObjectAddress depObject; + Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup); + + depObject.classId = foundDep->refclassid; + depObject.objectId = foundDep->refobjid; + depObject.objectSubId = foundDep->refobjsubid; + + if (object_address_present(&depObject, pendingObjects)) + continue; + + if ((foundDep->deptype == DEPENDENCY_EXTENSION) && + ((flags & PERFORM_DELETION_SKIP_EXTENSIONS) || + (creating_extension && + depObject.classId == ExtensionRelationId && + depObject.objectId == CurrentExtensionObject)) + ) + continue; + + if ((foundDep->deptype != DEPENDENCY_INTERNAL) && + (foundDep->deptype != DEPENDENCY_INTERNAL_AUTO) + ) + continue; + + depObjDesc = getObjectDescription(&depObject); + if (emsg == NULL) + emsg = palloc0(emsgbufsize); + else + strcat(emsg, " or "); + + if (strlen(depObjDesc) > emsgbufsize - strlen(emsg)) + { + char *tmpstr; + + emsgbufsize += strlen(depObjDesc) + 4; + tmpstr = palloc0(emsgbufsize); + memcpy(tmpstr, emsg, strlen(emsg)); + pfree(emsg); + emsg = tmpstr; + } + strcat(emsg, depObjDesc); + } while (HeapTupleIsValid(tup = systable_getnext(scan))); + ereport(ERROR, (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), - errmsg("cannot drop %s because %s requires it", - getObjectDescription(object), - otherObjDesc), - errhint("You can drop %s instead.", - otherObjDesc))); + errmsg("cannot drop %s because another object requires it", + getObjectDescription(object)), + errhint("You can try to drop one of the following: %s.", + emsg))); } /* -- 2.17.1 --------------2F243136085225DBA429D7A2--