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 <373141...@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-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org