diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index 4a5df7826..a7d2c2b97 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -272,7 +272,7 @@ ErrorIfModifyQueryNotSupported(Query *queryTree) continue; } - if (!IsA(targetEntry->expr, Const)) + if (contain_mutable_functions((Node *) targetEntry->expr)) { hasNonConstTargetEntryExprs = true; } @@ -354,8 +354,8 @@ ErrorIfModifyQueryNotSupported(Query *queryTree) if (hasNonConstTargetEntryExprs || hasNonConstQualExprs) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot plan sharded modification containing values " - "which are not constants or constant expressions"))); + errmsg("functions used in modification queries on distributed " + "tables must be marked IMMUTABLE"))); } if (specifiesPartitionValue) diff --git a/src/test/regress/expected/multi_modifications.out b/src/test/regress/expected/multi_modifications.out index d1df70c83..7bfd65e3b 100644 --- a/src/test/regress/expected/multi_modifications.out +++ b/src/test/regress/expected/multi_modifications.out @@ -155,16 +155,16 @@ SET client_min_messages TO DEFAULT; -- commands with non-constant partition values are unsupported INSERT INTO limit_orders VALUES (random() * 100, 'ORCL', 152, '2011-08-25 11:50:45', 'sell', 0.58); -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- commands with expressions that cannot be collapsed are unsupported INSERT INTO limit_orders VALUES (2036, 'GOOG', 5634, now(), 'buy', random()); -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- commands with mutable functions in their quals DELETE FROM limit_orders WHERE id = 246 AND bidder_id = (random() * 1000); -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- commands with mutable but non-volatilte functions(ie: stable func.) in their quals DELETE FROM limit_orders WHERE id = 246 AND placed_at = current_timestamp; -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- commands with multiple rows are unsupported INSERT INTO limit_orders VALUES (DEFAULT), (DEFAULT); ERROR: cannot perform distributed planning for the given modification @@ -317,6 +317,27 @@ WITH deleted_orders AS (INSERT INTO limit_orders DEFAULT VALUES RETURNING *) UPDATE limit_orders SET symbol = 'GM'; ERROR: cannot perform distributed planning for the given modification DETAIL: Common table expressions are not supported in distributed modifications. +SELECT symbol, bidder_id FROM limit_orders WHERE id = 246; + symbol | bidder_id +--------+----------- + GM | 18 +(1 row) + +-- updates referencing just a var are supported +UPDATE limit_orders SET bidder_id = id WHERE id = 246; +-- updates referencing a column are supported +UPDATE limit_orders SET bidder_id = bidder_id + 1 WHERE id = 246; +-- IMMUTABLE functions are allowed +UPDATE limit_orders SET symbol = LOWER(symbol) WHERE id = 246; +SELECT symbol, bidder_id FROM limit_orders WHERE id = 246; + symbol | bidder_id +--------+----------- + gm | 247 +(1 row) + +-- updates referencing non-IMMUTABLE functions are unsupported +UPDATE limit_orders SET placed_at = now() WHERE id = 246; +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- cursors are not supported UPDATE limit_orders SET symbol = 'GM' WHERE CURRENT OF cursor_name; ERROR: distributed modifications must target exactly one shard diff --git a/src/test/regress/expected/multi_upsert.out b/src/test/regress/expected/multi_upsert.out index cc16748d0..12864f4e4 100644 --- a/src/test/regress/expected/multi_upsert.out +++ b/src/test/regress/expected/multi_upsert.out @@ -223,15 +223,15 @@ DETAIL: Subqueries are not supported in distributed modifications. -- non mutable function call in the SET INSERT INTO upsert_test (part_key, other_col) VALUES (1, 1) ON CONFLICT (part_key) DO UPDATE SET other_col = random()::int; -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- non mutable function call in the WHERE INSERT INTO upsert_test (part_key, other_col) VALUES (1, 1) ON CONFLICT (part_key) DO UPDATE SET other_col = 5 WHERE upsert_test.other_col = random()::int; -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- non mutable function call in the arbiter WHERE INSERT INTO upsert_test (part_key, other_col) VALUES (1, 1) ON CONFLICT (part_key) WHERE part_key = random()::int DO UPDATE SET other_col = 5; -ERROR: cannot plan sharded modification containing values which are not constants or constant expressions +ERROR: functions used in modification queries on distributed tables must be marked IMMUTABLE -- error out on attempt to update the partition key INSERT INTO upsert_test (part_key, other_col) VALUES (1, 1) ON CONFLICT (part_key) DO UPDATE SET part_key = 15; diff --git a/src/test/regress/sql/multi_modifications.sql b/src/test/regress/sql/multi_modifications.sql index a619fdf28..69444d372 100644 --- a/src/test/regress/sql/multi_modifications.sql +++ b/src/test/regress/sql/multi_modifications.sql @@ -235,5 +235,21 @@ UPDATE limit_orders SET symbol = 'GM' WHERE id = 246 RETURNING *; WITH deleted_orders AS (INSERT INTO limit_orders DEFAULT VALUES RETURNING *) UPDATE limit_orders SET symbol = 'GM'; +SELECT symbol, bidder_id FROM limit_orders WHERE id = 246; + +-- updates referencing just a var are supported +UPDATE limit_orders SET bidder_id = id WHERE id = 246; + +-- updates referencing a column are supported +UPDATE limit_orders SET bidder_id = bidder_id + 1 WHERE id = 246; + +-- IMMUTABLE functions are allowed +UPDATE limit_orders SET symbol = LOWER(symbol) WHERE id = 246; + +SELECT symbol, bidder_id FROM limit_orders WHERE id = 246; + +-- updates referencing non-IMMUTABLE functions are unsupported +UPDATE limit_orders SET placed_at = now() WHERE id = 246; + -- cursors are not supported UPDATE limit_orders SET symbol = 'GM' WHERE CURRENT OF cursor_name;