From c15e049947bd0d17ae131f8b2d09b25a1ff573b7 Mon Sep 17 00:00:00 2001 From: yujun Date: Wed, 19 Feb 2025 18:46:11 +0800 Subject: [PATCH 01/10] revert #23421: add between predicate back --- .../glue/translator/ExpressionTranslator.java | 6 + .../nereids/parser/LogicalPlanBuilder.java | 8 +- .../rules/analysis/ExpressionAnalyzer.java | 9 ++ .../expression/ExpressionNormalization.java | 2 + .../rules/expression/ExpressionRuleType.java | 1 + .../expression/rules/BetweenToCompound.java | 58 ++++++++ .../rules/FoldConstantRuleOnBE.java | 4 +- .../nereids/trees/expressions/Between.java | 124 ++++++++++++++++++ .../visitor/ExpressionVisitor.java | 5 + .../doris/nereids/util/TypeCoercionUtils.java | 28 ++++ .../expression/ExpressionRewriteTest.java | 20 ++- .../rules/expression/SimplifyRangeTest.java | 8 +- .../expressions/ExpressionEqualsTest.java | 8 ++ .../expressions/ExpressionParserTest.java | 7 +- 14 files changed, 277 insertions(+), 11 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Between.java diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java index 166892f48a9db6..c0ba8c41a2990e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java @@ -52,6 +52,7 @@ import org.apache.doris.nereids.trees.expressions.And; import org.apache.doris.nereids.trees.expressions.ArrayItemReference; import org.apache.doris.nereids.trees.expressions.AssertNumRowsElement; +import org.apache.doris.nereids.trees.expressions.Between; import org.apache.doris.nereids.trees.expressions.BinaryArithmetic; import org.apache.doris.nereids.trees.expressions.CaseWhen; import org.apache.doris.nereids.trees.expressions.Cast; @@ -383,6 +384,11 @@ private Expr toBalancedTree(int low, int high, List children, return results.pop(); } + @Override + public Expr visitBetween(Between between, PlanTranslatorContext context) { + throw new RuntimeException("Unexpected invocation"); + } + @Override public Expr visitAnd(And and, PlanTranslatorContext context) { List children = and.children().stream().map( diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java index a0187112c96113..12dca848ac415f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java @@ -416,6 +416,7 @@ import org.apache.doris.nereids.trees.expressions.Add; import org.apache.doris.nereids.trees.expressions.Alias; import org.apache.doris.nereids.trees.expressions.And; +import org.apache.doris.nereids.trees.expressions.Between; import org.apache.doris.nereids.trees.expressions.BitAnd; import org.apache.doris.nereids.trees.expressions.BitNot; import org.apache.doris.nereids.trees.expressions.BitOr; @@ -3846,9 +3847,10 @@ private Expression withPredicate(Expression valueExpression, PredicateContext ct if (lower.equals(upper)) { outExpression = new EqualTo(valueExpression, lower); } else { - outExpression = new And( - new GreaterThanEqual(valueExpression, getExpression(ctx.lower)), - new LessThanEqual(valueExpression, getExpression(ctx.upper)) + outExpression = new Between( + valueExpression, + getExpression(ctx.lower), + getExpression(ctx.upper) ); } break; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java index d7f0f637250103..292a4fd29f4420 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java @@ -42,6 +42,7 @@ import org.apache.doris.nereids.trees.expressions.Alias; import org.apache.doris.nereids.trees.expressions.And; import org.apache.doris.nereids.trees.expressions.ArrayItemReference; +import org.apache.doris.nereids.trees.expressions.Between; import org.apache.doris.nereids.trees.expressions.BinaryArithmetic; import org.apache.doris.nereids.trees.expressions.BitNot; import org.apache.doris.nereids.trees.expressions.BoundStar; @@ -679,6 +680,14 @@ public Expression visitInPredicate(InPredicate inPredicate, ExpressionRewriteCon return TypeCoercionUtils.processInPredicate(newInPredicate); } + @Override + public Expression visitBetween(Between between, ExpressionRewriteContext context) { + List rewrittenChildren = between.children().stream() + .map(e -> e.accept(this, context)).collect(Collectors.toList()); + Between newBetween = between.withChildren(rewrittenChildren); + return TypeCoercionUtils.processBetween(newBetween); + } + @Override public Expression visitInSubquery(InSubquery inSubquery, ExpressionRewriteContext context) { // analyze subquery diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionNormalization.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionNormalization.java index 135f80111e980c..a70e4a205ed03c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionNormalization.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionNormalization.java @@ -18,6 +18,7 @@ package org.apache.doris.nereids.rules.expression; import org.apache.doris.nereids.rules.expression.check.CheckCast; +import org.apache.doris.nereids.rules.expression.rules.BetweenToCompound; import org.apache.doris.nereids.rules.expression.rules.ConvertAggStateCast; import org.apache.doris.nereids.rules.expression.rules.DigitalMaskingConvert; import org.apache.doris.nereids.rules.expression.rules.FoldConstantRule; @@ -47,6 +48,7 @@ public class ExpressionNormalization extends ExpressionRewrite { bottomUp( SupportJavaDateFormatter.INSTANCE, NormalizeBinaryPredicatesRule.INSTANCE, + BetweenToCompound.INSTANCE, InPredicateDedup.INSTANCE, InPredicateExtractNonConstant.INSTANCE, InPredicateToEqualToRule.INSTANCE, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java index baa5ebfe078da4..8002126d8b2de7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java @@ -23,6 +23,7 @@ public enum ExpressionRuleType { ADD_MIN_MAX, ARRAY_CONTAIN_TO_ARRAY_OVERLAP, + BETWEEN_TO_COMPOUND, BETWEEN_TO_EQUAL, CASE_WHEN_TO_IF, CHECK_CAST, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java new file mode 100644 index 00000000000000..be50e7363e20f8 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java @@ -0,0 +1,58 @@ +// 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.rules; + +import org.apache.doris.nereids.rules.expression.ExpressionPatternMatcher; +import org.apache.doris.nereids.rules.expression.ExpressionPatternRuleFactory; +import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext; +import org.apache.doris.nereids.rules.expression.ExpressionRuleType; +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; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * 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 BetweenToCompound implements ExpressionPatternRuleFactory { + + public static BetweenToCompound INSTANCE = new BetweenToCompound(); + + @Override + public List> buildRules() { + return ImmutableList.of( + matchesTopType(Between.class) + .thenApply(ctx -> rewrite(ctx.expr, ctx.rewriteContext)) + .toRule(ExpressionRuleType.BETWEEN_TO_COMPOUND) + ); + } + + public Expression rewrite(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/rules/FoldConstantRuleOnBE.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java index 90b044e2b81be7..483bec20a98bf9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java @@ -34,6 +34,7 @@ import org.apache.doris.nereids.rules.expression.ExpressionRuleType; import org.apache.doris.nereids.trees.expressions.Alias; import org.apache.doris.nereids.trees.expressions.ArrayItemReference; +import org.apache.doris.nereids.trees.expressions.Between; import org.apache.doris.nereids.trees.expressions.Cast; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Match; @@ -193,7 +194,8 @@ private static Expression replace( private static void collectConst(Expression expr, Map constMap, Map tExprMap, IdGenerator idGenerator) { - if (expr.isConstant() && !expr.isLiteral() && !expr.anyMatch(e -> shouldSkipFold((Expression) e))) { + if (expr.isConstant() && !expr.isLiteral() && !(expr instanceof Between) + && !expr.anyMatch(e -> shouldSkipFold((Expression) e))) { String id = idGenerator.getNextId().toString(); constMap.put(id, expr); Expr staleExpr; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Between.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Between.java new file mode 100644 index 00000000000000..0a16715872ade4 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Between.java @@ -0,0 +1,124 @@ +// 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.trees.expressions; + +import org.apache.doris.nereids.exceptions.UnboundException; +import org.apache.doris.nereids.trees.expressions.shape.TernaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.BooleanType; +import org.apache.doris.nereids.types.DataType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; +import java.util.Objects; + +/** + * Between predicate expression. + */ +public class Between extends Expression implements TernaryExpression { + + private final Expression compareExpr; + private final Expression lowerBound; + private final Expression upperBound; + /** + * Constructor of ComparisonPredicate. + * + * @param compareExpr compare of expression + * @param lowerBound left child of between predicate + * @param upperBound right child of between predicate + */ + + public Between(Expression compareExpr, Expression lowerBound, + Expression upperBound) { + super(ImmutableList.of(compareExpr, lowerBound, upperBound)); + this.compareExpr = compareExpr; + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } + + public Between(List children) { + super(children); + this.compareExpr = children.get(0); + this.lowerBound = children.get(1); + this.upperBound = children.get(2); + } + + @Override + public DataType getDataType() throws UnboundException { + return BooleanType.INSTANCE; + } + + @Override + public boolean nullable() throws UnboundException { + return lowerBound.nullable() || upperBound.nullable(); + } + + @Override + public String computeToSql() { + return compareExpr.toSql() + " BETWEEN " + lowerBound.toSql() + " AND " + upperBound.toSql(); + } + + @Override + public String toString() { + return compareExpr + " BETWEEN " + lowerBound + " AND " + upperBound; + } + + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitBetween(this, context); + } + + public Expression getCompareExpr() { + return compareExpr; + } + + public Expression getLowerBound() { + return lowerBound; + } + + public Expression getUpperBound() { + return upperBound; + } + + @Override + public Between withChildren(List children) { + Preconditions.checkArgument(children.size() == 3); + return new Between(children); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Between that = (Between) o; + return Objects.equals(compareExpr, that.compareExpr) + && Objects.equals(lowerBound, that.lowerBound) + && Objects.equals(upperBound, that.upperBound) + && Objects.equals(children, that.children); + } + + @Override + public int hashCode() { + return Objects.hash(compareExpr, lowerBound, upperBound); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java index 406d0835610a17..47200bd4dc77e1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java @@ -28,6 +28,7 @@ import org.apache.doris.nereids.trees.expressions.And; import org.apache.doris.nereids.trees.expressions.Any; import org.apache.doris.nereids.trees.expressions.ArrayItemReference; +import org.apache.doris.nereids.trees.expressions.Between; import org.apache.doris.nereids.trees.expressions.BinaryArithmetic; import org.apache.doris.nereids.trees.expressions.BinaryOperator; import org.apache.doris.nereids.trees.expressions.BitAnd; @@ -333,6 +334,10 @@ public R visitStructLiteral(StructLiteral structLiteral, C context) { return visitLiteral(structLiteral, context); } + public R visitBetween(Between between, C context) { + return visit(between, context); + } + public R visitCompoundPredicate(CompoundPredicate compoundPredicate, C context) { return visit(compoundPredicate, context); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index 5f8be613552c78..3be2644226d9e8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -25,6 +25,7 @@ import org.apache.doris.nereids.annotation.Developing; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.expressions.Add; +import org.apache.doris.nereids.trees.expressions.Between; import org.apache.doris.nereids.trees.expressions.BinaryArithmetic; import org.apache.doris.nereids.trees.expressions.BinaryOperator; import org.apache.doris.nereids.trees.expressions.BitAnd; @@ -1208,6 +1209,33 @@ public static Expression processCaseWhen(CaseWhen caseWhen) { .orElseThrow(() -> new AnalysisException("Cannot find common type for case when " + caseWhen)); } + /** + * process between type coercion. + */ + public static Expression processBetween(Between between) { + // check + between.checkLegalityBeforeTypeCoercion(); + + if (between.getLowerBound().getDataType().equals(between.getCompareExpr().getDataType()) + && between.getUpperBound().getDataType().equals(between.getCompareExpr().getDataType())) { + return between; + } + Optional optionalCommonType = TypeCoercionUtils.findWiderCommonTypeForComparison( + between.children() + .stream() + .map(Expression::getDataType) + .collect(Collectors.toList())); + + return optionalCommonType + .map(commonType -> { + List newChildren = between.children().stream() + .map(e -> TypeCoercionUtils.castIfNotMatchType(e, commonType)) + .collect(Collectors.toList()); + return between.withChildren(newChildren); + }) + .orElse(between); + } + private static boolean canCompareDate(DataType t1, DataType t2) { DataType dateType = t1; DataType anotherType = t2; diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java index 0db6295a3daa07..1d30d0ce6318d7 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java @@ -18,6 +18,7 @@ package org.apache.doris.nereids.rules.expression; import org.apache.doris.nereids.rules.expression.rules.AddMinMax; +import org.apache.doris.nereids.rules.expression.rules.BetweenToCompound; import org.apache.doris.nereids.rules.expression.rules.DistinctPredicatesRule; import org.apache.doris.nereids.rules.expression.rules.ExtractCommonFactorRule; import org.apache.doris.nereids.rules.expression.rules.InPredicateDedup; @@ -240,6 +241,19 @@ void testInPredicateDedup() { assertRewrite("a in (1, 2, 1, 2)", "a in (1, 2)"); } + @Test + void testBetweenToCompoundRule() { + executor = new ExpressionRuleExecutor(ImmutableList.of( + bottomUp( + BetweenToCompound.INSTANCE, + SimplifyNotExprRule.INSTANCE) + )); + + assertRewrite("a between c and d", "(a >= c) and (a <= d)"); + assertRewrite("a not between c and d)", "(a < c) or (a > d)"); + + } + @Test void testSimplifyCastRule() { executor = new ExpressionRuleExecutor(ImmutableList.of( @@ -310,7 +324,8 @@ void testDeadLoop() { void testAddMinMax() { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp( - AddMinMax.INSTANCE + AddMinMax.INSTANCE, + BetweenToCompound.INSTANCE ) )); @@ -376,7 +391,8 @@ void testSimplifyRangeAndAddMinMax() { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp( SimplifyRange.INSTANCE, - AddMinMax.INSTANCE + AddMinMax.INSTANCE, + BetweenToCompound.INSTANCE ) )); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java index b5d5aaab88ee49..c3e54094141715 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java @@ -22,6 +22,7 @@ import org.apache.doris.nereids.analyzer.UnboundSlot; import org.apache.doris.nereids.parser.NereidsParser; import org.apache.doris.nereids.rules.analysis.ExpressionAnalyzer; +import org.apache.doris.nereids.rules.expression.rules.BetweenToCompound; import org.apache.doris.nereids.rules.expression.rules.RangeInference; import org.apache.doris.nereids.rules.expression.rules.RangeInference.EmptyValue; import org.apache.doris.nereids.rules.expression.rules.RangeInference.RangeValue; @@ -95,7 +96,10 @@ public void testRangeInference() { @Test public void testSimplify() { executor = new ExpressionRuleExecutor(ImmutableList.of( - bottomUp(SimplifyRange.INSTANCE) + bottomUp( + SimplifyRange.INSTANCE, + BetweenToCompound.INSTANCE + ) )); assertRewrite("TA", "TA"); assertRewrite("TA > 3 or TA > null", "TA > 3 OR NULL"); @@ -109,7 +113,7 @@ public void testSimplify() { assertRewrite("TA > 3 or TA <=> null", "TA > 3 or TA <=> null"); assertRewrite("(TA < 1 or TA > 2) or (TA >= 0 and TA <= 3)", "TA IS NOT NULL OR NULL"); assertRewrite("TA between 10 and 20 or TA between 100 and 120 or TA between 15 and 25 or TA between 115 and 125", - "TA between 10 and 25 or TA between 100 and 125"); + "TA >= 10 and TA <= 25 or TA >= 100 and TA <= 125"); assertRewriteNotNull("TA > 3 and TA > null", "TA > 3 and NULL"); assertRewriteNotNull("TA > 3 and TA < null", "TA > 3 and NULL"); assertRewriteNotNull("TA > 3 and TA = null", "TA > 3 and NULL"); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionEqualsTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionEqualsTest.java index ca5793b687c092..c26c0205634832 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionEqualsTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionEqualsTest.java @@ -83,6 +83,14 @@ public void testComparisonPredicate() { Assertions.assertEquals(greaterThanEqual1.hashCode(), greaterThanEqual2.hashCode()); } + @Test + public void testBetween() { + Between between1 = new Between(child1, left1, right1); + Between between2 = new Between(child2, left2, right2); + Assertions.assertEquals(between1, between2); + Assertions.assertEquals(between1.hashCode(), between2.hashCode()); + } + @Test public void testNot() { Not not1 = new Not(child1); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java index cd0e21bb71d7d4..f33bd493824845 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java @@ -84,9 +84,10 @@ public void testSqlBetweenPredicate() { public void testExprBetweenPredicate() { parseExpression("c BETWEEN a AND b") .assertEquals( - new And( - new GreaterThanEqual(new UnboundSlot("c"), new UnboundSlot("a")), - new LessThanEqual(new UnboundSlot("c"), new UnboundSlot("b")) + new Between( + new UnboundSlot("c"), + new UnboundSlot("a"), + new UnboundSlot("b") ) ); } From 9000213c1604c90c8fd177a175cb220dd07bce32 Mon Sep 17 00:00:00 2001 From: yujun Date: Wed, 19 Feb 2025 21:51:50 +0800 Subject: [PATCH 02/10] fix test --- .../nereids/rules/expression/rules/BetweenToCompound.java | 2 +- .../java/org/apache/doris/nereids/parser/BetweenTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java index be50e7363e20f8..5384c37f539e46 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/BetweenToCompound.java @@ -44,7 +44,7 @@ public class BetweenToCompound implements ExpressionPatternRuleFactory { @Override public List> buildRules() { return ImmutableList.of( - matchesTopType(Between.class) + matchesType(Between.class) .thenApply(ctx -> rewrite(ctx.expr, ctx.rewriteContext)) .toRule(ExpressionRuleType.BETWEEN_TO_COMPOUND) ); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/BetweenTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/BetweenTest.java index c9ef4fbee27cbe..1ecdd28e3aa2ad 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/BetweenTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/BetweenTest.java @@ -17,7 +17,7 @@ package org.apache.doris.nereids.parser; -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; @@ -35,6 +35,6 @@ public void testBetween() { expression = "A between 1 and 2"; result = PARSER.parseExpression(expression); - Assertions.assertInstanceOf(And.class, result); + Assertions.assertInstanceOf(Between.class, result); } } From 0e782be31f93371be4f40e2ee891820e9b00bf53 Mon Sep 17 00:00:00 2001 From: yujun Date: Wed, 19 Feb 2025 22:38:11 +0800 Subject: [PATCH 03/10] fix expression translator visit between --- .../doris/nereids/glue/translator/ExpressionTranslator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java index c0ba8c41a2990e..2fdb7eb89649f8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java @@ -386,7 +386,9 @@ private Expr toBalancedTree(int low, int high, List children, @Override public Expr visitBetween(Between between, PlanTranslatorContext context) { - throw new RuntimeException("Unexpected invocation"); + And and = new And(new GreaterThanEqual(between.getCompareExpr(), between.getLowerBound()), + new LessThanEqual(between.getCompareExpr(), between.getUpperBound())); + return and.accept(this, context); } @Override From ac64fe50a0fca9f2b0530fc8a814cb905075bfff Mon Sep 17 00:00:00 2001 From: yujun Date: Fri, 28 Feb 2025 16:42:29 +0800 Subject: [PATCH 04/10] fix between cast type --- .../org/apache/doris/nereids/util/TypeCoercionUtils.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index 3be2644226d9e8..b038bac4df0053 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -1226,6 +1226,14 @@ public static Expression processBetween(Between between) { .map(Expression::getDataType) .collect(Collectors.toList())); + if (optionalCommonType.isPresent()) { + optionalCommonType = Optional.of(downgradeDecimalAndDateLikeType( + optionalCommonType.get(), + between.getCompareExpr(), + between.getLowerBound(), + between.getUpperBound())); + } + return optionalCommonType .map(commonType -> { List newChildren = between.children().stream() From 2fbc34b5720a6f546f993e6277df986de90a278b Mon Sep 17 00:00:00 2001 From: yujun Date: Fri, 28 Feb 2025 17:47:30 +0800 Subject: [PATCH 05/10] fix type --- .../doris/nereids/util/TypeCoercionUtils.java | 34 +++++++++++++++++-- .../rules/expression/SimplifyRangeTest.java | 5 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index b038bac4df0053..313feb597fca73 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -1220,6 +1220,33 @@ public static Expression processBetween(Between between) { && between.getUpperBound().getDataType().equals(between.getCompareExpr().getDataType())) { return between; } + + // process string literal + boolean hitString = false; + Expression newLowerBound = between.getLowerBound(); + Expression newUpperBound = between.getUpperBound(); + if (!(between.getCompareExpr().getDataType().isStringLikeType())) { + if (newLowerBound instanceof Literal && ((Literal) newLowerBound).isStringLikeLiteral()) { + Optional boundOpt = TypeCoercionUtils.characterLiteralTypeCoercion( + ((Literal) newLowerBound).getStringValue(), between.getCompareExpr().getDataType()); + if (boundOpt.isPresent()) { + newLowerBound = boundOpt.get(); + hitString = true; + } + } + if (newUpperBound instanceof Literal && ((Literal) newUpperBound).isStringLikeLiteral()) { + Optional boundOpt = TypeCoercionUtils.characterLiteralTypeCoercion( + ((Literal) newUpperBound).getStringValue(), between.getCompareExpr().getDataType()); + if (boundOpt.isPresent()) { + newUpperBound = boundOpt.get(); + hitString = true; + } + } + } + if (hitString) { + between = new Between(between.getCompareExpr(), newLowerBound, newUpperBound); + } + Optional optionalCommonType = TypeCoercionUtils.findWiderCommonTypeForComparison( between.children() .stream() @@ -1234,12 +1261,15 @@ public static Expression processBetween(Between between) { between.getUpperBound())); } + // lambda need a final variable + final Between finalBetween = between; + return optionalCommonType .map(commonType -> { - List newChildren = between.children().stream() + List newChildren = finalBetween.children().stream() .map(e -> TypeCoercionUtils.castIfNotMatchType(e, commonType)) .collect(Collectors.toList()); - return between.withChildren(newChildren); + return finalBetween.withChildren(newChildren); }) .orElse(between); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java index c3e54094141715..fbb6a78d4b00e0 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/SimplifyRangeTest.java @@ -244,6 +244,11 @@ public void testSimplify() { // random is non-foldable, so the two random(1, 10) are distinct, cann't merge range for them. Expression expr = rewrite("TA + random(1, 10) > 10 AND TA + random(1, 10) < 1", Maps.newHashMap()); Assertions.assertEquals("AND[((TA + random(1, 10)) > 10),((TA + random(1, 10)) < 1)]", expr.toSql()); + + expr = rewrite("TA + random(1, 10) between 10 and 20", Maps.newHashMap()); + Assertions.assertEquals("AND[((TA + random(1, 10)) >= 10),((TA + random(1, 10)) <= 20)]", expr.toSql()); + expr = rewrite("TA + random(1, 10) between 20 and 10", Maps.newHashMap()); + Assertions.assertEquals("AND[(TA + random(1, 10)) IS NULL,NULL]", expr.toSql()); } @Test From 245dc86b908dc09f85e5265926195f63c1e2ef22 Mon Sep 17 00:00:00 2001 From: yujun Date: Fri, 28 Feb 2025 18:20:22 +0800 Subject: [PATCH 06/10] fix test_date_trunc_prune/test_date_function_prune_mono: disable SIMPLIFY_NOT_EXPR --- .../partition_prune/test_date_function_prune_mono.groovy | 6 +++--- .../partition_prune/test_date_trunc_prune.groovy | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy index 7af54e3162b5e2..6ff101c84f2f26 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy @@ -124,9 +124,9 @@ suite("test_date_prune_mono") { for (int i = 0; i < 2; i++) { if (i == 0) { // forbid rewrite not a>1 to a<=1 - sql "set disable_nereids_rules = 'REWRITE_FILTER_EXPRESSION'" + sql "set disable_nereids_expression_rules = 'SIMPLIFY_NOT_EXPR'" } else { - sql "set disable_nereids_rules = ''" + sql "set disable_nereids_expression_rules = ''" } explain { sql """select * from mal_test_partition_range5_date_mono where not date(b)<="2020-01-14" """ @@ -307,4 +307,4 @@ suite("test_date_prune_mono") { sql "select * from mal_test_partition_range2_two_date_int_date_mono where date_trunc(date(dt),'minute') > '2017-2-1 00:00:00' and id>100;" contains("partitions=2/3 (p201702_2000,p201703_all)") } -} \ No newline at end of file +} diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy index c5eb3855247ad0..9a34d489527d78 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy @@ -124,9 +124,9 @@ suite("test_date_trunc_prune") { for (int i = 0; i < 2; i++) { if (i == 0) { // forbid rewrite not a>1 to a<=1 - sql "set disable_nereids_rules = 'REWRITE_FILTER_EXPRESSION'" + sql "set disable_nereids_expression_rules = 'SIMPLIFY_NOT_EXPR'" } else { - sql "set disable_nereids_rules = ''" + sql "set disable_nereids_expression_rules = ''" } explain { sql """select * from mal_test_partition_range5 where not date_trunc(b,'day')<="2020-01-14" """ @@ -359,4 +359,4 @@ suite("test_date_trunc_prune") { sql """select * from t_multi_column_partition where a=2 and date_trunc(dt,'day') <'2024-01-1 00:00:00';""" contains ("partitions=1/5 (p0)") } -} \ No newline at end of file +} From 694fadffe1bdaca243a1f24af1b6fe538d8ff1e6 Mon Sep 17 00:00:00 2001 From: yujun Date: Fri, 28 Feb 2025 18:36:05 +0800 Subject: [PATCH 07/10] OneRangePartitionEvaluator support visit between --- .../expression/rules/OneRangePartitionEvaluator.java | 10 ++++++++++ .../test_date_function_prune_mono.groovy | 6 +++--- .../partition_prune/test_date_trunc_prune.groovy | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java index 2bedd6db2336cb..4f3f7cfb4e10cd 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java @@ -30,6 +30,7 @@ import org.apache.doris.nereids.rules.expression.rules.OneRangePartitionEvaluator.EvaluateRangeResult; import org.apache.doris.nereids.rules.expression.rules.PartitionRangeExpander.PartitionSlotType; 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; @@ -376,6 +377,15 @@ public EvaluateRangeResult visitInPredicate(InPredicate inPredicate, EvaluateRan return result; } + @Override + public EvaluateRangeResult visitBetween(Between between, EvaluateRangeInput context) { + return visitAnd( + new And( + new GreaterThanEqual(between.getCompareExpr(), between.getLowerBound()), + new LessThanEqual(between.getCompareExpr(), between.getUpperBound())), + context); + } + @Override public EvaluateRangeResult visitIsNull(IsNull isNull, EvaluateRangeInput context) { EvaluateRangeResult result = evaluateChildrenThenThis(isNull, context); diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy index 6ff101c84f2f26..7af54e3162b5e2 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy @@ -124,9 +124,9 @@ suite("test_date_prune_mono") { for (int i = 0; i < 2; i++) { if (i == 0) { // forbid rewrite not a>1 to a<=1 - sql "set disable_nereids_expression_rules = 'SIMPLIFY_NOT_EXPR'" + sql "set disable_nereids_rules = 'REWRITE_FILTER_EXPRESSION'" } else { - sql "set disable_nereids_expression_rules = ''" + sql "set disable_nereids_rules = ''" } explain { sql """select * from mal_test_partition_range5_date_mono where not date(b)<="2020-01-14" """ @@ -307,4 +307,4 @@ suite("test_date_prune_mono") { sql "select * from mal_test_partition_range2_two_date_int_date_mono where date_trunc(date(dt),'minute') > '2017-2-1 00:00:00' and id>100;" contains("partitions=2/3 (p201702_2000,p201703_all)") } -} +} \ No newline at end of file diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy index 9a34d489527d78..c5eb3855247ad0 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy @@ -124,9 +124,9 @@ suite("test_date_trunc_prune") { for (int i = 0; i < 2; i++) { if (i == 0) { // forbid rewrite not a>1 to a<=1 - sql "set disable_nereids_expression_rules = 'SIMPLIFY_NOT_EXPR'" + sql "set disable_nereids_rules = 'REWRITE_FILTER_EXPRESSION'" } else { - sql "set disable_nereids_expression_rules = ''" + sql "set disable_nereids_rules = ''" } explain { sql """select * from mal_test_partition_range5 where not date_trunc(b,'day')<="2020-01-14" """ @@ -359,4 +359,4 @@ suite("test_date_trunc_prune") { sql """select * from t_multi_column_partition where a=2 and date_trunc(dt,'day') <'2024-01-1 00:00:00';""" contains ("partitions=1/5 (p0)") } -} +} \ No newline at end of file From cb0d9d041d241411533762cafe2469a00fbddd52 Mon Sep 17 00:00:00 2001 From: yujun Date: Fri, 28 Feb 2025 19:12:48 +0800 Subject: [PATCH 08/10] Revert "OneRangePartitionEvaluator support visit between" This reverts commit 5b4d664be6aabd23e35566fa7140f43a660324ba. --- .../expression/rules/OneRangePartitionEvaluator.java | 10 ---------- .../test_date_function_prune_mono.groovy | 6 +++--- .../partition_prune/test_date_trunc_prune.groovy | 6 +++--- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java index 4f3f7cfb4e10cd..2bedd6db2336cb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java @@ -30,7 +30,6 @@ import org.apache.doris.nereids.rules.expression.rules.OneRangePartitionEvaluator.EvaluateRangeResult; import org.apache.doris.nereids.rules.expression.rules.PartitionRangeExpander.PartitionSlotType; 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; @@ -377,15 +376,6 @@ public EvaluateRangeResult visitInPredicate(InPredicate inPredicate, EvaluateRan return result; } - @Override - public EvaluateRangeResult visitBetween(Between between, EvaluateRangeInput context) { - return visitAnd( - new And( - new GreaterThanEqual(between.getCompareExpr(), between.getLowerBound()), - new LessThanEqual(between.getCompareExpr(), between.getUpperBound())), - context); - } - @Override public EvaluateRangeResult visitIsNull(IsNull isNull, EvaluateRangeInput context) { EvaluateRangeResult result = evaluateChildrenThenThis(isNull, context); diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy index 7af54e3162b5e2..6ff101c84f2f26 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_function_prune_mono.groovy @@ -124,9 +124,9 @@ suite("test_date_prune_mono") { for (int i = 0; i < 2; i++) { if (i == 0) { // forbid rewrite not a>1 to a<=1 - sql "set disable_nereids_rules = 'REWRITE_FILTER_EXPRESSION'" + sql "set disable_nereids_expression_rules = 'SIMPLIFY_NOT_EXPR'" } else { - sql "set disable_nereids_rules = ''" + sql "set disable_nereids_expression_rules = ''" } explain { sql """select * from mal_test_partition_range5_date_mono where not date(b)<="2020-01-14" """ @@ -307,4 +307,4 @@ suite("test_date_prune_mono") { sql "select * from mal_test_partition_range2_two_date_int_date_mono where date_trunc(date(dt),'minute') > '2017-2-1 00:00:00' and id>100;" contains("partitions=2/3 (p201702_2000,p201703_all)") } -} \ No newline at end of file +} diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy index c5eb3855247ad0..9a34d489527d78 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_date_trunc_prune.groovy @@ -124,9 +124,9 @@ suite("test_date_trunc_prune") { for (int i = 0; i < 2; i++) { if (i == 0) { // forbid rewrite not a>1 to a<=1 - sql "set disable_nereids_rules = 'REWRITE_FILTER_EXPRESSION'" + sql "set disable_nereids_expression_rules = 'SIMPLIFY_NOT_EXPR'" } else { - sql "set disable_nereids_rules = ''" + sql "set disable_nereids_expression_rules = ''" } explain { sql """select * from mal_test_partition_range5 where not date_trunc(b,'day')<="2020-01-14" """ @@ -359,4 +359,4 @@ suite("test_date_trunc_prune") { sql """select * from t_multi_column_partition where a=2 and date_trunc(dt,'day') <'2024-01-1 00:00:00';""" contains ("partitions=1/5 (p0)") } -} \ No newline at end of file +} From bc585663597e6c875cf88722d86f014e9fb04aba Mon Sep 17 00:00:00 2001 From: yujun Date: Mon, 3 Mar 2025 10:27:52 +0800 Subject: [PATCH 09/10] update test --- .../doris/nereids/rules/expression/ExpressionRewriteTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java index 1d30d0ce6318d7..0d40b30c7178ed 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java @@ -250,7 +250,7 @@ void testBetweenToCompoundRule() { )); assertRewrite("a between c and d", "(a >= c) and (a <= d)"); - assertRewrite("a not between c and d)", "(a < c) or (a > d)"); + assertRewrite("a not between c and d", "(a < c) or (a > d)"); } From ee0951b2d81d803030dca70207de877003aedd71 Mon Sep 17 00:00:00 2001 From: yujun Date: Mon, 3 Mar 2025 11:12:57 +0800 Subject: [PATCH 10/10] update --- .../nereids/rules/expression/rules/FoldConstantRuleOnBE.java | 1 + 1 file changed, 1 insertion(+) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java index 483bec20a98bf9..d275bade59ce87 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java @@ -194,6 +194,7 @@ private static Expression replace( private static void collectConst(Expression expr, Map constMap, Map tExprMap, IdGenerator idGenerator) { + // skip BetweenPredicate need to be rewrite to CompoundPredicate if (expr.isConstant() && !expr.isLiteral() && !(expr instanceof Between) && !expr.anyMatch(e -> shouldSkipFold((Expression) e))) { String id = idGenerator.getNextId().toString();