This is an automated email from the ASF dual-hosted git repository. englefly pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new cc61c5f5cfa [fix](nereids) simplify self compare exclude non-foldable expression (#47054) cc61c5f5cfa is described below commit cc61c5f5cfa92e44cd0b2ea5939d5a04831f8638 Author: yujun <yu...@selectdb.com> AuthorDate: Thu Jan 16 15:54:16 2025 +0800 [fix](nereids) simplify self compare exclude non-foldable expression (#47054) ### What problem does this PR solve? #46905 add an rewrite expression rule to simplify self comparison, for example: `a = a` will evaluate to `TRUE`. But if `a` is non-foldable, it shouldn't simplify. for example: function `random` is non-foldable, then `random(1, 10) = random(1, 10)` cannot evaluate to `TRUE`. What's more, if an expression is non-deterministic, but if it's foldable, then self comparison also can fold it too. for example: function `user` is foldable and non-deterministic, then `user() = user()` can still simplify to `TRUE`. --- .../nereids/rules/expression/rules/SimplifySelfComparison.java | 7 ++++++- .../nereids/trees/expressions/functions/ExpressionTrait.java | 9 ++++++++- .../rules/expression/rules/SimplifySelfComparisonTest.java | 8 ++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparison.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparison.java index dbd89964710..76e93c44203 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparison.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparison.java @@ -54,7 +54,12 @@ public class SimplifySelfComparison implements ExpressionPatternRuleFactory { private Expression rewrite(ComparisonPredicate comparison) { Expression left = comparison.left(); - if (left.equals(comparison.right())) { + // expression maybe non-deterministic, but if it's foldable, then it still can simplify self comparison. + // for example, function `user()`, `current_timestamp()` are foldable and non-deterministic, + // then `user() = user()` and `current_timestamp() = current_timestamp()` can simplify to `TRUE`. + // function `random` is not foldable and non-deterministic, + // then `random(1, 10) = random(1, 10)` cann't simplify to `TRUE` + if (!left.containsNonfoldable() && left.equals(comparison.right())) { if (comparison instanceof EqualTo || comparison instanceof GreaterThanEqual || comparison instanceof LessThanEqual) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java index daaab359e84..6e33f2a5e11 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java @@ -77,6 +77,13 @@ public interface ExpressionTrait extends TreeNode<Expression> { return true; } + /** + * Identify the expression is containing non-foldable expr or not + */ + default boolean containsNonfoldable() { + return anyMatch(expr -> !((ExpressionTrait) expr).foldable()); + } + /** * Identify the expression itself is deterministic or not, default true */ @@ -85,7 +92,7 @@ public interface ExpressionTrait extends TreeNode<Expression> { } /** - * Identify the expression is containing deterministic expr or not + * Identify the expression is containing non-deterministic expr or not */ default boolean containsNondeterministic() { return anyMatch(expr -> !((ExpressionTrait) expr).isDeterministic()); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparisonTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparisonTest.java index be59404b467..28a5ed3b7c3 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparisonTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifySelfComparisonTest.java @@ -32,12 +32,20 @@ class SimplifySelfComparisonTest extends ExpressionRewriteTestHelper { ExpressionRewrite.bottomUp(SimplifySelfComparison.INSTANCE) )); + // foldable, cast assertRewriteAfterTypeCoercion("TA + TB = TA + TB", "NOT ((TA + TB) IS NULL) OR NULL"); assertRewriteAfterTypeCoercion("TA + TB >= TA + TB", "NOT ((TA + TB) IS NULL) OR NULL"); assertRewriteAfterTypeCoercion("TA + TB <= TA + TB", "NOT ((TA + TB) IS NULL) OR NULL"); assertRewriteAfterTypeCoercion("TA + TB <=> TA + TB", "TRUE"); assertRewriteAfterTypeCoercion("TA + TB > TA + TB", "(TA + TB) IS NULL AND NULL"); assertRewriteAfterTypeCoercion("TA + TB < TA + TB", "(TA + TB) IS NULL AND NULL"); + assertRewriteAfterTypeCoercion("DAYS_ADD(CA, 7) <=> DAYS_ADD(CA, 7)", "TRUE"); + assertRewriteAfterTypeCoercion("USER() = USER()", "TRUE"); + assertRewriteAfterTypeCoercion("CURRENT_TIMESTAMP() = CURRENT_TIMESTAMP()", "TRUE"); + + // not foldable, not cast + assertRewriteAfterTypeCoercion("random(5, 10) = random(5, 10)", "random(5, 10) = random(5, 10)"); + assertRewriteAfterTypeCoercion("random(5, 10) + 100 = random(5, 10) + 100", "random(5, 10) + 100 = random(5, 10) + 100"); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org