pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
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.c index 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.out index 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.sql index 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--

Message-ID: <no-message-id-25494@localhost>
Permalink:  ../no-message-id-25494@localhost/
Also on:    postgresql.org/message-id/no-message-id-25494@localhost

 ·  · 

reply

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