From a87c6fb2b0169306c5c4d0008a9d4692aeaa23cd Mon Sep 17 00:00:00 2001 From: jian he Date: Sat, 5 Apr 2025 15:15:13 +0800 Subject: [PATCH v7 1/2] mark conislocal as false while merging valid constraint If the child already has a valid constraint and we are creating an invalid one with same definition on it, the child's constraint will remain valid, but can no longer be marked as local. CREATE TABLE ttchk (a int); ALTER TABLE ttchk ADD CONSTRAINT cc check (a is NOT NULL) NOT VALID; CREATE TABLE ttchk_child(a int) INHERITS(ttchk); --queryA select conrelid::regclass::text as relname, conname, convalidated, conislocal, coninhcount, connoinherit from pg_constraint where conname like '%cc%' order by 1, 2; with the patch applied, the result of queryA will remain the same before and after running pg_dump. Discussion: https://postgr.es/m/CACJufxECVsdWSC4J0wo2LF-+QoacsfX_Scv-NGzQxWjzPF1coA@mail.gmail.com --- src/backend/catalog/heap.c | 21 +++++++++++++++++---- src/test/regress/expected/inherit.out | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index b807ab66668..2b28b05b9cb 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -2826,11 +2826,24 @@ MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr, { if (is_local) con->conislocal = true; - else if (pg_add_s16_overflow(con->coninhcount, 1, + else + { + if(pg_add_s16_overflow(con->coninhcount, 1, &con->coninhcount)) - ereport(ERROR, - errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("too many inheritance parents")); + ereport(ERROR, + errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("too many inheritance parents")); + + /* + * If the child already has a valid constraint and we are + * creating an invalid one with same definition on it, then the + * child's constraint will remain valid, but can no longer + * marked as local. + */ + if (!is_initially_valid && con->convalidated && + is_enforced && con->conenforced) + con->conislocal = false; + } } if (is_no_inherit) diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out index 2a8bfba768e..e063f48d343 100644 --- a/src/test/regress/expected/inherit.out +++ b/src/test/regress/expected/inherit.out @@ -1571,7 +1571,7 @@ order by 1, 2; relname | conname | convalidated | conislocal | coninhcount | connoinherit -------------------------+----------------------+--------------+------------+-------------+-------------- invalid_check_con | inh_check_constraint | f | t | 0 | f - invalid_check_con_child | inh_check_constraint | t | t | 1 | f + invalid_check_con_child | inh_check_constraint | t | f | 1 | f (2 rows) -- We don't drop the invalid_check_con* tables, to test dump/reload with -- 2.34.1