diff --git a/src/backend/distributed/commands/cluster.c b/src/backend/distributed/commands/cluster.c index c539aa066..4cffbaf51 100644 --- a/src/backend/distributed/commands/cluster.c +++ b/src/backend/distributed/commands/cluster.c @@ -19,6 +19,7 @@ #include "distributed/commands/utility_hook.h" #include "distributed/listutils.h" #include "distributed/metadata_cache.h" +#include "distributed/multi_partitioning_utils.h" static bool IsClusterStmtVerbose_compat(ClusterStmt *clusterStmt); @@ -69,6 +70,27 @@ PreprocessClusterStmt(Node *node, const char *clusterCommand, return NIL; } + /* + * We do not support CLUSTER command on partitioned tables as it can not be run inside + * transaction blocks. PostgreSQL currently does not support CLUSTER command on + * partitioned tables in a transaction block. Although Citus can execute commands + * outside of transaction block -- such as VACUUM -- we cannot do that here because + * CLUSTER command is also not allowed from a function call as well. By default, Citus + * uses `worker_apply_shard_ddl_command()`, where we should avoid it for this case. + */ + if (PartitionedTable(relationId)) + { + if (EnableUnsupportedFeatureMessages) + { + ereport(WARNING, (errmsg("not propagating CLUSTER command for partitioned " + "table to worker nodes"), + errhint("Provide a child partition table names in order to " + "CLUSTER distributed partitioned tables."))); + } + + return NIL; + } + if (IsClusterStmtVerbose_compat(clusterStmt)) { ereport(ERROR, (errmsg("cannot run CLUSTER command"), diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 0e9357957..3c596bbb1 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -611,6 +611,7 @@ SELECT * FROM FKTABLE ORDER BY id; (2 rows) \c - - - :master_port +SET search_path TO pg15; -- test NULL NOT DISTINCT clauses -- set the next shard id so that the error messages are easier to maintain SET citus.next_shard_id TO 960050; @@ -675,7 +676,40 @@ INSERT INTO reference_uniq_test VALUES (1, NULL); ERROR: duplicate key value violates unique constraint "reference_uniq_test_x_y_key_960054" DETAIL: Key (x, y)=(1, null) already exists. CONTEXT: while executing command on localhost:xxxxx +-- +-- PG15 introduces CLUSTER command support for partitioned tables. However, similar to +-- CLUSTER commands with no table name, these queries can not be run inside a transaction +-- block. Therefore, we do not propagate such queries. +-- +-- Should print a warning that it will not be propagated to worker nodes. +CLUSTER sale USING sale_pk; +WARNING: not propagating CLUSTER command for partitioned table to worker nodes +HINT: Provide a child partition table names in order to CLUSTER distributed partitioned tables. +-- verify that we can cluster the partition tables only when replication factor is 1 +CLUSTER sale_newyork USING sale_newyork_pkey; +ERROR: modifications on partitions when replication factor is greater than 1 is not supported +HINT: Run the query on the parent table "sale" instead. +-- create a new partitioned table with shard replicaiton factor 1 +SET citus.shard_replication_factor = 1; +CREATE TABLE sale_repl_factor_1 ( LIKE sale ) + PARTITION BY list (state_code); +ALTER TABLE sale_repl_factor_1 ADD CONSTRAINT sale_repl_factor_1_pk PRIMARY KEY (state_code, sale_date); +CREATE TABLE sale_newyork_repl_factor_1 PARTITION OF sale_repl_factor_1 FOR VALUES IN ('NY'); +CREATE TABLE sale_california_repl_factor_1 PARTITION OF sale_repl_factor_1 FOR VALUES IN ('CA'); +SELECT create_distributed_table('sale_repl_factor_1', 'state_code'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- Should print a warning that it will not be propagated to worker nodes. +CLUSTER sale_repl_factor_1 USING sale_repl_factor_1_pk; +WARNING: not propagating CLUSTER command for partitioned table to worker nodes +HINT: Provide a child partition table names in order to CLUSTER distributed partitioned tables. +-- verify that we can still cluster the partition tables now since replication factor is 1 +CLUSTER sale_newyork_repl_factor_1 USING sale_newyork_repl_factor_1_pkey; -- Clean up +RESET citus.shard_replication_factor; \set VERBOSITY terse SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 296ef016e..9cfa5960d 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -337,6 +337,7 @@ DELETE FROM PKTABLE WHERE id = 1 OR id = 2; SELECT * FROM FKTABLE ORDER BY id; \c - - - :master_port +SET search_path TO pg15; -- test NULL NOT DISTINCT clauses -- set the next shard id so that the error messages are easier to maintain @@ -378,7 +379,38 @@ INSERT INTO reference_uniq_test VALUES (1, 1), (1, NULL), (NULL, 1); -- the following will fail INSERT INTO reference_uniq_test VALUES (1, NULL); +-- +-- PG15 introduces CLUSTER command support for partitioned tables. However, similar to +-- CLUSTER commands with no table name, these queries can not be run inside a transaction +-- block. Therefore, we do not propagate such queries. +-- + +-- Should print a warning that it will not be propagated to worker nodes. +CLUSTER sale USING sale_pk; + +-- verify that we can cluster the partition tables only when replication factor is 1 +CLUSTER sale_newyork USING sale_newyork_pkey; + +-- create a new partitioned table with shard replicaiton factor 1 +SET citus.shard_replication_factor = 1; +CREATE TABLE sale_repl_factor_1 ( LIKE sale ) + PARTITION BY list (state_code); + +ALTER TABLE sale_repl_factor_1 ADD CONSTRAINT sale_repl_factor_1_pk PRIMARY KEY (state_code, sale_date); + +CREATE TABLE sale_newyork_repl_factor_1 PARTITION OF sale_repl_factor_1 FOR VALUES IN ('NY'); +CREATE TABLE sale_california_repl_factor_1 PARTITION OF sale_repl_factor_1 FOR VALUES IN ('CA'); + +SELECT create_distributed_table('sale_repl_factor_1', 'state_code'); + +-- Should print a warning that it will not be propagated to worker nodes. +CLUSTER sale_repl_factor_1 USING sale_repl_factor_1_pk; + +-- verify that we can still cluster the partition tables now since replication factor is 1 +CLUSTER sale_newyork_repl_factor_1 USING sale_newyork_repl_factor_1_pkey; + -- Clean up +RESET citus.shard_replication_factor; \set VERBOSITY terse SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE;