From 1cf5c190aa66a6599daa6ed75cbc83459f55fe2f Mon Sep 17 00:00:00 2001 From: Mehmet YILMAZ Date: Fri, 27 Dec 2024 16:02:12 +0300 Subject: [PATCH] Error out for ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION (#7814) PG17 added support for ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION. Relevant PG commit: https://github.com/postgres/postgres/commit/5d06e99a3 We currently don't support propagating this command for Citus tables. It is added to future work. This PR disallows `ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION` on all Citus table types (local, distributed, and partitioned distributed) by adding an error check in `ErrorIfUnsupportedAlterTableStmt`. A new regression test verifies that each table type fails with a consistent error message when attempting to set an expression. --- src/backend/distributed/commands/table.c | 11 +++++++ src/test/regress/expected/pg17.out | 41 ++++++++++++++++++++++++ src/test/regress/sql/pg17.sql | 32 ++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/src/backend/distributed/commands/table.c b/src/backend/distributed/commands/table.c index c395892b5..67b731a25 100644 --- a/src/backend/distributed/commands/table.c +++ b/src/backend/distributed/commands/table.c @@ -3664,6 +3664,17 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement) break; } +#if PG_VERSION_NUM >= PG_VERSION_17 + case AT_SetExpression: + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg( + "ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION commands " + "are currently unsupported."))); + break; + } + +#endif #if PG_VERSION_NUM >= PG_VERSION_15 case AT_SetAccessMethod: { diff --git a/src/test/regress/expected/pg17.out b/src/test/regress/expected/pg17.out index fe925516b..4d086be82 100644 --- a/src/test/regress/expected/pg17.out +++ b/src/test/regress/expected/pg17.out @@ -1376,6 +1376,47 @@ DROP TABLE test_local_table CASCADE; DROP TABLE test_alter_access_method CASCADE; DROP TABLE test_partitioned_alter CASCADE; -- End of Test for ALTER TABLE SET ACCESS METHOD DEFAULT +-- Test for ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION +-- Step 1: Local table setup (non-distributed) +CREATE TABLE test_local_table_expr (id int, col int); +SELECT citus_add_local_table_to_metadata('test_local_table_expr'); + citus_add_local_table_to_metadata +--------------------------------------------------------------------- + +(1 row) + +-- Step 2: Attempt to set expression on a Citus local table (should fail) +ALTER TABLE test_local_table_expr ALTER COLUMN col SET EXPRESSION AS (id * 4); +ERROR: ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION commands are currently unsupported. +-- Step 3: Create and distribute a table +CREATE TABLE test_distributed_table_expr (id int, col int); +SELECT create_distributed_table('test_distributed_table_expr', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- Step 4: Attempt to set expression on a distributed table (should fail) +ALTER TABLE test_distributed_table_expr ALTER COLUMN col SET EXPRESSION AS (id * 4); +ERROR: ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION commands are currently unsupported. +-- Step 5: Create and distribute a partitioned table +CREATE TABLE test_partitioned_expr (id int, val text) PARTITION BY RANGE (id); +CREATE TABLE test_partitioned_expr_part1 PARTITION OF test_partitioned_expr + FOR VALUES FROM (1) TO (100); +SELECT create_distributed_table('test_partitioned_expr', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- Step 6: Attempt to set expression on a partitioned, distributed table (should fail) +ALTER TABLE test_partitioned_expr ALTER COLUMN val SET EXPRESSION AS (id * 4); +ERROR: ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION commands are currently unsupported. +-- Cleanup +DROP TABLE test_local_table_expr CASCADE; +DROP TABLE test_distributed_table_expr CASCADE; +DROP TABLE test_partitioned_expr CASCADE; +-- End of Test for ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION \set VERBOSITY terse SET client_min_messages TO WARNING; DROP SCHEMA pg17 CASCADE; diff --git a/src/test/regress/sql/pg17.sql b/src/test/regress/sql/pg17.sql index 88d1a475f..6ca506267 100644 --- a/src/test/regress/sql/pg17.sql +++ b/src/test/regress/sql/pg17.sql @@ -741,6 +741,38 @@ DROP TABLE test_alter_access_method CASCADE; DROP TABLE test_partitioned_alter CASCADE; -- End of Test for ALTER TABLE SET ACCESS METHOD DEFAULT +-- Test for ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION + +-- Step 1: Local table setup (non-distributed) +CREATE TABLE test_local_table_expr (id int, col int); + +SELECT citus_add_local_table_to_metadata('test_local_table_expr'); + +-- Step 2: Attempt to set expression on a Citus local table (should fail) +ALTER TABLE test_local_table_expr ALTER COLUMN col SET EXPRESSION AS (id * 4); + +-- Step 3: Create and distribute a table +CREATE TABLE test_distributed_table_expr (id int, col int); +SELECT create_distributed_table('test_distributed_table_expr', 'id'); + +-- Step 4: Attempt to set expression on a distributed table (should fail) +ALTER TABLE test_distributed_table_expr ALTER COLUMN col SET EXPRESSION AS (id * 4); + +-- Step 5: Create and distribute a partitioned table +CREATE TABLE test_partitioned_expr (id int, val text) PARTITION BY RANGE (id); +CREATE TABLE test_partitioned_expr_part1 PARTITION OF test_partitioned_expr + FOR VALUES FROM (1) TO (100); +SELECT create_distributed_table('test_partitioned_expr', 'id'); + +-- Step 6: Attempt to set expression on a partitioned, distributed table (should fail) +ALTER TABLE test_partitioned_expr ALTER COLUMN val SET EXPRESSION AS (id * 4); + +-- Cleanup +DROP TABLE test_local_table_expr CASCADE; +DROP TABLE test_distributed_table_expr CASCADE; +DROP TABLE test_partitioned_expr CASCADE; +-- End of Test for ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION + \set VERBOSITY terse SET client_min_messages TO WARNING; DROP SCHEMA pg17 CASCADE;