diff --git a/src/backend/distributed/commands/multi_copy.c b/src/backend/distributed/commands/multi_copy.c index e8dadb35d..e8083dba9 100644 --- a/src/backend/distributed/commands/multi_copy.c +++ b/src/backend/distributed/commands/multi_copy.c @@ -2830,18 +2830,21 @@ CopyStatementHasFormat(CopyStmt *copyStatement, char *formatName) /* - * ErrorIfMergeInCopy Raises an exception if the MERGE is called in the COPY. + * ErrorIfMergeInCopy Raises an exception if the MERGE is called in the COPY + * where Citus tables are involved, as we don't support this yet + * Relevant PG17 commit: c649fa24a */ static void ErrorIfMergeInCopy(CopyStmt *copyStatement) { -#if PG_VERSION_NUM < 150000 +#if PG_VERSION_NUM < 170000 return; #else if (!copyStatement->relation && (IsA(copyStatement->query, MergeStmt))) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MERGE not supported in COPY"))); + errmsg("MERGE with Citus tables " + "is not yet supported in COPY"))); } #endif } diff --git a/src/backend/distributed/planner/merge_planner.c b/src/backend/distributed/planner/merge_planner.c index cf3f13eab..5fee6e956 100644 --- a/src/backend/distributed/planner/merge_planner.c +++ b/src/backend/distributed/planner/merge_planner.c @@ -173,6 +173,7 @@ GetMergeJoinTree(Query *mergeQuery) * jointree with an empty fromlist. This works because the fromlist of a merge query * join tree consists of range table references only, and range table references are * disregarded by the WhereClauseList() walker. + * Relevant PG17 commit: 0294df2f1 */ mergeJointree = makeFromExpr(NIL, mergeQuery->mergeJoinCondition); #else @@ -995,15 +996,17 @@ ConvertSourceRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte, /* - * ErrorIfMergeHasReturningList raises an exception if the MERGE - * has a RETURNING clause. + * ErrorIfMergeHasReturningList raises an exception if the MERGE has + * a RETURNING clause, as we don't support this yet for Citus tables + * Relevant PG17 commit: c649fa24a */ static void ErrorIfMergeHasReturningList(Query *query) { if (query->returningList) { - ereport(ERROR, (errmsg("MERGE with RETURNING is not yet supported"))); + ereport(ERROR, (errmsg("MERGE with RETURNING is not yet supported " + "for Citus tables"))); } } diff --git a/src/test/regress/expected/merge_unsupported.out b/src/test/regress/expected/merge_unsupported.out index 7cad6a150..669ae0be7 100644 --- a/src/test/regress/expected/merge_unsupported.out +++ b/src/test/regress/expected/merge_unsupported.out @@ -1,4 +1,15 @@ SHOW server_version \gset +SELECT CASE + WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+' + WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16' + WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14' + ELSE 'Unsupported version' + END AS version_category; + version_category +--------------------------------------------------------------------- + 17+ +(1 row) + SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 \gset \if :server_version_ge_15 @@ -13,26 +24,10 @@ NOTICE: schema "pgmerge_schema" does not exist, skipping CREATE SCHEMA pgmerge_schema; SET search_path TO pgmerge_schema; SET citus.use_citus_managed_tables to true; -DROP TABLE IF EXISTS target; -NOTICE: table "target" does not exist, skipping -DROP TABLE IF EXISTS source; -NOTICE: table "source" does not exist, skipping CREATE TABLE target (tid integer, balance integer) WITH (autovacuum_enabled=off); CREATE TABLE source (sid integer, delta integer) -- no index WITH (autovacuum_enabled=off); -SELECT citus_add_local_table_to_metadata('target'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - -SELECT citus_add_local_table_to_metadata('source'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - \set SHOW_CONTEXT errors -- used in a CTE WITH foo AS ( @@ -45,19 +40,19 @@ COPY ( MERGE INTO target USING source ON (true) WHEN MATCHED THEN DELETE ) TO stdout; -ERROR: MERGE not supported in COPY +ERROR: MERGE with Citus tables is not yet supported in COPY -- used in a CTE with RETURNING WITH foo AS ( MERGE INTO target USING source ON (true) WHEN MATCHED THEN DELETE RETURNING target.* ) SELECT * FROM foo; -ERROR: MERGE with RETURNING is not yet supported +ERROR: MERGE with RETURNING is not yet supported for Citus tables -- used in COPY with RETURNING COPY ( MERGE INTO target USING source ON (true) WHEN MATCHED THEN DELETE RETURNING target.* ) TO stdout; -ERROR: MERGE not supported in COPY +ERROR: MERGE with Citus tables is not yet supported in COPY -- unsupported relation types -- view CREATE VIEW tv AS SELECT count(tid) AS tid FROM target; @@ -102,5 +97,5 @@ WHEN NOT MATCHED THEN WHEN MATCHED AND tid < 2 THEN DELETE RETURNING *; -ERROR: MERGE with RETURNING is not yet supported +ERROR: MERGE with RETURNING is not yet supported for Citus tables ROLLBACK; diff --git a/src/test/regress/expected/merge_unsupported_0.out b/src/test/regress/expected/merge_unsupported_0.out index 8b26f4ae9..b788c1670 100644 --- a/src/test/regress/expected/merge_unsupported_0.out +++ b/src/test/regress/expected/merge_unsupported_0.out @@ -1,4 +1,15 @@ SHOW server_version \gset +SELECT CASE + WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+' + WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16' + WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14' + ELSE 'Unsupported version' + END AS version_category; + version_category +--------------------------------------------------------------------- + 15_16 +(1 row) + SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 \gset \if :server_version_ge_15 @@ -13,26 +24,10 @@ NOTICE: schema "pgmerge_schema" does not exist, skipping CREATE SCHEMA pgmerge_schema; SET search_path TO pgmerge_schema; SET citus.use_citus_managed_tables to true; -DROP TABLE IF EXISTS target; -NOTICE: table "target" does not exist, skipping -DROP TABLE IF EXISTS source; -NOTICE: table "source" does not exist, skipping CREATE TABLE target (tid integer, balance integer) WITH (autovacuum_enabled=off); CREATE TABLE source (sid integer, delta integer) -- no index WITH (autovacuum_enabled=off); -SELECT citus_add_local_table_to_metadata('target'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - -SELECT citus_add_local_table_to_metadata('source'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - \set SHOW_CONTEXT errors -- used in a CTE WITH foo AS ( diff --git a/src/test/regress/expected/merge_unsupported_1.out b/src/test/regress/expected/merge_unsupported_1.out index a7e3fbf20..187c5d630 100644 --- a/src/test/regress/expected/merge_unsupported_1.out +++ b/src/test/regress/expected/merge_unsupported_1.out @@ -1,4 +1,15 @@ SHOW server_version \gset +SELECT CASE + WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+' + WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16' + WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14' + ELSE 'Unsupported version' + END AS version_category; + version_category +--------------------------------------------------------------------- + 14 +(1 row) + SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 \gset \if :server_version_ge_15 diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 9f571e40a..d945a07d6 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -437,11 +437,6 @@ MERGE INTO tbl1 USING targq ON (true) WHEN MATCHED THEN DELETE; ERROR: The required join operation is missing between the target's distribution column and any expression originating from the source. The issue may arise from a non-equi-join. DETAIL: Without a equi-join condition on the target's distribution column, the source rows cannot be efficiently redistributed, and the NOT-MATCHED condition cannot be evaluated unambiguously. This can result in incorrect or unexpected results when attempting to merge tables in a distributed setting -COPY ( - MERGE INTO tbl1 USING tbl2 ON (true) - WHEN MATCHED THEN DELETE -) TO stdout; -ERROR: MERGE not supported in COPY MERGE INTO tbl1 t USING tbl2 ON (true) diff --git a/src/test/regress/expected/pgmerge.out b/src/test/regress/expected/pgmerge.out index 5d9588977..ea7cc42c5 100644 --- a/src/test/regress/expected/pgmerge.out +++ b/src/test/regress/expected/pgmerge.out @@ -167,7 +167,7 @@ COPY ( MERGE INTO target USING source ON (true) WHEN MATCHED THEN DELETE ) TO stdout; -ERROR: MERGE not supported in COPY +ERROR: MERGE with Citus tables is not yet supported in COPY -- unsupported relation types -- materialized view CREATE MATERIALIZED VIEW mv AS SELECT * FROM target; diff --git a/src/test/regress/sql/merge_unsupported.sql b/src/test/regress/sql/merge_unsupported.sql index 634ea8ba1..ef95e01ea 100644 --- a/src/test/regress/sql/merge_unsupported.sql +++ b/src/test/regress/sql/merge_unsupported.sql @@ -1,6 +1,12 @@ SHOW server_version \gset +SELECT CASE + WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+' + WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16' + WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14' + ELSE 'Unsupported version' + END AS version_category; SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 \gset \if :server_version_ge_15 @@ -17,17 +23,11 @@ SET search_path TO pgmerge_schema; SET citus.use_citus_managed_tables to true; -DROP TABLE IF EXISTS target; -DROP TABLE IF EXISTS source; CREATE TABLE target (tid integer, balance integer) WITH (autovacuum_enabled=off); CREATE TABLE source (sid integer, delta integer) -- no index WITH (autovacuum_enabled=off); -SELECT citus_add_local_table_to_metadata('target'); -SELECT citus_add_local_table_to_metadata('source'); - - \set SHOW_CONTEXT errors -- used in a CTE WITH foo AS ( diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 25ada1cc2..276092dcd 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -287,11 +287,6 @@ WITH targq AS ( MERGE INTO tbl1 USING targq ON (true) WHEN MATCHED THEN DELETE; -COPY ( - MERGE INTO tbl1 USING tbl2 ON (true) - WHEN MATCHED THEN DELETE -) TO stdout; - MERGE INTO tbl1 t USING tbl2 ON (true)