This is an automated email from the ASF dual-hosted git repository. huajianlan 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 c0b56400ed [feature](nereids)support one expression-rewrite rule: inPredicateToEqualTo (#12046) c0b56400ed is described below commit c0b56400edeca75c94ca32de60c8a20f87f4eaa5 Author: Fy <fuyu0...@pku.edu.cn> AuthorDate: Mon Aug 29 15:54:06 2022 +0800 [feature](nereids)support one expression-rewrite rule: inPredicateToEqualTo (#12046) Add one expression rewrite rule: rewrite InPredicate to an EqualTo Expression, if there exists exactly one element in InPredicate Options. Examples: 1. where A in (x) ==> where A = x 2. where A not in (x) ==> where not A = x --- .../rewrite/ExpressionNormalization.java | 2 + .../rewrite/rules/InPredicateToEqualToRule.java | 48 ++++++++++++++++++++++ .../nereids/trees/expressions/InPredicate.java | 6 +-- .../expression/rewrite/ExpressionRewriteTest.java | 23 +++++++++++ .../data/nereids_syntax_p0/inpredicate.out | 7 ++++ .../suites/nereids_syntax_p0/inpredicate.groovy | 8 ++++ 6 files changed, 91 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java index 33a1be951d..99087e3393 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java @@ -18,6 +18,7 @@ package org.apache.doris.nereids.rules.expression.rewrite; import org.apache.doris.nereids.rules.expression.rewrite.rules.BetweenToCompoundRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.InPredicateToEqualToRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeBinaryPredicatesRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyCastRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyNotExprRule; @@ -35,6 +36,7 @@ public class ExpressionNormalization extends ExpressionRewrite { public static final List<ExpressionRewriteRule> NORMALIZE_REWRITE_RULES = ImmutableList.of( NormalizeBinaryPredicatesRule.INSTANCE, BetweenToCompoundRule.INSTANCE, + InPredicateToEqualToRule.INSTANCE, SimplifyNotExprRule.INSTANCE, SimplifyCastRule.INSTANCE, TypeCoercion.INSTANCE diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/InPredicateToEqualToRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/InPredicateToEqualToRule.java new file mode 100644 index 0000000000..e21c4fe24d --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/InPredicateToEqualToRule.java @@ -0,0 +1,48 @@ +// 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.EqualTo; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.InPredicate; + +import java.util.List; + +/** + * Rewrite InPredicate to an EqualTo Expression, if there exists exactly one element in InPredicate.options + * Examples: + * where A in (x) ==> where A = x + * where A not in (x) ==> where not A = x (After ExpressionTranslator, "not A = x" will be translated to "A != x") + */ +public class InPredicateToEqualToRule extends AbstractExpressionRewriteRule { + + public static InPredicateToEqualToRule INSTANCE = new InPredicateToEqualToRule(); + + @Override + public Expression visitInPredicate(InPredicate inPredicate, ExpressionRewriteContext context) { + Expression left = inPredicate.getCompareExpr(); + List<Expression> right = inPredicate.getOptions(); + if (right.size() != 1) { + return new InPredicate(left.accept(this, context), right); + } + return new EqualTo(left.accept(this, context), right.get(0).accept(this, context)); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java index 8f6b5f14ab..432280b4f9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java @@ -39,10 +39,10 @@ public class InPredicate extends Expression { private final Expression compareExpr; private final List<Expression> options; - public InPredicate(Expression compareExpr, List<Expression> optionsList) { - super(new Builder<Expression>().add(compareExpr).addAll(optionsList).build().toArray(new Expression[0])); + public InPredicate(Expression compareExpr, List<Expression> options) { + super(new Builder<Expression>().add(compareExpr).addAll(options).build().toArray(new Expression[0])); this.compareExpr = Objects.requireNonNull(compareExpr, "Compare Expr cannot be null"); - this.options = ImmutableList.copyOf(Objects.requireNonNull(optionsList, "In list cannot be null")); + this.options = ImmutableList.copyOf(Objects.requireNonNull(options, "In list cannot be null")); } public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { 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 1f0196a34e..79e8903e3c 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 @@ -21,6 +21,7 @@ import org.apache.doris.nereids.parser.NereidsParser; import org.apache.doris.nereids.rules.expression.rewrite.rules.BetweenToCompoundRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.DistinctPredicatesRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.ExtractCommonFactorRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.InPredicateToEqualToRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeBinaryPredicatesRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyCastRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyNotExprRule; @@ -151,6 +152,28 @@ public class ExpressionRewriteTest { } + @Test + public void testInPredicateToEqualToRule() { + executor = new ExpressionRuleExecutor(ImmutableList.of(InPredicateToEqualToRule.INSTANCE)); + + assertRewrite("a in (1)", "a = 1"); + assertRewrite("a in (1, 2)", "a in (1, 2)"); + assertRewrite("a not in (1)", "not a = 1"); + assertRewrite("a not in (1, 2)", "not a in (1, 2)"); + assertRewrite("a in (a in (1))", "a = (a = 1)"); + assertRewrite("a in (a in (1, 2))", "a = (a in (1, 2))"); + assertRewrite("(a in (1)) in (1)", "(a = 1) = 1"); + assertRewrite("(a in (1, 2)) in (1)", "(a in (1, 2)) = 1"); + assertRewrite("(a in (1)) in (1, 2)", "(a = 1) in (1, 2)"); + assertRewrite("case a when b in (1) then a else c end in (1)", + "case a when b = 1 then a else c end = 1"); + assertRewrite("case a when b not in (1) then a else c end not in (1)", + "not case a when not b = 1 then a else c end = 1"); + assertRewrite("case a when b not in (1) then a else c end in (1, 2)", + "case a when not b = 1 then a else c end in (1, 2)"); + + } + @Test public void testSimplifyCastRule() { executor = new ExpressionRuleExecutor(ImmutableList.of(SimplifyCastRule.INSTANCE)); diff --git a/regression-test/data/nereids_syntax_p0/inpredicate.out b/regression-test/data/nereids_syntax_p0/inpredicate.out index b2bd323f6f..cee03178b5 100644 --- a/regression-test/data/nereids_syntax_p0/inpredicate.out +++ b/regression-test/data/nereids_syntax_p0/inpredicate.out @@ -24,3 +24,10 @@ 29 Supplier#000000029 VVSymB3fbwaN ARGENTINA4 ARGENTINA AMERICA 11-773-203-7342 9 Supplier#000000009 ,gJ6K2MKveYxQT IRAN 6 IRAN MIDDLE EAST 20-338-906-3675 +-- !in_predicate_9 -- +15 Supplier#000000015 DF35PepL5saAK INDIA 0 INDIA ASIA 18-687-542-7601 + +-- !in_predicate_10 -- +29 Supplier#000000029 VVSymB3fbwaN ARGENTINA4 ARGENTINA AMERICA 11-773-203-7342 +9 Supplier#000000009 ,gJ6K2MKveYxQT IRAN 6 IRAN MIDDLE EAST 20-338-906-3675 + diff --git a/regression-test/suites/nereids_syntax_p0/inpredicate.groovy b/regression-test/suites/nereids_syntax_p0/inpredicate.groovy index d17a2dc198..be6f405396 100644 --- a/regression-test/suites/nereids_syntax_p0/inpredicate.groovy +++ b/regression-test/suites/nereids_syntax_p0/inpredicate.groovy @@ -55,5 +55,13 @@ suite("inpredicate") { order_qt_in_predicate_8 """ SELECT * FROM supplier WHERE s_nation not in ('PERU', 'ETHIOPIA'); """ + + order_qt_in_predicate_9 """ + SELECT * FROM supplier WHERE s_suppkey in (15); + """ + + order_qt_in_predicate_10 """ + SELECT * FROM supplier WHERE s_suppkey not in (15); + """ } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org