diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index 5142cde60..aa972659f 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -939,6 +939,13 @@ MultiShardModifyQuerySupported(Query *originalQuery, "ON instead", NULL, NULL); } + else if (FindNodeCheck((Node *) originalQuery, CitusIsVolatileFunction)) + { + errorMessage = DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED, + "functions used in UPDATE queries on distributed " + "tables must not be VOLATILE", + NULL, NULL); + } else if (resultPartitionMethod == DISTRIBUTE_BY_NONE) { errorMessage = DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED, diff --git a/src/test/regress/expected/multi_shard_update_delete.out b/src/test/regress/expected/multi_shard_update_delete.out index 0ef6cbf6b..ce597cafc 100644 --- a/src/test/regress/expected/multi_shard_update_delete.out +++ b/src/test/regress/expected/multi_shard_update_delete.out @@ -699,10 +699,26 @@ SET value_2 = 5 * random() FROM events_test_table WHERE users_test_table.user_id = events_test_table.user_id; ERROR: functions used in UPDATE queries on distributed tables must not be VOLATILE +-- Recursive modify planner does not take care of following test because the query +-- is fully pushdownable, yet not allowed because it would lead to inconsistent replicas. +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table) subquery +WHERE users_test_table.user_id = subquery.user_id; +ERROR: functions used in UPDATE queries on distributed tables must not be VOLATILE -- Volatile functions in a subquery are recursively planned UPDATE users_test_table SET value_2 = 5 WHERE users_test_table.user_id IN (SELECT user_id * random() FROM events_test_table); +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table) subquery; +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table OFFSET 0) subquery +WHERE users_test_table.user_id = subquery.user_id; +-- Make following tests consistent +UPDATE users_test_table SET value_2 = 0; -- Local tables are not supported UPDATE users_test_table SET value_2 = 5 @@ -738,7 +754,7 @@ DECLARE test_cursor CURSOR FOR SELECT * FROM users_test_table; FETCH test_cursor; user_id | value_1 | value_2 | value_3 ---------+---------+---------+--------- - 8 | 4 | 13 | 0 + 8 | 4 | 0 | 0 (1 row) UPDATE users_test_table SET value_2 = 5 WHERE CURRENT OF test_cursor; diff --git a/src/test/regress/expected/multi_shard_update_delete_0.out b/src/test/regress/expected/multi_shard_update_delete_0.out index 457c36f8a..3d340c29a 100644 --- a/src/test/regress/expected/multi_shard_update_delete_0.out +++ b/src/test/regress/expected/multi_shard_update_delete_0.out @@ -722,10 +722,26 @@ SET value_2 = 5 * random() FROM events_test_table WHERE users_test_table.user_id = events_test_table.user_id; ERROR: functions used in UPDATE queries on distributed tables must not be VOLATILE +-- Recursive modify planner does not take care of following test because the query +-- is fully pushdownable, yet not allowed because it would lead to inconsistent replicas. +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table) subquery +WHERE users_test_table.user_id = subquery.user_id; +ERROR: functions used in UPDATE queries on distributed tables must not be VOLATILE -- Volatile functions in a subquery are recursively planned UPDATE users_test_table SET value_2 = 5 WHERE users_test_table.user_id IN (SELECT user_id * random() FROM events_test_table); +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table) subquery; +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table OFFSET 0) subquery +WHERE users_test_table.user_id = subquery.user_id; +-- Make following tests consistent +UPDATE users_test_table SET value_2 = 0; -- Local tables are not supported UPDATE users_test_table SET value_2 = 5 @@ -761,7 +777,7 @@ DECLARE test_cursor CURSOR FOR SELECT * FROM users_test_table; FETCH test_cursor; user_id | value_1 | value_2 | value_3 ---------+---------+---------+--------- - 8 | 4 | 13 | 0 + 8 | 4 | 0 | 0 (1 row) UPDATE users_test_table SET value_2 = 5 WHERE CURRENT OF test_cursor; diff --git a/src/test/regress/sql/multi_shard_update_delete.sql b/src/test/regress/sql/multi_shard_update_delete.sql index 6f493a529..147db404c 100644 --- a/src/test/regress/sql/multi_shard_update_delete.sql +++ b/src/test/regress/sql/multi_shard_update_delete.sql @@ -580,11 +580,30 @@ SET value_2 = 5 * random() FROM events_test_table WHERE users_test_table.user_id = events_test_table.user_id; +-- Recursive modify planner does not take care of following test because the query +-- is fully pushdownable, yet not allowed because it would lead to inconsistent replicas. +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table) subquery +WHERE users_test_table.user_id = subquery.user_id; + -- Volatile functions in a subquery are recursively planned UPDATE users_test_table SET value_2 = 5 WHERE users_test_table.user_id IN (SELECT user_id * random() FROM events_test_table); +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table) subquery; + +UPDATE users_test_table +SET value_2 = subquery.random FROM (SELECT user_id, random() + FROM events_test_table OFFSET 0) subquery +WHERE users_test_table.user_id = subquery.user_id; + +-- Make following tests consistent +UPDATE users_test_table SET value_2 = 0; + -- Local tables are not supported UPDATE users_test_table SET value_2 = 5