From 79cabe7ecad47729b677cf9b5555f6259c6a7bd2 Mon Sep 17 00:00:00 2001 From: Colm Date: Wed, 3 Dec 2025 08:01:01 +0000 Subject: [PATCH] PG18: CHECK constraints can be ENFORCED / NOT ENFORCED. (#8349) DESCRIPTION: Adds propagation of ENFORCED / NOT ENFORCED on CHECK constraints. Add propagation support to Citus ruleutils and appropriate regress tests. Relevant PG commit: ca87c41. --- .../distributed/deparser/citus_ruleutils.c | 7 +++ src/test/regress/expected/pg18.out | 61 +++++++++++++++++++ src/test/regress/sql/pg18.sql | 36 +++++++++++ 3 files changed, 104 insertions(+) diff --git a/src/backend/distributed/deparser/citus_ruleutils.c b/src/backend/distributed/deparser/citus_ruleutils.c index ebdb78cc9..77d7ac535 100644 --- a/src/backend/distributed/deparser/citus_ruleutils.c +++ b/src/backend/distributed/deparser/citus_ruleutils.c @@ -547,6 +547,13 @@ pg_get_tableschemadef_string(Oid tableRelationId, IncludeSequenceDefaults appendStringInfoString(&buffer, "("); appendStringInfoString(&buffer, checkString); appendStringInfoString(&buffer, ")"); + +#if PG_VERSION_NUM >= PG_VERSION_18 + if (!checkConstraint->ccenforced) + { + appendStringInfoString(&buffer, " NOT ENFORCED"); + } +#endif } /* close create table's outer parentheses */ diff --git a/src/test/regress/expected/pg18.out b/src/test/regress/expected/pg18.out index b248afff7..a043eeaca 100644 --- a/src/test/regress/expected/pg18.out +++ b/src/test/regress/expected/pg18.out @@ -1352,6 +1352,67 @@ SELECT * FROM contacts ORDER BY contact_id; ALTER TABLE contacts ALTER CONSTRAINT fk_customer ENFORCED; ERROR: alter table command is currently unsupported DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ENABLE|DISABLE|NO FORCE|FORCE ROW LEVEL SECURITY, ATTACH|DETACH PARTITION and TYPE subcommands are supported. +-- PG18 Feature: ENFORCED / NOT ENFORCED check constraints +-- PG18 commit: https://github.com/postgres/postgres/commit/ca87c415e +-- In Citus, CHECK constraints are propagated on promoting a postgres table +-- to a citus table, on adding a new CHECK constraint to a citus table, and +-- on adding a node to a citus cluster. Postgres does not support altering a +-- check constraint's enforcement status, so Citus does not either. +CREATE TABLE NE_CHECK_TBL (x int, y int, + CONSTRAINT CHECK_X CHECK (x > 3) NOT ENFORCED, + CONSTRAINT CHECK_Y CHECK (y < 20) ENFORCED +); +SELECT create_distributed_table('ne_check_tbl', 'x'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- CHECK_X is NOT ENFORCED, so these inserts should succeed +INSERT INTO NE_CHECK_TBL (x) VALUES (5), (4), (3), (2), (6), (1); +SELECT x FROM NE_CHECK_TBL ORDER BY x; + x +--------------------------------------------------------------------- + 1 + 2 + 3 + 4 + 5 + 6 +(6 rows) + +-- CHECK_Y is ENFORCED, so this insert should fail +INSERT INTO NE_CHECK_TBL (x, y) VALUES (1, 15), (2, 25), (3, 10), (4, 30); +ERROR: new row for relation "ne_check_tbl_4754045" violates check constraint "check_y" +DETAIL: Failing row contains (4, 30). +CONTEXT: while executing command on localhost:xxxxx +-- Test adding new constraints with enforcement status +ALTER TABLE NE_CHECK_TBL + ADD CONSTRAINT CHECK_Y2 CHECK (y > 10) NOT ENFORCED; +-- CHECK_Y2 is NOT ENFORCED, so these inserts should succeed +INSERT INTO NE_CHECK_TBL (x, y) VALUES (1, 8), (2, 9), (3, 10), (4, 11); +SELECT x, y FROM NE_CHECK_TBL ORDER BY x, y; + x | y +--------------------------------------------------------------------- + 1 | 8 + 1 | + 2 | 9 + 2 | + 3 | 10 + 3 | + 4 | 11 + 4 | + 5 | + 6 | +(10 rows) + +ALTER TABLE NE_CHECK_TBL + ADD CONSTRAINT CHECK_X2 CHECK (x < 10) ENFORCED; +-- CHECK_X2 is ENFORCED, so these inserts should fail +INSERT INTO NE_CHECK_TBL (x) VALUES (5), (15), (8), (12); +ERROR: new row for relation "ne_check_tbl_4754044" violates check constraint "check_x2_4754044" +DETAIL: Failing row contains (15, null). +CONTEXT: while executing command on localhost:xxxxx -- cleanup with minimum verbosity SET client_min_messages TO ERROR; RESET search_path; diff --git a/src/test/regress/sql/pg18.sql b/src/test/regress/sql/pg18.sql index 7750c27b4..3b75cecf0 100644 --- a/src/test/regress/sql/pg18.sql +++ b/src/test/regress/sql/pg18.sql @@ -854,6 +854,42 @@ SELECT * FROM contacts ORDER BY contact_id; -- so the following command should fail ALTER TABLE contacts ALTER CONSTRAINT fk_customer ENFORCED; +-- PG18 Feature: ENFORCED / NOT ENFORCED check constraints +-- PG18 commit: https://github.com/postgres/postgres/commit/ca87c415e + +-- In Citus, CHECK constraints are propagated on promoting a postgres table +-- to a citus table, on adding a new CHECK constraint to a citus table, and +-- on adding a node to a citus cluster. Postgres does not support altering a +-- check constraint's enforcement status, so Citus does not either. + +CREATE TABLE NE_CHECK_TBL (x int, y int, + CONSTRAINT CHECK_X CHECK (x > 3) NOT ENFORCED, + CONSTRAINT CHECK_Y CHECK (y < 20) ENFORCED +); + +SELECT create_distributed_table('ne_check_tbl', 'x'); + +-- CHECK_X is NOT ENFORCED, so these inserts should succeed +INSERT INTO NE_CHECK_TBL (x) VALUES (5), (4), (3), (2), (6), (1); +SELECT x FROM NE_CHECK_TBL ORDER BY x; + +-- CHECK_Y is ENFORCED, so this insert should fail +INSERT INTO NE_CHECK_TBL (x, y) VALUES (1, 15), (2, 25), (3, 10), (4, 30); + +-- Test adding new constraints with enforcement status +ALTER TABLE NE_CHECK_TBL + ADD CONSTRAINT CHECK_Y2 CHECK (y > 10) NOT ENFORCED; + +-- CHECK_Y2 is NOT ENFORCED, so these inserts should succeed +INSERT INTO NE_CHECK_TBL (x, y) VALUES (1, 8), (2, 9), (3, 10), (4, 11); +SELECT x, y FROM NE_CHECK_TBL ORDER BY x, y; + +ALTER TABLE NE_CHECK_TBL + ADD CONSTRAINT CHECK_X2 CHECK (x < 10) ENFORCED; + +-- CHECK_X2 is ENFORCED, so these inserts should fail +INSERT INTO NE_CHECK_TBL (x) VALUES (5), (15), (8), (12); + -- cleanup with minimum verbosity SET client_min_messages TO ERROR; RESET search_path;