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 2015/09/14 06:18:45 UTC

tajo git commit: TAJO-1835: TajoClient::executeQueryAndGetResult should throw Query(Failed|Killed)Exception.

Repository: tajo
Updated Branches:
  refs/heads/master 738feac8e -> fb5da6647


TAJO-1835: TajoClient::executeQueryAndGetResult should throw Query(Failed|Killed)Exception.

Closes #754


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

Branch: refs/heads/master
Commit: fb5da6647f0b60b4cc1d353e3cc3fe68a617950f
Parents: 738feac
Author: Hyunsik Choi <hy...@apache.org>
Authored: Sun Sep 13 21:15:13 2015 -0700
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Sun Sep 13 21:15:13 2015 -0700

----------------------------------------------------------------------
 CHANGES                                         |  3 +++
 .../org/apache/tajo/client/QueryClientImpl.java | 21 +++++++++-------
 .../org/apache/tajo/client/QueryStatus.java     |  3 +++
 .../org/apache/tajo/jdbc/WaitingResultSet.java  |  2 +-
 .../tajo/cli/tsql/TestTajoCliNegatives.java     |  2 +-
 .../apache/tajo/master/exec/QueryExecutor.java  | 25 +++++++++++++++++++-
 .../plan/verifier/PreLogicalPlanVerifier.java   | 19 ++++++++-------
 7 files changed, 55 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index fdab8bc..28dcfa5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -36,6 +36,9 @@ Release 0.11.0 - unreleased
 
   IMPROVEMENT
 
+    TAJO-1835: TajoClient::executeQueryAndGetResult should throw 
+    Query(Failed|Killed)Exception. (hyunsik)
+
     TAJO-1831: Add a shutdown hook manager in order to set priorities. (jinho)
 
     TAJO-1817: Improve SQL parser error message. (hyunsik)

http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
index 20e56ac..8b7f749 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
@@ -26,6 +26,7 @@ import org.apache.tajo.QueryIdFactory;
 import org.apache.tajo.SessionVars;
 import org.apache.tajo.TajoIdProtos.SessionIdProto;
 import org.apache.tajo.TajoProtos;
+import org.apache.tajo.TajoProtos.QueryState;
 import org.apache.tajo.auth.UserRoleInfo;
 import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.Schema;
@@ -217,7 +218,8 @@ public class QueryClientImpl implements QueryClient {
     }
   }
 
-  public ResultSet getQueryResultAndWait(QueryId queryId) throws QueryNotFoundException {
+  public ResultSet getQueryResultAndWait(QueryId queryId)
+      throws QueryNotFoundException, QueryKilledException, QueryFailedException {
 
     if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
       return createNullResultSet(queryId);
@@ -225,18 +227,19 @@ public class QueryClientImpl implements QueryClient {
 
     QueryStatus status = TajoClientUtil.waitCompletion(this, queryId);
 
-    if (status.getState() == TajoProtos.QueryState.QUERY_SUCCEEDED) {
+    if (status.getState() == QueryState.QUERY_SUCCEEDED) {
       if (status.hasResult()) {
         return getQueryResult(queryId);
       } else {
         return createNullResultSet(queryId);
       }
-
+    } else if (status.getState() == QueryState.QUERY_KILLED) {
+      throw new QueryKilledException();
+    } else if (status.getState() == QueryState.QUERY_FAILED) {
+      throw new QueryFailedException(status.getErrorMessage());
     } else {
-      LOG.warn("Query (" + status.getQueryId() + ") failed: " + status.getState());
-
-      //TODO throw SQLException(?)
-      return createNullResultSet(queryId);
+      throw new TajoInternalError("Illegal query status: " + status.getState().name() +
+          ", cause: " + status.getErrorMessage());
     }
   }
 
@@ -453,8 +456,8 @@ public class QueryClientImpl implements QueryClient {
     long currentTimeMillis = System.currentTimeMillis();
     long timeKillIssued = currentTimeMillis;
     while ((currentTimeMillis < timeKillIssued + 10000L)
-        && ((status.getState() != TajoProtos.QueryState.QUERY_KILLED)
-        || (status.getState() == TajoProtos.QueryState.QUERY_KILL_WAIT))) {
+        && ((status.getState() != QueryState.QUERY_KILLED)
+        || (status.getState() == QueryState.QUERY_KILL_WAIT))) {
       try {
         Thread.sleep(100L);
       } catch (InterruptedException ie) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
index 809c675..68d5638 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
@@ -21,6 +21,7 @@ package org.apache.tajo.client;
 import org.apache.tajo.QueryId;
 import org.apache.tajo.TajoProtos.QueryState;
 import org.apache.tajo.ipc.ClientProtos.GetQueryStatusResponse;
+import org.apache.tajo.util.VersionInfo;
 
 public class QueryStatus {
   private QueryId queryId;
@@ -43,6 +44,8 @@ public class QueryStatus {
     hasResult = proto.getHasResult();
     if (proto.hasErrorMessage()) {
       errorText = proto.getErrorMessage();
+    } else {
+      errorText = "Internal error. Please check out log files in ${tajo_install_dir}/logs files.";
     }
     if (proto.hasErrorTrace()) {
       errorTrace = proto.getErrorTrace();

http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
index aa26027..c9967b4 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
@@ -59,7 +59,7 @@ public class WaitingResultSet extends FetchResultSet {
       QueryStatus status = TajoClientUtil.waitCompletion(tajoClient, queryId);
 
       if (status.getState() != TajoProtos.QueryState.QUERY_SUCCEEDED) {
-        throw new SQLException(status.getErrorMessage() != null ? status.getErrorMessage() : "unknown error",
+        throw new SQLException(status.getErrorMessage(),
             SQLExceptionUtil.toSQLState(ResultCode.INTERNAL_ERROR), ResultCode.INTERNAL_ERROR.getNumber());
       }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
index c593859..689caa7 100644
--- a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
@@ -132,6 +132,6 @@ public class TestTajoCliNegatives extends QueryTestCaseBase {
   public void testQueryFailure() throws Exception {
     setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
     assertScriptFailure("select fail(3, l_orderkey, 'testQueryFailure') from default.lineitem" ,
-        "ERROR: No error message\n");
+        "ERROR: Internal error. Please check out log files in ${tajo_install_dir}/logs files.\n");
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
index 83b7df4..a4a916a 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
@@ -132,7 +132,14 @@ public class QueryExecutor {
       execNonFromQuery(queryContext, session, sql, plan, response);
 
     } else { // it requires distributed execution. So, the query is forwarded to a query master.
-      executeDistributedQuery(queryContext, session, plan, sql, jsonExpr, response);
+
+      // Checking if CTAS is already finished due to 'IF NOT EXISTS' option
+      if (checkIfCtasAlreadyDone(rootNode)) {
+        response.setState(OK);
+        response.setResultType(ResultType.NO_RESULT);
+      } else {
+        executeDistributedQuery(queryContext, session, plan, sql, jsonExpr, response);
+      }
     }
 
     response.setSessionVars(ProtoUtil.convertFromMap(session.getAllVariables()));
@@ -140,6 +147,22 @@ public class QueryExecutor {
     return response.build();
   }
 
+  /**
+   * Check if CTAS is already done
+   * @param rootNode
+   * @return
+   */
+  private boolean checkIfCtasAlreadyDone(LogicalNode rootNode) {
+    if (rootNode.getChild(0).getType() == NodeType.CREATE_TABLE) {
+      CreateTableNode createTable = (CreateTableNode) rootNode.getChild(0);
+      if (createTable.isIfNotExists() && catalog.existsTable(createTable.getTableName())) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
   public void execSetSession(Session session, LogicalPlan plan,
                              SubmitQueryResponse.Builder response) {
     SetSessionNode setSessionNode = ((LogicalRootNode) plan.getRootBlock().getRoot()).getChild();

http://git-wip-us.apache.org/repos/asf/tajo/blob/fb5da664/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java
index a227187..f40548c 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java
@@ -168,17 +168,20 @@ public class PreLogicalPlanVerifier extends BaseAlgebraVisitor<PreLogicalPlanVer
     }
   }
 
-  private boolean assertRelationNoExistence(Context context, String tableName) {
+  private static String guessTableName(Context context, String givenName) {
     String qualifiedName;
-
-    if (CatalogUtil.isFQTableName(tableName)) {
-      qualifiedName = tableName;
+    if (CatalogUtil.isFQTableName(givenName)) {
+      qualifiedName = givenName;
     } else {
-      qualifiedName = CatalogUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE), tableName);
-    }
-    if(qualifiedName == null) {
-      System.out.println("A");
+      qualifiedName = CatalogUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE), givenName);
     }
+
+    return qualifiedName;
+  }
+
+  private boolean assertRelationNoExistence(Context context, String tableName) {
+    String qualifiedName = guessTableName(context, tableName);
+
     if (catalog.existsTable(qualifiedName)) {
       context.state.addVerification(new DuplicateTableException(qualifiedName));
       return false;