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/1ca077fd Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/1ca077fd Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/1ca077fd Branch: refs/heads/master Commit: 1ca077fd065bc5689e7614073c174b5a2bb11d96 Parents: 20a1a15 Author: Tianyi Wang <[email protected]> Authored: Thu May 17 18:38:34 2018 -0700 Committer: Impala Public Jenkins <[email protected]> Committed: Thu May 24 09:49:14 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/1ca077fd/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()); } }
