mirror of https://github.com/citusdata/citus.git
PG17 compatibility: Fix Test Failure in multi_alter_table_add_const (#7733)
In earlier versions of PostgreSQL, exclusion constraints were not allowed on partitioned tables. This is why the error in your regression test (ERROR: exclusion constraints are not supported on partitioned tables) was raised in PostgreSQL 16. In PostgreSQL 17, exclusion constraints are now allowed on partitioned tables, which is why the error no longer appears when you attempt to add an exclusion constraint. The constraint exclusion mechanism, described in the documentation, relies on CHECK constraints to decide which partitions or child tables need to be queried. [CHECK constraints](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-CONSTRAINT-EXCLUSION) ```diff -- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =); -ERROR: exclusion constraints are not supported on partitioned tables -- Check "ADD CHECK" SET client_min_messages TO DEBUG1; ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD CHECK (dist_col > 0); DEBUG: the constraint name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglonglo_537570f5_5_check DEBUG: verifying table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc" DEBUG: verifying table "p1" RESET client_min_messages; SELECT con.conname FROM pg_catalog.pg_constraint con INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace WHERE rel.relname = 'citus_local_partitioned_table'; conname -------------------------------------------------- + citus_local_partitioned_table_partition_col_excl citus_local_partitioned_table_check -(1 row) +(2 rows) ```pull/7792/head
parent
aa8ed4c60b
commit
351b1ca63c
|
@ -1119,9 +1119,6 @@ SELECT con.conname
|
|||
|
||||
\c - - :master_host :master_port
|
||||
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;
|
||||
-- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it
|
||||
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
|
||||
ERROR: exclusion constraints are not supported on partitioned tables
|
||||
-- Check "ADD CHECK"
|
||||
SET client_min_messages TO DEBUG1;
|
||||
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD CHECK (dist_col > 0);
|
||||
|
|
|
@ -1013,6 +1013,110 @@ RESET citus.local_table_join_policy;
|
|||
RESET client_min_messages;
|
||||
DROP TABLE reference_table;
|
||||
-- End for Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470.
|
||||
-- Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment
|
||||
-- Step 1: Create a distributed partitioned table
|
||||
\c - - :master_host :master_port
|
||||
SET search_path TO pg17;
|
||||
CREATE TABLE distributed_partitioned_table (
|
||||
id serial NOT NULL,
|
||||
partition_col int NOT NULL,
|
||||
PRIMARY KEY (id, partition_col)
|
||||
) PARTITION BY RANGE (partition_col);
|
||||
-- Add partitions to the distributed partitioned table
|
||||
CREATE TABLE distributed_partitioned_table_p1 PARTITION OF distributed_partitioned_table
|
||||
FOR VALUES FROM (1) TO (100);
|
||||
CREATE TABLE distributed_partitioned_table_p2 PARTITION OF distributed_partitioned_table
|
||||
FOR VALUES FROM (100) TO (200);
|
||||
-- Distribute the table
|
||||
SELECT create_distributed_table('distributed_partitioned_table', 'id');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Step 2: Create a partitioned Citus local table
|
||||
CREATE TABLE local_partitioned_table (
|
||||
id serial NOT NULL,
|
||||
partition_col int NOT NULL,
|
||||
PRIMARY KEY (id, partition_col)
|
||||
) PARTITION BY RANGE (partition_col);
|
||||
-- Add partitions to the local partitioned table
|
||||
CREATE TABLE local_partitioned_table_p1 PARTITION OF local_partitioned_table
|
||||
FOR VALUES FROM (1) TO (100);
|
||||
CREATE TABLE local_partitioned_table_p2 PARTITION OF local_partitioned_table
|
||||
FOR VALUES FROM (100) TO (200);
|
||||
SELECT citus_add_local_table_to_metadata('local_partitioned_table');
|
||||
citus_add_local_table_to_metadata
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Verify the Citus tables
|
||||
SELECT table_name, citus_table_type FROM pg_catalog.citus_tables
|
||||
WHERE table_name::regclass::text LIKE '%_partitioned_table' ORDER BY 1;
|
||||
ERROR: relation "pg_catalog.citus_tables" does not exist
|
||||
-- Step 3: Add an exclusion constraint with a name to the distributed partitioned table
|
||||
ALTER TABLE distributed_partitioned_table ADD CONSTRAINT dist_exclude_named EXCLUDE USING btree (id WITH =, partition_col WITH =);
|
||||
-- Step 4: Verify propagation of exclusion constraint to worker nodes
|
||||
\c - - :public_worker_1_host :worker_1_port
|
||||
SET search_path TO pg17;
|
||||
SELECT conname FROM pg_constraint WHERE conrelid = 'pg17.distributed_partitioned_table'::regclass AND conname = 'dist_exclude_named';
|
||||
conname
|
||||
---------------------------------------------------------------------
|
||||
dist_exclude_named
|
||||
(1 row)
|
||||
|
||||
-- Step 5: Add an exclusion constraint with a name to the Citus local partitioned table
|
||||
\c - - :master_host :master_port
|
||||
SET search_path TO pg17;
|
||||
ALTER TABLE local_partitioned_table ADD CONSTRAINT local_exclude_named EXCLUDE USING btree (partition_col WITH =);
|
||||
-- Step 6: Verify the exclusion constraint on the local partitioned table
|
||||
SELECT conname, contype FROM pg_constraint WHERE conname = 'local_exclude_named' AND contype = 'x';
|
||||
conname | contype
|
||||
---------------------------------------------------------------------
|
||||
local_exclude_named | x
|
||||
(1 row)
|
||||
|
||||
-- Step 7: Add exclusion constraints without names to both tables
|
||||
ALTER TABLE distributed_partitioned_table ADD EXCLUDE USING btree (id WITH =, partition_col WITH =);
|
||||
ALTER TABLE local_partitioned_table ADD EXCLUDE USING btree (partition_col WITH =);
|
||||
-- Step 8: Verify the unnamed exclusion constraints were added
|
||||
SELECT conname, contype FROM pg_constraint WHERE conrelid = 'local_partitioned_table'::regclass AND contype = 'x';
|
||||
conname | contype
|
||||
---------------------------------------------------------------------
|
||||
local_exclude_named | x
|
||||
local_partitioned_table_partition_col_excl | x
|
||||
(2 rows)
|
||||
|
||||
\c - - :public_worker_1_host :worker_1_port
|
||||
SET search_path TO pg17;
|
||||
SELECT conname, contype FROM pg_constraint WHERE conrelid = 'pg17.distributed_partitioned_table'::regclass AND contype = 'x';
|
||||
conname | contype
|
||||
---------------------------------------------------------------------
|
||||
dist_exclude_named | x
|
||||
distributed_partitioned_table_id_partition_col_excl | x
|
||||
(2 rows)
|
||||
|
||||
-- Step 9: Drop the exclusion constraints from both tables
|
||||
\c - - :master_host :master_port
|
||||
SET search_path TO pg17;
|
||||
ALTER TABLE distributed_partitioned_table DROP CONSTRAINT dist_exclude_named;
|
||||
ALTER TABLE local_partitioned_table DROP CONSTRAINT local_exclude_named;
|
||||
-- Step 10: Verify the constraints were dropped
|
||||
SELECT * FROM pg_constraint WHERE conname = 'dist_exclude_named' AND contype = 'x';
|
||||
oid | conname | connamespace | contype | condeferrable | condeferred | convalidated | conrelid | contypid | conindid | conparentid | confrelid | confupdtype | confdeltype | confmatchtype | conislocal | coninhcount | connoinherit | conkey | confkey | conpfeqop | conppeqop | conffeqop | confdelsetcols | conexclop | conbin
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM pg_constraint WHERE conname = 'local_exclude_named' AND contype = 'x';
|
||||
oid | conname | connamespace | contype | condeferrable | condeferred | convalidated | conrelid | contypid | conindid | conparentid | confrelid | confupdtype | confdeltype | confmatchtype | conislocal | coninhcount | connoinherit | conkey | confkey | conpfeqop | conppeqop | conffeqop | confdelsetcols | conexclop | conbin
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
-- Step 11: Clean up - Drop the tables
|
||||
DROP TABLE distributed_partitioned_table CASCADE;
|
||||
DROP TABLE local_partitioned_table CASCADE;
|
||||
-- End of Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment
|
||||
DROP SCHEMA pg17 CASCADE;
|
||||
NOTICE: drop cascades to 5 other objects
|
||||
DETAIL: drop cascades to function fake_am_handler(internal)
|
||||
|
|
|
@ -785,9 +785,6 @@ SELECT con.conname
|
|||
\c - - :master_host :master_port
|
||||
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;
|
||||
|
||||
-- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it
|
||||
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
|
||||
|
||||
-- Check "ADD CHECK"
|
||||
SET client_min_messages TO DEBUG1;
|
||||
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD CHECK (dist_col > 0);
|
||||
|
|
|
@ -499,6 +499,81 @@ RESET client_min_messages;
|
|||
DROP TABLE reference_table;
|
||||
-- End for Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470.
|
||||
|
||||
-- Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment
|
||||
-- Step 1: Create a distributed partitioned table
|
||||
\c - - :master_host :master_port
|
||||
SET search_path TO pg17;
|
||||
CREATE TABLE distributed_partitioned_table (
|
||||
id serial NOT NULL,
|
||||
partition_col int NOT NULL,
|
||||
PRIMARY KEY (id, partition_col)
|
||||
) PARTITION BY RANGE (partition_col);
|
||||
-- Add partitions to the distributed partitioned table
|
||||
CREATE TABLE distributed_partitioned_table_p1 PARTITION OF distributed_partitioned_table
|
||||
FOR VALUES FROM (1) TO (100);
|
||||
CREATE TABLE distributed_partitioned_table_p2 PARTITION OF distributed_partitioned_table
|
||||
FOR VALUES FROM (100) TO (200);
|
||||
-- Distribute the table
|
||||
SELECT create_distributed_table('distributed_partitioned_table', 'id');
|
||||
|
||||
-- Step 2: Create a partitioned Citus local table
|
||||
CREATE TABLE local_partitioned_table (
|
||||
id serial NOT NULL,
|
||||
partition_col int NOT NULL,
|
||||
PRIMARY KEY (id, partition_col)
|
||||
) PARTITION BY RANGE (partition_col);
|
||||
-- Add partitions to the local partitioned table
|
||||
CREATE TABLE local_partitioned_table_p1 PARTITION OF local_partitioned_table
|
||||
FOR VALUES FROM (1) TO (100);
|
||||
CREATE TABLE local_partitioned_table_p2 PARTITION OF local_partitioned_table
|
||||
FOR VALUES FROM (100) TO (200);
|
||||
SELECT citus_add_local_table_to_metadata('local_partitioned_table');
|
||||
|
||||
-- Verify the Citus tables
|
||||
SELECT table_name, citus_table_type FROM pg_catalog.citus_tables
|
||||
WHERE table_name::regclass::text LIKE '%_partitioned_table' ORDER BY 1;
|
||||
|
||||
-- Step 3: Add an exclusion constraint with a name to the distributed partitioned table
|
||||
ALTER TABLE distributed_partitioned_table ADD CONSTRAINT dist_exclude_named EXCLUDE USING btree (id WITH =, partition_col WITH =);
|
||||
|
||||
-- Step 4: Verify propagation of exclusion constraint to worker nodes
|
||||
\c - - :public_worker_1_host :worker_1_port
|
||||
SET search_path TO pg17;
|
||||
SELECT conname FROM pg_constraint WHERE conrelid = 'pg17.distributed_partitioned_table'::regclass AND conname = 'dist_exclude_named';
|
||||
|
||||
-- Step 5: Add an exclusion constraint with a name to the Citus local partitioned table
|
||||
\c - - :master_host :master_port
|
||||
SET search_path TO pg17;
|
||||
ALTER TABLE local_partitioned_table ADD CONSTRAINT local_exclude_named EXCLUDE USING btree (partition_col WITH =);
|
||||
|
||||
-- Step 6: Verify the exclusion constraint on the local partitioned table
|
||||
SELECT conname, contype FROM pg_constraint WHERE conname = 'local_exclude_named' AND contype = 'x';
|
||||
|
||||
-- Step 7: Add exclusion constraints without names to both tables
|
||||
ALTER TABLE distributed_partitioned_table ADD EXCLUDE USING btree (id WITH =, partition_col WITH =);
|
||||
ALTER TABLE local_partitioned_table ADD EXCLUDE USING btree (partition_col WITH =);
|
||||
|
||||
-- Step 8: Verify the unnamed exclusion constraints were added
|
||||
SELECT conname, contype FROM pg_constraint WHERE conrelid = 'local_partitioned_table'::regclass AND contype = 'x';
|
||||
\c - - :public_worker_1_host :worker_1_port
|
||||
SET search_path TO pg17;
|
||||
SELECT conname, contype FROM pg_constraint WHERE conrelid = 'pg17.distributed_partitioned_table'::regclass AND contype = 'x';
|
||||
|
||||
-- Step 9: Drop the exclusion constraints from both tables
|
||||
\c - - :master_host :master_port
|
||||
SET search_path TO pg17;
|
||||
ALTER TABLE distributed_partitioned_table DROP CONSTRAINT dist_exclude_named;
|
||||
ALTER TABLE local_partitioned_table DROP CONSTRAINT local_exclude_named;
|
||||
|
||||
-- Step 10: Verify the constraints were dropped
|
||||
SELECT * FROM pg_constraint WHERE conname = 'dist_exclude_named' AND contype = 'x';
|
||||
SELECT * FROM pg_constraint WHERE conname = 'local_exclude_named' AND contype = 'x';
|
||||
|
||||
-- Step 11: Clean up - Drop the tables
|
||||
DROP TABLE distributed_partitioned_table CASCADE;
|
||||
DROP TABLE local_partitioned_table CASCADE;
|
||||
-- End of Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment
|
||||
|
||||
DROP SCHEMA pg17 CASCADE;
|
||||
DROP ROLE regress_maintain;
|
||||
DROP ROLE regress_no_maintain;
|
||||
|
|
Loading…
Reference in New Issue