aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2024-08-08 19:35:13 -0400
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2024-08-08 19:35:13 -0400
commit8c0944ac878d3d3e433da8feb2f7e134be8353f3 (patch)
tree2ece3788d6ab1b659fb1a108e46cc0b3863717d5 /src/backend/commands/tablecmds.c
parentb5a5027c9796e2958392f4682928d47b5b0d0e47 (diff)
downloadpostgresql-8c0944ac878d3d3e433da8feb2f7e134be8353f3.tar.gz
postgresql-8c0944ac878d3d3e433da8feb2f7e134be8353f3.zip
Refuse ATTACH of a table referenced by a foreign key
Trying to attach a table as a partition which is already on the referenced side of a foreign key on the partitioned table that it is being attached to, leads to strange behavior: we try to clone the foreign key from the parent to the partition, but this new FK points to the partition itself, and the mix of pg_constraint rows and triggers doesn't behave well. Rather than trying to untangle the mess (which might be possible given sufficient time), I opted to forbid the ATTACH. This doesn't seem a problematic restriction, given that we already fail to create the foreign key if you do it the other way around, that is, having the partition first and the FK second. Backpatch to all supported branches. Reported-by: Alexander Lakhin <exclusion@gmail.com> Reviewed-by: Tender Wang <tndrwang@gmail.com> Discussion: https://postgr.es/m/18541-628a61bc267cd2d3@postgresql.org
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 8e3e3919f75..44629fb52f4 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -10318,6 +10318,23 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel)
{
ForeignKeyCacheInfo *fk = lfirst(cell);
+ /*
+ * Refuse to attach a table as partition that this partitioned table
+ * already has a foreign key to. This isn't useful schema, which is
+ * proven by the fact that there have been no user complaints that
+ * it's already impossible to achieve this in the opposite direction,
+ * i.e., creating a foreign key that references a partition. This
+ * restriction allows us to dodge some complexities around
+ * pg_constraint and pg_trigger row creations that would be needed
+ * during ATTACH/DETACH for this kind of relationship.
+ */
+ 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);
}