This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new f04008b56d2 branch-4.1: [fix](expr opt) Preserve cast-induced 
nullability in comparisons #67730 (#67843)
f04008b56d2 is described below

commit f04008b56d26768f4419f7b7d69209cbcb417b9b
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Sep 12 00:50:06 2026 +0800

    branch-4.1: [fix](expr opt) Preserve cast-induced nullability in 
comparisons #67730 (#67843)
    
    Cherry-picked from #67730
    
    Co-authored-by: morrySnow <[email protected]>
---
 .../rules/SimplifyComparisonPredicate.java         | 25 ++++++++++--------
 .../rules/SimplifyComparisonPredicateTest.java     | 30 ++++++++++++++++++++++
 2 files changed, 45 insertions(+), 10 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
index 335fe783071..6e3a53bc4cd 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
@@ -486,6 +486,7 @@ public class SimplifyComparisonPredicate implements 
ExpressionPatternRuleFactory
 
     private static Expression 
processTypeRangeLimitComparison(ComparisonPredicate cp, Expression left,
             NumericLiteral right) {
+        Expression nullabilityExpression = left;
         BigDecimal typeMinValue = null;
         BigDecimal typeMaxValue = null;
         // cmp float like have lost precision, for example float.max_value + 
0.01 still eval to float.max_value
@@ -501,7 +502,11 @@ public class SimplifyComparisonPredicate implements 
ExpressionPatternRuleFactory
         // cast(child as dataType2) range should be:
         //  [ max(childDataType.min_value, dataType2.min_value), 
min(childDataType.max_value, dataType2.max_value)]
         if (left instanceof Cast) {
-            left = ((Cast) left).child();
+            Cast cast = (Cast) left;
+            left = cast.child();
+            if (!Cast.castNullable(false, left.getDataType(), 
cast.getDataType())) {
+                nullabilityExpression = left;
+            }
             if (left.getDataType().isIntegerLikeType() || 
left.getDataType().isDecimalV3Type()) {
                 Optional<Pair<BigDecimal, BigDecimal>> minMaxOpt =
                         
TypeCoercionUtils.getDataTypeMinMaxValue(left.getDataType());
@@ -524,7 +529,7 @@ public class SimplifyComparisonPredicate implements 
ExpressionPatternRuleFactory
         int cmpMax = literal.compareTo(typeMaxValue);
         if (cp instanceof EqualTo) {
             if (cmpMin < 0 || cmpMax > 0) {
-                return ExpressionUtils.falseOrNull(left);
+                return ExpressionUtils.falseOrNull(nullabilityExpression);
             }
         } else if (cp instanceof NullSafeEqual) {
             if (cmpMin < 0 || cmpMax > 0) {
@@ -532,37 +537,37 @@ public class SimplifyComparisonPredicate implements 
ExpressionPatternRuleFactory
             }
         } else if (cp instanceof GreaterThan) {
             if (cmpMin < 0) {
-                return ExpressionUtils.trueOrNull(left);
+                return ExpressionUtils.trueOrNull(nullabilityExpression);
             }
             if (cmpMax >= 0) {
-                return ExpressionUtils.falseOrNull(left);
+                return ExpressionUtils.falseOrNull(nullabilityExpression);
             }
         } else if (cp instanceof GreaterThanEqual) {
             if (cmpMin <= 0) {
-                return ExpressionUtils.trueOrNull(left);
+                return ExpressionUtils.trueOrNull(nullabilityExpression);
             }
             if (cmpMax == 0) {
                 return new EqualTo(cp.left(), cp.right());
             }
             if (cmpMax > 0) {
-                return ExpressionUtils.falseOrNull(left);
+                return ExpressionUtils.falseOrNull(nullabilityExpression);
             }
         } else if (cp instanceof LessThan) {
             if (cmpMin <= 0) {
-                return ExpressionUtils.falseOrNull(left);
+                return ExpressionUtils.falseOrNull(nullabilityExpression);
             }
             if (cmpMax > 0) {
-                return ExpressionUtils.trueOrNull(left);
+                return ExpressionUtils.trueOrNull(nullabilityExpression);
             }
         } else if (cp instanceof LessThanEqual) {
             if (cmpMin < 0) {
-                return ExpressionUtils.falseOrNull(left);
+                return ExpressionUtils.falseOrNull(nullabilityExpression);
             }
             if (cmpMin == 0) {
                 return new EqualTo(cp.left(), cp.right());
             }
             if (cmpMax >= 0) {
-                return ExpressionUtils.trueOrNull(left);
+                return ExpressionUtils.trueOrNull(nullabilityExpression);
             }
         }
         return cp;
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
index 7d6967e6b3b..21f98158e4e 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
@@ -33,6 +33,7 @@ import 
org.apache.doris.nereids.trees.expressions.LessThanEqual;
 import org.apache.doris.nereids.trees.expressions.Not;
 import org.apache.doris.nereids.trees.expressions.NullSafeEqual;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
+import org.apache.doris.nereids.trees.expressions.TryCast;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
@@ -928,6 +929,35 @@ class SimplifyComparisonPredicateTest extends 
ExpressionRewriteTestHelper {
         NO_CHANGE_CP // no change cmp type
     }
 
+    @Test
+    void testTypeRangeLimitPreservesCastNullability() {
+        executor = new ExpressionRuleExecutor(ImmutableList.of(
+                bottomUp(SimplifyComparisonPredicate.INSTANCE)
+        ));
+
+        SlotReference nonNullableBigInt = new SlotReference("bigint_slot", 
BigIntType.INSTANCE, false);
+        List<Cast> nullableCasts = ImmutableList.of(
+                new Cast(nonNullableBigInt, TinyIntType.INSTANCE),
+                new TryCast(nonNullableBigInt, TinyIntType.INSTANCE));
+        for (Cast nullableCast : nullableCasts) {
+            assertRewrite(new GreaterThan(nullableCast, new 
TinyIntLiteral((byte) 127)),
+                    ExpressionUtils.falseOrNull(nullableCast));
+            assertRewrite(new LessThan(nullableCast, new TinyIntLiteral((byte) 
-128)),
+                    ExpressionUtils.falseOrNull(nullableCast));
+            assertRewrite(new LessThanEqual(nullableCast, new 
TinyIntLiteral((byte) 127)),
+                    ExpressionUtils.trueOrNull(nullableCast));
+        }
+
+        SlotReference nonNullableTinyInt = new SlotReference("tinyint_slot", 
TinyIntType.INSTANCE, false);
+        List<Cast> safeCasts = ImmutableList.of(
+                new Cast(nonNullableTinyInt, SmallIntType.INSTANCE),
+                new TryCast(nonNullableTinyInt, SmallIntType.INSTANCE));
+        for (Cast safeCast : safeCasts) {
+            assertRewrite(new GreaterThan(safeCast, new 
SmallIntLiteral((short) 127)),
+                    BooleanLiteral.FALSE);
+        }
+    }
+
     @Test
     void testTypeRangeLimit() {
         executor = new ExpressionRuleExecutor(ImmutableList.of(


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to