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
