From fe7d25ef77c77e02b673771888c20f316c9ddc98 Mon Sep 17 00:00:00 2001 From: Mehmet Yilmaz Date: Mon, 20 Jan 2025 19:29:08 +0000 Subject: [PATCH] fix --- citus-tools | 1 + .../worker/worker_shard_visibility.c | 58 ++++++++++++------- src/test/regress/expected/pg17.out | 26 +++++++++ src/test/regress/sql/pg17.sql | 25 ++++++++ 4 files changed, 90 insertions(+), 20 deletions(-) create mode 160000 citus-tools diff --git a/citus-tools b/citus-tools new file mode 160000 index 000000000..3376bd684 --- /dev/null +++ b/citus-tools @@ -0,0 +1 @@ +Subproject commit 3376bd6845f0614908ed304f5033bd644c82d3bf diff --git a/src/backend/distributed/worker/worker_shard_visibility.c b/src/backend/distributed/worker/worker_shard_visibility.c index f783d514d..797092f7b 100644 --- a/src/backend/distributed/worker/worker_shard_visibility.c +++ b/src/backend/distributed/worker/worker_shard_visibility.c @@ -441,7 +441,7 @@ FilterShardsFromPgclass(Node *node, void *context) /* * We process the whole rtable rather than visiting individual RangeTblEntry's * in the walker, since we need to know the varno to generate the right - * fiter. + * filter. */ int varno = 0; RangeTblEntry *rangeTableEntry = NULL; @@ -471,29 +471,47 @@ FilterShardsFromPgclass(Node *node, void *context) /* make sure the expression is in the right memory context */ MemoryContext originalContext = MemoryContextSwitchTo(queryContext); + /* add relation_is_a_known_shard(oid) IS NOT TRUE to the quals of the query */ + Node *newQual = CreateRelationIsAKnownShardFilter(varno); - /* add relation_is_a_known_shard(oid) IS NOT TRUE to the quals of the query */ - Node *newQual = CreateRelationIsAKnownShardFilter(varno); - Node *oldQuals = query->jointree->quals; - if (oldQuals) - { - query->jointree->quals = (Node *) makeBoolExpr( - AND_EXPR, - list_make2(oldQuals, newQual), - -1); - } - else - { - query->jointree->quals = newQual; - } +#if PG_VERSION_NUM >= PG_VERSION_17 + /* + * In PG17, MERGE queries introduce a new struct `mergeJoinCondition`. + * We need to handle this condition safely. + */ + if (query->mergeJoinCondition != NULL) + { + /* Add the filter to mergeJoinCondition */ + query->mergeJoinCondition = (Node *) makeBoolExpr( + AND_EXPR, + list_make2(query->mergeJoinCondition, newQual), + -1); + } + else +#endif + { + /* Handle older versions or queries without mergeJoinCondition */ + Node *oldQuals = query->jointree->quals; + if (oldQuals) + { + query->jointree->quals = (Node *) makeBoolExpr( + AND_EXPR, + list_make2(oldQuals, newQual), + -1); + } + else + { + query->jointree->quals = newQual; + } + } - MemoryContextSwitchTo(originalContext); - } + MemoryContextSwitchTo(originalContext); + } - return query_tree_walker((Query *) node, FilterShardsFromPgclass, context, 0); - } + return query_tree_walker((Query *) node, FilterShardsFromPgclass, context, 0); + } - return expression_tree_walker(node, FilterShardsFromPgclass, context); + return expression_tree_walker(node, FilterShardsFromPgclass, context); } diff --git a/src/test/regress/expected/pg17.out b/src/test/regress/expected/pg17.out index 83507bb15..eb94a3a37 100644 --- a/src/test/regress/expected/pg17.out +++ b/src/test/regress/expected/pg17.out @@ -2690,6 +2690,32 @@ SELECT * FROM sensor_readings ORDER BY 1; (4 rows) -- End of MERGE ... WHEN NOT MATCHED BY SOURCE tests +-- Issue #7846 +-- Create a non-distributed table with a random suffix +CREATE TABLE non_dist_table_12345 (id INTEGER); +-- Test crash scenario on a non-distributed table +MERGE INTO non_dist_table_12345 AS target_0 +USING pg_catalog.pg_class AS ref_0 +ON target_0.id = ref_0.relpages +WHEN NOT MATCHED THEN DO NOTHING; +-- Create a distributed table with a random suffix +CREATE TABLE dist_table_67890 (id INTEGER); +SELECT create_distributed_table('dist_table_67890', 'id'); + create_distributed_table +-------------------------- + +(1 row) + +-- Test crash scenario on a distributed table +MERGE INTO dist_table_67890 AS target_0 +USING pg_catalog.pg_class AS ref_0 +ON target_0.id = ref_0.relpages +WHEN NOT MATCHED THEN DO NOTHING; +ERROR: MERGE INTO an distributed table from Postgres table is not yet supported +-- Cleanup +DROP TABLE IF EXISTS non_dist_table_12345; +DROP TABLE IF EXISTS dist_table_67890 CASCADE; +-- End of Issue #7846 \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 e4843db44..a71997773 100644 --- a/src/test/regress/sql/pg17.sql +++ b/src/test/regress/sql/pg17.sql @@ -1451,6 +1451,31 @@ SELECT * FROM sensor_readings ORDER BY 1; -- End of MERGE ... WHEN NOT MATCHED BY SOURCE tests +-- Issue #7846 +-- Create a non-distributed table with a random suffix +CREATE TABLE non_dist_table_12345 (id INTEGER); + +-- Test crash scenario on a non-distributed table +MERGE INTO non_dist_table_12345 AS target_0 +USING pg_catalog.pg_class AS ref_0 +ON target_0.id = ref_0.relpages +WHEN NOT MATCHED THEN DO NOTHING; + +-- Create a distributed table with a random suffix +CREATE TABLE dist_table_67890 (id INTEGER); +SELECT create_distributed_table('dist_table_67890', 'id'); + +-- Test crash scenario on a distributed table +MERGE INTO dist_table_67890 AS target_0 +USING pg_catalog.pg_class AS ref_0 +ON target_0.id = ref_0.relpages +WHEN NOT MATCHED THEN DO NOTHING; + +-- Cleanup +DROP TABLE IF EXISTS non_dist_table_12345; +DROP TABLE IF EXISTS dist_table_67890 CASCADE; +-- End of Issue #7846 + \set VERBOSITY terse SET client_min_messages TO WARNING; DROP SCHEMA pg17 CASCADE;