You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/07/08 02:07:11 UTC

[doris] branch master updated: [enhancement](nereids) add betweentocompound rewrite rule for ssb (#10630)

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

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c3a25bf14 [enhancement](nereids) add betweentocompound rewrite rule for ssb (#10630)
6c3a25bf14 is described below

commit 6c3a25bf143af994a5588e465614af8ff99ee31d
Author: yinzhijian <37...@qq.com>
AuthorDate: Fri Jul 8 10:07:04 2022 +0800

    [enhancement](nereids) add betweentocompound rewrite rule for ssb (#10630)
    
    add betweentocompound rewrite rule for ssb.
    for example:
    1. A BETWEEN X AND Y ==> A >= X AND A <= Y
    2. A NOT BETWEEN X AND Y ==> A < X OR A > Y
---
 .../apache/doris/nereids/jobs/AnalyzeRulesJob.java |  4 +-
 .../expression/rewrite/ExpressionRuleExecutor.java |  6 ++-
 .../rewrite/rules/BetweenToCompoundRule.java       | 44 ++++++++++++++++++++++
 ...ule.java => NormalizeBinaryPredicatesRule.java} |  4 +-
 .../rewrite/rules/SimplifyNotExprRule.java         | 18 +++++++++
 .../expression/rewrite/ExpressionRewriteTest.java  |  4 +-
 .../rewrite/logical/PushDownPredicateTest.java     | 10 ++++-
 7 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/AnalyzeRulesJob.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/AnalyzeRulesJob.java
index ed8bba9b0b..a80e76219f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/AnalyzeRulesJob.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/AnalyzeRulesJob.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.jobs;
 
 import org.apache.doris.nereids.PlannerContext;
+import org.apache.doris.nereids.rules.analysis.BindFunction;
 import org.apache.doris.nereids.rules.analysis.BindRelation;
 import org.apache.doris.nereids.rules.analysis.BindSlotReference;
 
@@ -37,7 +38,8 @@ public class AnalyzeRulesJob extends BatchRulesJob {
         rulesJob.addAll(ImmutableList.of(
                 bottomUpBatch(ImmutableList.of(
                         new BindRelation(),
-                        new BindSlotReference())
+                        new BindSlotReference(),
+                        new BindFunction())
                 )));
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRuleExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRuleExecutor.java
index 55c2ef0060..65b5a9bd5e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRuleExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRuleExecutor.java
@@ -17,7 +17,8 @@
 
 package org.apache.doris.nereids.rules.expression.rewrite;
 
-import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeExpressionRule;
+import org.apache.doris.nereids.rules.expression.rewrite.rules.BetweenToCompoundRule;
+import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeBinaryPredicatesRule;
 import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyNotExprRule;
 import org.apache.doris.nereids.trees.expressions.Expression;
 
@@ -32,8 +33,9 @@ import java.util.List;
 public class ExpressionRuleExecutor {
 
     public static final List<ExpressionRewriteRule> REWRITE_RULES = ImmutableList.of(
+        new BetweenToCompoundRule(),
         new SimplifyNotExprRule(),
-        new NormalizeExpressionRule()
+        new NormalizeBinaryPredicatesRule()
     );
 
     private final ExpressionRewriteContext ctx;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/BetweenToCompoundRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/BetweenToCompoundRule.java
new file mode 100644
index 0000000000..f728e24a47
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/BetweenToCompoundRule.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.rules.expression.rewrite.rules;
+
+import org.apache.doris.nereids.rules.expression.rewrite.AbstractExpressionRewriteRule;
+import org.apache.doris.nereids.rules.expression.rewrite.ExpressionRewriteContext;
+import org.apache.doris.nereids.trees.expressions.And;
+import org.apache.doris.nereids.trees.expressions.Between;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
+import org.apache.doris.nereids.trees.expressions.LessThanEqual;
+
+/**
+ * Rewrites BetweenPredicates into an equivalent conjunctive CompoundPredicate,
+ * "not between" is first processed by the BetweenToCompoundRule and then by the SimplifyNotExprRule.
+ * Examples:
+ * A BETWEEN X AND Y ==> A >= X AND A <= Y
+ */
+public class BetweenToCompoundRule extends AbstractExpressionRewriteRule {
+
+    public static BetweenToCompoundRule INSTANCE = new BetweenToCompoundRule();
+
+    @Override
+    public Expression visitBetween(Between expr, ExpressionRewriteContext context) {
+        Expression left = new GreaterThanEqual<>(expr.getCompareExpr(), expr.getLowerBound());
+        Expression right = new LessThanEqual<>(expr.getCompareExpr(), expr.getUpperBound());
+        return new And<>(left, right);
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/NormalizeExpressionRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/NormalizeBinaryPredicatesRule.java
similarity index 93%
rename from fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/NormalizeExpressionRule.java
rename to fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/NormalizeBinaryPredicatesRule.java
index 8da9c1e5f9..7021a7d19b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/NormalizeExpressionRule.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/NormalizeBinaryPredicatesRule.java
@@ -34,9 +34,9 @@ import org.apache.doris.nereids.trees.expressions.LessThanEqual;
  * For example:
  * 5 > id -> id < 5
  */
-public class NormalizeExpressionRule extends AbstractExpressionRewriteRule {
+public class NormalizeBinaryPredicatesRule extends AbstractExpressionRewriteRule {
 
-    public static NormalizeExpressionRule INSTANCE = new NormalizeExpressionRule();
+    public static NormalizeBinaryPredicatesRule INSTANCE = new NormalizeBinaryPredicatesRule();
 
     @Override
     public Expression visitComparisonPredicate(ComparisonPredicate expr, ExpressionRewriteContext context) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyNotExprRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyNotExprRule.java
index 4b7bb6fd1e..43aa3ecad3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyNotExprRule.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyNotExprRule.java
@@ -20,13 +20,16 @@ package org.apache.doris.nereids.rules.expression.rewrite.rules;
 import org.apache.doris.nereids.rules.expression.rewrite.AbstractExpressionRewriteRule;
 import org.apache.doris.nereids.rules.expression.rewrite.ExpressionRewriteContext;
 import org.apache.doris.nereids.trees.NodeType;
+import org.apache.doris.nereids.trees.expressions.And;
 import org.apache.doris.nereids.trees.expressions.ComparisonPredicate;
+import org.apache.doris.nereids.trees.expressions.CompoundPredicate;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.GreaterThan;
 import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
 import org.apache.doris.nereids.trees.expressions.LessThan;
 import org.apache.doris.nereids.trees.expressions.LessThanEqual;
 import org.apache.doris.nereids.trees.expressions.Not;
+import org.apache.doris.nereids.trees.expressions.Or;
 
 /**
  * Rewrite rule of NOT expression.
@@ -39,6 +42,8 @@ import org.apache.doris.nereids.trees.expressions.Not;
  * not a >= b -> a < b.
  * not a <= b -> a > b.
  * not a=b -> not a=b.
+ * not and(a >= b, a <= c) -> or(a < b, a > c)
+ * not or(a >= b, a <= c) -> and(a < b, a > c)
  */
 public class SimplifyNotExprRule extends AbstractExpressionRewriteRule {
 
@@ -66,6 +71,19 @@ public class SimplifyNotExprRule extends AbstractExpressionRewriteRule {
                 default:
                     return expr;
             }
+        } else if (child instanceof CompoundPredicate) {
+            CompoundPredicate cp = (CompoundPredicate) expr.child();
+            Expression left =  rewrite(new Not(cp.left()), context);
+            Expression right = rewrite(new Not(cp.right()), context);
+            NodeType type = cp.getType();
+            switch (type) {
+                case AND:
+                    return new Or<>(left, right);
+                case OR:
+                    return new And<>(left, right);
+                default:
+                    return expr;
+            }
         }
 
         if (child instanceof Not) {
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
index 5eef34a270..792e33cdeb 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
@@ -18,7 +18,7 @@
 package org.apache.doris.nereids.rules.expression.rewrite;
 
 import org.apache.doris.nereids.parser.NereidsParser;
-import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeExpressionRule;
+import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeBinaryPredicatesRule;
 import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyNotExprRule;
 import org.apache.doris.nereids.trees.expressions.Expression;
 
@@ -47,7 +47,7 @@ public class ExpressionRewriteTest {
 
     @Test
     public void testNormalizeExpressionRewrite() {
-        executor = new ExpressionRuleExecutor(NormalizeExpressionRule.INSTANCE);
+        executor = new ExpressionRuleExecutor(NormalizeBinaryPredicatesRule.INSTANCE);
 
         assertRewrite("2 > x", "x < 2");
         assertRewrite("2 >= x", "x <= 2");
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushDownPredicateTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushDownPredicateTest.java
index 015dcc8cc8..9f6a890179 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushDownPredicateTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushDownPredicateTest.java
@@ -35,10 +35,13 @@ import org.apache.doris.nereids.operators.plans.logical.LogicalProject;
 import org.apache.doris.nereids.properties.PhysicalProperties;
 import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.trees.expressions.Add;
+import org.apache.doris.nereids.trees.expressions.And;
 import org.apache.doris.nereids.trees.expressions.Between;
 import org.apache.doris.nereids.trees.expressions.EqualTo;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.GreaterThan;
+import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
+import org.apache.doris.nereids.trees.expressions.LessThanEqual;
 import org.apache.doris.nereids.trees.expressions.Literal;
 import org.apache.doris.nereids.trees.expressions.Subtract;
 import org.apache.doris.nereids.trees.plans.Plan;
@@ -215,6 +218,11 @@ public class PushDownPredicateTest implements Plans {
         Expression whereCondition2 = new EqualTo<>(rScore.getOutput().get(1), rCourse.getOutput().get(0));
         // student.age between 18 and 20
         Expression whereCondition3 = new Between<>(rStudent.getOutput().get(2), Literal.of(18), Literal.of(20));
+        // student.age >= 18 and student.age <= 20
+        Expression whereCondition3result = new And<>(
+                new GreaterThanEqual<>(rStudent.getOutput().get(2), Literal.of(18)),
+                new LessThanEqual<>(rStudent.getOutput().get(2), Literal.of(20)));
+
         // score.grade > 60
         Expression whereCondition4 = new GreaterThan<>(rScore.getOutput().get(2), Literal.of(60));
 
@@ -256,7 +264,7 @@ public class PushDownPredicateTest implements Plans {
 
         Assertions.assertEquals(((LogicalJoin) join2).getCondition().get(), whereCondition2);
         Assertions.assertEquals(((LogicalJoin) join3).getCondition().get(), whereCondition1);
-        Assertions.assertEquals(((LogicalFilter) op1).getPredicates(), whereCondition3);
+        Assertions.assertEquals(((LogicalFilter) op1).getPredicates().sql(), whereCondition3result.sql());
         Assertions.assertEquals(((LogicalFilter) op2).getPredicates(), whereCondition4);
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org