diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java index 8e1ba48..6790069 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java @@ -46,6 +46,7 @@ import org.apache.hadoop.hive.ql.hooks.ReadEntity; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.optimizer.physical.StageIDsRearranger; +import org.apache.hadoop.hive.ql.parse.ASTNode; import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer; import org.apache.hadoop.hive.ql.plan.Explain; import org.apache.hadoop.hive.ql.plan.ExplainWork; @@ -163,11 +164,11 @@ public JSONObject getJSONLogicalPlan(PrintStream out, ExplainWork work) throws E public JSONObject getJSONPlan(PrintStream out, ExplainWork work) throws Exception { - return getJSONPlan(out, work.getAstStringTree(), work.getRootTasks(), work.getFetchTask(), + return getJSONPlan(out, work.getAstTree(), work.getRootTasks(), work.getFetchTask(), work.isFormatted(), work.getExtended(), work.isAppendTaskType()); } - public JSONObject getJSONPlan(PrintStream out, String ast, List> tasks, Task fetchTask, + public JSONObject getJSONPlan(PrintStream out, ASTNode ast, List> tasks, Task fetchTask, boolean jsonOutput, boolean isExtended, boolean appendTaskType) throws Exception { // If the user asked for a formatted output, dump the json output @@ -180,7 +181,7 @@ public JSONObject getJSONPlan(PrintStream out, String ast, List> tasks, // Print out the parse AST if (ast != null && isExtended) { - String jsonAST = outputAST(ast, out, jsonOutput, 0); + String jsonAST = outputAST(ast.dump(), out, jsonOutput, 0); if (out != null) { out.println(); } diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/ExplainSemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/ExplainSemanticAnalyzer.java index 38b6d96..1eae654 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/ExplainSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/ExplainSemanticAnalyzer.java @@ -95,7 +95,7 @@ public void analyzeInternal(ASTNode ast) throws SemanticException { pCtx, tasks, fetchTask, - input.dump(), + input, sem, extended, formatted, diff --git ql/src/java/org/apache/hadoop/hive/ql/plan/ExplainWork.java ql/src/java/org/apache/hadoop/hive/ql/plan/ExplainWork.java index f258d51..3e43d0b 100644 --- ql/src/java/org/apache/hadoop/hive/ql/plan/ExplainWork.java +++ ql/src/java/org/apache/hadoop/hive/ql/plan/ExplainWork.java @@ -26,8 +26,10 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.ql.exec.Task; import org.apache.hadoop.hive.ql.hooks.ReadEntity; +import org.apache.hadoop.hive.ql.parse.ASTNode; import org.apache.hadoop.hive.ql.parse.ParseContext; import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer; +import org.apache.hadoop.hive.ql.parse.ParseContext; /** * ExplainWork. @@ -39,6 +41,7 @@ private Path resFile; private ArrayList> rootTasks; private Task fetchTask; + private ASTNode astTree; private String astStringTree; private HashSet inputs; private ParseContext pCtx; @@ -61,7 +64,7 @@ public ExplainWork(Path resFile, ParseContext pCtx, List> rootTasks, Task fetchTask, - String astStringTree, + ASTNode astTree, BaseSemanticAnalyzer analyzer, boolean extended, boolean formatted, @@ -71,7 +74,7 @@ public ExplainWork(Path resFile, this.resFile = resFile; this.rootTasks = new ArrayList>(rootTasks); this.fetchTask = fetchTask; - this.astStringTree = astStringTree; + this.astTree = astTree; this.analyzer = analyzer; this.inputs = analyzer.getInputs(); this.extended = extended; @@ -106,7 +109,14 @@ public void setFetchTask(Task fetchTask) { this.fetchTask = fetchTask; } + public ASTNode getAstTree() { + return astTree; + } + public String getAstStringTree() { + if (astStringTree == null) { + astStringTree = astTree.dump(); + } return astStringTree; } diff --git ql/src/test/org/apache/hadoop/hive/ql/parse/TestUpdateDeleteSemanticAnalyzer.java ql/src/test/org/apache/hadoop/hive/ql/parse/TestUpdateDeleteSemanticAnalyzer.java index b2b0645..8d62794 100644 --- ql/src/test/org/apache/hadoop/hive/ql/parse/TestUpdateDeleteSemanticAnalyzer.java +++ ql/src/test/org/apache/hadoop/hive/ql/parse/TestUpdateDeleteSemanticAnalyzer.java @@ -62,7 +62,7 @@ public void testInsertSelect() throws Exception { try { ReturnInfo rc = parseAndAnalyze("insert into table T select a, b from U", "testInsertSelect"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); @@ -73,7 +73,7 @@ public void testInsertSelect() throws Exception { public void testDeleteAllNonPartitioned() throws Exception { try { ReturnInfo rc = parseAndAnalyze("delete from T", "testDeleteAllNonPartitioned"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -83,7 +83,7 @@ public void testDeleteAllNonPartitioned() throws Exception { public void testDeleteWhereNoPartition() throws Exception { try { ReturnInfo rc = parseAndAnalyze("delete from T where a > 5", "testDeleteWhereNoPartition"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -93,7 +93,7 @@ public void testDeleteWhereNoPartition() throws Exception { public void testDeleteAllPartitioned() throws Exception { try { ReturnInfo rc = parseAndAnalyze("delete from U", "testDeleteAllPartitioned"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -103,7 +103,7 @@ public void testDeleteAllPartitioned() throws Exception { public void testDeleteAllWherePartitioned() throws Exception { try { ReturnInfo rc = parseAndAnalyze("delete from U where a > 5", "testDeleteAllWherePartitioned"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -114,7 +114,7 @@ public void testDeleteOnePartition() throws Exception { try { ReturnInfo rc = parseAndAnalyze("delete from U where ds = 'today'", "testDeleteFromPartitionOnly"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -125,7 +125,7 @@ public void testDeleteOnePartitionWhere() throws Exception { try { ReturnInfo rc = parseAndAnalyze("delete from U where ds = 'today' and a > 5", "testDeletePartitionWhere"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -135,7 +135,7 @@ public void testDeleteOnePartitionWhere() throws Exception { public void testUpdateAllNonPartitioned() throws Exception { try { ReturnInfo rc = parseAndAnalyze("update T set a = 5", "testUpdateAllNonPartitioned"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -146,7 +146,7 @@ public void testUpdateAllNonPartitionedWhere() throws Exception { try { ReturnInfo rc = parseAndAnalyze("update T set a = 5 where b > 5", "testUpdateAllNonPartitionedWhere"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -156,7 +156,7 @@ public void testUpdateAllNonPartitionedWhere() throws Exception { public void testUpdateAllPartitioned() throws Exception { try { ReturnInfo rc = parseAndAnalyze("update U set a = 5", "testUpdateAllPartitioned"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -167,7 +167,7 @@ public void testUpdateAllPartitionedWhere() throws Exception { try { ReturnInfo rc = parseAndAnalyze("update U set a = 5 where b > 5", "testUpdateAllPartitionedWhere"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -178,7 +178,7 @@ public void testUpdateOnePartition() throws Exception { try { ReturnInfo rc = parseAndAnalyze("update U set a = 5 where ds = 'today'", "testUpdateOnePartition"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -189,7 +189,7 @@ public void testUpdateOnePartitionWhere() throws Exception { try { ReturnInfo rc = parseAndAnalyze("update U set a = 5 where ds = 'today' and b > 5", "testUpdateOnePartitionWhere"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); } @@ -201,7 +201,7 @@ public void testInsertValues() throws Exception { ReturnInfo rc = parseAndAnalyze("insert into table T values ('abc', 3), ('ghi', null)", "testInsertValues"); - LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer)rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); @@ -215,7 +215,7 @@ public void testInsertValuesPartitioned() throws Exception { "('abc', 3, 'today'), ('ghi', 5, 'tomorrow')", "testInsertValuesPartitioned"); - LOG.info(explain((SemanticAnalyzer) rc.sem, rc.plan, rc.ast.dump())); + LOG.info(explain((SemanticAnalyzer) rc.sem, rc.plan, rc.ast)); } finally { cleanupTables(); @@ -288,7 +288,7 @@ private ReturnInfo parseAndAnalyze(String query, String testName) return new ReturnInfo(tree, sem, plan); } - private String explain(SemanticAnalyzer sem, QueryPlan plan, String astStringTree) throws + private String explain(SemanticAnalyzer sem, QueryPlan plan, ASTNode astTree) throws IOException { FileSystem fs = FileSystem.get(conf); File f = File.createTempFile("TestSemanticAnalyzer", "explain"); @@ -296,7 +296,7 @@ private String explain(SemanticAnalyzer sem, QueryPlan plan, String astStringTre fs.create(tmp); fs.deleteOnExit(tmp); ExplainWork work = new ExplainWork(tmp, sem.getParseContext(), sem.getRootTasks(), - sem.getFetchTask(), astStringTree, sem, true, false, false, false, false); + sem.getFetchTask(), astTree, sem, true, false, false, false, false); ExplainTask task = new ExplainTask(); task.setWork(work); task.initialize(conf, plan, null);