You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/01/14 18:07:25 UTC

git commit: TAJO-122: Add EXPLAIN clause to show a logical plan. (DaeMyung Kang via hyunsik)

Updated Branches:
  refs/heads/master 29ae39807 -> 01829fbdd


TAJO-122: Add EXPLAIN clause to show a logical plan. (DaeMyung Kang via hyunsik)


Project: http://git-wip-us.apache.org/repos/asf/incubator-tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tajo/commit/01829fbd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/01829fbd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/01829fbd

Branch: refs/heads/master
Commit: 01829fbddf7c5b988397d023c9f3cec0cea07c3f
Parents: 29ae398
Author: Hyunsik Choi <hy...@apache.org>
Authored: Wed Jan 15 02:02:12 2014 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Wed Jan 15 02:03:06 2014 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |  3 +++
 .../main/java/org/apache/tajo/cli/TajoCli.java  | 17 ++++++++++++-
 .../java/org/apache/tajo/client/TajoClient.java | 13 ++++++++++
 tajo-client/src/main/proto/ClientProtos.proto   | 10 ++++++++
 .../main/proto/TajoMasterClientProtocol.proto   |  3 ++-
 .../org/apache/tajo/master/GlobalEngine.java    | 12 ++++++++++
 .../tajo/master/TajoMasterClientService.java    | 25 ++++++++++++++++++++
 7 files changed, 81 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8f7efd7..947e652 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,9 @@ Release 0.8.0 - unreleased
 
   NEW FEATURES
 
+    TAJO-122: Add EXPLAIN clause to show a logical plan. 
+    (DaeMyung Kang via hyunsik)
+
     TAJO-438: Date literal support. (Jae Young Lee via jihoon)
 
     TAJO-474: Add query admin utility. (DaeMyung Kang via hyunsik)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
index 2e7a92c..fb9f515 100644
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
@@ -288,7 +288,22 @@ public class TajoCli {
       } else if (cmds[0].equalsIgnoreCase("detach") && cmds.length > 1 && cmds[1].equalsIgnoreCase("table")) {
         // this command should be moved to GlobalEngine
         invokeCommand(cmds);
-
+      } else if (cmds[0].equalsIgnoreCase("explain") && cmds.length > 1) {
+        String sql = stripped.substring(8);
+        ClientProtos.ExplainQueryResponse response = client.explainQuery(sql);
+        if (response == null) {
+          sout.println("response is null");
+        } else {
+          if (response.hasExplain()) {
+            sout.println(response.getExplain());
+          } else {
+            if (response.hasErrorMessage()) {
+                sout.println(response.getErrorMessage());
+            } else {
+                sout.println("No Explain");
+            }
+          }
+        }
       } else { // submit a query to TajoMaster
         ClientProtos.GetQueryStatusResponse response = client.executeQuery(stripped);
         if (response == null) {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
index 70b4c53..7eabc08 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
@@ -115,6 +115,19 @@ public class TajoClient {
     }
   }
 
+  public ExplainQueryResponse explainQuery(final String sql) throws ServiceException {
+    return new ServerCallable<ExplainQueryResponse>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public ExplainQueryResponse call(NettyClientBase client) throws ServiceException {
+        final ExplainQueryRequest.Builder builder = ExplainQueryRequest.newBuilder();
+        builder.setQuery(sql);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.explainQuery(null, builder.build());
+      }
+    }.withRetries();
+  }
+
   /**
    * It submits a query statement and get a response immediately.
    * The response only contains a query id, and submission status.

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/tajo-client/src/main/proto/ClientProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto
index 59ef85b..05cd4e9 100644
--- a/tajo-client/src/main/proto/ClientProtos.proto
+++ b/tajo-client/src/main/proto/ClientProtos.proto
@@ -37,6 +37,16 @@ message UpdateSessionVariableRequest {
   repeated string unsetVariables = 3;
 }
 
+message ExplainQueryRequest {
+  required string query = 1;
+}
+
+message ExplainQueryResponse {
+  required ResultCode resultCode = 1;
+  optional string explain = 2;
+  optional string errorMessage = 3;
+}
+
 message QueryRequest {
   optional SessionIdProto sessionId = 1;
   required string query = 2;

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
index dbdd911..4a25905 100644
--- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
+++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
@@ -32,6 +32,7 @@ service TajoMasterClientProtocolService {
   rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto);
   rpc submitQuery(QueryRequest) returns (GetQueryStatusResponse);
   rpc updateQuery(QueryRequest) returns (UpdateQueryResponse);
+  rpc explainQuery(ExplainQueryRequest) returns (ExplainQueryResponse);
   rpc getQueryResult(GetQueryResultRequest) returns (GetQueryResultResponse);
   rpc getQueryList(GetQueryListRequest) returns (GetQueryListResponse);
   rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
@@ -59,4 +60,4 @@ service TajoMasterClientProtocolService {
   // getUDFDesc
   // registerJars
   // getListRegisteredJars
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
index ed7828e..5bd2924 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
@@ -188,6 +188,18 @@ public class GlobalEngine extends AbstractService {
     }
   }
 
+  public String explainQuery(String sql) throws IOException, SQLException, PlanningException {
+    LOG.info("SQL: " + sql);
+    // parse the query
+
+    final boolean hiveQueryMode = context.getConf().getBoolVar(TajoConf.ConfVars.HIVE_QUERY_MODE);
+    Expr planningContext = hiveQueryMode ? converter.parse(sql) : analyzer.parse(sql);
+    LOG.info("hive.query.mode:" + hiveQueryMode);
+
+    LogicalPlan plan = createLogicalPlan(planningContext);
+    return plan.toString();
+  }
+
   public QueryId updateQuery(String sql) throws IOException, SQLException, PlanningException {
     LOG.info("SQL: " + sql);
     // parse the query

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/01829fbd/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
index e4aae9d..9bcdf53 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
@@ -124,6 +124,31 @@ public class TajoMasterClientService extends AbstractService {
     }
 
     @Override
+    public ExplainQueryResponse explainQuery(RpcController controller,
+                                           ExplainQueryRequest request)
+        throws ServiceException {
+
+      try {
+        if(LOG.isDebugEnabled()) {
+          LOG.debug("ExplainQuery [" + request.getQuery() + "]");
+        }
+        ClientProtos.ExplainQueryResponse.Builder responseBuilder = ClientProtos.ExplainQueryResponse.newBuilder();
+        responseBuilder.setResultCode(ResultCode.OK);
+        String plan = context.getGlobalEngine().explainQuery(request.getQuery());
+        if(LOG.isDebugEnabled()) {
+          LOG.debug("ExplainQuery [" + plan + "]");
+        }
+        responseBuilder.setExplain(plan);
+        return responseBuilder.build();
+      } catch (Exception e) {
+        LOG.error(e.getMessage(), e);
+        ClientProtos.ExplainQueryResponse.Builder responseBuilder = ClientProtos.ExplainQueryResponse.newBuilder();
+        responseBuilder.setResultCode(ResultCode.ERROR);
+        responseBuilder.setErrorMessage(e.getMessage());
+        return responseBuilder.build();
+      }
+    }
+    @Override
     public GetQueryStatusResponse submitQuery(RpcController controller,
                                            QueryRequest request)
         throws ServiceException {