| From: | Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | Andrew Dunstan <andrew(at)dunslane(dot)net>, jian he <jian(dot)universality(at)gmail(dot)com> |
| Subject: | Re: Fix bug of CHECK constraint enforceability recursion |
| Date: | 2026-05-26 05:48:02 |
| Message-ID: | 75584501-84F3-4F8D-A315-D5E37DEAEC10@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
> On May 26, 2026, at 11:51, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> wrote:
>
> Hi,
>
> I just tested “Add support for altering CHECK constraint enforceability” and found an issue where recursion is not handled properly.
>
> Here is a repro with inheritance tables:
> ```
> evantest=# create table p(a int constraint ck check (a > 0) enforced);
> CREATE TABLE
> evantest=# create table c() inherits (p);
> CREATE TABLE
> evantest=# alter table c alter constraint ck not enforced;
> ALTER TABLE
> evantest=# insert into c values (-1);
> INSERT 0 1
> evantest=# alter table p alter constraint ck enforced;
> ALTER TABLE
> evantest=# insert into c values (-2);
> INSERT 0 1
> evantest=# select * from p;
> a
> ----
> -1
> -2
> (2 rows)
> ```
>
> In this repro, the constraint on parent table p is already ENFORCED, but the constraint on child table c was altered to NOT ENFORCED. So when altering p to ENFORCED again, it didn't recurse to c.
>
> The same problem can happen with partitioned tables as well:
> ```
> evantest=# create table p (a int, constraint ck check (a > 0) enforced) partition by range (a);
> CREATE TABLE
> evantest=# create table p1 partition of p for values from (-100) to (100);
> CREATE TABLE
> evantest=# insert into p1 values (-1);
> ERROR: new row for relation "p1" violates check constraint "ck"
> DETAIL: Failing row contains (-1).
> evantest=# alter table p1 alter constraint ck not enforced;
> ALTER TABLE
> evantest=# insert into p1 values (-1);
> INSERT 0 1
> evantest=# alter table p alter constraint ck enforced;
> ALTER TABLE
> evantest=# insert into p1 values (-2);
> INSERT 0 1
> evantest=#
> evantest=# select * from p;
> a
> ----
> -1
> -2
> (2 rows)
> ```
>
> For the solution, I think we should always recurse to descendant tables unless the constraint is NO INHERIT, because both partitioned tables and inheritance children can currently be altered to have different enforceability. So we cannot rely on whether the parent constraint itself was changed.
>
> See the attached patch for details. I also added regress test cases for the fix.
>
> Best regards,
> --
> Chao Li (Evan)
> HighGo Software Co., Ltd.
> https://www.highgo.com/
>
>
>
>
> <v1-0001-Fix-CHECK-constraint-enforceability-recursion.patch>
Merged the doc change from [1] into this thread as they are for the same feature.
[1] https://postgr.es/m/711B1ED3-1781-4B6C-A573-B58AF20770E5@gmail.com
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
| Attachment | Content-Type | Size |
|---|---|---|
| v2-0001-Fix-CHECK-constraint-enforceability-recursion.patch | application/octet-stream | 8.4 KB |
| v2-0002-doc-Clarify-ALTER-CONSTRAINT-enforceability-behav.patch | application/octet-stream | 2.2 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | shveta malik | 2026-05-26 05:50:03 | Re: [PATCH] Release replication slot on error in SQL-callable slot functions |
| Previous Message | Chao Li | 2026-05-26 05:42:48 | Re: doc: Clarify ALTER CONSTRAINT enforceability wording |