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

Reply via email to