[ https://issues.apache.org/jira/browse/IMPALA-7769?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16679202#comment-16679202 ]
Paul Rogers commented on IMPALA-7769: ------------------------------------- An example failure in {{PlannerTest.testEmpt()}}, for the following case: {noformat} # IMPALA-1860: INSERT/CTAS should evaluate and apply constant predicates. with t as (select * from functional.alltypes where coalesce(NULL) > 10) insert into functional.alltypes partition(year, month) select * from t {noformat} Monitor the rewrite output. We get: {noformat} Before: coalesce(NULL) > 10 After: NULL > 10 {noformat} Here, the {{NULL}} on the second line is actually {{CAST(NULL AS TINYINT)}}. The expression should have been further rewritten to just {{NULL}}. The problem is that the constant folding rule looks for expressions that contains literals, but here is needs to also look for a CAST of a NULL literal. > Handle CAST(NULL AS type) in rewrites > ------------------------------------- > > Key: IMPALA-7769 > URL: https://issues.apache.org/jira/browse/IMPALA-7769 > Project: IMPALA > Issue Type: Improvement > Components: Frontend > Affects Versions: Impala 3.0 > Reporter: Paul Rogers > Priority: Minor > > Consider the following query: > {code:sql} > SELECT IFNULL(NULL + 1, id) FROM alltypessmall; > {code} > Visualize the rewritten query after analysis (using the new > {{FullRewriteTest}}.) We get: > {code:sql} > SELECT CASE WHEN CAST(NULL AS INT) IS NULL THEN id ELSE NULL END FROM > alltypessmall > {code} > (This is what the expression actually contains. The {{toSql()}} method lies > and says that the statement is: > {code:sql} > SELECT CASE WHEN NULL IS NULL THEN id ELSE NULL END FROM alltypessmall > {code} > which causes confusion when debugging.) > Expected: > {code:sql} > SELECT id FROM alltypessmall > {code} > Another case: > {code:sql} > CASE WHEN NULL + 1 THEN 10 ELSE 20 END > {code} > Ensure the {{NULL + 1}} is constant folded with a cast. Then, in {{CASE}}: > {code:java} > for (int i = loopStart; i < numChildren - 1; i += 2) { > if (expr.getChild(i).isLiteral()) { > canSimplify = true; > break; > } > } > {code} > The {{isLiteral()}} method won’t match the cast and the simplification won’t > fire. > The reason is that there are multiple rewrites, one of which has a flaw. > # Rewrite {{IFNULL to CASE}} > # Rewrite {{NULL + 1}} to {{CAST(NULL AS SMALLINT)}} > # Try to rewrite {{CAST(NULL AS SMALLINT) IS NULL}}, but fail because CAST is > not a literal. > In addition to the {{CASE}} issue above, the {{FoldConstantsRule}} itself is > tripped up. It is supposed to simplify the {{... IS NULL}} expression above, > but does not. > The code in question in {{FoldConstantsRule.apply()}} is: > {code:java} > for (Expr child: expr.getChildren()) if (!child.isLiteral()) return expr; > {code} > In fact, this check is too restrictive. Need a new {{isLiteralLike()}} which > should work like {{IsNullLiteral()}}: > * True if the node is a literal. > * True if the node is a cast of a literal. > (Can't change {{isLiteral()}} since there are places that assume that this > existing predicate indicates that the node is exactly a {{LiteralExpr}}.) > Impala already has a predicate that does what is needed: {{isConstant()}}. > However, the code in {{FoldConstantsRule.apply()}} specifically excludes > calling it: > {code:java} > // Avoid calling Expr.isConstant() because that would lead to repeated > traversals > // of the Expr tree. Assumes the bottom-up application of this rule. > Constant > // children should have been folded at this point. > {code} > The new method solves the repeated traversal problem. With it, the test query > now simplifies to the expected result. -- This message was sent by Atlassian JIRA (v7.6.3#76005) --------------------------------------------------------------------- To unsubscribe, e-mail: issues-all-unsubscr...@impala.apache.org For additional commands, e-mail: issues-all-h...@impala.apache.org