values_to_any.diff.no-cfbot
text/plain
Filename: values_to_any.diff.no-cfbot
Type: text/plain
Part: 0
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index e0d1899c29b..2bf883a818f 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -1214,6 +1214,29 @@ inline_cte_walker(Node *node, inline_cte_walker_context *context)
return expression_tree_walker(node, inline_cte_walker, context);
}
+/*
+ * The function traverses the tree looking for elements of type var.
+ * If it finds it, it returns true.
+ */
+static bool
+values_simplicity_check_walker(Node *node, void *ctx)
+{
+ if (node == NULL)
+ {
+ return false;
+ }
+ else if(IsA(node, Var))
+ return true;
+ else if(IsA(node, Query))
+ return query_tree_walker((Query *) node,
+ values_simplicity_check_walker,
+ (void*) ctx,
+ QTW_EXAMINE_RTES_BEFORE);
+
+ return expression_tree_walker(node, values_simplicity_check_walker,
+ (void *) ctx);
+}
+
/*
* Attempt to transform 'testexpr' over the VALUES subquery into
* a ScalarArrayOpExpr.
@@ -1258,7 +1281,10 @@ convert_VALUES_to_ANY(PlannerInfo *root, Node *testexpr, Query *values)
*/
if (rte->rtekind != RTE_VALUES ||
list_length(rte->values_lists) < 2 ||
- contain_volatile_functions((Node *) rte->values_lists))
+ contain_volatile_functions((Node *) rte->values_lists) ||
+ expression_tree_walker((Node *) (rte->values_lists),
+ values_simplicity_check_walker,
+ NULL))
return NULL;
foreach(lc, rte->values_lists)
@@ -1279,7 +1305,9 @@ convert_VALUES_to_ANY(PlannerInfo *root, Node *testexpr, Query *values)
value = eval_const_expressions(root, value);
if (!IsA(value, Const))
- return NULL;
+ {
+ haveNonConst = true;
+ }
exprs = lappend(exprs, value);
}
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index c6867720a69..bff1582d388 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -3027,18 +3027,15 @@ EXPLAIN (COSTS OFF)
SELECT ten FROM onek t WHERE unique1 IN (VALUES (0), ((2 IN
(SELECT (3)))::integer)
);
- QUERY PLAN
-----------------------------------------------------
- Nested Loop
- -> Unique
- -> Sort
- Sort Key: "*VALUES*".column1
- -> Values Scan on "*VALUES*"
- SubPlan 1
- -> Result
- -> Index Scan using onek_unique1 on onek t
- Index Cond: (unique1 = "*VALUES*".column1)
-(9 rows)
+ QUERY PLAN
+------------------------------------------------------------------------------------------------
+ Bitmap Heap Scan on onek t
+ Recheck Cond: (unique1 = ANY (ARRAY[0, ((ANY (2 = (hashed SubPlan 1).col1)))::integer]))
+ -> Bitmap Index Scan on onek_unique1
+ Index Cond: (unique1 = ANY (ARRAY[0, ((ANY (2 = (hashed SubPlan 1).col1)))::integer]))
+ SubPlan 1
+ -> Result
+(6 rows)
-- Alow to transformation and hold conversion between types of colemns and
-- declared type of column pointed in RTE