From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Subject: [PATCH] Refuse ATTACH of a table referenced by a foreign key
Date: Wed, 7 Aug 2024 17:53:29 -0400
---
src/backend/commands/tablecmds.c | 7 +++++++
src/test/regress/expected/foreign_key.out | 17 +++++++++++++++++
src/test/regress/sql/foreign_key.sql | 17 +++++++++++++++++
3 files changed, 41 insertions(+)
inline patch 1: src/backend/commands/tablecmds.c, src/test/regress/expected/foreign_key.out, src/test/regress/sql/foreign_key.sql (+41/-0 lines) download inline-1.patchdiff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.cindex 1f94f4fdbb..05c5e2b175 100644--- a/src/backend/commands/tablecmds.c+++ b/src/backend/commands/tablecmds.c@@ -10759,6 +10759,13 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel)
{
ForeignKeyCacheInfo *fk = lfirst(cell);
+ if (fk->confrelid == RelationGetRelid(partRel))+ ereport(ERROR,+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),+ errmsg("can't attach table \"%s\" as a partition which is referenced by foreign key \"%s\"",+ RelationGetRelationName(partRel),+ get_constraint_name(fk->conoid))));+
clone = lappend_oid(clone, fk->conoid);
}
diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.outindex 46764bd9e3..fed3d99b34 100644--- a/src/test/regress/expected/foreign_key.out+++ b/src/test/regress/expected/foreign_key.out@@ -1967,6 +1967,23 @@ INSERT INTO fk_notpartitioned_pk VALUES (1600, 601), (1600, 1601);
ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2
FOR VALUES IN (1600);
-- leave these tables around intentionally
+-- Verify that attaching a table that's referenced by an existing FK+-- in the parent throws an error+CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY);+CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITION BY LIST (a);+ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1);+ERROR: can't attach table "fk_partitioned_pk_6" as a partition which is referenced by foreign key "fk_partitioned_fk_6_a_fkey"+DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6;+-- This case is similar to above, but the referenced relation is one level+-- lower in the hierarchy. This one fails in a different way as the above,+-- because we don't bother to protect against this case explicitly. If the+-- current error stops happening, we'll need to add a better protection.+CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) PARTITION BY list (a);+CREATE TABLE fk_partitioned_pk_61 PARTITION OF fk_partitioned_pk_6 FOR VALUES IN (1);+CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_61) PARTITION BY LIST (a);+ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1);+ERROR: cannot ALTER TABLE "fk_partitioned_pk_61" because it is being used by active queries in this session+DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6;
-- test the case when the referenced table is owned by a different user
create role regress_other_partitioned_fk_owner;
grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner;
diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sqlindex f5e0938999..d1aac5357f 100644--- a/src/test/regress/sql/foreign_key.sql+++ b/src/test/regress/sql/foreign_key.sql@@ -1417,6 +1417,23 @@ ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2
-- leave these tables around intentionally
+-- Verify that attaching a table that's referenced by an existing FK+-- in the parent throws an error+CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY);+CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITION BY LIST (a);+ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1);+DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6;++-- This case is similar to above, but the referenced relation is one level+-- lower in the hierarchy. This one fails in a different way as the above,+-- because we don't bother to protect against this case explicitly. If the+-- current error stops happening, we'll need to add a better protection.+CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) PARTITION BY list (a);+CREATE TABLE fk_partitioned_pk_61 PARTITION OF fk_partitioned_pk_6 FOR VALUES IN (1);+CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_61) PARTITION BY LIST (a);+ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1);+DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6;+
-- test the case when the referenced table is owned by a different user
create role regress_other_partitioned_fk_owner;
grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner;
--
2.39.2
--oookcz4qaoqowmni--
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: alvherre@alvh.no-ip.org
Subject: Re: [PATCH] Refuse ATTACH of a table referenced by a foreign key
In-Reply-To: <no-message-id-25494@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox