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 <[email protected]> Authored: Sun Sep 13 21:15:13 2015 -0700 Committer: Hyunsik Choi <[email protected]> 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;
