IMPALA-4025: Part 1: Generalize and cleanup StmtRewriter This patch generalizes StmtRewriter, allowing it to be subclassed. The base class would traverse the stmt tree while the subclasses can install hooks to execute specific rewrite rules at certain places. Existing rewriting rules are moved into SubqueryRewriter.
Change-Id: I9e7a6108d3d49be12ae032fdb54b5c3c23152a47 Reviewed-on: http://gerrit.cloudera.org:8080/10495 Reviewed-by: Vuk Ercegovac <[email protected]> Tested-by: Impala Public Jenkins <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/impala/repo Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/41d7cd90 Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/41d7cd90 Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/41d7cd90 Branch: refs/heads/2.x Commit: 41d7cd908a05dabe31775dabf188d3b2136c25d2 Parents: 71e22a5 Author: Tianyi Wang <[email protected]> Authored: Thu May 17 18:38:34 2018 -0700 Committer: Impala Public Jenkins <[email protected]> Committed: Fri May 25 23:17:16 2018 +0000 ---------------------------------------------------------------------- .../apache/impala/analysis/AnalysisContext.java | 81 +- .../apache/impala/analysis/StmtRewriter.java | 1830 +++++++++--------- 2 files changed, 961 insertions(+), 950 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/impala/blob/41d7cd90/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java b/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java index 791e528..3e7f0cc 100644 --- a/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java +++ b/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java @@ -426,52 +426,47 @@ public class AnalysisContext { private void analyze(StmtTableCache stmtTableCache) throws AnalysisException { Preconditions.checkNotNull(analysisResult_); Preconditions.checkNotNull(analysisResult_.stmt_); - try { + analysisResult_.analyzer_ = createAnalyzer(stmtTableCache); + analysisResult_.stmt_.analyze(analysisResult_.analyzer_); + boolean isExplain = analysisResult_.isExplainStmt(); + + // Apply expr and subquery rewrites. + boolean reAnalyze = false; + ExprRewriter rewriter = analysisResult_.analyzer_.getExprRewriter(); + if (analysisResult_.requiresExprRewrite()) { + rewriter.reset(); + analysisResult_.stmt_.rewriteExprs(rewriter); + reAnalyze = rewriter.changed(); + } + if (analysisResult_.requiresSubqueryRewrite()) { + new StmtRewriter.SubqueryRewriter().rewrite(analysisResult_); + reAnalyze = true; + } + if (reAnalyze) { + // The rewrites should have no user-visible effect. Remember the original result + // types and column labels to restore them after the rewritten stmt has been + // reset() and re-analyzed. For a CTAS statement, the types represent column types + // of the table that will be created, including the partition columns, if any. + List<Type> origResultTypes = Lists.newArrayList(); + for (Expr e: analysisResult_.stmt_.getResultExprs()) { + origResultTypes.add(e.getType()); + } + List<String> origColLabels = + Lists.newArrayList(analysisResult_.stmt_.getColLabels()); + + // Re-analyze the stmt with a new analyzer. analysisResult_.analyzer_ = createAnalyzer(stmtTableCache); + analysisResult_.stmt_.reset(); analysisResult_.stmt_.analyze(analysisResult_.analyzer_); - boolean isExplain = analysisResult_.isExplainStmt(); - - // Apply expr and subquery rewrites. - boolean reAnalyze = false; - ExprRewriter rewriter = analysisResult_.analyzer_.getExprRewriter(); - if (analysisResult_.requiresExprRewrite()) { - rewriter.reset(); - analysisResult_.stmt_.rewriteExprs(rewriter); - reAnalyze = rewriter.changed(); - } - if (analysisResult_.requiresSubqueryRewrite()) { - StmtRewriter.rewrite(analysisResult_); - reAnalyze = true; - } - if (reAnalyze) { - // The rewrites should have no user-visible effect. Remember the original result - // types and column labels to restore them after the rewritten stmt has been - // reset() and re-analyzed. For a CTAS statement, the types represent column types - // of the table that will be created, including the partition columns, if any. - List<Type> origResultTypes = Lists.newArrayList(); - for (Expr e: analysisResult_.stmt_.getResultExprs()) { - origResultTypes.add(e.getType()); - } - List<String> origColLabels = - Lists.newArrayList(analysisResult_.stmt_.getColLabels()); - - // Re-analyze the stmt with a new analyzer. - analysisResult_.analyzer_ = createAnalyzer(stmtTableCache); - analysisResult_.stmt_.reset(); - analysisResult_.stmt_.analyze(analysisResult_.analyzer_); - - // Restore the original result types and column labels. - analysisResult_.stmt_.castResultExprs(origResultTypes); - analysisResult_.stmt_.setColLabels(origColLabels); - if (LOG.isTraceEnabled()) { - LOG.trace("rewrittenStmt: " + analysisResult_.stmt_.toSql()); - } - if (isExplain) analysisResult_.stmt_.setIsExplain(); - Preconditions.checkState(!analysisResult_.requiresSubqueryRewrite()); + + // Restore the original result types and column labels. + analysisResult_.stmt_.castResultExprs(origResultTypes); + analysisResult_.stmt_.setColLabels(origColLabels); + if (LOG.isTraceEnabled()) { + LOG.trace("rewrittenStmt: " + analysisResult_.stmt_.toSql()); } - } catch (AnalysisException e) { - // Don't wrap AnalysisExceptions in another AnalysisException - throw e; + if (isExplain) analysisResult_.stmt_.setIsExplain(); + Preconditions.checkState(!analysisResult_.requiresSubqueryRewrite()); } }
