| From: | shihao zhong <zhong950419(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | jian he <jian(dot)universality(at)gmail(dot)com>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Nikolay Samokhvalov <nik(at)postgres(dot)ai>, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> |
| Subject: | [PG19] Three bugs with a CHECK constraint that only the child enforces |
| Date: | 2026-10-09 04:42:29 |
| Message-ID: | CAGRkXqSGE=fQrjCoNQsyiCZRKfQ4SrB015CAR=3pXYB5tB=ieg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi hackers,
I used Opus to analyze the new features in PG19, and it found three
bugs with a CHECK constraint that a child enforces and its parent
does not. Each item has a script and a patch with its number.
"Before" is 19 and master today. "After" is with the patch, and is
the output I expect.
1. ALTER CONSTRAINT ... ENFORCED on the parent does not check a child
whose constraint is ENFORCED but NOT VALID. The parent is marked
validated anyway, so a query on it can miss the child's bad row.
create table p (a int, constraint c check (a > 0) not enforced);
create table k (a int);
insert into k values (-1);
alter table k add constraint c check (a > 0) not valid;
alter table k inherit p;
alter table p alter constraint c enforced;
select count(*) from (select a from p union all select 1) s
where a < 0;
Before:
ALTER TABLE
count
-------
0
After 0001:
ERROR: check constraint "c" of relation "k" is violated by some row
count
-------
1
2. ALTER COLUMN TYPE on the parent turns the child's constraint back
to NOT ENFORCED. The child's constraint is dropped and recreated from
the parent's definition.
create table p2 (a int, constraint c check (a > 0) not enforced);
create table k2 () inherits (p2);
alter table k2 alter constraint c enforced;
alter table p2 alter column a type bigint;
insert into k2 values (-1);
Before:
INSERT 0 1
After 0002:
ERROR: new row for relation "k2" violates check constraint "c"
DETAIL: Failing row contains (-1).
3. pg_dump prints only the parent's definition, so the child is NOT
ENFORCED after a restore. pg_upgrade is fine.
create table p3 (a int, constraint c check (a > 0) not enforced);
create table k3 () inherits (p3);
alter table k3 alter constraint c enforced;
Before, pg_dump -s has:
ALTER TABLE public.p3
ADD CONSTRAINT c CHECK ((a > 0)) NOT ENFORCED;
After 0003, it also has:
ALTER TABLE public.k3 ALTER CONSTRAINT c ENFORCED;
1 is new in 19. 2 and 3 are easy to hit in 19, but they are also in
18, see v18-forms.sh. 0002 and 0003 use the new ALTER CONSTRAINT, so
they do not apply to 18 as they are. I think these belong on the open
items list.
Nikolay has a patch for a nearby case in [1], ADD CONSTRAINT on a
child. These three are separate. 0001 touches the same function, so
one of the two will need a rebase.
[1]
https://postgr.es/m/CAM527d8qCH4q1xV-TftDmm3eBcBie9AxfdTtThPUoGWnYT08gw@mail.gmail.com
Thanks,
Shihao
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Sho Ito | 2026-10-09 04:48:20 | Re: [PATCH v1] Reject zero resource kinds in test_resowner_many() |
| Previous Message | Paul A Jungwirth | 2026-10-09 04:30:24 | Fix WITHOUT OVERLAPS PKs used for functional grouping |