[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
This commit is contained in:
@ -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
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
"""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user