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