values_to_any.diff.no-cfbot

text/plain

Filename: values_to_any.diff.no-cfbot
Type: text/plain
Part: 0
Message: Re: Replace IN VALUES with ANY in WHERE clauses during optimization
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