Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1shCky-00EZlH-W7 for pgsql-hackers@arkaria.postgresql.org; Thu, 22 Aug 2024 18:42:01 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1shCkw-004hcx-To for pgsql-hackers@arkaria.postgresql.org; Thu, 22 Aug 2024 18:41:59 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1shCkv-004hcb-9t for pgsql-hackers@lists.postgresql.org; Thu, 22 Aug 2024 18:41:59 +0000 Received: from fhigh1-smtp.messagingengine.com ([103.168.172.152]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1shCks-000wRZ-U2 for pgsql-hackers@postgresql.org; Thu, 22 Aug 2024 18:41:56 +0000 Received: from phl-compute-06.internal (phl-compute-06.nyi.internal [10.202.2.46]) by mailfhigh.nyi.internal (Postfix) with ESMTP id 45F671151AB4; Thu, 22 Aug 2024 14:41:53 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-06.internal (MEProxy); Thu, 22 Aug 2024 14:41:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1724352113; x= 1724438513; bh=SJfo7wfgUMfRMyoqdzZmU8iFihjFbzFgcWByRVMC3Bg=; b=l b1ipyHD7i+Vssmty3vbOMt3GUgeS8jhAQ0HftxUc2JpHfKAfMQ2bNTsQFtLrGAWT 2LfYydM3RA7DmYZVbxxB9eaKdoME0FVYU+7NilnvyWctsEJYf/eziwsBp7cXXgAl B/wyjh72QTYRNfZ6bhEab6Co8+q5LlFJ8apHLd0Yq4rkxE1Femri3UJ3dSgmd+ye KDdmJErQLlXxTfxSuXhOmmz6kXakhD3C4VaEJP2gYZe9dsoLKn3HfmpyzQ6Efkjw 9lm6glfKzWPkt82oQg/92B1ICpYZNrvfYqQS9+f59vhW2TLkniwOeIVVbLBvZwfh UT4sBkUbrjeKII6zaGrJg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddruddvtddguddviecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpeffhffvvefukfggtggugfgjsehmkeerredttdej necuhfhrohhmpeetlhhvrghrohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhrvgesrghlvh hhrdhnohdqihhprdhorhhgqeenucggtffrrghtthgvrhhnpeduleekkefgtddttedtkefg uddvieffleetgeejiefhteehkeevfeettdduvdfhueenucffohhmrghinhepvghnthgvrh hprhhishgvuggsrdgtohhmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehm rghilhhfrhhomheprghlvhhhvghrrhgvsegrlhhvhhdrnhhoqdhiphdrohhrghdpnhgspg hrtghpthhtohepjedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepjhhgughrsegu rghlihgsohdrtghomhdprhgtphhtthhopegvgigtlhhushhiohhnsehgmhgrihhlrdgtoh hmpdhrtghpthhtohepthhnughrfigrnhhgsehgmhgrihhlrdgtohhmpdhrtghpthhtohep iihhjhifphhkuhesghhmrghilhdrtghomhdprhgtphhtthhopehguhhilhhlrghumhgvse hlvghlrghrghgvrdhinhhfohdprhgtphhtthhopehpghhsqhhlqdhhrggtkhgvrhhssehp ohhsthhgrhgvshhqlhdrohhrghdprhgtphhtthhopehthhhomhgrshdrsggrvghhlhgvrh dvsehssggsrdgthh X-ME-Proxy: Feedback-ID: ia2694551:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 22 Aug 2024 14:41:52 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alvh.no-ip.org; s=schmee; t=1724352110; bh=vErGdsUlQLhHLqWiFQskuyIpa40SMGM42eXyf9GrGEA=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=JbKudF9t3cMKpLq2mz/Yh85IZiwBchj+CWH4WYiI8RLAfiLSzjXoMz46+HxErT5KQ RS7Vr5br/UdIZOFfLA2dSBzxIELv+gGDJxaXMluSP95+Dym9M3WGw5qi/fntUdSlx8 5T9GaPS/ozI1JoaZp1DL7qYlJerTuDBecdDScfEcLm0lxYIc2q9xAxtdXME0oeshx2 shBOslO5e7h51SMZ3c4T+EwogVzSs/a2OIcFlDq1LAlpjXpx9xqKdr66XF3PcvmpqC 6i3cmTAt4SFdefbYDezS6R0x28Zs7WqK0uihS1vhExLKI6tKSmLI4SJeVKy+vCUFwd /VMociw6ZQKJg== Received: by schmee.alvh.no-ip.org (Postfix, from userid 1000) id 2BC77E9; Thu, 22 Aug 2024 14:41:50 -0400 (-04) Date: Thu, 22 Aug 2024 14:41:50 -0400 From: Alvaro Herrera To: Tender Wang Cc: Junwang Zhao , Jehan-Guillaume de Rorthais , "pgsql-hackers@postgresql.org" , Alexander Lakhin , Baehler Thomas SBB CFF FFS , Guillaume Lelarge Subject: Re: [BUG] Fix DETACH with FK pointing to a partitioned table fails Message-ID: <202408221841.hecaenywo5nm@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="gxt7bkvuz5n2cmsd" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --gxt7bkvuz5n2cmsd Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2024-Aug-22, Tender Wang wrote: > I apply the v14 patch on branch REL_14_STABLE. I run this thread issue and I > find below error. > [...] > ERROR: cache lookup failed for constraint 16400 > > I haven't look into details to find out where cause above error. Right, we try to drop the constraint twice. We can dodge this by collecting all constraints to drop in the loop and process them in a single performMultipleDeletions, as in the attached v14-2. TBH I think it's a bit infuriating that we lose the constraint (which was explicitly declared) because of ATTACH/DETACH. So the behavior of v15 and above is better. > By the way, I run above SQL sequences on REL_14_STABLE without your > partch. I didn't find reporting error, and running oidjoins.sql > didn't report warnings. Do I miss something? I think the action triggers are missing, so if you keep rows in the r_1 table after you've detached them, you can still delete them from the referenced table p, instead of getting the error that you should get. -- Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/ "In fact, the basic problem with Perl 5's subroutines is that they're not crufty enough, so the cruft leaks out into user-defined code instead, by the Conservation of Cruft Principle." (Larry Wall, Apocalypse 6) --gxt7bkvuz5n2cmsd Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v14-2-0001-drop-constraint-when-detaching.patch" From 43fc7215c1519e698fe1d58edd46f87da8529186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 21 Aug 2024 17:47:03 -0400 Subject: [PATCH v14-2] drop constraint when detaching --- src/backend/commands/tablecmds.c | 84 ++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c39e6799ca..3a8ffe30eb 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -18129,6 +18129,7 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent, new_repl[Natts_pg_class]; HeapTuple tuple, newtuple; + ObjectAddresses *dropobjs = NULL; if (concurrent) { @@ -18143,8 +18144,8 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent, DropClonedTriggersFromPartition(RelationGetRelid(partRel)); /* - * Detach any foreign keys that are inherited. This includes creating - * additional action triggers. + * Detach any foreign keys that are inherited -- or, if they reference + * partitioned tables, drop them. */ fks = copyObject(RelationGetFKeyList(partRel)); foreach(cell, fks) @@ -18152,7 +18153,6 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent, ForeignKeyCacheInfo *fk = lfirst(cell); HeapTuple contup; Form_pg_constraint conform; - Constraint *fkconstraint; contup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fk->conoid)); if (!HeapTupleIsValid(contup)) @@ -18167,39 +18167,71 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent, continue; } - /* unset conparentid and adjust conislocal, coninhcount, etc. */ + /* Mark the constraint as independent */ ConstraintSetParentConstraint(fk->conoid, InvalidOid, InvalidOid); /* - * Make the action triggers on the referenced relation. When this was - * a partition the action triggers pointed to the parent rel (they - * still do), but now we need separate ones of our own. + * If the constraint references a partitioned table, just drop the + * constraint, because it's more work to preserve the constraint + * correctly. + * + * If it references a plain table, then we can create the action + * triggers and it'll be okay. */ - fkconstraint = makeNode(Constraint); - fkconstraint->contype = CONSTRAINT_FOREIGN; - fkconstraint->conname = pstrdup(NameStr(conform->conname)); - fkconstraint->deferrable = conform->condeferrable; - fkconstraint->initdeferred = conform->condeferred; - fkconstraint->location = -1; - fkconstraint->pktable = NULL; - fkconstraint->fk_attrs = NIL; - fkconstraint->pk_attrs = NIL; - fkconstraint->fk_matchtype = conform->confmatchtype; - fkconstraint->fk_upd_action = conform->confupdtype; - fkconstraint->fk_del_action = conform->confdeltype; - fkconstraint->old_conpfeqop = NIL; - fkconstraint->old_pktable_oid = InvalidOid; - fkconstraint->skip_validation = false; - fkconstraint->initially_valid = true; + if (get_rel_relkind(fk->confrelid) == RELKIND_PARTITIONED_TABLE) + { + ObjectAddress constraddr; - createForeignKeyActionTriggers(partRel, conform->confrelid, - fkconstraint, fk->conoid, - conform->conindid); + /* make the dependency deletions above visible */ + CommandCounterIncrement(); + + /* + * Remember the constraint and its triggers for later deletion. + */ + if (dropobjs == NULL) + dropobjs = new_object_addresses(); + ObjectAddressSet(constraddr, ConstraintRelationId, fk->conoid); + add_exact_object_address(&constraddr, dropobjs); + } + else + { + Constraint *fkconstraint; + + /* + * Make the action triggers on the referenced relation. When this + * was a partition the action triggers pointed to the parent rel + * (they still do), but now we need separate ones of our own. + */ + fkconstraint = makeNode(Constraint); + fkconstraint->contype = CONSTRAINT_FOREIGN; + fkconstraint->conname = pstrdup(NameStr(conform->conname)); + fkconstraint->deferrable = conform->condeferrable; + fkconstraint->initdeferred = conform->condeferred; + fkconstraint->location = -1; + fkconstraint->pktable = NULL; + fkconstraint->fk_attrs = NIL; + fkconstraint->pk_attrs = NIL; + fkconstraint->fk_matchtype = conform->confmatchtype; + fkconstraint->fk_upd_action = conform->confupdtype; + fkconstraint->fk_del_action = conform->confdeltype; + fkconstraint->old_conpfeqop = NIL; + fkconstraint->old_pktable_oid = InvalidOid; + fkconstraint->skip_validation = false; + fkconstraint->initially_valid = true; + + createForeignKeyActionTriggers(partRel, conform->confrelid, + fkconstraint, fk->conoid, + conform->conindid); + } ReleaseSysCache(contup); } list_free_deep(fks); + /* If we collected any constraints for deletion, do so now. */ + if (dropobjs != NULL) + performMultipleDeletions(dropobjs, DROP_CASCADE, 0); + /* * Any sub-constraints that are in the referenced-side of a larger * constraint have to be removed. This partition is no longer part of the -- 2.39.2 --gxt7bkvuz5n2cmsd--