From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
---|---|
To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
Cc: | yannsalaun1(at)gmail(dot)com |
Subject: | BUG #17945: Different order of definition of a constraint causes constraint violation |
Date: | 2023-05-25 14:39:13 |
Message-ID: | 17945-e6eb09170cd63524@postgresql.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 17945
Logged by: Yann Salaün
Email address: yannsalaun1(at)gmail(dot)com
PostgreSQL version: 15.3
Operating system: Linux
Description:
This is a bug report with a reproducible case where different orders of
definition of a SQL constraint causes different behavior.
To be more specific, if the constraint is defined inside the table
definition as in
```sql
CREATE TABLE node (
id integer PRIMARY KEY,
parent_id integer REFERENCES node(id) ON DELETE CASCADE
);
```
the behavior is not the same as when the constraint is defined after all
tables are defined (like in the output of pg_dump) as in
```sql
CREATE TABLE node (
id integer PRIMARY KEY,
parent_id integer
);
-- define all other tables...
ALTER TABLE node
ADD CONSTRAINT nodes_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES
node(id) ON DELETE CASCADE;
```
The reproductible case comes from an application with tables modelling
filesystem trees. When a parent node is deleted, children are deleted in
cascade via foreign key constraints.
Here is the full psql script to reproduce the problem:
```sql
-- Schema definition
CREATE TABLE node (
id integer PRIMARY KEY,
parent_id integer
);
CREATE TABLE dir (
id integer PRIMARY KEY REFERENCES node(id) ON DELETE CASCADE
);
CREATE TABLE file (
id integer PRIMARY KEY REFERENCES node(id) ON DELETE CASCADE
);
CREATE TABLE t (
main_dir_id integer REFERENCES dir(id) ON DELETE SET NULL,
main_file_id integer REFERENCES file(id) ON DELETE SET NULL,
other_file_id integer REFERENCES file(id) ON DELETE SET NULL
);
-- Constraint definition. If we inline this constraint in the table
definition, the SQL error below disappears.
ALTER TABLE node
ADD CONSTRAINT nodes_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES
node(id) ON DELETE CASCADE;
-- Data insertion
-- main_dir
INSERT INTO node (id) VALUES (1);
INSERT INTO dir (id) VALUES (1);
-- main_file in main_dir
INSERT INTO node (id, parent_id) VALUES (2, 1);
INSERT INTO file (id) VALUES (2);
-- other_file
INSERT INTO node (id) VALUES (3);
INSERT INTO file (id) VALUES (3);
INSERT INTO t (main_dir_id, main_file_id, other_file_id) VALUES (1, 2, 3);
-- Data deletion in a transaction.
BEGIN;
-- First, delete other_file (this sets t.other_file_id to NULL via ON DELETE
SET NULL)
DELETE FROM node WHERE id = 3;
-- Then delete main_dir (this sets t.main_dir_id and t.main_file_id to NULL
via ON DELETE SET NULL)
DELETE FROM node WHERE id = 1;
-- The second DELETE statement returns the following error.
-- ERROR: 23503: insert or update on table "t" violates foreign key
constraint "t_main_file_id_fkey"
-- DETAIL: Key (main_file_id)=(2) is not present in table "file".
-- SCHEMA NAME: public
-- TABLE NAME: t
-- CONSTRAINT NAME: t_main_file_id_fkey
-- LOCATION: ri_ReportViolation, ri_triggers.c:2528
ROLLBACK;
```
I believe this psql script is sufficient to reproduce the bug. Let me know
if that's not the case, I would be happy to provide more details.
Thanks for your answer.
Yann
From | Date | Subject | |
---|---|---|---|
Next Message | PG Bug reporting form | 2023-05-25 15:21:26 | BUG #17946: LC_MONETARY & DO LANGUAGE plperl - BUG |
Previous Message | PG Bug reporting form | 2023-05-25 14:04:39 | BUG #17944: Partial index on boolean field is not picked when using = while the index is created with is |