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

wzhou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 3c93437b7a6191a9ca1ef3acc740fefd2ae54bcf
Author: wzhou-code <[email protected]>
AuthorDate: Thu Feb 1 15:09:29 2024 -0800

    IMPALA-12770: Fix infinite loop for nested Case expressions
    
    ExprRewriter enter infinite loop when run following query with
    nested Case expressions:
    
    select
      case
        case ''
          when 'abc' then t4.string_col
        end
        when 'none' then 'Total'
      end
    as fcol from functional.alltypes as t4 limit 1;
    
    The 'case' expr is set as literal NULL expression for outer case
    expression since all 'when' expr are false in inner case expression.
    This causes function SimplifyConditionalsRule.simplifyCaseExpr() to
    be called recusively and enter infinite loop.
    
    This patch fixes the issue by not rewriting a case expression if 'case'
    expr is literal NULL expression.
    
    Testing:
     - Manually ran above query successfully.
     - Added new test cases in ExprRewriteRulesTest.testCaseWithExpr.
     - Passed core-tests.
    
    Change-Id: Iaea1b3a35967f92b3e4f3445a378ed58adaa7da5
    Reviewed-on: http://gerrit.cloudera.org:8080/20982
    Reviewed-by: Impala Public Jenkins <[email protected]>
    Tested-by: Impala Public Jenkins <[email protected]>
---
 .../org/apache/impala/rewrite/SimplifyConditionalsRule.java  |  5 ++++-
 .../org/apache/impala/analysis/ExprRewriteRulesTest.java     | 12 ++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git 
a/fe/src/main/java/org/apache/impala/rewrite/SimplifyConditionalsRule.java 
b/fe/src/main/java/org/apache/impala/rewrite/SimplifyConditionalsRule.java
index 33d50cf83..15c752520 100644
--- a/fe/src/main/java/org/apache/impala/rewrite/SimplifyConditionalsRule.java
+++ b/fe/src/main/java/org/apache/impala/rewrite/SimplifyConditionalsRule.java
@@ -208,7 +208,10 @@ public class SimplifyConditionalsRule implements 
ExprRewriteRule {
   private Expr simplifyCaseExpr(CaseExpr expr, Analyzer analyzer)
       throws AnalysisException {
     Expr caseExpr = expr.hasCaseExpr() ? expr.getChild(0) : null;
-    if (expr.hasCaseExpr() && !Expr.IS_LITERAL.apply(caseExpr)) return expr;
+    if (expr.hasCaseExpr() &&
+        (!Expr.IS_LITERAL.apply(caseExpr) || 
Expr.IS_NULL_LITERAL.apply(caseExpr))) {
+      return expr;
+    }
 
     int numChildren = expr.getChildren().size();
     int loopStart = expr.hasCaseExpr() ? 1 : 0;
diff --git 
a/fe/src/test/java/org/apache/impala/analysis/ExprRewriteRulesTest.java 
b/fe/src/test/java/org/apache/impala/analysis/ExprRewriteRulesTest.java
index dd38aface..2fe863434 100644
--- a/fe/src/test/java/org/apache/impala/analysis/ExprRewriteRulesTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/ExprRewriteRulesTest.java
@@ -475,6 +475,18 @@ public class ExprRewriteRulesTest extends FrontendTestBase 
{
     RewritesOk("case 0 when null then id else 1 end", rule, "1");
     // All non-constant, don't rewrite.
     RewritesOk("case id when 1 then 1 when 2 then 2 else 3 end", rule, null);
+    // IMPALA-12770: Fix infinite loop for nested Case expressions.
+    // Case NULL, don't rewrite.
+    RewritesOk("case NULL when id then id else 1 end", rule, null);
+    // Nested Case expressions.
+    RewritesOk("case case 1 when 0 then 0 when 1 then id end "
+        + "when 2 then id + 2 else id + 3 end",
+        rule, "CASE id WHEN 2 THEN id + 2 ELSE id + 3 END");
+    // 'when' are all FALSE for inner Case expression, set 'case' expr as NULL 
for outer
+    // Case expression.
+    RewritesOk("case case 3 when 0 then id when 1 then id + 1 end "
+        + "when 2 then id + 2 end",
+        rule, "CASE NULL WHEN 2 THEN id + 2 END");
   }
 
   @Test

Reply via email to