From 6c8d9595dc1b2b62e3cc5ce3bc1c970b6eedcbc2 Mon Sep 17 00:00:00 2001 From: Jehan-Guillaume de Rorthais Date: Fri, 30 Sep 2022 23:54:04 +0200 Subject: [PATCH 2/3] Fix bug where a self-FK was cloned twice on partitions A tbale with a self-foreign keys appears on both the referenced and referencing side of the constraint. Because of this, when creating or attaching a new partition to a table, the self-FK was cloned twice, by CloneFkReferenced() and CloneFkReferencing() functions. --- src/backend/commands/tablecmds.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 7d8a75d23c..d19d917571 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -9968,6 +9968,9 @@ CloneForeignKeyConstraints(List **wqueue, Relation parentRel, * clone those constraints to the given partition. This is to be called * when the partition is being created or attached. * + * Note that this ignore self-referenced FK. Those are handled in + * CloneFkReferencing(). + * * This recurses to partitions, if the relation being attached is partitioned. * Recursion is done by calling addFkRecurseReferenced. */ @@ -10047,10 +10050,14 @@ CloneFkReferenced(Relation parentRel, Relation partitionRel) constrForm = (Form_pg_constraint) GETSTRUCT(tuple); /* - * As explained above: don't try to clone a constraint for which we're - * going to clone the parent. + * As explained above and in the function header: + * - don't try to clone a constraint for which we're going to clone + * the parent. + * - don't clone a self-referenced constraint here as it is handled + * on the CloneFkReferencing() side */ - if (list_member_oid(clone, constrForm->conparentid)) + if (list_member_oid(clone, constrForm->conparentid) || + constrForm->conrelid == RelationGetRelid(parentRel)) { ReleaseSysCache(tuple); continue; -- 2.37.3