diff --git a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java index 0ca867697c..d5437d0759 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java @@ -1004,7 +1004,7 @@ private String getExplainOutput(BaseSemanticAnalyzer sem, QueryPlan plan, PrintStream ps = new PrintStream(baos); try { List> rootTasks = sem.getAllRootTasks(); - task.getJSONPlan(ps, rootTasks, sem.getFetchTask(), false, true, true); + task.getJSONPlan(ps, rootTasks, sem.getFetchTask(), false, true, true, sem.getCboInfo()); ret = baos.toString(); } catch (Exception e) { LOG.warn("Exception generating explain output: " + e, e); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java b/ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java index 79e938aebd..732a6684f2 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java @@ -71,7 +71,7 @@ */ public class QueryPlan implements Serializable { private static final long serialVersionUID = 1L; - + private String cboInfo; private String queryString; @@ -154,6 +154,7 @@ public QueryPlan(String queryString, BaseSemanticAnalyzer sem, Long startTime, S this.acidResourcesInQuery = sem.hasTransactionalInQuery(); this.acidSinks = sem.getAcidFileSinks(); this.acidDdlDesc = sem.getAcidDdlDesc(); + this.cboInfo = sem.getCboInfo(); } /** @@ -837,4 +838,8 @@ public HiveOperation getOperation() { public Boolean getAutoCommitValue() { return autoCommitValue; } + + public String getCboInfo() { + return cboInfo; + } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java index 14c639806a..d93e27a35c 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java @@ -218,11 +218,12 @@ public JSONObject getJSONLogicalPlan(PrintStream out, ExplainWork work) throws E public JSONObject getJSONPlan(PrintStream out, ExplainWork work) throws Exception { return getJSONPlan(out, work.getRootTasks(), work.getFetchTask(), - work.isFormatted(), work.getExtended(), work.isAppendTaskType()); + work.isFormatted(), work.getExtended(), work.isAppendTaskType(), work.getCboInfo()); } public JSONObject getJSONPlan(PrintStream out, List> tasks, Task fetchTask, - boolean jsonOutput, boolean isExtended, boolean appendTaskType) throws Exception { + boolean jsonOutput, boolean isExtended, boolean appendTaskType, String cboInfo) + throws Exception { // If the user asked for a formatted output, dump the json output // in the output stream @@ -268,6 +269,9 @@ public JSONObject getJSONPlan(PrintStream out, List> tasks, Task fetc } if (jsonOutput) { + if (cboInfo != null) { + outJSONObject.put("cboInfo", cboInfo); + } outJSONObject.put("STAGE DEPENDENCIES", jsonDependencies); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/hooks/HiveProtoLoggingHook.java b/ql/src/java/org/apache/hadoop/hive/ql/hooks/HiveProtoLoggingHook.java index 906c2db2fb..082ac80bc8 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/hooks/HiveProtoLoggingHook.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/hooks/HiveProtoLoggingHook.java @@ -461,7 +461,7 @@ private JSONObject getExplainPlan(QueryPlan plan, HiveConf conf, HookContext hoo plan.getFetchTask(), // FetchTask null, // analyzer config, // explainConfig - null // cboInfo + plan.getCboInfo() ); ExplainTask explain = (ExplainTask) TaskFactory.get(work, conf); explain.initialize(hookContext.getQueryState(), plan, null, null); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java index ebea31d21f..f85bd40231 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java @@ -187,6 +187,10 @@ public boolean skipAuthorization() { return false; } + public String getCboInfo() { + return ctx.getCboInfo(); + } + class RowFormatParams { String fieldDelim = null; String fieldEscape = null; diff --git a/ql/src/test/org/apache/hadoop/hive/ql/exec/TestExplainTask.java b/ql/src/test/org/apache/hadoop/hive/ql/exec/TestExplainTask.java index 5a7772255a..6450795502 100644 --- a/ql/src/test/org/apache/hadoop/hive/ql/exec/TestExplainTask.java +++ b/ql/src/test/org/apache/hadoop/hive/ql/exec/TestExplainTask.java @@ -218,8 +218,8 @@ public void testGetJSONPlan() throws Exception { JsonNode result = objectMapper.readTree(uut.getJSONPlan(null, tasks, null, true, - false, false).toString()); - JsonNode expected = objectMapper.readTree("{\"STAGE DEPENDENCIES\":{\"mockTaskId\":" + + false, false, "Plan Optimized by CBO").toString()); + JsonNode expected = objectMapper.readTree("{\"cboInfo\":\"Plan Optimized by CBO\", \"STAGE DEPENDENCIES\":{\"mockTaskId\":" + "{\"ROOT STAGE\":\"TRUE\",\"BACKUP STAGE\":\"backup-id-mock\"}},\"STAGE PLANS\":" + "{\"mockTaskId\":{}}}");