This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch branch-2.1 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push: new c412de8db89 [fix](Nereids) simplify range result wrong when reference is nullable (#41356) (#42096) c412de8db89 is described below commit c412de8db8920ae437a5f2fe6f1eb822a3775e9b Author: morrySnow <101034200+morrys...@users.noreply.github.com> AuthorDate: Fri Oct 18 22:14:21 2024 +0800 [fix](Nereids) simplify range result wrong when reference is nullable (#41356) (#42096) pick from master #41356 if reference is nullable and simplify result is boolean literal. the real result should be: IF(${reference} IS NULL, NULL, ${not_null_result}) --- .../rules/expression/rules/SimplifyRange.java | 244 ++++++++------ .../apache/doris/nereids/util/ExpressionUtils.java | 12 + .../rules/expression/SimplifyRangeTest.java | 358 ++++++++++++--------- 3 files changed, 358 insertions(+), 256 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java index 98d752facb4..054956822d5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java @@ -19,6 +19,7 @@ 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.trees.expressions.And; import org.apache.doris.nereids.trees.expressions.ComparisonPredicate; import org.apache.doris.nereids.trees.expressions.CompoundPredicate; @@ -34,7 +35,9 @@ import org.apache.doris.nereids.trees.expressions.Not; import org.apache.doris.nereids.trees.expressions.Or; import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.BooleanType; import org.apache.doris.nereids.util.ExpressionUtils; import com.google.common.collect.BoundType; @@ -81,90 +84,91 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { @Override public List<ExpressionPatternMatcher<? extends Expression>> buildRules() { return ImmutableList.of( - matchesTopType(CompoundPredicate.class).then(SimplifyRange::rewrite) + matchesTopType(CompoundPredicate.class) + .thenApply(ctx -> SimplifyRange.rewrite(ctx.expr, ctx.rewriteContext)) ); } /** rewrite */ - public static Expression rewrite(CompoundPredicate expr) { - ValueDesc valueDesc = expr.accept(new RangeInference(), null); - Expression simplifiedExpr = valueDesc.toExpression(); - return simplifiedExpr == null ? valueDesc.expr : simplifiedExpr; + public static Expression rewrite(CompoundPredicate expr, ExpressionRewriteContext context) { + ValueDesc valueDesc = expr.accept(new RangeInference(), context); + Expression exprForNonNull = valueDesc.toExpressionForNonNull(); + if (exprForNonNull == null) { + // this mean cannot simplify + return valueDesc.exprForNonNull; + } + return exprForNonNull; } - private static class RangeInference extends ExpressionVisitor<ValueDesc, Void> { + private static class RangeInference extends ExpressionVisitor<ValueDesc, ExpressionRewriteContext> { @Override - public ValueDesc visit(Expression expr, Void context) { - return new UnknownValue(expr); + public ValueDesc visit(Expression expr, ExpressionRewriteContext context) { + return new UnknownValue(context, expr); } - private ValueDesc buildRange(ComparisonPredicate predicate) { + private ValueDesc buildRange(ExpressionRewriteContext context, ComparisonPredicate predicate) { Expression right = predicate.child(1); if (right.isNullLiteral()) { - // it's safe to return empty value if >, >=, <, <= and = with null - if ((predicate instanceof GreaterThan || predicate instanceof GreaterThanEqual - || predicate instanceof LessThan || predicate instanceof LessThanEqual - || predicate instanceof EqualTo)) { - return new EmptyValue(predicate.child(0), predicate); - } else { - return new UnknownValue(predicate); - } + return new UnknownValue(context, predicate); } // only handle `NumericType` and `DateLikeType` if (right.isLiteral() && (right.getDataType().isNumericType() || right.getDataType().isDateLikeType())) { - return ValueDesc.range(predicate); + return ValueDesc.range(context, predicate); } - return new UnknownValue(predicate); + return new UnknownValue(context, predicate); } @Override - public ValueDesc visitGreaterThan(GreaterThan greaterThan, Void context) { - return buildRange(greaterThan); + public ValueDesc visitGreaterThan(GreaterThan greaterThan, ExpressionRewriteContext context) { + return buildRange(context, greaterThan); } @Override - public ValueDesc visitGreaterThanEqual(GreaterThanEqual greaterThanEqual, Void context) { - return buildRange(greaterThanEqual); + public ValueDesc visitGreaterThanEqual(GreaterThanEqual greaterThanEqual, ExpressionRewriteContext context) { + return buildRange(context, greaterThanEqual); } @Override - public ValueDesc visitLessThan(LessThan lessThan, Void context) { - return buildRange(lessThan); + public ValueDesc visitLessThan(LessThan lessThan, ExpressionRewriteContext context) { + return buildRange(context, lessThan); } @Override - public ValueDesc visitLessThanEqual(LessThanEqual lessThanEqual, Void context) { - return buildRange(lessThanEqual); + public ValueDesc visitLessThanEqual(LessThanEqual lessThanEqual, ExpressionRewriteContext context) { + return buildRange(context, lessThanEqual); } @Override - public ValueDesc visitEqualTo(EqualTo equalTo, Void context) { - return buildRange(equalTo); + public ValueDesc visitEqualTo(EqualTo equalTo, ExpressionRewriteContext context) { + return buildRange(context, equalTo); } @Override - public ValueDesc visitInPredicate(InPredicate inPredicate, Void context) { + public ValueDesc visitInPredicate(InPredicate inPredicate, ExpressionRewriteContext context) { // only handle `NumericType` and `DateLikeType` - if (ExpressionUtils.isAllLiteral(inPredicate.getOptions()) + if (ExpressionUtils.isAllNonNullLiteral(inPredicate.getOptions()) && (ExpressionUtils.matchNumericType(inPredicate.getOptions()) || ExpressionUtils.matchDateLikeType(inPredicate.getOptions()))) { - return ValueDesc.discrete(inPredicate); + return ValueDesc.discrete(context, inPredicate); } - return new UnknownValue(inPredicate); + return new UnknownValue(context, inPredicate); } @Override - public ValueDesc visitAnd(And and, Void context) { - return simplify(and, ExpressionUtils.extractConjunction(and), ValueDesc::intersect, ExpressionUtils::and); + public ValueDesc visitAnd(And and, ExpressionRewriteContext context) { + return simplify(context, and, ExpressionUtils.extractConjunction(and), + ValueDesc::intersect, ExpressionUtils::and); } @Override - public ValueDesc visitOr(Or or, Void context) { - return simplify(or, ExpressionUtils.extractDisjunction(or), ValueDesc::union, ExpressionUtils::or); + public ValueDesc visitOr(Or or, ExpressionRewriteContext context) { + return simplify(context, or, ExpressionUtils.extractDisjunction(or), + ValueDesc::union, ExpressionUtils::or); } - private ValueDesc simplify(Expression originExpr, List<Expression> predicates, + private ValueDesc simplify(ExpressionRewriteContext context, + Expression originExpr, List<Expression> predicates, BinaryOperator<ValueDesc> op, BinaryOperator<Expression> exprOp) { Multimap<Expression, ValueDesc> groupByReference @@ -193,52 +197,58 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } // use UnknownValue to wrap different references - return new UnknownValue(valuePerRefs, originExpr, exprOp); + return new UnknownValue(context, valuePerRefs, originExpr, exprOp); } } private abstract static class ValueDesc { - Expression expr; + ExpressionRewriteContext context; + Expression exprForNonNull; Expression reference; - public ValueDesc(Expression reference, Expression expr) { - this.expr = expr; + public ValueDesc(ExpressionRewriteContext context, Expression reference, Expression exprForNonNull) { + this.context = context; + this.exprForNonNull = exprForNonNull; this.reference = reference; } public abstract ValueDesc union(ValueDesc other); - public static ValueDesc union(RangeValue range, DiscreteValue discrete, boolean reverseOrder) { + public static ValueDesc union(ExpressionRewriteContext context, + RangeValue range, DiscreteValue discrete, boolean reverseOrder) { long count = discrete.values.stream().filter(x -> range.range.test(x)).count(); if (count == discrete.values.size()) { return range; } - Expression originExpr = ExpressionUtils.or(range.expr, discrete.expr); + Expression exprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.or(range.exprForNonNull, discrete.exprForNonNull), context); List<ValueDesc> sourceValues = reverseOrder ? ImmutableList.of(discrete, range) : ImmutableList.of(range, discrete); - return new UnknownValue(sourceValues, originExpr, ExpressionUtils::or); + return new UnknownValue(context, sourceValues, exprForNonNull, ExpressionUtils::or); } public abstract ValueDesc intersect(ValueDesc other); - public static ValueDesc intersect(RangeValue range, DiscreteValue discrete) { - DiscreteValue result = new DiscreteValue(discrete.reference, discrete.expr); + public static ValueDesc intersect(ExpressionRewriteContext context, RangeValue range, DiscreteValue discrete) { + DiscreteValue result = new DiscreteValue(context, discrete.reference, discrete.exprForNonNull); discrete.values.stream().filter(x -> range.range.contains(x)).forEach(result.values::add); if (!result.values.isEmpty()) { return result; } - return new EmptyValue(range.reference, ExpressionUtils.and(range.expr, discrete.expr)); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.and(range.exprForNonNull, discrete.exprForNonNull), context); + return new EmptyValue(context, range.reference, originExprForNonNull); } - public abstract Expression toExpression(); + public abstract Expression toExpressionForNonNull(); - public static ValueDesc range(ComparisonPredicate predicate) { + public static ValueDesc range(ExpressionRewriteContext context, ComparisonPredicate predicate) { Literal value = (Literal) predicate.right(); if (predicate instanceof EqualTo) { - return new DiscreteValue(predicate.left(), predicate, value); + return new DiscreteValue(context, predicate.left(), predicate, value); } - RangeValue rangeValue = new RangeValue(predicate.left(), predicate); + RangeValue rangeValue = new RangeValue(context, predicate.left(), predicate); if (predicate instanceof GreaterThanEqual) { rangeValue.range = Range.atLeast(value); } else if (predicate instanceof GreaterThan) { @@ -252,17 +262,17 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { return rangeValue; } - public static ValueDesc discrete(InPredicate in) { + public static ValueDesc discrete(ExpressionRewriteContext context, InPredicate in) { // Set<Literal> literals = (Set) Utils.fastToImmutableSet(in.getOptions()); Set<Literal> literals = in.getOptions().stream().map(Literal.class::cast).collect(Collectors.toSet()); - return new DiscreteValue(in.getCompareExpr(), in, literals); + return new DiscreteValue(context, in.getCompareExpr(), in, literals); } } private static class EmptyValue extends ValueDesc { - public EmptyValue(Expression reference, Expression expr) { - super(reference, expr); + public EmptyValue(ExpressionRewriteContext context, Expression reference, Expression exprForNonNull) { + super(context, reference, exprForNonNull); } @Override @@ -276,8 +286,12 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } @Override - public Expression toExpression() { - return BooleanLiteral.FALSE; + public Expression toExpressionForNonNull() { + if (reference.nullable()) { + return new And(new IsNull(reference), new NullLiteral(BooleanType.INSTANCE)); + } else { + return BooleanLiteral.FALSE; + } } } @@ -289,8 +303,8 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { private static class RangeValue extends ValueDesc { Range<Literal> range; - public RangeValue(Expression reference, Expression expr) { - super(reference, expr); + public RangeValue(ExpressionRewriteContext context, Expression reference, Expression exprForNonNull) { + super(context, reference, exprForNonNull); } @Override @@ -300,19 +314,23 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } try { if (other instanceof RangeValue) { + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context); RangeValue o = (RangeValue) other; if (range.isConnected(o.range)) { - RangeValue rangeValue = new RangeValue(reference, ExpressionUtils.or(expr, other.expr)); + RangeValue rangeValue = new RangeValue(context, reference, originExprForNonNull); rangeValue.range = range.span(o.range); return rangeValue; } - Expression originExpr = ExpressionUtils.or(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::or); + return new UnknownValue(context, ImmutableList.of(this, other), + originExprForNonNull, ExpressionUtils::or); } - return union(this, (DiscreteValue) other, false); + return union(context, this, (DiscreteValue) other, false); } catch (Exception e) { - Expression originExpr = ExpressionUtils.or(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::or); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context); + return new UnknownValue(context, ImmutableList.of(this, other), + originExprForNonNull, ExpressionUtils::or); } } @@ -323,23 +341,27 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } try { if (other instanceof RangeValue) { + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context); RangeValue o = (RangeValue) other; if (range.isConnected(o.range)) { - RangeValue rangeValue = new RangeValue(reference, ExpressionUtils.and(expr, other.expr)); + RangeValue rangeValue = new RangeValue(context, reference, originExprForNonNull); rangeValue.range = range.intersection(o.range); return rangeValue; } - return new EmptyValue(reference, ExpressionUtils.and(expr, other.expr)); + return new EmptyValue(context, reference, originExprForNonNull); } - return intersect(this, (DiscreteValue) other); + return intersect(context, this, (DiscreteValue) other); } catch (Exception e) { - Expression originExpr = ExpressionUtils.and(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::and); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context); + return new UnknownValue(context, ImmutableList.of(this, other), + originExprForNonNull, ExpressionUtils::and); } } @Override - public Expression toExpression() { + public Expression toExpressionForNonNull() { List<Expression> result = Lists.newArrayList(); if (range.hasLowerBound()) { if (range.lowerBoundType() == BoundType.CLOSED) { @@ -357,11 +379,12 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } if (!result.isEmpty()) { return ExpressionUtils.and(result); - } else if (reference.nullable()) { - // when reference is nullable, we should filter null slot. - return new Not(new IsNull(reference)); } else { - return BooleanLiteral.TRUE; + if (reference.nullable()) { + return new Or(new Not(new IsNull(reference)), new NullLiteral(BooleanType.INSTANCE)); + } else { + return BooleanLiteral.TRUE; + } } } @@ -379,12 +402,14 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { private static class DiscreteValue extends ValueDesc { Set<Literal> values; - public DiscreteValue(Expression reference, Expression expr, Literal... values) { - this(reference, expr, Arrays.asList(values)); + public DiscreteValue(ExpressionRewriteContext context, + Expression reference, Expression exprForNonNull, Literal... values) { + this(context, reference, exprForNonNull, Arrays.asList(values)); } - public DiscreteValue(Expression reference, Expression expr, Collection<Literal> values) { - super(reference, expr); + public DiscreteValue(ExpressionRewriteContext context, + Expression reference, Expression exprForNonNull, Collection<Literal> values) { + super(context, reference, exprForNonNull); this.values = Sets.newTreeSet(values); } @@ -395,15 +420,19 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } try { if (other instanceof DiscreteValue) { - DiscreteValue discreteValue = new DiscreteValue(reference, ExpressionUtils.or(expr, other.expr)); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context); + DiscreteValue discreteValue = new DiscreteValue(context, reference, originExprForNonNull); discreteValue.values.addAll(((DiscreteValue) other).values); discreteValue.values.addAll(this.values); return discreteValue; } - return union((RangeValue) other, this, true); + return union(context, (RangeValue) other, this, true); } catch (Exception e) { - Expression originExpr = ExpressionUtils.or(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::or); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context); + return new UnknownValue(context, ImmutableList.of(this, other), + originExprForNonNull, ExpressionUtils::or); } } @@ -414,24 +443,28 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { } try { if (other instanceof DiscreteValue) { - DiscreteValue discreteValue = new DiscreteValue(reference, ExpressionUtils.and(expr, other.expr)); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context); + DiscreteValue discreteValue = new DiscreteValue(context, reference, originExprForNonNull); discreteValue.values.addAll(((DiscreteValue) other).values); discreteValue.values.retainAll(this.values); if (discreteValue.values.isEmpty()) { - return new EmptyValue(reference, ExpressionUtils.and(expr, other.expr)); + return new EmptyValue(context, reference, originExprForNonNull); } else { return discreteValue; } } - return intersect((RangeValue) other, this); + return intersect(context, (RangeValue) other, this); } catch (Exception e) { - Expression originExpr = ExpressionUtils.and(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::and); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context); + return new UnknownValue(context, ImmutableList.of(this, other), + originExprForNonNull, ExpressionUtils::and); } } @Override - public Expression toExpression() { + public Expression toExpressionForNonNull() { // NOTICE: it's related with `InPredicateToEqualToRule` // They are same processes, so must change synchronously. if (values.size() == 1) { @@ -459,42 +492,43 @@ public class SimplifyRange implements ExpressionPatternRuleFactory { private final List<ValueDesc> sourceValues; private final BinaryOperator<Expression> mergeExprOp; - private UnknownValue(Expression expr) { - super(expr, expr); + private UnknownValue(ExpressionRewriteContext context, Expression expr) { + super(context, expr, expr); sourceValues = ImmutableList.of(); mergeExprOp = null; } - public UnknownValue(List<ValueDesc> sourceValues, Expression originExpr, - BinaryOperator<Expression> mergeExprOp) { - super(sourceValues.get(0).reference, originExpr); + public UnknownValue(ExpressionRewriteContext context, + List<ValueDesc> sourceValues, Expression exprForNonNull, BinaryOperator<Expression> mergeExprOp) { + super(context, sourceValues.get(0).reference, exprForNonNull); this.sourceValues = ImmutableList.copyOf(sourceValues); this.mergeExprOp = mergeExprOp; } @Override public ValueDesc union(ValueDesc other) { - Expression originExpr = ExpressionUtils.or(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::or); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context); + return new UnknownValue(context, ImmutableList.of(this, other), originExprForNonNull, ExpressionUtils::or); } @Override public ValueDesc intersect(ValueDesc other) { - Expression originExpr = ExpressionUtils.and(expr, other.expr); - return new UnknownValue(ImmutableList.of(this, other), originExpr, ExpressionUtils::and); + Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate( + ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context); + return new UnknownValue(context, ImmutableList.of(this, other), originExprForNonNull, ExpressionUtils::and); } @Override - public Expression toExpression() { + public Expression toExpressionForNonNull() { if (sourceValues.isEmpty()) { - return expr; + return exprForNonNull; } - - Expression result = sourceValues.get(0).toExpression(); + Expression result = sourceValues.get(0).toExpressionForNonNull(); for (int i = 1; i < sourceValues.size(); i++) { - result = mergeExprOp.apply(result, sourceValues.get(i).toExpression()); + result = mergeExprOp.apply(result, sourceValues.get(i).toExpressionForNonNull()); } - return result; + return FoldConstantRuleOnFE.evaluate(result, context); } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java index 2f238b68757..c42af8c29c7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java @@ -467,6 +467,18 @@ public class ExpressionUtils { return true; } + /** + * return true if all children are literal but not null literal. + */ + public static boolean isAllNonNullLiteral(List<Expression> children) { + for (Expression child : children) { + if ((!(child instanceof Literal)) || (child instanceof NullLiteral)) { + return false; + } + } + return true; + } + /** matchNumericType */ public static boolean matchNumericType(List<Expression> children) { for (Expression child : children) { 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 30155b3bf77..1f622619dd6 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 @@ -30,7 +30,9 @@ import org.apache.doris.nereids.trees.plans.RelationId; import org.apache.doris.nereids.types.BigIntType; import org.apache.doris.nereids.types.BooleanType; import org.apache.doris.nereids.types.DataType; -import org.apache.doris.nereids.types.DoubleType; +import org.apache.doris.nereids.types.DateTimeV2Type; +import org.apache.doris.nereids.types.DateV2Type; +import org.apache.doris.nereids.types.DecimalV3Type; import org.apache.doris.nereids.types.IntegerType; import org.apache.doris.nereids.types.StringType; import org.apache.doris.nereids.types.TinyIntType; @@ -63,34 +65,40 @@ public class SimplifyRangeTest extends ExpressionRewrite { bottomUp(SimplifyRange.INSTANCE) )); assertRewrite("TA", "TA"); - assertRewrite("TA > 3 or TA > null", "TA > 3"); - assertRewrite("TA > 3 or TA < null", "TA > 3"); - assertRewrite("TA > 3 or TA = null", "TA > 3"); - assertRewrite("TA > 3 or TA <> null", "TA > 3 or TA <> null"); + assertRewrite("TA > 3 or TA > null", "TA > 3 OR NULL"); + assertRewrite("TA > 3 or TA < null", "TA > 3 OR NULL"); + assertRewrite("TA > 3 or TA = null", "TA > 3 OR NULL"); + assertRewrite("TA > 3 or TA <> null", "TA > 3 or null"); assertRewrite("TA > 3 or TA <=> null", "TA > 3 or TA <=> null"); - assertRewrite("TA > 3 and TA > null", "false"); - assertRewrite("TA > 3 and TA < null", "false"); - assertRewrite("TA > 3 and TA = null", "false"); - assertRewrite("TA > 3 and TA <> null", "TA > 3 and TA <> null"); + 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"); + assertRewrite("(TA > 3 and TA > null) is null", "(TA > 3 and null) is null"); + assertRewrite("TA > 3 and TA > null", "TA > 3 and null"); + assertRewrite("TA > 3 and TA < null", "TA > 3 and null"); + assertRewrite("TA > 3 and TA = null", "TA > 3 and null"); + assertRewrite("TA > 3 and TA <> null", "TA > 3 and null"); assertRewrite("TA > 3 and TA <=> null", "TA > 3 and TA <=> null"); assertRewrite("(TA >= 1 and TA <=3 ) or (TA > 5 and TA < 7)", "(TA >= 1 and TA <=3 ) or (TA > 5 and TA < 7)"); - assertRewrite("(TA > 3 and TA < 1) or (TA > 7 and TA < 5)", "FALSE"); - assertRewrite("TA > 3 and TA < 1", "FALSE"); + assertRewriteNotNull("(TA > 3 and TA < 1) or (TA > 7 and TA < 5)", "FALSE"); + assertRewrite("(TA > 3 and TA < 1) or (TA > 7 and TA < 5)", "TA is null and null"); + assertRewriteNotNull("TA > 3 and TA < 1", "FALSE"); + assertRewrite("TA > 3 and TA < 1", "TA is null and null"); assertRewrite("TA >= 3 and TA < 3", "TA >= 3 and TA < 3"); - assertRewrite("TA = 1 and TA > 10", "FALSE"); + assertRewriteNotNull("TA = 1 and TA > 10", "FALSE"); + assertRewrite("TA = 1 and TA > 10", "TA is null and null"); assertRewrite("TA > 5 or TA < 1", "TA > 5 or TA < 1"); assertRewrite("TA > 5 or TA > 1 or TA > 10", "TA > 1"); - assertRewrite("TA > 5 or TA > 1 or TA < 10", "TA IS NOT NULL"); + assertRewrite("TA > 5 or TA > 1 or TA < 10", "TA is not null or null"); assertRewriteNotNull("TA > 5 or TA > 1 or TA < 10", "TRUE"); assertRewrite("TA > 5 and TA > 1 and TA > 10", "TA > 10"); assertRewrite("TA > 5 and TA > 1 and TA < 10", "TA > 5 and TA < 10"); assertRewrite("TA > 1 or TA < 1", "TA > 1 or TA < 1"); - assertRewrite("TA > 1 or TA < 10", "TA IS NOT NULL"); + assertRewrite("TA > 1 or TA < 10", "TA is not null or null"); assertRewriteNotNull("TA > 1 or TA < 10", "TRUE"); assertRewrite("TA > 5 and TA < 10", "TA > 5 and TA < 10"); assertRewrite("TA > 5 and TA > 10", "TA > 10"); - assertRewrite("TA > 5 + 1 and TA > 10", "TA > 5 + 1 and TA > 10"); - assertRewrite("TA > 5 + 1 and TA > 10", "TA > 5 + 1 and TA > 10"); + assertRewrite("TA > 5 + 1 and TA > 10", "cast(TA as smallint) > 6 and TA > 10"); assertRewrite("(TA > 1 and TA > 10) or TA > 20", "TA > 10"); assertRewrite("(TA > 1 or TA > 10) and TA > 20", "TA > 20"); assertRewrite("(TA + TB > 1 or TA + TB > 10) and TA + TB > 20", "TA + TB > 20"); @@ -100,44 +108,53 @@ public class SimplifyRangeTest extends ExpressionRewrite { assertRewrite("((TB > 30 and TA > 40) and TA > 20) and (TB > 10 and TB > 20)", "TB > 30 and TA > 40"); assertRewrite("(TA > 10 and TB > 10) or (TB > 10 and TB > 20)", "TA > 10 and TB > 10 or TB > 20"); assertRewrite("((TA > 10 or TA > 5) and TB > 10) or (TB > 10 and (TB > 20 or TB < 10))", "(TA > 5 and TB > 10) or (TB > 10 and (TB > 20 or TB < 10))"); - assertRewrite("TA in (1,2,3) and TA > 10", "FALSE"); + assertRewriteNotNull("TA in (1,2,3) and TA > 10", "FALSE"); + assertRewrite("TA in (1,2,3) and TA > 10", "TA is null and null"); assertRewrite("TA in (1,2,3) and TA >= 1", "TA in (1,2,3)"); assertRewrite("TA in (1,2,3) and TA > 1", "TA IN (2, 3)"); assertRewrite("TA in (1,2,3) or TA >= 1", "TA >= 1"); assertRewrite("TA in (1)", "TA in (1)"); assertRewrite("TA in (1,2,3) and TA < 10", "TA in (1,2,3)"); - assertRewrite("TA in (1,2,3) and TA < 1", "FALSE"); + assertRewriteNotNull("TA in (1,2,3) and TA < 1", "FALSE"); + assertRewrite("TA in (1,2,3) and TA < 1", "TA is null and null"); assertRewrite("TA in (1,2,3) or TA < 1", "TA in (1,2,3) or TA < 1"); assertRewrite("TA in (1,2,3) or TA in (2,3,4)", "TA in (1,2,3,4)"); assertRewrite("TA in (1,2,3) or TA in (4,5,6)", "TA in (1,2,3,4,5,6)"); - assertRewrite("TA in (1,2,3) and TA in (4,5,6)", "FALSE"); + assertRewrite("TA in (1,2,3) and TA in (4,5,6)", "TA is null and null"); + assertRewriteNotNull("TA in (1,2,3) and TA in (4,5,6)", "FALSE"); assertRewrite("TA in (1,2,3) and TA in (3,4,5)", "TA = 3"); assertRewrite("TA + TB in (1,2,3) and TA + TB in (3,4,5)", "TA + TB = 3"); assertRewrite("TA in (1,2,3) and DA > 1.5", "TA in (1,2,3) and DA > 1.5"); - assertRewrite("TA = 1 and TA = 3", "FALSE"); - assertRewrite("TA in (1) and TA in (3)", "FALSE"); + assertRewriteNotNull("TA = 1 and TA = 3", "FALSE"); + assertRewrite("TA = 1 and TA = 3", "TA is null and null"); + assertRewriteNotNull("TA in (1) and TA in (3)", "FALSE"); + assertRewrite("TA in (1) and TA in (3)", "TA is null and null"); assertRewrite("TA in (1) and TA in (1)", "TA = 1"); - assertRewrite("(TA > 3 and TA < 1) and TB < 5", "FALSE"); - assertRewrite("(TA > 3 and TA < 1) or TB < 5", "TB < 5"); + assertRewriteNotNull("(TA > 3 and TA < 1) and TB < 5", "FALSE"); + assertRewrite("(TA > 3 and TA < 1) and TB < 5", "TA is null and null and TB < 5"); + assertRewrite("TA > 3 and TB < 5 and TA < 1", "TA is null and null and TB < 5"); + assertRewrite("(TA > 3 and TA < 1) or TB < 5", "(TA is null and null) or TB < 5"); assertRewrite("((IA = 1 AND SC ='1') OR SC = '1212') AND IA =1", "((IA = 1 AND SC ='1') OR SC = '1212') AND IA =1"); assertRewrite("TA + TC", "TA + TC"); assertRewrite("(TA + TC >= 1 and TA + TC <=3 ) or (TA + TC > 5 and TA + TC < 7)", "(TA + TC >= 1 and TA + TC <=3 ) or (TA + TC > 5 and TA + TC < 7)"); - assertRewrite("(TA + TC > 3 and TA + TC < 1) or (TA + TC > 7 and TA + TC < 5)", "FALSE"); - assertRewrite("TA + TC > 3 and TA + TC < 1", "FALSE"); + assertRewriteNotNull("(TA + TC > 3 and TA + TC < 1) or (TA + TC > 7 and TA + TC < 5)", "FALSE"); + assertRewrite("(TA + TC > 3 and TA + TC < 1) or (TA + TC > 7 and TA + TC < 5)", "(TA + TC) is null and null"); + assertRewriteNotNull("TA + TC > 3 and TA + TC < 1", "FALSE"); + assertRewrite("TA + TC > 3 and TA + TC < 1", "(TA + TC) is null and null"); assertRewrite("TA + TC >= 3 and TA + TC < 3", "TA + TC >= 3 and TA + TC < 3"); - assertRewrite("TA + TC = 1 and TA + TC > 10", "FALSE"); + assertRewriteNotNull("TA + TC = 1 and TA + TC > 10", "FALSE"); + assertRewrite("TA + TC = 1 and TA + TC > 10", "(TA + TC) is null and null"); assertRewrite("TA + TC > 5 or TA + TC < 1", "TA + TC > 5 or TA + TC < 1"); assertRewrite("TA + TC > 5 or TA + TC > 1 or TA + TC > 10", "TA + TC > 1"); - assertRewrite("TA + TC > 5 or TA + TC > 1 or TA + TC < 10", "(not (TA + TC) IS NULL)"); + assertRewrite("TA + TC > 5 or TA + TC > 1 or TA + TC < 10", "(TA + TC) is not null or null"); assertRewrite("TA + TC > 5 and TA + TC > 1 and TA + TC > 10", "TA + TC > 10"); assertRewrite("TA + TC > 5 and TA + TC > 1 and TA + TC < 10", "TA + TC > 5 and TA + TC < 10"); assertRewrite("TA + TC > 1 or TA + TC < 1", "TA + TC > 1 or TA + TC < 1"); - assertRewrite("TA + TC > 1 or TA + TC < 10", "(not (TA + TC) IS NULL)"); + assertRewrite("TA + TC > 1 or TA + TC < 10", "(TA + TC) is not null or null"); assertRewrite("TA + TC > 5 and TA + TC < 10", "TA + TC > 5 and TA + TC < 10"); assertRewrite("TA + TC > 5 and TA + TC > 10", "TA + TC > 10"); - assertRewrite("TA + TC > 5 + 1 and TA + TC > 10", "TA + TC > 5 + 1 and TA + TC > 10"); - assertRewrite("TA + TC > 5 + 1 and TA + TC > 10", "TA + TC > 5 + 1 and TA + TC > 10"); + assertRewrite("TA + TC > 5 + 1 and TA + TC > 10", "TA + TC > 10"); assertRewrite("(TA + TC > 1 and TA + TC > 10) or TA + TC > 20", "TA + TC > 10"); assertRewrite("(TA + TC > 1 or TA + TC > 10) and TA + TC > 20", "TA + TC > 20"); assertRewrite("(TA + TC + TB > 1 or TA + TC + TB > 10) and TA + TC + TB > 20", "TA + TC + TB > 20"); @@ -147,25 +164,31 @@ public class SimplifyRangeTest extends ExpressionRewrite { assertRewrite("((TB > 30 and TA + TC > 40) and TA + TC > 20) and (TB > 10 and TB > 20)", "TB > 30 and TA + TC > 40"); assertRewrite("(TA + TC > 10 and TB > 10) or (TB > 10 and TB > 20)", "TA + TC > 10 and TB > 10 or TB > 20"); assertRewrite("((TA + TC > 10 or TA + TC > 5) and TB > 10) or (TB > 10 and (TB > 20 or TB < 10))", "(TA + TC > 5 and TB > 10) or (TB > 10 and (TB > 20 or TB < 10))"); - assertRewrite("TA + TC in (1,2,3) and TA + TC > 10", "FALSE"); + assertRewriteNotNull("TA + TC in (1,2,3) and TA + TC > 10", "FALSE"); + assertRewrite("TA + TC in (1,2,3) and TA + TC > 10", "(TA + TC) is null and null"); assertRewrite("TA + TC in (1,2,3) and TA + TC >= 1", "TA + TC in (1,2,3)"); assertRewrite("TA + TC in (1,2,3) and TA + TC > 1", "(TA + TC) IN (2, 3)"); assertRewrite("TA + TC in (1,2,3) or TA + TC >= 1", "TA + TC >= 1"); assertRewrite("TA + TC in (1)", "TA + TC in (1)"); assertRewrite("TA + TC in (1,2,3) and TA + TC < 10", "TA + TC in (1,2,3)"); - assertRewrite("TA + TC in (1,2,3) and TA + TC < 1", "FALSE"); + assertRewriteNotNull("TA + TC in (1,2,3) and TA + TC < 1", "FALSE"); + assertRewrite("TA + TC in (1,2,3) and TA + TC < 1", "(TA + TC) is null and null"); assertRewrite("TA + TC in (1,2,3) or TA + TC < 1", "TA + TC in (1,2,3) or TA + TC < 1"); assertRewrite("TA + TC in (1,2,3) or TA + TC in (2,3,4)", "TA + TC in (1,2,3,4)"); assertRewrite("TA + TC in (1,2,3) or TA + TC in (4,5,6)", "TA + TC in (1,2,3,4,5,6)"); - assertRewrite("TA + TC in (1,2,3) and TA + TC in (4,5,6)", "FALSE"); + assertRewriteNotNull("TA + TC in (1,2,3) and TA + TC in (4,5,6)", "FALSE"); + assertRewrite("TA + TC in (1,2,3) and TA + TC in (4,5,6)", "(TA + TC) is null and null"); assertRewrite("TA + TC in (1,2,3) and TA + TC in (3,4,5)", "TA + TC = 3"); assertRewrite("TA + TC + TB in (1,2,3) and TA + TC + TB in (3,4,5)", "TA + TC + TB = 3"); assertRewrite("TA + TC in (1,2,3) and DA > 1.5", "TA + TC in (1,2,3) and DA > 1.5"); - assertRewrite("TA + TC = 1 and TA + TC = 3", "FALSE"); - assertRewrite("TA + TC in (1) and TA + TC in (3)", "FALSE"); + assertRewriteNotNull("TA + TC = 1 and TA + TC = 3", "FALSE"); + assertRewrite("TA + TC = 1 and TA + TC = 3", "(TA + TC) is null and null"); + assertRewriteNotNull("TA + TC in (1) and TA + TC in (3)", "FALSE"); + assertRewrite("TA + TC in (1) and TA + TC in (3)", "(TA + TC) is null and null"); assertRewrite("TA + TC in (1) and TA + TC in (1)", "TA + TC = 1"); - assertRewrite("(TA + TC > 3 and TA + TC < 1) and TB < 5", "FALSE"); - assertRewrite("(TA + TC > 3 and TA + TC < 1) or TB < 5", "TB < 5"); + assertRewriteNotNull("(TA + TC > 3 and TA + TC < 1) and TB < 5", "FALSE"); + assertRewrite("(TA + TC > 3 and TA + TC < 1) and TB < 5", "(TA + TC) is null and null and TB < 5"); + assertRewrite("(TA + TC > 3 and TA + TC < 1) or TB < 5", "((TA + TC) is null and null) OR TB < 5"); assertRewrite("(TA + TC > 3 OR TA < 1) AND TB = 2) AND IA =1", "(TA + TC > 3 OR TA < 1) AND TB = 2) AND IA =1"); @@ -176,67 +199,79 @@ public class SimplifyRangeTest extends ExpressionRewrite { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp(SimplifyRange.INSTANCE) )); - assertRewrite("TA", "TA"); + assertRewrite("AA", "AA"); assertRewrite( - "(TA >= date '2024-01-01' and TA <= date '2024-01-03') or (TA > date '2024-01-05' and TA < date '2024-01-07')", - "(TA >= date '2024-01-01' and TA <= date '2024-01-03') or (TA > date '2024-01-05' and TA < date '2024-01-07')"); + "(AA >= date '2024-01-01' and AA <= date '2024-01-03') or (AA > date '2024-01-05' and AA < date '2024-01-07')", + "(AA >= date '2024-01-01' and AA <= date '2024-01-03') or (AA > date '2024-01-05' and AA < date '2024-01-07')"); + assertRewriteNotNull( + "(AA > date '2024-01-03' and AA < date '2024-01-01') or (AA > date '2024-01-07'and AA < date '2024-01-05')", + "false"); assertRewrite( - "(TA > date '2024-01-03' and TA < date '2024-01-01') or (TA > date '2024-01-07'and TA < date '2024-01-05')", - "FALSE"); - assertRewrite("TA > date '2024-01-03' and TA < date '2024-01-01'", "FALSE"); - assertRewrite("TA >= date '2024-01-01' and TA < date '2024-01-01'", - "TA >= date '2024-01-01' and TA < date '2024-01-01'"); - assertRewrite("TA = date '2024-01-01' and TA > date '2024-01-10'", "FALSE"); - assertRewrite("TA > date '2024-01-05' or TA < date '2024-01-01'", - "TA > date '2024-01-05' or TA < date '2024-01-01'"); - assertRewrite("TA > date '2024-01-05' or TA > date '2024-01-01' or TA > date '2024-01-10'", - "TA > date '2024-01-01'"); - assertRewrite("TA > date '2024-01-05' or TA > date '2024-01-01' or TA < date '2024-01-10'", "cast(TA as date) IS NOT NULL"); - assertRewriteNotNull("TA > date '2024-01-05' or TA > date '2024-01-01' or TA < date '2024-01-10'", "TRUE"); - assertRewrite("TA > date '2024-01-05' and TA > date '2024-01-01' and TA > date '2024-01-10'", - "TA > date '2024-01-10'"); - assertRewrite("TA > date '2024-01-05' and TA > date '2024-01-01' and TA < date '2024-01-10'", - "TA > date '2024-01-05' and TA < date '2024-01-10'"); - assertRewrite("TA > date '2024-01-05' or TA < date '2024-01-05'", - "TA > date '2024-01-05' or TA < date '2024-01-05'"); - assertRewrite("TA > date '2024-01-01' or TA < date '2024-01-10'", "cast(TA as date) IS NOT NULL"); - assertRewriteNotNull("TA > date '2024-01-01' or TA < date '2024-01-10'", "TRUE"); - assertRewrite("TA > date '2024-01-05' and TA < date '2024-01-10'", - "TA > date '2024-01-05' and TA < date '2024-01-10'"); - assertRewrite("TA > date '2024-01-05' and TA > date '2024-01-10'", "TA > date '2024-01-10'"); - assertRewrite("(TA > date '2024-01-01' and TA > date '2024-01-10') or TA > date '2024-01-20'", - "TA > date '2024-01-10'"); - assertRewrite("(TA > date '2024-01-01' or TA > date '2024-01-10') and TA > date '2024-01-20'", - "TA > date '2024-01-20'"); - assertRewrite("TA > date '2024-01-05' or TA > date '2024-01-05'", "TA > date '2024-01-05'"); + "(AA > date '2024-01-03' and AA < date '2024-01-01') or (AA > date '2024-01-07'and AA < date '2024-01-05')", + "AA is null and null"); + assertRewriteNotNull("AA > date '2024-01-03' and AA < date '2024-01-01'", "FALSE"); + assertRewrite("AA > date '2024-01-03' and AA < date '2024-01-01'", "AA is null and null"); + assertRewrite("AA >= date '2024-01-01' and AA < date '2024-01-01'", + "AA >= date '2024-01-01' and AA < date '2024-01-01'"); + assertRewriteNotNull("AA = date '2024-01-01' and AA > date '2024-01-10'", "FALSE"); + assertRewrite("AA = date '2024-01-01' and AA > date '2024-01-10'", "AA is null and null"); + assertRewrite("AA > date '2024-01-05' or AA < date '2024-01-01'", + "AA > date '2024-01-05' or AA < date '2024-01-01'"); + assertRewrite("AA > date '2024-01-05' or AA > date '2024-01-01' or AA > date '2024-01-10'", + "AA > date '2024-01-01'"); + assertRewrite("AA > date '2024-01-05' or AA > date '2024-01-01' or AA < date '2024-01-10'", "AA is not null or null"); + assertRewriteNotNull("AA > date '2024-01-05' or AA > date '2024-01-01' or AA < date '2024-01-10'", "TRUE"); + assertRewrite("AA > date '2024-01-05' and AA > date '2024-01-01' and AA > date '2024-01-10'", + "AA > date '2024-01-10'"); + assertRewrite("AA > date '2024-01-05' and AA > date '2024-01-01' and AA < date '2024-01-10'", + "AA > date '2024-01-05' and AA < date '2024-01-10'"); + assertRewrite("AA > date '2024-01-05' or AA < date '2024-01-05'", + "AA > date '2024-01-05' or AA < date '2024-01-05'"); + assertRewrite("AA > date '2024-01-01' or AA < date '2024-01-10'", "AA is not null or null"); + assertRewriteNotNull("AA > date '2024-01-01' or AA < date '2024-01-10'", "TRUE"); + assertRewrite("AA > date '2024-01-05' and AA < date '2024-01-10'", + "AA > date '2024-01-05' and AA < date '2024-01-10'"); + assertRewrite("AA > date '2024-01-05' and AA > date '2024-01-10'", "AA > date '2024-01-10'"); + assertRewrite("(AA > date '2024-01-01' and AA > date '2024-01-10') or AA > date '2024-01-20'", + "AA > date '2024-01-10'"); + assertRewrite("(AA > date '2024-01-01' or AA > date '2024-01-10') and AA > date '2024-01-20'", + "AA > date '2024-01-20'"); + assertRewrite("AA > date '2024-01-05' or AA > date '2024-01-05'", "AA > date '2024-01-05'"); assertRewrite( - "(TA > date '2024-01-10' or TA > date '2024-01-20') and (TB > date '2024-01-10' and TB < date '2024-01-20')", - "TA > date '2024-01-10' and (TB > date '2024-01-10' and TB < date '2024-01-20') "); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and TA > date '2024-01-10'", + "(AA > date '2024-01-10' or AA > date '2024-01-20') and (AB > date '2024-01-10' and AB < date '2024-01-20')", + "AA > date '2024-01-10' and (AB > date '2024-01-10' and AB < date '2024-01-20') "); + assertRewriteNotNull("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA > date '2024-01-10'", "FALSE"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA > date '2024-01-10'", "AA is null and null"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA >= date '2024-01-01'", + "AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03')"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA > date '2024-01-01'", + "AA IN (date '2024-01-02', date '2024-01-03')"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') or AA >= date '2024-01-01'", + "AA >= date '2024-01-01'"); + assertRewrite("AA in (date '2024-01-01')", "AA in (date '2024-01-01')"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA < date '2024-01-10'", + "AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03')"); + assertRewriteNotNull("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA < date '2024-01-01'", "FALSE"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and TA >= date '2024-01-01'", - "TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03')"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and TA > date '2024-01-01'", - "TA IN (date '2024-01-02', date '2024-01-03')"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') or TA >= date '2024-01-01'", - "TA >= date '2024-01-01'"); - assertRewrite("TA in (date '2024-01-01')", "TA in (date '2024-01-01')"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and TA < date '2024-01-10'", - "TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03')"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and TA < date '2024-01-01'", + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') and AA < date '2024-01-01'", + "AA is null and null"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') or AA < date '2024-01-01'", + "AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') or AA < date '2024-01-01'"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02') or AA in (date '2024-01-02', date '2024-01-03')", + "AA in (date '2024-01-01',date '2024-01-02',date '2024-01-03')"); + assertRewriteNotNull("AA in (date '2024-01-01',date '2024-01-02') and AA in (date '2024-01-03', date '2024-01-04')", "FALSE"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') or TA < date '2024-01-01'", - "TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03') or TA < date '2024-01-01'"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02') or TA in (date '2024-01-02', date '2024-01-03')", - "TA in (date '2024-01-01',date '2024-01-02',date '2024-01-03')"); - assertRewrite("TA in (date '2024-01-01',date '2024-01-02') and TA in (date '2024-01-03', date '2024-01-04')", - "FALSE"); - assertRewrite("TA = date '2024-01-03' and TA = date '2024-01-01'", "FALSE"); - assertRewrite("TA in (date '2024-01-01') and TA in (date '2024-01-03')", "FALSE"); - assertRewrite("TA in (date '2024-01-03') and TA in (date '2024-01-03')", "TA = date '2024-01-03'"); - assertRewrite("(TA > date '2024-01-03' and TA < date '2024-01-01') and TB < date '2024-01-05'", "FALSE"); - assertRewrite("(TA > date '2024-01-03' and TA < date '2024-01-01') or TB < date '2024-01-05'", - "TB < date '2024-01-05'"); + assertRewrite("AA in (date '2024-01-01',date '2024-01-02') and AA in (date '2024-01-03', date '2024-01-04')", + "AA is null and null"); + assertRewriteNotNull("AA = date '2024-01-03' and AA = date '2024-01-01'", "FALSE"); + assertRewrite("AA = date '2024-01-03' and AA = date '2024-01-01'", "AA is null and null"); + assertRewriteNotNull("AA in (date '2024-01-01') and AA in (date '2024-01-03')", "FALSE"); + assertRewrite("AA in (date '2024-01-01') and AA in (date '2024-01-03')", "AA is null and null"); + assertRewrite("AA in (date '2024-01-03') and AA in (date '2024-01-03')", "AA = date '2024-01-03'"); + assertRewriteNotNull("(AA > date '2024-01-03' and AA < date '2024-01-01') and AB < date '2024-01-05'", "FALSE"); + assertRewrite("(AA > date '2024-01-03' and AA < date '2024-01-01') and AB < date '2024-01-05'", "AA is null and null and AB < date '2024-01-05'"); + assertRewrite("AA > date '2024-01-03' and AB < date '2024-01-05' and AA < date '2024-01-01'", "AA is null and null and AB < date '2024-01-05'"); + assertRewrite("(AA > date '2024-01-03' and AA < date '2024-01-01') or AB < date '2024-01-05'", "(AA is null and null) or AB < date '2024-01-05'"); } @Test @@ -244,69 +279,84 @@ public class SimplifyRangeTest extends ExpressionRewrite { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp(SimplifyRange.INSTANCE) )); - assertRewrite("TA", "TA"); + assertRewrite("CA", "CA"); assertRewrite( - "(TA >= timestamp '2024-01-01 00:00:00' and TA <= timestamp '2024-01-03 00:00:00') or (TA > timestamp '2024-01-05 00:00:00' and TA < timestamp '2024-01-07 00:00:00')", - "(TA >= timestamp '2024-01-01 00:00:00' and TA <= timestamp '2024-01-03 00:00:00') or (TA > timestamp '2024-01-05 00:00:00' and TA < timestamp '2024-01-07 00:00:00')"); - assertRewrite( - "(TA > timestamp '2024-01-03 00:00:10' and TA < timestamp '2024-01-01 00:00:10') or (TA > timestamp '2024-01-07 00:00:10'and TA < timestamp '2024-01-05 00:00:10')", + "(CA >= timestamp '2024-01-01 00:00:00' and CA <= timestamp '2024-01-03 00:00:00') or (CA > timestamp '2024-01-05 00:00:00' and CA < timestamp '2024-01-07 00:00:00')", + "(CA >= timestamp '2024-01-01 00:00:00' and CA <= timestamp '2024-01-03 00:00:00') or (CA > timestamp '2024-01-05 00:00:00' and CA < timestamp '2024-01-07 00:00:00')"); + assertRewriteNotNull( + "(CA > timestamp '2024-01-03 00:00:10' and CA < timestamp '2024-01-01 00:00:10') or (CA > timestamp '2024-01-07 00:00:10'and CA < timestamp '2024-01-05 00:00:10')", "FALSE"); - assertRewrite("TA > timestamp '2024-01-03 00:00:10' and TA < timestamp '2024-01-01 01:00:00'", "FALSE"); - assertRewrite("TA >= timestamp '2024-01-01 00:00:10' and TA < timestamp '2024-01-01 00:00:10'", - "TA >= timestamp '2024-01-01 00:00:10' and TA < timestamp '2024-01-01 00:00:10'"); - assertRewrite("TA = timestamp '2024-01-01 10:00:10' and TA > timestamp '2024-01-10 00:00:10'", "FALSE"); - assertRewrite("TA > timestamp '2024-01-05 00:00:10' or TA < timestamp '2024-01-01 00:00:10'", - "TA > timestamp '2024-01-05 00:00:10' or TA < timestamp '2024-01-01 00:00:10'"); - assertRewrite("TA > timestamp '2024-01-05 00:00:10' or TA > timestamp '2024-01-01 00:00:10' or TA > timestamp '2024-01-10 00:00:10'", - "TA > timestamp '2024-01-01 00:00:10'"); - assertRewrite("TA > timestamp '2024-01-05 00:00:10' or TA > timestamp '2024-01-01 00:00:10' or TA < timestamp '2024-01-10 00:00:10'", "cast(TA as datetime) IS NOT NULL"); - assertRewriteNotNull("TA > timestamp '2024-01-05 00:00:10' or TA > timestamp '2024-01-01 00:00:10' or TA < timestamp '2024-01-10 00:00:10'", "TRUE"); - assertRewrite("TA > timestamp '2024-01-05 00:00:10' and TA > timestamp '2024-01-01 00:00:10' and TA > timestamp '2024-01-10 00:00:15'", - "TA > timestamp '2024-01-10 00:00:15'"); - assertRewrite("TA > timestamp '2024-01-05 00:00:10' and TA > timestamp '2024-01-01 00:00:10' and TA < timestamp '2024-01-10 00:00:10'", - "TA > timestamp '2024-01-05 00:00:10' and TA < timestamp '2024-01-10 00:00:10'"); - assertRewrite("TA > timestamp '2024-01-05 00:00:10' or TA < timestamp '2024-01-05 00:00:10'", - "TA > timestamp '2024-01-05 00:00:10' or TA < timestamp '2024-01-05 00:00:10'"); - assertRewrite("TA > timestamp '2024-01-01 00:02:10' or TA < timestamp '2024-01-10 00:02:10'", "cast(TA as datetime) IS NOT NULL"); - assertRewriteNotNull("TA > timestamp '2024-01-01 00:00:00' or TA < timestamp '2024-01-10 00:00:00'", "TRUE"); - assertRewrite("TA > timestamp '2024-01-05 01:00:00' and TA < timestamp '2024-01-10 01:00:00'", - "TA > timestamp '2024-01-05 01:00:00' and TA < timestamp '2024-01-10 01:00:00'"); - assertRewrite("TA > timestamp '2024-01-05 01:00:00' and TA > timestamp '2024-01-10 01:00:00'", "TA > timestamp '2024-01-10 01:00:00'"); - assertRewrite("(TA > timestamp '2024-01-01 01:00:00' and TA > timestamp '2024-01-10 01:00:00') or TA > timestamp '2024-01-20 01:00:00'", - "TA > timestamp '2024-01-10 01:00:00'"); - assertRewrite("(TA > timestamp '2024-01-01 01:00:00' or TA > timestamp '2024-01-10 01:00:00') and TA > timestamp '2024-01-20 01:00:00'", - "TA > timestamp '2024-01-20 01:00:00'"); - assertRewrite("TA > timestamp '2024-01-05 01:00:00' or TA > timestamp '2024-01-05 01:00:00'", "TA > timestamp '2024-01-05 01:00:00'"); assertRewrite( - "(TA > timestamp '2024-01-10 01:00:00' or TA > timestamp '2024-01-20 01:00:00') and (TB > timestamp '2024-01-10 01:00:00' and TB < timestamp '2024-01-20 01:00:00')", - "TA > timestamp '2024-01-10 01:00:00' and (TB > timestamp '2024-01-10 01:00:00' and TB < timestamp '2024-01-20 01:00:00') "); - assertRewrite("TA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 03:00:00') and TA > timestamp '2024-01-10 01:00:00'", + "(CA > timestamp '2024-01-03 00:00:10' and CA < timestamp '2024-01-01 00:00:10') or (CA > timestamp '2024-01-07 00:00:10'and CA < timestamp '2024-01-05 00:00:10')", + "CA is null and null"); + assertRewriteNotNull("CA > timestamp '2024-01-03 00:00:10' and CA < timestamp '2024-01-01 01:00:00'", "FALSE"); + assertRewrite("CA > timestamp '2024-01-03 00:00:10' and CA < timestamp '2024-01-01 01:00:00'", "CA is null and null"); + assertRewrite("CA >= timestamp '2024-01-01 00:00:10' and CA < timestamp '2024-01-01 00:00:10'", + "CA >= timestamp '2024-01-01 00:00:10' and CA < timestamp '2024-01-01 00:00:10'"); + assertRewriteNotNull("CA = timestamp '2024-01-01 10:00:10' and CA > timestamp '2024-01-10 00:00:10'", "FALSE"); + assertRewrite("CA = timestamp '2024-01-01 10:00:10' and CA > timestamp '2024-01-10 00:00:10'", "CA is null and null"); + assertRewrite("CA > timestamp '2024-01-05 00:00:10' or CA < timestamp '2024-01-01 00:00:10'", + "CA > timestamp '2024-01-05 00:00:10' or CA < timestamp '2024-01-01 00:00:10'"); + assertRewrite("CA > timestamp '2024-01-05 00:00:10' or CA > timestamp '2024-01-01 00:00:10' or CA > timestamp '2024-01-10 00:00:10'", + "CA > timestamp '2024-01-01 00:00:10'"); + assertRewrite("CA > timestamp '2024-01-05 00:00:10' or CA > timestamp '2024-01-01 00:00:10' or CA < timestamp '2024-01-10 00:00:10'", "CA is not null or null"); + assertRewriteNotNull("CA > timestamp '2024-01-05 00:00:10' or CA > timestamp '2024-01-01 00:00:10' or CA < timestamp '2024-01-10 00:00:10'", "TRUE"); + assertRewrite("CA > timestamp '2024-01-05 00:00:10' and CA > timestamp '2024-01-01 00:00:10' and CA > timestamp '2024-01-10 00:00:15'", + "CA > timestamp '2024-01-10 00:00:15'"); + assertRewrite("CA > timestamp '2024-01-05 00:00:10' and CA > timestamp '2024-01-01 00:00:10' and CA < timestamp '2024-01-10 00:00:10'", + "CA > timestamp '2024-01-05 00:00:10' and CA < timestamp '2024-01-10 00:00:10'"); + assertRewrite("CA > timestamp '2024-01-05 00:00:10' or CA < timestamp '2024-01-05 00:00:10'", + "CA > timestamp '2024-01-05 00:00:10' or CA < timestamp '2024-01-05 00:00:10'"); + assertRewrite("CA > timestamp '2024-01-01 00:02:10' or CA < timestamp '2024-01-10 00:02:10'", "CA is not null or null"); + assertRewriteNotNull("CA > timestamp '2024-01-01 00:00:00' or CA < timestamp '2024-01-10 00:00:00'", "TRUE"); + assertRewrite("CA > timestamp '2024-01-05 01:00:00' and CA < timestamp '2024-01-10 01:00:00'", + "CA > timestamp '2024-01-05 01:00:00' and CA < timestamp '2024-01-10 01:00:00'"); + assertRewrite("CA > timestamp '2024-01-05 01:00:00' and CA > timestamp '2024-01-10 01:00:00'", "CA > timestamp '2024-01-10 01:00:00'"); + assertRewrite("(CA > timestamp '2024-01-01 01:00:00' and CA > timestamp '2024-01-10 01:00:00') or CA > timestamp '2024-01-20 01:00:00'", + "CA > timestamp '2024-01-10 01:00:00'"); + assertRewrite("(CA > timestamp '2024-01-01 01:00:00' or CA > timestamp '2024-01-10 01:00:00') and CA > timestamp '2024-01-20 01:00:00'", + "CA > timestamp '2024-01-20 01:00:00'"); + assertRewrite("CA > timestamp '2024-01-05 01:00:00' or CA > timestamp '2024-01-05 01:00:00'", "CA > timestamp '2024-01-05 01:00:00'"); + assertRewrite( + "(CA > timestamp '2024-01-10 01:00:00' or CA > timestamp '2024-01-20 01:00:00') and (CB > timestamp '2024-01-10 01:00:00' and CB < timestamp '2024-01-20 01:00:00')", + "CA > timestamp '2024-01-10 01:00:00' and (CB > timestamp '2024-01-10 01:00:00' and CB < timestamp '2024-01-20 01:00:00') "); + assertRewriteNotNull("CA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 03:00:00') and CA > timestamp '2024-01-10 01:00:00'", "FALSE"); - assertRewrite("TA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 01:50:00',timestamp '2024-01-03 02:00:00') and TA >= timestamp '2024-01-01'", - "TA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 01:50:00',timestamp '2024-01-03 02:00:00')"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and TA > timestamp '2024-01-01 02:10:00'", - "TA IN (timestamp '2024-01-02 02:00:00', timestamp '2024-01-03 02:00:00')"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') or TA >= timestamp '2024-01-01 01:00:00'", - "TA >= timestamp '2024-01-01 01:00:00'"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00')", "TA in (timestamp '2024-01-01 02:00:00')"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and TA < timestamp '2024-01-10 02:00:00'", - "TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00')"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and TA < timestamp '2024-01-01 02:00:00'", + assertRewrite("CA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 03:00:00') and CA > timestamp '2024-01-10 01:00:00'", + "CA is null and null"); + assertRewrite("CA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 01:50:00',timestamp '2024-01-03 02:00:00') and CA >= timestamp '2024-01-01'", + "CA in (timestamp '2024-01-01 01:00:00',timestamp '2024-01-02 01:50:00',timestamp '2024-01-03 02:00:00')"); + assertRewrite("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and CA > timestamp '2024-01-01 02:10:00'", + "CA IN (timestamp '2024-01-02 02:00:00', timestamp '2024-01-03 02:00:00')"); + assertRewrite("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') or CA >= timestamp '2024-01-01 01:00:00'", + "CA >= timestamp '2024-01-01 01:00:00'"); + assertRewrite("CA in (timestamp '2024-01-01 02:00:00')", "CA in (timestamp '2024-01-01 02:00:00')"); + assertRewrite("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and CA < timestamp '2024-01-10 02:00:00'", + "CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00')"); + assertRewriteNotNull("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and CA < timestamp '2024-01-01 02:00:00'", "FALSE"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and TA < timestamp '2024-01-01 02:00:01'", - "TA = timestamp '2024-01-01 02:00:00'"); - assertRewrite("TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') or TA < timestamp '2024-01-01 01:00:00'", - "TA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') or TA < timestamp '2024-01-01 01:00:00'"); - assertRewrite("TA in (timestamp '2024-01-01 00:00:00',timestamp '2024-01-02 00:00:00') or TA in (timestamp '2024-01-02 00:00:00', timestamp '2024-01-03 00:00:00')", - "TA in (timestamp '2024-01-01 00:00:00',timestamp '2024-01-02 00:00:00',timestamp '2024-01-03 00:00:00')"); - assertRewrite("TA in (timestamp '2024-01-01 00:50:00',timestamp '2024-01-02 00:50:00') and TA in (timestamp '2024-01-03 00:50:00', timestamp '2024-01-04 00:50:00')", + assertRewrite("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and CA < timestamp '2024-01-01 02:00:00'", + "CA is null and null"); + assertRewrite("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') and CA < timestamp '2024-01-01 02:00:01'", + "CA = timestamp '2024-01-01 02:00:00'"); + assertRewrite("CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') or CA < timestamp '2024-01-01 01:00:00'", + "CA in (timestamp '2024-01-01 02:00:00',timestamp '2024-01-02 02:00:00',timestamp '2024-01-03 02:00:00') or CA < timestamp '2024-01-01 01:00:00'"); + assertRewrite("CA in (timestamp '2024-01-01 00:00:00',timestamp '2024-01-02 00:00:00') or CA in (timestamp '2024-01-02 00:00:00', timestamp '2024-01-03 00:00:00')", + "CA in (timestamp '2024-01-01 00:00:00',timestamp '2024-01-02 00:00:00',timestamp '2024-01-03 00:00:00')"); + assertRewriteNotNull("CA in (timestamp '2024-01-01 00:50:00',timestamp '2024-01-02 00:50:00') and CA in (timestamp '2024-01-03 00:50:00', timestamp '2024-01-04 00:50:00')", "FALSE"); - assertRewrite("TA = timestamp '2024-01-03 00:50:00' and TA = timestamp '2024-01-01 00:50:00'", "FALSE"); - assertRewrite("TA in (timestamp '2024-01-01 00:50:00') and TA in (timestamp '2024-01-03 00:50:00')", "FALSE"); - assertRewrite("TA in (timestamp '2024-01-03 00:50:00') and TA in (timestamp '2024-01-03 00:50:00')", "TA = timestamp '2024-01-03 00:50:00'"); - assertRewrite("(TA > timestamp '2024-01-03 00:50:00' and TA < timestamp '2024-01-01 00:50:00') and TB < timestamp '2024-01-05 00:50:00'", "FALSE"); - assertRewrite("(TA > timestamp '2024-01-03 00:50:00' and TA < timestamp '2024-01-01 00:50:00') or TB < timestamp '2024-01-05 00:50:00'", - "TB < timestamp '2024-01-05 00:50:00'"); + assertRewrite("CA in (timestamp '2024-01-01 00:50:00',timestamp '2024-01-02 00:50:00') and CA in (timestamp '2024-01-03 00:50:00', timestamp '2024-01-04 00:50:00')", + "CA is null and null"); + assertRewriteNotNull("CA = timestamp '2024-01-03 00:50:00' and CA = timestamp '2024-01-01 00:50:00'", "FALSE"); + assertRewrite("CA = timestamp '2024-01-03 00:50:00' and CA = timestamp '2024-01-01 00:50:00'", "CA is null and null"); + assertRewriteNotNull("CA in (timestamp '2024-01-01 00:50:00') and CA in (timestamp '2024-01-03 00:50:00')", "FALSE"); + assertRewrite("CA in (timestamp '2024-01-01 00:50:00') and CA in (timestamp '2024-01-03 00:50:00')", "CA is null and null"); + assertRewrite("CA in (timestamp '2024-01-03 00:50:00') and CA in (timestamp '2024-01-03 00:50:00')", "CA = timestamp '2024-01-03 00:50:00'"); + assertRewriteNotNull("(CA > timestamp '2024-01-03 00:50:00' and CA < timestamp '2024-01-01 00:50:00') and CB < timestamp '2024-01-05 00:50:00'", "FALSE"); + assertRewrite("(CA > timestamp '2024-01-03 00:50:00' and CA < timestamp '2024-01-01 00:50:00') and CB < timestamp '2024-01-05 00:50:00'", "CA is null and null and CB < timestamp '2024-01-05 00:50:00'"); + assertRewrite("CA > timestamp '2024-01-03 00:50:00' and CB < timestamp '2024-01-05 00:50:00' and CA < timestamp '2024-01-01 00:50:00'", "CA is null and null and CB < timestamp '2024-01-05 00:50:00'"); + assertRewrite("(CA > timestamp '2024-01-03 00:50:00' and CA < timestamp '2024-01-01 00:50:00') or CB < timestamp '2024-01-05 00:50:00'", + "(CA is null and null) OR CB < timestamp '2024-01-05 00:50:00'"); } private void assertRewrite(String expression, String expected) { @@ -322,7 +372,9 @@ public class SimplifyRangeTest extends ExpressionRewrite { private void assertRewriteNotNull(String expression, String expected) { Map<String, Slot> mem = Maps.newHashMap(); Expression needRewriteExpression = replaceNotNullUnboundSlot(PARSER.parseExpression(expression), mem); + needRewriteExpression = typeCoercion(needRewriteExpression); Expression expectedExpression = replaceNotNullUnboundSlot(PARSER.parseExpression(expected), mem); + expectedExpression = typeCoercion(expectedExpression); Expression rewrittenExpression = executor.rewrite(needRewriteExpression, context); Assertions.assertEquals(expectedExpression, rewrittenExpression); } @@ -374,11 +426,15 @@ public class SimplifyRangeTest extends ExpressionRewrite { case 'I': return IntegerType.INSTANCE; case 'D': - return DoubleType.INSTANCE; + return DecimalV3Type.createDecimalV3Type(2, 1); case 'S': return StringType.INSTANCE; case 'B': return BooleanType.INSTANCE; + case 'C': + return DateTimeV2Type.SYSTEM_DEFAULT; + case 'A': + return DateV2Type.INSTANCE; default: return BigIntType.INSTANCE; } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org