aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/plan/setrefs.c10
-rw-r--r--src/test/regress/expected/update.out31
-rw-r--r--src/test/regress/sql/update.sql10
3 files changed, 47 insertions, 4 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 8a5ee01ab6d..1b6d5af5baf 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -2054,8 +2054,6 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
/* If not supplied by input plans, evaluate the contained expr */
return fix_join_expr_mutator((Node *) phv->phexpr, context);
}
- if (IsA(node, Param))
- return fix_param_node(context->root, (Param *) node);
/* Try matching more complex expressions too, if tlists have any */
if (context->outer_itlist && context->outer_itlist->has_non_vars)
{
@@ -2073,6 +2071,9 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
if (newvar)
return (Node *) newvar;
}
+ /* Special cases (apply only AFTER failing to match to lower tlist) */
+ if (IsA(node, Param))
+ return fix_param_node(context->root, (Param *) node);
fix_expr_common(context->root, node);
return expression_tree_mutator(node,
fix_join_expr_mutator,
@@ -2158,8 +2159,6 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
/* If not supplied by input plan, evaluate the contained expr */
return fix_upper_expr_mutator((Node *) phv->phexpr, context);
}
- if (IsA(node, Param))
- return fix_param_node(context->root, (Param *) node);
/* Try matching more complex expressions too, if tlist has any */
if (context->subplan_itlist->has_non_vars)
{
@@ -2169,6 +2168,9 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
if (newvar)
return (Node *) newvar;
}
+ /* Special cases (apply only AFTER failing to match to lower tlist) */
+ if (IsA(node, Param))
+ return fix_param_node(context->root, (Param *) node);
fix_expr_common(context->root, node);
return expression_tree_mutator(node,
fix_upper_expr_mutator,
diff --git a/src/test/regress/expected/update.out b/src/test/regress/expected/update.out
index 49730ea3c55..a7fb98b6c61 100644
--- a/src/test/regress/expected/update.out
+++ b/src/test/regress/expected/update.out
@@ -169,6 +169,37 @@ SELECT a, b, char_length(c) FROM update_test;
42 | 12 | 10000
(4 rows)
+-- Check multi-assignment with a Result node to handle a one-time filter.
+EXPLAIN (VERBOSE, COSTS OFF)
+UPDATE update_test t
+ SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a)
+ WHERE CURRENT_USER = SESSION_USER;
+ QUERY PLAN
+------------------------------------------------------------------
+ Update on public.update_test t
+ -> Result
+ Output: $1, $2, t.c, (SubPlan 1 (returns $1,$2)), t.ctid
+ One-Time Filter: ("current_user"() = "session_user"())
+ -> Seq Scan on public.update_test t
+ Output: t.c, t.a, t.ctid
+ SubPlan 1 (returns $1,$2)
+ -> Seq Scan on public.update_test s
+ Output: s.b, s.a
+ Filter: (s.a = t.a)
+(10 rows)
+
+UPDATE update_test t
+ SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a)
+ WHERE CURRENT_USER = SESSION_USER;
+SELECT a, b, char_length(c) FROM update_test;
+ a | b | char_length
+-----+----+-------------
+ 101 | 21 |
+ | |
+ 12 | 41 | 10000
+ 12 | 42 | 10000
+(4 rows)
+
-- Test ON CONFLICT DO UPDATE
INSERT INTO upsert_test VALUES(1, 'Boo');
-- uncorrelated sub-select:
diff --git a/src/test/regress/sql/update.sql b/src/test/regress/sql/update.sql
index e0cf5d12a92..adfe2da4dae 100644
--- a/src/test/regress/sql/update.sql
+++ b/src/test/regress/sql/update.sql
@@ -88,6 +88,16 @@ UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car';
SELECT a, b, char_length(c) FROM update_test;
+-- Check multi-assignment with a Result node to handle a one-time filter.
+EXPLAIN (VERBOSE, COSTS OFF)
+UPDATE update_test t
+ SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a)
+ WHERE CURRENT_USER = SESSION_USER;
+UPDATE update_test t
+ SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a)
+ WHERE CURRENT_USER = SESSION_USER;
+SELECT a, b, char_length(c) FROM update_test;
+
-- Test ON CONFLICT DO UPDATE
INSERT INTO upsert_test VALUES(1, 'Boo');
-- uncorrelated sub-select: