Marginal improvement in sublink planning: allow unknownEqFalse optimization
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Aug 2008 19:58:24 +0000 (19:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Aug 2008 19:58:24 +0000 (19:58 +0000)
to be used for SubLinks that are underneath a top-level OR clause.  Just as at
the very top level of WHERE, it's not necessary to be accurate about whether
the sublink returns FALSE or NULL, because either result has the same impact
on whether the WHERE will succeed.

src/backend/optimizer/plan/subselect.c

index 441dd55045c7dec76667c43d224731bc78a47296..04ccd62f1b336924d740264c6ca6d7bc6fe9df9c 100644 (file)
@@ -1148,10 +1148,14 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
         * take steps to preserve AND/OR flatness of a qual.  We assume the input
         * has been AND/OR flattened and so we need no recursion here.
         *
-        * If we recurse down through anything other than an AND node, we are
-        * definitely not at top qual level anymore.  (Due to the coding here, we
-        * will not get called on the List subnodes of an AND, so no check is
-        * needed for List.)
+        * (Due to the coding here, we will not get called on the List subnodes of
+        * an AND; and the input is *not* yet in implicit-AND format.  So no check
+        * is needed for a bare List.)
+        *
+        * Anywhere within the top-level AND/OR clause structure, we can tell
+        * make_subplan() that NULL and FALSE are interchangeable.  So isTopQual
+        * propagates down in both cases.  (Note that this is unlike the meaning
+        * of "top level qual" used in most other places in Postgres.)
         */
        if (and_clause(node))
        {
@@ -1174,14 +1178,14 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
                return (Node *) make_andclause(newargs);
        }
 
-       /* otherwise not at qual top-level */
-       locContext.isTopQual = false;
-
        if (or_clause(node))
        {
                List       *newargs = NIL;
                ListCell   *l;
 
+               /* Still at qual top-level */
+               locContext.isTopQual = context->isTopQual;
+
                foreach(l, ((BoolExpr *) node)->args)
                {
                        Node       *newarg;
@@ -1195,6 +1199,12 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
                return (Node *) make_orclause(newargs);
        }
 
+       /*
+        * If we recurse down through anything other than an AND or OR node,
+        * we are definitely not at top qual level anymore.
+        */
+       locContext.isTopQual = false;
+
        return expression_tree_mutator(node,
                                                                   process_sublinks_mutator,
                                                                   (void *) &locContext);