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

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


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 4849ebc3ad0 [fix](Nereids) simplify range produce true when reference 
is nullable (#28386) (#28470)
4849ebc3ad0 is described below

commit 4849ebc3ad0a6812d28f2d685d9939202d4ec2bc
Author: morrySnow <101034200+morrys...@users.noreply.github.com>
AuthorDate: Sat Dec 16 18:32:21 2023 +0800

    [fix](Nereids) simplify range produce true when reference is nullable 
(#28386) (#28470)
    
    if reference is nullable, even if range is all, we should not return
    true, but should return reference is not null. for example,
    
    before simplify: c1 > 5 or c1 < 10
    after simplify:
        c1 is nullable: c1 IS NOT NULL
        c1 is not nullable: TRUE
---
 .../rules/expression/rules/SimplifyRange.java      | 15 ++++++++--
 .../rules/expression/SimplifyRangeTest.java        | 32 ++++++++++++++++++++--
 2 files changed, 42 insertions(+), 5 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 2fd7f4167d8..c0cb834b2f4 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
@@ -28,8 +28,10 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.GreaterThan;
 import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
 import org.apache.doris.nereids.trees.expressions.InPredicate;
+import org.apache.doris.nereids.trees.expressions.IsNull;
 import org.apache.doris.nereids.trees.expressions.LessThan;
 import org.apache.doris.nereids.trees.expressions.LessThanEqual;
+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;
@@ -204,7 +206,7 @@ public class SimplifyRange extends 
AbstractExpressionRewriteRule {
         public static ValueDesc intersect(RangeValue range, DiscreteValue 
discrete) {
             DiscreteValue result = new DiscreteValue(discrete.reference, 
discrete.expr);
             discrete.values.stream().filter(x -> 
range.range.contains(x)).forEach(result.values::add);
-            if (result.values.size() > 0) {
+            if (!result.values.isEmpty()) {
                 return result;
             }
             return new EmptyValue(range.reference, 
ExpressionUtils.and(range.expr, discrete.expr));
@@ -333,12 +335,19 @@ public class SimplifyRange extends 
AbstractExpressionRewriteRule {
                     result.add(new LessThan(reference, range.upperEndpoint()));
                 }
             }
-            return result.isEmpty() ? BooleanLiteral.TRUE : 
ExpressionUtils.and(result);
+            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;
+            }
         }
 
         @Override
         public String toString() {
-            return range == null ? "UnknwonRange" : range.toString();
+            return range == null ? "UnknownRange" : range.toString();
         }
     }
 
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 33a22dae78d..175a300eb1d 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
@@ -67,11 +67,13 @@ public class SimplifyRangeTest {
         assertRewrite("TA = 1 and TA > 10", "FALSE");
         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", "TRUE");
+        assertRewrite("TA > 5 or TA > 1 or TA < 10", "TA IS NOT 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", "TRUE");
+        assertRewrite("TA > 1 or TA < 10", "TA IS NOT 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");
@@ -115,6 +117,14 @@ public class SimplifyRangeTest {
         Assertions.assertEquals(expectedExpression, rewrittenExpression);
     }
 
+    private void assertRewriteNotNull(String expression, String expected) {
+        Map<String, Slot> mem = Maps.newHashMap();
+        Expression needRewriteExpression = 
replaceNotNullUnboundSlot(PARSER.parseExpression(expression), mem);
+        Expression expectedExpression = 
replaceNotNullUnboundSlot(PARSER.parseExpression(expected), mem);
+        Expression rewrittenExpression = 
executor.rewrite(needRewriteExpression, context);
+        Assertions.assertEquals(expectedExpression, rewrittenExpression);
+    }
+
     private Expression replaceUnboundSlot(Expression expression, Map<String, 
Slot> mem) {
         List<Expression> children = Lists.newArrayList();
         boolean hasNewChildren = false;
@@ -133,6 +143,24 @@ public class SimplifyRangeTest {
         return hasNewChildren ? expression.withChildren(children) : expression;
     }
 
+    private Expression replaceNotNullUnboundSlot(Expression expression, 
Map<String, Slot> mem) {
+        List<Expression> children = Lists.newArrayList();
+        boolean hasNewChildren = false;
+        for (Expression child : expression.children()) {
+            Expression newChild = replaceNotNullUnboundSlot(child, mem);
+            if (newChild != child) {
+                hasNewChildren = true;
+            }
+            children.add(newChild);
+        }
+        if (expression instanceof UnboundSlot) {
+            String name = ((UnboundSlot) expression).getName();
+            mem.putIfAbsent(name, new SlotReference(name, 
getType(name.charAt(0)), false));
+            return mem.get(name);
+        }
+        return hasNewChildren ? expression.withChildren(children) : expression;
+    }
+
     private DataType getType(char t) {
         switch (t) {
             case 'T':


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to