This is an automated email from the ASF dual-hosted git repository.

maxyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit d992c8e3f7faad5d886c5ac1bf95b685e97bd84b
Author: xuejing zhao <[email protected]>
AuthorDate: Tue Mar 29 11:15:02 2022 +0800

    resolve pull_up_sublinks fixme (#13317)
    
    PostgreSQL only processes EXISTS_SUBLINK in not clause, does not process 
ANY_SUBLINK | ALL_SUBLINK, and notclause in not-clause.
    
    the second param of canonicalize_qual in pull_up_sublinks_qual_recurse is 
false because expr must not be a check constraint.
    
    before commit 220e45b in gpdb5
    we optimize ANY_SUBLINK or ALL_SUBLINK in not clause in that case:
    NOT val op ANY (subq) => val op' ALL (subq)
    NOT val op ALL (subq) => val op' ANY (subq)
    
    after commit 220e45b (11 years ago): Improve the planner's simplification 
of NOT constructs.
    
    we optimize ANY_SUBLINK or ALL_SUBLINK in not clause in that case:
    NOT val op ANY (subq) =>val NOT op ALL (subq)
    NOT val op ALL  (subq) =>val NOT op ANY (subq)
    
    then in 
preprocess_expression-->eval_const_expressions-->eval_const_expressions_mutator
    we call negate_clause to optimize val NOT op to val op'.
    here we use negate_clause instead make_notclause for ANY_SUBLINK or 
ALL_SUBLINK in not clause to simply expr in advance.
    
    the test case in notin.sql can cover this pr, so here do not add new cases.
    
    explain select c2 from t2 where not c2 < all (select c2 from t2);
    explain select c3 from t3 where not c3 <> any (select c4 from t4);
---
 src/backend/optimizer/prep/prepjointree.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/backend/optimizer/prep/prepjointree.c 
b/src/backend/optimizer/prep/prepjointree.c
index a41a940982..b4ed3c570d 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -594,14 +594,14 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node 
*node,
                        SubLink    *sublink = (SubLink *) arg;
                        if (sublink->subLinkType == EXISTS_SUBLINK)
                        {
-                Node      *boolConst;
+                               Node       *boolConst;
 
-                /*
-                 * Check if the EXISTS sublink doesn't actually need to be 
executed at all,
-                 * and return TRUE/FALSE directly for it in that case.
-                 */
-                if ((boolConst = remove_useless_EXISTS_sublink(root, (Query 
*)sublink->subselect, true)) != NULL)
-                    return boolConst;
+                               /*
+                                * Check if the EXISTS sublink doesn't actually 
need to be executed at all,
+                                * and return TRUE/FALSE directly for it in 
that case.
+                                */
+                               if ((boolConst = 
remove_useless_EXISTS_sublink(root, (Query *)sublink->subselect, true)) != NULL)
+                                       return boolConst;
 
                                if ((j = convert_EXISTS_sublink_to_join(root, 
sublink, true,
                                                                                
                                available_rels1)) != NULL)
@@ -666,14 +666,17 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node 
*node,
                         *               val NOT IN (subq)               =>  
val <> ALL (subq)
                         *               NOT val op ANY (subq)   =>  val op' 
ALL (subq)
                         *               NOT val op ALL (subq)   =>  val op' 
ANY (subq)
+                        *
+                        *   postgresql do not process ANY_SUBLINK or 
ALL_SUBLINK expr in not clause,
+                        *   this is an enhanced optimization by GPDB.
+                        *   we can use negate_clause instead of make_notclause 
to simplify the expr.
+                        *   the is_check param for canonicalize_qual is false,
+                        *   because expr is a qual not check constraint here.
                         */
                        else if (sublink->subLinkType == ANY_SUBLINK || 
sublink->subLinkType == ALL_SUBLINK)
                        {
                                sublink->subLinkType = (sublink->subLinkType == 
ANY_SUBLINK) ? ALL_SUBLINK : ANY_SUBLINK;
-                               /* GPDB_12_MERGE_FIXME: Is 'is_check=false' 
correct here? And in fact,
-                                * is this transformation correct at all? If it 
is, why doesn't upstream do it?
-                                */
-                               sublink->testexpr = (Node *) 
canonicalize_qual(make_notclause((Expr *) sublink->testexpr), false);
+                               sublink->testexpr = (Node *) 
canonicalize_qual((Expr*)negate_clause(sublink->testexpr), false);
                                return pull_up_sublinks_qual_recurse(root, 
(Node *) sublink,
                                                                                
                                jtlink1, available_rels1,
                                                                                
                                jtlink2, available_rels2);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to