Hi,

While debugging the pull-up sublink codes, I noticed the
convert_VALUES_to_ANY().
The function is to convert "where colX in VALUES(xxx)" into SAOP. It
firstly scans the values_list to
make sure no volatile function is in this list, then it scans this
values_list again to check that it
only includes Const items.

We can merge the two scans into one. This can reduce the time complexity
from 2O(n) to O(n).

Also, add a brace for better/more consistent style in the attached patch.

-- 
Thanks,
Tender Wang
From 0eeb7487ba5bdacd260987514cd0a77eb8c88eaa Mon Sep 17 00:00:00 2001
From: Tender Wang <tndrw...@gmail.com>
Date: Sun, 27 Jul 2025 15:26:20 +0800
Subject: [PATCH] A little cosmetic to convert_VALUES_to_ANY().

In original logic, we have to do two passes iteration over the
values_lists. One is to check if have volatile functions, the other
one is to check if have no Const. We can merge above two iterations into
one. Also add a brace for better/more consistent style.
---
 src/backend/optimizer/plan/subselect.c    | 9 ++++++---
 src/backend/optimizer/prep/prepjointree.c | 4 ++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/backend/optimizer/plan/subselect.c 
b/src/backend/optimizer/plan/subselect.c
index d71ed958e31..7a275f430f2 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -1255,11 +1255,10 @@ convert_VALUES_to_ANY(PlannerInfo *root, Node 
*testexpr, Query *values)
 
        /*
         * Also, check that only RTE corresponds to VALUES; the list of values 
has
-        * at least two items and no volatile functions.
+        * at least two items.
         */
        if (rte->rtekind != RTE_VALUES ||
-               list_length(rte->values_lists) < 2 ||
-               contain_volatile_functions((Node *) rte->values_lists))
+               list_length(rte->values_lists) < 2)
                return NULL;
 
        foreach(lc, rte->values_lists)
@@ -1267,6 +1266,10 @@ convert_VALUES_to_ANY(PlannerInfo *root, Node *testexpr, 
Query *values)
                List       *elem = lfirst(lc);
                Node       *value = linitial(elem);
 
+               /* Must have no volatile functions */
+               if (contain_volatile_functions(value))
+                       return NULL;
+
                /*
                 * Prepare an evaluation of the right side of the operator with
                 * substitution of the given value.
diff --git a/src/backend/optimizer/prep/prepjointree.c 
b/src/backend/optimizer/prep/prepjointree.c
index 35e8d3c183b..d9908d16d79 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -848,13 +848,13 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node 
*node,
                        if ((saop = convert_VALUES_to_ANY(root,
                                                                                
          sublink->testexpr,
                                                                                
          (Query *) sublink->subselect)) != NULL)
-
+                       {
                                /*
                                 * The VALUES sequence was simplified.  Nothing 
more to do
                                 * here.
                                 */
                                return (Node *) saop;
-
+                       }
                        if ((j = convert_ANY_sublink_to_join(root, sublink,
                                                                                
                 available_rels1)) != NULL)
                        {
-- 
2.34.1

Reply via email to