From 2241a9b8b374aeda6049cf8bc1763088f0cbcba2 Mon Sep 17 00:00:00 2001 From: Mehmet Yilmaz Date: Fri, 8 Nov 2024 11:14:55 +0000 Subject: [PATCH 1/2] multi_alter_table_add_const update update . move the tests update update update style update update update review update update Update src/test/regress/sql/pg17.sql Co-authored-by: Naisila Puka <37271756+naisila@users.noreply.github.com> comment update review update fix whitespace --- ...ter_table_add_constraints_without_name.out | 3 - src/test/regress/expected/pg17.out | 159 ++++++++++++++++++ ...ter_table_add_constraints_without_name.sql | 3 - src/test/regress/sql/pg17.sql | 103 ++++++++++++ 4 files changed, 262 insertions(+), 6 deletions(-) diff --git a/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out b/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out index 0b048946cf0..0c268264d3c 100644 --- a/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out +++ b/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out @@ -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); diff --git a/src/test/regress/expected/pg17.out b/src/test/regress/expected/pg17.out index d9d05196a40..54297041cc2 100644 --- a/src/test/regress/expected/pg17.out +++ b/src/test/regress/expected/pg17.out @@ -955,6 +955,165 @@ DROP TABLE pt_3; DROP TABLE pt_4; DROP TABLE alt_test; -- End of partition with identity columns testing +-- 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 +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) + +-- Additional test for long names and sequential execution mode +-- Create schema if it doesn't already exist +CREATE SCHEMA IF NOT EXISTS AT_AddConstNoName; +CREATE TABLE AT_AddConstNoName.dist_partitioned_table ( + dist_col int, + another_col int, + partition_col timestamp +) PARTITION BY RANGE (partition_col); +CREATE TABLE AT_AddConstNoName.p1 PARTITION OF AT_AddConstNoName.dist_partitioned_table +FOR VALUES FROM ('2021-01-01') TO ('2022-01-01'); +CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.dist_partitioned_table +FOR VALUES FROM ('2020-01-01') TO ('2021-01-01'); +SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'partition_col'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- Step 1.1: Insert and query data from long name partition +INSERT INTO AT_AddConstNoName.dist_partitioned_table (dist_col, another_col, partition_col) +VALUES (1, 10, '2020-06-01'), (2, 20, '2020-09-01'); +SELECT * FROM AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc; + dist_col | another_col | partition_col +--------------------------------------------------------------------- + 1 | 10 | Mon Jun 01 00:00:00 2020 + 2 | 20 | Tue Sep 01 00:00:00 2020 +(2 rows) + +-- Step 1.2: Verify sequential execution mode +EXPLAIN SELECT * FROM AT_AddConstNoName.dist_partitioned_table WHERE partition_col = '2020-06-01'; + QUERY PLAN +--------------------------------------------------------------------- + Custom Scan (Citus Adaptive) (cost=0.00..0.00 rows=0 width=0) + Task Count: 1 + Tasks Shown: All + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Seq Scan on longlonglonglonglonglonglonglonglonglonglonglon_537570f5_361817 dist_partitioned_table (cost=0.00..33.12 rows=9 width=16) + Filter: (partition_col = '2020-06-01 00:00:00'::timestamp without time zone) +(7 rows) + +-- Step 1.3: Add exclusion constraints on parent table +ALTER TABLE AT_AddConstNoName.dist_partitioned_table +ADD CONSTRAINT long_name_exclude EXCLUDE USING btree (dist_col WITH =, partition_col WITH =); +-- Verify the constraint was added +SELECT conname FROM pg_constraint WHERE conrelid = 'AT_AddConstNoName.dist_partitioned_table'::regclass AND conname = 'long_name_exclude'; + conname +--------------------------------------------------------------------- + long_name_exclude +(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 citus_tables +WHERE table_name::regclass::text like '%_partitioned_table' ORDER BY 1; + table_name | citus_table_type +--------------------------------------------------------------------- + distributed_partitioned_table | distributed + at_addconstnoname.dist_partitioned_table | distributed + local_partitioned_table | local +(3 rows) + +-- 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 +SELECT conname FROM pg_constraint WHERE conrelid = '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 +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 +SELECT conname, contype FROM pg_constraint WHERE conrelid = '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 +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, local_partitioned_table; +DROP TABLE AT_AddConstNoName.p1, + AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc, + AT_AddConstNoName.dist_partitioned_table; +DROP SCHEMA AT_AddConstNoName CASCADE; +-- End of Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment -- Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470. -- Enable DEBUG-level logging to capture detailed execution plans -- Create the tables diff --git a/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql b/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql index 700e37f6e48..f5fd653f5ac 100644 --- a/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql +++ b/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql @@ -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); diff --git a/src/test/regress/sql/pg17.sql b/src/test/regress/sql/pg17.sql index 5326ede72b0..828fd5a8795 100644 --- a/src/test/regress/sql/pg17.sql +++ b/src/test/regress/sql/pg17.sql @@ -464,6 +464,109 @@ DROP TABLE alt_test; -- End of partition with identity columns testing +-- 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 +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'); + +-- Additional test for long names and sequential execution mode +-- Create schema if it doesn't already exist +CREATE SCHEMA IF NOT EXISTS AT_AddConstNoName; + +CREATE TABLE AT_AddConstNoName.dist_partitioned_table ( + dist_col int, + another_col int, + partition_col timestamp +) PARTITION BY RANGE (partition_col); +CREATE TABLE AT_AddConstNoName.p1 PARTITION OF AT_AddConstNoName.dist_partitioned_table +FOR VALUES FROM ('2021-01-01') TO ('2022-01-01'); +CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.dist_partitioned_table +FOR VALUES FROM ('2020-01-01') TO ('2021-01-01'); +SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'partition_col'); + +-- Step 1.1: Insert and query data from long name partition +INSERT INTO AT_AddConstNoName.dist_partitioned_table (dist_col, another_col, partition_col) +VALUES (1, 10, '2020-06-01'), (2, 20, '2020-09-01'); +SELECT * FROM AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc; + +-- Step 1.2: Verify sequential execution mode +EXPLAIN SELECT * FROM AT_AddConstNoName.dist_partitioned_table WHERE partition_col = '2020-06-01'; + +-- Step 1.3: Add exclusion constraints on parent table +ALTER TABLE AT_AddConstNoName.dist_partitioned_table +ADD CONSTRAINT long_name_exclude EXCLUDE USING btree (dist_col WITH =, partition_col WITH =); + +-- Verify the constraint was added +SELECT conname FROM pg_constraint WHERE conrelid = 'AT_AddConstNoName.dist_partitioned_table'::regclass AND conname = 'long_name_exclude'; + +-- 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 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 +SELECT conname FROM pg_constraint WHERE conrelid = '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 +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 +SELECT conname, contype FROM pg_constraint WHERE conrelid = 'distributed_partitioned_table'::regclass AND contype = 'x'; + +-- Step 9: Drop the exclusion constraints from both tables +\c - - :master_host :master_port +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, local_partitioned_table; +DROP TABLE AT_AddConstNoName.p1, + AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc, + AT_AddConstNoName.dist_partitioned_table; +DROP SCHEMA AT_AddConstNoName CASCADE; +-- End of Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment + -- Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470. -- Enable DEBUG-level logging to capture detailed execution plans From ee562600c075a820d70a11ecc09be7b216d16465 Mon Sep 17 00:00:00 2001 From: Mehmet Yilmaz Date: Mon, 23 Dec 2024 11:36:55 +0000 Subject: [PATCH 2/2] update --- src/test/regress/expected/pg17.out | 195 +++++++++++------------------ src/test/regress/sql/pg17.sql | 120 +++++++----------- 2 files changed, 116 insertions(+), 199 deletions(-) diff --git a/src/test/regress/expected/pg17.out b/src/test/regress/expected/pg17.out index 54297041cc2..fbe8ebbe134 100644 --- a/src/test/regress/expected/pg17.out +++ b/src/test/regress/expected/pg17.out @@ -955,9 +955,68 @@ DROP TABLE pt_3; DROP TABLE pt_4; DROP TABLE alt_test; -- End of partition with identity columns testing +-- Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470. +-- Enable DEBUG-level logging to capture detailed execution plans +-- Create the tables +CREATE TABLE postgres_table (key int, value text, value_2 jsonb); +CREATE TABLE reference_table (key int, value text, value_2 jsonb); +SELECT create_reference_table('reference_table'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table (key int, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- Insert test data +INSERT INTO postgres_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; +INSERT INTO reference_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; +INSERT INTO distributed_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; +-- Set local table join policy to auto before running the tests +SET citus.local_table_join_policy TO 'auto'; +SET client_min_messages TO DEBUG1; +-- Correlated sublinks are supported in PostgreSQL 17 +SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) +WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); +DEBUG: Wrapping relation "postgres_table" to a subquery +DEBUG: generating subplan XXX_1 for subquery SELECT key FROM pg17.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (pg17.distributed_table d1 JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM pg17.distributed_table WHERE ((d1.key OPERATOR(pg_catalog.=) distributed_table.key) AND (distributed_table.key OPERATOR(pg_catalog.=) 5)))) + count +--------------------------------------------------------------------- + 1 +(1 row) + +SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) +WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); +DEBUG: Wrapping relation "postgres_table" to a subquery +DEBUG: generating subplan XXX_1 for subquery SELECT key FROM pg17.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (pg17.distributed_table d1 JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM pg17.distributed_table WHERE ((d1.key OPERATOR(pg_catalog.=) distributed_table.key) AND (distributed_table.key OPERATOR(pg_catalog.=) 5)))) + count +--------------------------------------------------------------------- + 1 +(1 row) + +SET citus.local_table_join_policy TO 'prefer-distributed'; +SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) +WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); +DEBUG: Wrapping relation "distributed_table" "d1" to a subquery +DEBUG: generating subplan XXX_1 for subquery SELECT key FROM pg17.distributed_table d1 WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT d1_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) d1_1) d1 JOIN pg17.postgres_table USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM pg17.distributed_table WHERE ((d1.key OPERATOR(pg_catalog.=) distributed_table.key) AND (distributed_table.key OPERATOR(pg_catalog.=) 5)))) +ERROR: direct joins between distributed and local tables are not supported +HINT: Use CTE's or subqueries to select from local tables and use them in joins +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, @@ -975,57 +1034,6 @@ SELECT create_distributed_table('distributed_partitioned_table', 'id'); (1 row) --- Additional test for long names and sequential execution mode --- Create schema if it doesn't already exist -CREATE SCHEMA IF NOT EXISTS AT_AddConstNoName; -CREATE TABLE AT_AddConstNoName.dist_partitioned_table ( - dist_col int, - another_col int, - partition_col timestamp -) PARTITION BY RANGE (partition_col); -CREATE TABLE AT_AddConstNoName.p1 PARTITION OF AT_AddConstNoName.dist_partitioned_table -FOR VALUES FROM ('2021-01-01') TO ('2022-01-01'); -CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.dist_partitioned_table -FOR VALUES FROM ('2020-01-01') TO ('2021-01-01'); -SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'partition_col'); - create_distributed_table ---------------------------------------------------------------------- - -(1 row) - --- Step 1.1: Insert and query data from long name partition -INSERT INTO AT_AddConstNoName.dist_partitioned_table (dist_col, another_col, partition_col) -VALUES (1, 10, '2020-06-01'), (2, 20, '2020-09-01'); -SELECT * FROM AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc; - dist_col | another_col | partition_col ---------------------------------------------------------------------- - 1 | 10 | Mon Jun 01 00:00:00 2020 - 2 | 20 | Tue Sep 01 00:00:00 2020 -(2 rows) - --- Step 1.2: Verify sequential execution mode -EXPLAIN SELECT * FROM AT_AddConstNoName.dist_partitioned_table WHERE partition_col = '2020-06-01'; - QUERY PLAN ---------------------------------------------------------------------- - Custom Scan (Citus Adaptive) (cost=0.00..0.00 rows=0 width=0) - Task Count: 1 - Tasks Shown: All - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Seq Scan on longlonglonglonglonglonglonglonglonglonglonglon_537570f5_361817 dist_partitioned_table (cost=0.00..33.12 rows=9 width=16) - Filter: (partition_col = '2020-06-01 00:00:00'::timestamp without time zone) -(7 rows) - --- Step 1.3: Add exclusion constraints on parent table -ALTER TABLE AT_AddConstNoName.dist_partitioned_table -ADD CONSTRAINT long_name_exclude EXCLUDE USING btree (dist_col WITH =, partition_col WITH =); --- Verify the constraint was added -SELECT conname FROM pg_constraint WHERE conrelid = 'AT_AddConstNoName.dist_partitioned_table'::regclass AND conname = 'long_name_exclude'; - conname ---------------------------------------------------------------------- - long_name_exclude -(1 row) - -- Step 2: Create a partitioned Citus local table CREATE TABLE local_partitioned_table ( id serial NOT NULL, @@ -1044,20 +1052,15 @@ SELECT citus_add_local_table_to_metadata('local_partitioned_table'); (1 row) -- Verify the Citus tables -SELECT table_name, citus_table_type FROM citus_tables -WHERE table_name::regclass::text like '%_partitioned_table' ORDER BY 1; - table_name | citus_table_type ---------------------------------------------------------------------- - distributed_partitioned_table | distributed - at_addconstnoname.dist_partitioned_table | distributed - local_partitioned_table | local -(3 rows) - +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 -SELECT conname FROM pg_constraint WHERE conrelid = 'distributed_partitioned_table'::regclass AND conname = 'dist_exclude_named'; +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 @@ -1065,6 +1068,7 @@ SELECT conname FROM pg_constraint WHERE conrelid = 'distributed_partitioned_tabl -- 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'; @@ -1085,7 +1089,8 @@ SELECT conname, contype FROM pg_constraint WHERE conrelid = 'local_partitioned_t (2 rows) \c - - :public_worker_1_host :worker_1_port -SELECT conname, contype FROM pg_constraint WHERE conrelid = 'distributed_partitioned_table'::regclass AND contype = 'x'; +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 @@ -1094,6 +1099,7 @@ SELECT conname, contype FROM pg_constraint WHERE conrelid = 'distributed_partiti -- 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 @@ -1108,70 +1114,9 @@ SELECT * FROM pg_constraint WHERE conname = 'local_exclude_named' AND contype = (0 rows) -- Step 11: Clean up - Drop the tables -DROP TABLE distributed_partitioned_table, local_partitioned_table; -DROP TABLE AT_AddConstNoName.p1, - AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc, - AT_AddConstNoName.dist_partitioned_table; -DROP SCHEMA AT_AddConstNoName CASCADE; +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 --- Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470. --- Enable DEBUG-level logging to capture detailed execution plans --- Create the tables -CREATE TABLE postgres_table (key int, value text, value_2 jsonb); -CREATE TABLE reference_table (key int, value text, value_2 jsonb); -SELECT create_reference_table('reference_table'); - create_reference_table ---------------------------------------------------------------------- - -(1 row) - -CREATE TABLE distributed_table (key int, value text, value_2 jsonb); -SELECT create_distributed_table('distributed_table', 'key'); - create_distributed_table ---------------------------------------------------------------------- - -(1 row) - --- Insert test data -INSERT INTO postgres_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; -INSERT INTO reference_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; -INSERT INTO distributed_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; --- Set local table join policy to auto before running the tests -SET citus.local_table_join_policy TO 'auto'; -SET client_min_messages TO DEBUG1; --- Correlated sublinks are supported in PostgreSQL 17 -SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) -WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); -DEBUG: Wrapping relation "postgres_table" to a subquery -DEBUG: generating subplan XXX_1 for subquery SELECT key FROM pg17.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (pg17.distributed_table d1 JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM pg17.distributed_table WHERE ((d1.key OPERATOR(pg_catalog.=) distributed_table.key) AND (distributed_table.key OPERATOR(pg_catalog.=) 5)))) - count ---------------------------------------------------------------------- - 1 -(1 row) - -SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) -WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); -DEBUG: Wrapping relation "postgres_table" to a subquery -DEBUG: generating subplan XXX_1 for subquery SELECT key FROM pg17.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (pg17.distributed_table d1 JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM pg17.distributed_table WHERE ((d1.key OPERATOR(pg_catalog.=) distributed_table.key) AND (distributed_table.key OPERATOR(pg_catalog.=) 5)))) - count ---------------------------------------------------------------------- - 1 -(1 row) - -SET citus.local_table_join_policy TO 'prefer-distributed'; -SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) -WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); -DEBUG: Wrapping relation "distributed_table" "d1" to a subquery -DEBUG: generating subplan XXX_1 for subquery SELECT key FROM pg17.distributed_table d1 WHERE (key OPERATOR(pg_catalog.=) 5) -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT d1_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) d1_1) d1 JOIN pg17.postgres_table USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM pg17.distributed_table WHERE ((d1.key OPERATOR(pg_catalog.=) distributed_table.key) AND (distributed_table.key OPERATOR(pg_catalog.=) 5)))) -ERROR: direct joins between distributed and local tables are not supported -HINT: Use CTE's or subqueries to select from local tables and use them in joins -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. DROP SCHEMA pg17 CASCADE; NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to function fake_am_handler(internal) diff --git a/src/test/regress/sql/pg17.sql b/src/test/regress/sql/pg17.sql index 828fd5a8795..f0c6d5b65e3 100644 --- a/src/test/regress/sql/pg17.sql +++ b/src/test/regress/sql/pg17.sql @@ -464,9 +464,45 @@ DROP TABLE alt_test; -- End of partition with identity columns testing +-- Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470. +-- Enable DEBUG-level logging to capture detailed execution plans + +-- Create the tables +CREATE TABLE postgres_table (key int, value text, value_2 jsonb); +CREATE TABLE reference_table (key int, value text, value_2 jsonb); +SELECT create_reference_table('reference_table'); +CREATE TABLE distributed_table (key int, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table', 'key'); + +-- Insert test data +INSERT INTO postgres_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; +INSERT INTO reference_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; +INSERT INTO distributed_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; + +-- Set local table join policy to auto before running the tests +SET citus.local_table_join_policy TO 'auto'; +SET client_min_messages TO DEBUG1; + +-- Correlated sublinks are supported in PostgreSQL 17 +SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) +WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); + +SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) +WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); + +SET citus.local_table_join_policy TO 'prefer-distributed'; +SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) +WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); + +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, @@ -480,36 +516,6 @@ FOR VALUES FROM (100) TO (200); -- Distribute the table SELECT create_distributed_table('distributed_partitioned_table', 'id'); --- Additional test for long names and sequential execution mode --- Create schema if it doesn't already exist -CREATE SCHEMA IF NOT EXISTS AT_AddConstNoName; - -CREATE TABLE AT_AddConstNoName.dist_partitioned_table ( - dist_col int, - another_col int, - partition_col timestamp -) PARTITION BY RANGE (partition_col); -CREATE TABLE AT_AddConstNoName.p1 PARTITION OF AT_AddConstNoName.dist_partitioned_table -FOR VALUES FROM ('2021-01-01') TO ('2022-01-01'); -CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.dist_partitioned_table -FOR VALUES FROM ('2020-01-01') TO ('2021-01-01'); -SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'partition_col'); - --- Step 1.1: Insert and query data from long name partition -INSERT INTO AT_AddConstNoName.dist_partitioned_table (dist_col, another_col, partition_col) -VALUES (1, 10, '2020-06-01'), (2, 20, '2020-09-01'); -SELECT * FROM AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc; - --- Step 1.2: Verify sequential execution mode -EXPLAIN SELECT * FROM AT_AddConstNoName.dist_partitioned_table WHERE partition_col = '2020-06-01'; - --- Step 1.3: Add exclusion constraints on parent table -ALTER TABLE AT_AddConstNoName.dist_partitioned_table -ADD CONSTRAINT long_name_exclude EXCLUDE USING btree (dist_col WITH =, partition_col WITH =); - --- Verify the constraint was added -SELECT conname FROM pg_constraint WHERE conrelid = 'AT_AddConstNoName.dist_partitioned_table'::regclass AND conname = 'long_name_exclude'; - -- Step 2: Create a partitioned Citus local table CREATE TABLE local_partitioned_table ( id serial NOT NULL, @@ -524,18 +530,20 @@ 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 citus_tables -WHERE table_name::regclass::text like '%_partitioned_table' ORDER BY 1; +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 -SELECT conname FROM pg_constraint WHERE conrelid = 'distributed_partitioned_table'::regclass AND conname = 'dist_exclude_named'; +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 @@ -548,10 +556,12 @@ 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 -SELECT conname, contype FROM pg_constraint WHERE conrelid = 'distributed_partitioned_table'::regclass AND contype = 'x'; +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; @@ -560,48 +570,10 @@ SELECT * FROM pg_constraint WHERE conname = 'dist_exclude_named' AND contype = ' SELECT * FROM pg_constraint WHERE conname = 'local_exclude_named' AND contype = 'x'; -- Step 11: Clean up - Drop the tables -DROP TABLE distributed_partitioned_table, local_partitioned_table; -DROP TABLE AT_AddConstNoName.p1, - AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc, - AT_AddConstNoName.dist_partitioned_table; -DROP SCHEMA AT_AddConstNoName CASCADE; +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 --- Correlated sublinks are now supported as of PostgreSQL 17, resolving issue #4470. --- Enable DEBUG-level logging to capture detailed execution plans - --- Create the tables -CREATE TABLE postgres_table (key int, value text, value_2 jsonb); -CREATE TABLE reference_table (key int, value text, value_2 jsonb); -SELECT create_reference_table('reference_table'); -CREATE TABLE distributed_table (key int, value text, value_2 jsonb); -SELECT create_distributed_table('distributed_table', 'key'); - --- Insert test data -INSERT INTO postgres_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; -INSERT INTO reference_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; -INSERT INTO distributed_table SELECT i, i::varchar(256), '{}'::jsonb FROM generate_series(1, 10) i; - --- Set local table join policy to auto before running the tests -SET citus.local_table_join_policy TO 'auto'; -SET client_min_messages TO DEBUG1; - --- Correlated sublinks are supported in PostgreSQL 17 -SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) -WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); - -SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) -WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); - -SET citus.local_table_join_policy TO 'prefer-distributed'; -SELECT COUNT(*) FROM distributed_table d1 JOIN postgres_table USING (key) -WHERE d1.key IN (SELECT key FROM distributed_table WHERE d1.key = key AND key = 5); - -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. - DROP SCHEMA pg17 CASCADE; DROP ROLE regress_maintain; DROP ROLE regress_no_maintain;