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

Reply via email to