diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 08c4648f936..7c1b2f4cfe6 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -1215,8 +1215,8 @@ inline_cte_walker(Node *node, inline_cte_walker_context *context) } /* - * The function traverses the tree looking for elements of type var. - * If it finds it, it returns true. + * The function traverses the tree looking for subqueries particularly + * elements of type RangeTblEntry. If it finds it, it returns true. */ static bool values_simplicity_check_walker(Node *node, void *ctx) @@ -1225,7 +1225,7 @@ values_simplicity_check_walker(Node *node, void *ctx) { return false; } - else if(IsA(node, Var)) + else if(IsA(node, RangeTblEntry)) return true; else if(IsA(node, Query)) return query_tree_walker((Query *) node, @@ -1302,6 +1302,22 @@ convert_VALUES_to_ANY(Query *query, Node *testexpr) List *elem = lfirst(lc); Node *value = linitial(elem); + if(IsA(value, Var)) + { + /* + * We don't risk optimizing if the var is volatile, either. + */ + if(contain_volatile_functions(value)) + return NULL; + + /* + * Upper-level vars will now be one level closer to their + * parent than before; in particular, anything that had been level 1 + * becomes level zero. + */ + IncrementVarSublevelsUp(value, -1, 1); + } + value = eval_const_expressions(NULL, value); if (!IsA(value, Const)) diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 5138a00349c..63e0114f177 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -3095,3 +3095,14 @@ SELECT ten FROM onek t WHERE 1.0 IN (VALUES (1), (3)); -> Values Scan on "*VALUES*" (5 rows) +EXPLAIN (COSTS OFF) +SELECT * FROM onek t1, lateral (SELECT * FROM onek t2 WHERE t2.ten IN (values (t1.ten), (1))); + QUERY PLAN +-------------------------------------------------- + Nested Loop + Join Filter: (t2.ten = ANY (ARRAY[t1.ten, 1])) + -> Seq Scan on onek t1 + -> Materialize + -> Seq Scan on onek t2 +(5 rows) + diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index 480f8d7b852..088619f0ffc 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -1357,3 +1357,6 @@ SELECT ten FROM onek t WHERE 1.0 IN ((VALUES (1), (3))::integer); EXPLAIN (COSTS OFF) SELECT ten FROM onek t WHERE 1.0 IN (VALUES (1), (3)); + +EXPLAIN (COSTS OFF) +SELECT * FROM onek t1, lateral (SELECT * FROM onek t2 WHERE t2.ten IN (values (t1.ten), (1)));