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/03 15:11:59 UTC
tajo git commit: TAJO-1749: Refine JDBC exceptions to better handle
exceptional cases.
Repository: tajo
Updated Branches:
refs/heads/master 3e8f4a030 -> 688bc5c11
TAJO-1749: Refine JDBC exceptions to better handle exceptional cases.
Closes #722
Project: http://git-wip-us.apache.org/repos/asf/tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/688bc5c1
Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/688bc5c1
Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/688bc5c1
Branch: refs/heads/master
Commit: 688bc5c1111054cb486cdc915edc8fc0097add4a
Parents: 3e8f4a0
Author: Hyunsik Choi <hy...@apache.org>
Authored: Thu Sep 3 22:08:08 2015 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Thu Sep 3 22:08:08 2015 +0900
----------------------------------------------------------------------
CHANGES | 3 +
.../apache/tajo/client/SessionConnection.java | 4 +-
.../org/apache/tajo/client/TajoClientImpl.java | 6 +-
.../v2/exception/ClientConnectionException.java | 5 +-
.../org/apache/tajo/jdbc/TajoSQLException.java | 43 +++++
.../org/apache/tajo/jdbc/WaitingResultSet.java | 10 +-
.../apache/tajo/exception/ErrorMessages.java | 7 +-
.../apache/tajo/exception/SQLExceptionUtil.java | 94 ++++++++++-
.../apache/tajo/exception/TajoException.java | 5 +
tajo-common/src/main/proto/errors.proto | 49 +++---
.../tajo/master/exec/CreateTableExecutor.java | 1 +
.../apache/tajo/master/exec/DDLExecutor.java | 3 +-
.../org/apache/tajo/jdbc/JdbcConnection.java | 25 ++-
.../apache/tajo/jdbc/TajoPreparedStatement.java | 20 +--
.../org/apache/tajo/jdbc/TajoStatement.java | 39 ++---
.../java/org/apache/tajo/jdbc/TestTajoJdbc.java | 6 -
.../apache/tajo/jdbc/TestTajoJdbcNegative.java | 156 +++++++++++++++++++
.../org/apache/tajo/rpc/NettyClientBase.java | 13 +-
18 files changed, 396 insertions(+), 93 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 32cf77f..d3d47be 100644
--- a/CHANGES
+++ b/CHANGES
@@ -549,6 +549,9 @@ Release 0.11.0 - unreleased
SUB TASKS
+ TAJO-1749: Refine JDBC exceptions to better handle exceptional
+ cases. (hyunsik)
+
TAJO-1737: Implement SQL Parser rule for Map type. (hyunsik)
TAJO-1787: Remove unused and legacy exceptions. (hyunsik)
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java b/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
index 7f33fdd..b63d35b 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
@@ -19,6 +19,7 @@
package org.apache.tajo.client;
import com.google.protobuf.ServiceException;
+import io.netty.channel.ConnectTimeoutException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tajo.SessionVars;
@@ -46,6 +47,7 @@ import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringResponse;
import org.apache.tajo.service.ServiceTracker;
import org.apache.tajo.util.CommonTestingUtil;
import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.NetUtils;
import org.apache.tajo.util.ProtoUtil;
import java.io.Closeable;
@@ -136,7 +138,7 @@ public class SessionConnection implements Closeable {
connections.incrementAndGet();
} catch (Throwable t) {
- throw new ClientConnectionException(t);
+ throw new TajoRuntimeException(new ClientConnectionException(t));
}
return client;
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java
index a6c07ea..5a689a1 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java
@@ -57,8 +57,7 @@ public class TajoClientImpl extends SessionConnection implements TajoClient, Que
* @param properties configurations
* @throws java.io.IOException
*/
- public TajoClientImpl(ServiceTracker tracker, @Nullable String baseDatabase, KeyValueSet properties)
- throws SQLException {
+ public TajoClientImpl(ServiceTracker tracker, @Nullable String baseDatabase, KeyValueSet properties) {
super(tracker, baseDatabase, properties);
@@ -75,8 +74,7 @@ public class TajoClientImpl extends SessionConnection implements TajoClient, Que
* @param properties configurations
* @throws java.io.IOException
*/
- public TajoClientImpl(InetSocketAddress addr, @Nullable String baseDatabase, KeyValueSet properties)
- throws SQLException {
+ public TajoClientImpl(InetSocketAddress addr, @Nullable String baseDatabase, KeyValueSet properties) {
this(new DummyServiceTracker(addr), baseDatabase, properties);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-client/src/main/java/org/apache/tajo/client/v2/exception/ClientConnectionException.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/v2/exception/ClientConnectionException.java b/tajo-client/src/main/java/org/apache/tajo/client/v2/exception/ClientConnectionException.java
index a7fb08a..fcbbfe3 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/v2/exception/ClientConnectionException.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/v2/exception/ClientConnectionException.java
@@ -19,10 +19,11 @@
package org.apache.tajo.client.v2.exception;
import org.apache.tajo.error.Errors;
+import org.apache.tajo.exception.TajoException;
import org.apache.tajo.exception.TajoRuntimeException;
-public class ClientConnectionException extends TajoRuntimeException {
+public class ClientConnectionException extends TajoException {
public ClientConnectionException(Throwable t) {
- super(Errors.ResultCode.CLIENT_CONNECTION_EXCEPTION, t.getMessage());
+ super(Errors.ResultCode.CLIENT_CONNECTION_EXCEPTION, t, t.getMessage());
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoSQLException.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoSQLException.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoSQLException.java
new file mode 100644
index 0000000..53d39cb
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoSQLException.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import org.apache.tajo.error.Errors;
+import org.apache.tajo.exception.ErrorMessages;
+import org.apache.tajo.exception.ExceptionUtil;
+import org.apache.tajo.exception.SQLExceptionUtil;
+import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos;
+
+import java.sql.SQLException;
+
+public class TajoSQLException extends SQLException {
+
+ public TajoSQLException(PrimitiveProtos.ReturnState returnState) {
+ super(returnState.getMessage(), SQLExceptionUtil.toSQLState(returnState.getReturnCode()),
+ ExceptionUtil.toTajoException(returnState));
+ }
+
+ public TajoSQLException(Errors.ResultCode code, String...args) {
+ super(ErrorMessages.getMessage(code, args), SQLExceptionUtil.toSQLState(code));
+ }
+
+ public TajoSQLException(Errors.ResultCode code, Throwable t, String...args) {
+ super(ErrorMessages.getMessage(code, args), SQLExceptionUtil.toSQLState(code), t);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/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 68cc2fc..aa26027 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
@@ -18,7 +18,6 @@
package org.apache.tajo.jdbc;
-import com.google.protobuf.ServiceException;
import org.apache.tajo.QueryId;
import org.apache.tajo.TajoProtos;
import org.apache.tajo.catalog.CatalogUtil;
@@ -27,6 +26,7 @@ import org.apache.tajo.catalog.TableDesc;
import org.apache.tajo.client.QueryClient;
import org.apache.tajo.client.QueryStatus;
import org.apache.tajo.client.TajoClientUtil;
+import org.apache.tajo.error.Errors.ResultCode;
import org.apache.tajo.exception.SQLExceptionUtil;
import org.apache.tajo.exception.TajoException;
import org.apache.tajo.ipc.ClientProtos;
@@ -59,15 +59,13 @@ public class WaitingResultSet extends FetchResultSet {
QueryStatus status = TajoClientUtil.waitCompletion(tajoClient, queryId);
if (status.getState() != TajoProtos.QueryState.QUERY_SUCCEEDED) {
- throw new ServiceException(status.getErrorMessage() != null ? status.getErrorMessage() :
- status.getErrorTrace() != null ? status.getErrorTrace() :
- "Failed to execute query by unknown reason");
+ throw new SQLException(status.getErrorMessage() != null ? status.getErrorMessage() : "unknown error",
+ SQLExceptionUtil.toSQLState(ResultCode.INTERNAL_ERROR), ResultCode.INTERNAL_ERROR.getNumber());
}
+
ClientProtos.GetQueryResultResponse response = tajoClient.getResultResponse(queryId);
TableDesc tableDesc = CatalogUtil.newTableDesc(response.getTableDesc());
return tableDesc.getLogicalSchema();
- } catch (ServiceException e) {
- throw new SQLException(e);
} catch (TajoException e) {
throw SQLExceptionUtil.toSQLException(e);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
index 3b11eab..a3f18e3 100644
--- a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
@@ -116,8 +116,9 @@ public class ErrorMessages {
ADD_MESSAGE(INVALID_INPUTS_FOR_CROSS_JOIN, "At least one of both inputs for the cross join must be a simple " +
"relation.");
- ADD_MESSAGE(CLIENT_CONNECTION_EXCEPTION, "Client connection to '%s' has error: %s", 2);
+ ADD_MESSAGE(CLIENT_CONNECTION_EXCEPTION, "%s", 1);
ADD_MESSAGE(CLIENT_UNABLE_TO_ESTABLISH_CONNECTION, "Client is unable to establish connection to '%s'", 1);
+ ADD_MESSAGE(CLIENT_CONNECTION_DOES_NOT_EXIST, "This connection has been closed.");
}
private static void ADD_MESSAGE(ResultCode code, String msgFormat) {
@@ -169,7 +170,9 @@ public class ErrorMessages {
}
} else {
- throw new TajoInternalError("Argument mismatch: code=" + code.name() + ", args=" + concat(args));
+ throw new TajoInternalError(
+ "Error message arguments are invalid: code=" + code.name() + ", args=" + concat(args) +
+ ". Please report this bug to https://issues.apache.org/jira/browse/TAJO.");
}
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
index e326ae2..0e22a87 100644
--- a/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
@@ -32,11 +32,79 @@ public class SQLExceptionUtil {
private static final Map<ResultCode, String> SQLSTATES = Maps.newHashMap();
static {
- // TODO - All SQLState should be be filled
- SQLSTATES.put(ResultCode.FEATURE_NOT_SUPPORTED, "0A000");
- SQLSTATES.put(ResultCode.NOT_IMPLEMENTED, "0A000");
-
- SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601");
+ SQLSTATES.put(ResultCode.INTERNAL_ERROR, "XX000");
+ SQLSTATES.put(ResultCode.NOT_IMPLEMENTED, "0A000");
+ SQLSTATES.put(ResultCode.FEATURE_NOT_SUPPORTED, "0A000");
+ SQLSTATES.put(ResultCode.INVALID_RPC_CALL, "08P01"); // Protocol violation
+
+
+ // Class 61 - Query Management and Scheduler
+ SQLSTATES.put(ResultCode.QUERY_FAILED, "61T01");
+ SQLSTATES.put(ResultCode.QUERY_KILLED, "61T02");
+ SQLSTATES.put(ResultCode.QUERY_TIMEOUT, "61T03");
+ SQLSTATES.put(ResultCode.QUERY_NOT_FOUND, "61T04");
+ SQLSTATES.put(ResultCode.NO_DATA, "61T05");
+ SQLSTATES.put(ResultCode.INCOMPLETE_QUERY, "61T06");
+
+
+ // Class 62 - Session
+ SQLSTATES.put(ResultCode.INVALID_SESSION, "62T01");
+ SQLSTATES.put(ResultCode.NO_SUCH_SESSION_VARIABLE, "62T02");
+ SQLSTATES.put(ResultCode.INVALID_SESSION_VARIABLE, "62T03");
+
+
+ // Data Exception (SQLState Class - 22)
+ SQLSTATES.put(ResultCode.DIVISION_BY_ZERO, "22012");
+
+
+ // Section: Class 42 - Syntax Error or Access Rule Violation
+ SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601");
+
+ SQLSTATES.put(ResultCode.UNDEFINED_DATABASE, "42T01");
+ SQLSTATES.put(ResultCode.UNDEFINED_SCHEMA, "42T02");
+ SQLSTATES.put(ResultCode.UNDEFINED_TABLE, "42P01");
+ SQLSTATES.put(ResultCode.UNDEFINED_COLUMN, "42703");
+ SQLSTATES.put(ResultCode.UNDEFINED_FUNCTION, "42883");
+ SQLSTATES.put(ResultCode.UNDEFINED_INDEX_FOR_TABLE, "42T03");
+ SQLSTATES.put(ResultCode.UNDEFINED_INDEX_FOR_COLUMNS, "42T04");
+ SQLSTATES.put(ResultCode.UNDEFINED_PARTITION, "42T05");
+ SQLSTATES.put(ResultCode.UNDEFINED_PARTITION_METHOD, "42T06");
+ SQLSTATES.put(ResultCode.UNDEFINED_OPERATOR, "42883"); // == UNDEFINED_FUNCTION
+ SQLSTATES.put(ResultCode.UNDEFINED_PARTITION_KEY, "42T07");
+
+ SQLSTATES.put(ResultCode.DUPLICATE_TABLESPACE, "42T08");
+ SQLSTATES.put(ResultCode.DUPLICATE_DATABASE, "42P04");
+ SQLSTATES.put(ResultCode.DUPLICATE_SCHEMA, "42P06");
+ SQLSTATES.put(ResultCode.DUPLICATE_TABLE, "42P07");
+ SQLSTATES.put(ResultCode.DUPLICATE_COLUMN, "42701");
+ SQLSTATES.put(ResultCode.DUPLICATE_ALIAS, "42712");
+ SQLSTATES.put(ResultCode.DUPLICATE_FUNCTION, "42723");
+ SQLSTATES.put(ResultCode.DUPLICATE_INDEX, "42710");
+ SQLSTATES.put(ResultCode.DUPLICATE_PARTITION, "42T09");
+
+ SQLSTATES.put(ResultCode.AMBIGUOUS_TABLE, "42723");
+ SQLSTATES.put(ResultCode.AMBIGUOUS_COLUMN, "42723");
+ SQLSTATES.put(ResultCode.AMBIGUOUS_FUNCTION, "42723");
+ SQLSTATES.put(ResultCode.AMBIGUOUS_PARTITION_DIRECTORY, "42T10");
+
+ SQLSTATES.put(ResultCode.CANNOT_CAST, "42846");
+ SQLSTATES.put(ResultCode.GROUPING_ERROR, "42803");
+ SQLSTATES.put(ResultCode.WINDOWING_ERROR, "42P20");
+ SQLSTATES.put(ResultCode.INVALID_RECURSION, "42P19");
+ SQLSTATES.put(ResultCode.SET_OPERATION_SCHEMA_MISMATCH, "42601");
+ SQLSTATES.put(ResultCode.SET_OPERATION_DATATYPE_MISMATCH, "42601");
+ SQLSTATES.put(ResultCode.INVALID_FOREIGN_KEY, "42830");
+ SQLSTATES.put(ResultCode.INVALID_NAME, "42602");
+ SQLSTATES.put(ResultCode.INVALID_COLUMN_DEFINITION, "42611");
+ SQLSTATES.put(ResultCode.NAME_TOO_LONG, "42622");
+ SQLSTATES.put(ResultCode.RESERVED_NAME, "42939");
+ SQLSTATES.put(ResultCode.DATATYPE_MISMATCH, "42804");
+ SQLSTATES.put(ResultCode.INDETERMINATE_DATATYPE, "42P18");
+
+ // Client Connection
+ SQLSTATES.put(ResultCode.CLIENT_CONNECTION_EXCEPTION, "08001");
+ SQLSTATES.put(ResultCode.CLIENT_UNABLE_TO_ESTABLISH_CONNECTION, "08002");
+ SQLSTATES.put(ResultCode.CLIENT_CONNECTION_DOES_NOT_EXIST, "08003");
}
public static boolean isThisError(SQLException e, ResultCode code) {
@@ -73,8 +141,20 @@ public class SQLExceptionUtil {
}
}
- public static SQLException toSQLException(TajoException e) throws SQLException {
- return toSQLException(e.getErrorCode(), e.getMessage());
+ public static String toSQLState(ResultCode code) {
+ if (SQLSTATES.containsKey(code)) {
+ return SQLSTATES.get(code);
+ } else {
+ return "42000";
+ }
+ }
+
+ public static SQLException toSQLException(DefaultTajoException e) throws SQLException {
+ if (e instanceof TajoRuntimeException) {
+ return toSQLException(e.getErrorCode(), ((TajoRuntimeException) e).getCause().getMessage());
+ } else {
+ return toSQLException(e.getErrorCode(), e.getMessage());
+ }
}
public static SQLException toSQLException(ReturnState state) throws SQLException {
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
index b5d236e..df74072 100644
--- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
@@ -43,6 +43,11 @@ public class TajoException extends Exception implements DefaultTajoException {
this.code = code;
}
+ public TajoException(ResultCode code, Throwable t, String ... args) {
+ super(ErrorMessages.getMessage(code, args), t);
+ this.code = code;
+ }
+
public TajoException(ResultCode code, String ... args) {
super(ErrorMessages.getMessage(code, args));
this.code = code;
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-common/src/main/proto/errors.proto
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto
index 21746f3..f830b11 100644
--- a/tajo-common/src/main/proto/errors.proto
+++ b/tajo-common/src/main/proto/errors.proto
@@ -68,31 +68,31 @@ import "stacktrace.proto";
enum ResultCode {
// Class
// 00 - Successful Completion
- OK = 0;
+ OK = 0;
- WARNING = 100; // Warning
+ WARNING = 100; // Warning
// General Errors
- INTERNAL_ERROR = 201; // Error caused by internal bugs (See also TajoInternalException.java)
- NOT_IMPLEMENTED = 202; // Planned, but not implemented yet.
- FEATURE_NOT_SUPPORTED = 203; // SQLState: 0A000 - Unsupported feature (usually for unreasonable feature)
- INVALID_RPC_CALL = 204; // When invalid RPC call is invoked (e.g., wrong message and absent fields)
+ INTERNAL_ERROR = 201; // SQLState: XX000 - Error caused by internal bugs (See TajoInternalException)
+ NOT_IMPLEMENTED = 202; // SQLState: 0A000 - Not implemented yet, but planned.
+ FEATURE_NOT_SUPPORTED = 203; // SQLState: 0A000 - Unsupported feature (usually for unreasonable feature)
+ INVALID_RPC_CALL = 204; // SQLState: 08P01 - When invalid RPC call is invoked (e.g., wrong message and absent fields)
// Query Management and Scheduler
- QUERY_FAILED = 301; // SQLState: ? - Query failed
- QUERY_KILLED = 302; // SQLState: ? - Query killed
- QUERY_TIMEOUT = 303; // SQLState: ? - Timeout for the query
- QUERY_NOT_FOUND = 304; // No such query in TajoMaster
- NO_DATA = 305; // No data due to query fail or error
- INCOMPLETE_QUERY = 306; // It occurs when a client requests something of a completed query.
+ QUERY_FAILED = 301; // SQLState: 61T01 - Query failed
+ QUERY_KILLED = 302; // SQLState: 61T02 - Query killed
+ QUERY_TIMEOUT = 303; // SQLState: 61T03 - Timeout for the query
+ QUERY_NOT_FOUND = 304; // SQLState: 61T04 - No such query in TajoMaster
+ NO_DATA = 305; // SQLState: 61T05 - No data due to query fail or error
+ INCOMPLETE_QUERY = 306; // SQLState: 61T06 - It occurs when a client requests something of a completed query.
// Session
- INVALID_SESSION = 401; // Session already was invalid
- NO_SUCH_SESSION_VARIABLE = 402; // Session variable not found
- INVALID_SESSION_VARIABLE = 403; // Session variable is invalid (type mismatch or out of range)
+ INVALID_SESSION = 401; // SQLState: 62T01 - Session already was invalid
+ NO_SUCH_SESSION_VARIABLE = 402; // SQLState: 62T01 - Session variable not found
+ INVALID_SESSION_VARIABLE = 403; // SQLState: 62T01 - Session variable is invalid (type mismatch or out of range)
// Data Exception (SQLState Class - 22)
- DIVISION_BY_ZERO = 451; // SQLState: 22012 - Division by zero
+ DIVISION_BY_ZERO = 451; // SQLState: 22012 - Division by zero
// Section: Class 42 - Syntax Error or Access Rule Violation
@@ -101,9 +101,9 @@ enum ResultCode {
INSUFFICIENT_PRIVILEGE = 503; // SQLState: 42501
UNDEFINED_TABLESPACE = 511; // ?
- UNDEFINED_DATABASE = 512; // ?
- UNDEFINED_SCHEMA = 513; // ?
- UNDEFINED_TABLE = 514; // ?
+ UNDEFINED_DATABASE = 512; // SQLState: 42T01
+ UNDEFINED_SCHEMA = 513; // SQLState:
+ UNDEFINED_TABLE = 514; // SQLState: 42P01
UNDEFINED_COLUMN = 515; // SQLState: 42703
UNDEFINED_FUNCTION = 516; // SQLState: 42883
UNDEFINED_INDEX_FOR_TABLE = 517; // ?
@@ -121,10 +121,10 @@ enum ResultCode {
DUPLICATE_COLUMN = 535; // SQLState: 42701
DUPLICATE_ALIAS = 536; // SQLState: 42712
DUPLICATE_FUNCTION = 537; // SQLState: 42723
- DUPLICATE_INDEX = 538; // SQLState: ?
- DUPLICATE_PARTITION = 539; // SQLState: ?
+ DUPLICATE_INDEX = 538; // SQLState: 42T07
+ DUPLICATE_PARTITION = 539; // SQLState: 42T08
- AMBIGUOUS_TABLE = 541; // ?
+ AMBIGUOUS_TABLE = 541; // SQLState: 42P09
AMBIGUOUS_COLUMN = 542; // SQLState: 42702;
AMBIGUOUS_FUNCTION = 543; // SQLState: 42725;
AMBIGUOUS_PARTITION_DIRECTORY = 544; // ?
@@ -170,10 +170,11 @@ enum ResultCode {
INVALID_TABLE_PROPERTY = 1004; // SQLState: ? - Invalid Table Property
MISSING_TABLE_PROPERTY = 1005; // SQLState: ? - Missing table property
-
+ // Client Connection
CLIENT_CONNECTION_EXCEPTION = 1101; // SQLState: 08000 - Client connection error
CLIENT_UNABLE_TO_ESTABLISH_CONNECTION = 1102; // SQLState: 08001 -
- CLIENT_PROTOCOL_PROTOCOL_VIOLATION = 1103; // SQLState: ?
+ CLIENT_CONNECTION_DOES_NOT_EXIST = 1103; // SQLState: 08003 - Client connection has been closed.
+ CLIENT_PROTOCOL_PROTOCOL_VIOLATION = 1104; // SQLState: ?
// 53 - Invalid Operand or Inconsistent Specification
INSUFFICIENT_RESOURCE = 53000;
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
index 38f722d..24f420c 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
@@ -108,6 +108,7 @@ public class CreateTableExecutor {
tableSpace.createTable(desc, ifNotExists);
catalog.createTable(desc);
+ LOG.info("relation '" + qualifiedName + "' created.");
return desc;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
index e3d91bb..a0f9adc 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
@@ -251,11 +251,12 @@ public class DDLExecutor {
}
}
- catalog.createDatabase(databaseName, tablespaceName);
String normalized = databaseName;
Path databaseDir = StorageUtil.concatPath(context.getConf().getVar(TajoConf.ConfVars.WAREHOUSE_DIR), normalized);
FileSystem fs = databaseDir.getFileSystem(context.getConf());
fs.mkdirs(databaseDir);
+ catalog.createDatabase(databaseName, tablespaceName);
+ LOG.info("database \"" + databaseName + "\" created.");
}
public void dropDatabase(QueryContext queryContext, String databaseName, boolean ifExists)
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java
index b098b16..85dbdbe 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java
@@ -27,14 +27,17 @@ import org.apache.tajo.client.CatalogAdminClient;
import org.apache.tajo.client.QueryClient;
import org.apache.tajo.client.TajoClient;
import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.client.v2.exception.ClientConnectionException;
import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.exception.SQLExceptionUtil;
-import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.error.Errors;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.*;
import org.apache.tajo.jdbc.util.QueryStringDecoder;
import org.apache.tajo.rpc.RpcUtils;
import org.apache.tajo.util.KeyValueSet;
import java.io.IOException;
+import java.net.ConnectException;
import java.net.URI;
import java.sql.*;
import java.util.List;
@@ -66,17 +69,19 @@ public class JdbcConnection implements Connection {
this.properties = properties;
try {
+
if (!rawURI.startsWith(TajoDriver.TAJO_JDBC_URL_PREFIX)) {
- throw new SQLException("Invalid URL: " + rawURI, "TAJO-001");
+ // its impossible case
+ throw new TajoInternalError("Invalid URL: " + rawURI);
}
// URI form: jdbc:tajo://hostname:port/databasename
int startIdx = rawURI.indexOf(":");
if (startIdx < 0) {
- throw new SQLException("Invalid URL: " + rawURI, "TAJO-001");
+ throw new TajoInternalError("Invalid URL: " + rawURI);
}
- String uri = rawURI.substring(startIdx+1, rawURI.length());
+ String uri = rawURI.substring(startIdx + 1, rawURI.length());
try {
this.uri = URI.create(uri);
} catch (IllegalArgumentException iae) {
@@ -116,8 +121,12 @@ public class JdbcConnection implements Connection {
try {
tajoClient = new TajoClientImpl(RpcUtils.createSocketAddr(hostName, port), databaseName, clientProperties);
- } catch (Exception e) {
- throw new SQLException("Cannot create TajoClient instance:" + e.getMessage(), "TAJO-002");
+ } catch (Throwable t) {
+ if (t instanceof DefaultTajoException) {
+ throw SQLExceptionUtil.toSQLException((DefaultTajoException) t);
+ } else {
+ throw new TajoSQLException(ResultCode.INTERNAL_ERROR, t, t.getMessage());
+ }
}
closed.set(false);
}
@@ -182,7 +191,7 @@ public class JdbcConnection implements Connection {
@Override
public Statement createStatement() throws SQLException {
if (isClosed()) {
- throw new SQLException("Can't create Statement, connection is closed");
+ throw new TajoSQLException(ResultCode.CLIENT_CONNECTION_DOES_NOT_EXIST);
}
return new TajoStatement(this, tajoClient);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
index 0574bf9..6b47f97 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
@@ -61,7 +61,7 @@ public class TajoPreparedStatement extends TajoStatement implements PreparedStat
@Override
public void clearParameters() throws SQLException {
- checkConnection("Can't clear parameters");
+ checkConnection();
this.parameters.clear();
}
@@ -83,7 +83,7 @@ public class TajoPreparedStatement extends TajoStatement implements PreparedStat
}
protected TajoResultSetBase executeImmediate(String sql) throws SQLException {
- checkConnection("Can't execute");
+ checkConnection();
try {
if (sql.contains("?")) {
@@ -152,7 +152,7 @@ public class TajoPreparedStatement extends TajoStatement implements PreparedStat
@Override
public ResultSetMetaData getMetaData() throws SQLException {
- checkConnection("Can't get metadata");
+ checkConnection();
if(resultSet != null) {
return resultSet.getMetaData();
} else {
@@ -223,7 +223,7 @@ public class TajoPreparedStatement extends TajoStatement implements PreparedStat
@Override
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
this.parameters.put(parameterIndex, "" + x);
}
@@ -281,25 +281,25 @@ public class TajoPreparedStatement extends TajoStatement implements PreparedStat
@Override
public void setDouble(int parameterIndex, double x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
this.parameters.put(parameterIndex,"" + x);
}
@Override
public void setFloat(int parameterIndex, float x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
this.parameters.put(parameterIndex,"" + x);
}
@Override
public void setInt(int parameterIndex, int x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
this.parameters.put(parameterIndex,"" + x);
}
@Override
public void setLong(int parameterIndex, long x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
this.parameters.put(parameterIndex,"" + x);
}
@@ -378,13 +378,13 @@ public class TajoPreparedStatement extends TajoStatement implements PreparedStat
@Override
public void setShort(int parameterIndex, short x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
this.parameters.put(parameterIndex,"" + x);
}
@Override
public void setString(int parameterIndex, String x) throws SQLException {
- checkConnection("Can't set parameters");
+ checkConnection();
x=x.replace("'", "\\'");
this.parameters.put(parameterIndex,"'" + x +"'");
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
index 5354e60..6039e9c 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
@@ -17,19 +17,16 @@
*/
package org.apache.tajo.jdbc;
-import com.google.common.collect.Lists;
import org.apache.tajo.QueryId;
import org.apache.tajo.SessionVars;
import org.apache.tajo.client.TajoClient;
import org.apache.tajo.client.TajoClientUtil;
+import org.apache.tajo.error.Errors.ResultCode;
import org.apache.tajo.exception.SQLExceptionUtil;
+import org.apache.tajo.exception.TajoException;
import org.apache.tajo.ipc.ClientProtos;
import java.sql.*;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.tajo.client.TajoClientUtil.NULL_RESULT_SET;
public class TajoStatement implements Statement {
protected JdbcConnection conn;
@@ -79,7 +76,7 @@ public class TajoStatement implements Statement {
@Override
public void cancel() throws SQLException {
- checkConnection("Can't cancel query");
+ checkConnection();
if (resultSet == null || resultSet.getQueryId().isNull()) {
return;
}
@@ -99,7 +96,7 @@ public class TajoStatement implements Statement {
@Override
public void clearWarnings() throws SQLException {
- checkConnection("Can't clear warnings");
+ checkConnection();
warningChain = null;
}
@@ -146,7 +143,7 @@ public class TajoStatement implements Statement {
@Override
public ResultSet executeQuery(String sql) throws SQLException {
- checkConnection("Can't execute");
+ checkConnection();
return executeSQL(sql);
}
@@ -173,16 +170,20 @@ public class TajoStatement implements Statement {
}
}
- protected void checkConnection(String errorMsg) throws SQLException {
- if (isClosed) {
- throw new SQLException(errorMsg + " after statement has been closed");
+ protected void checkConnection() throws SQLException {
+ if (isClosed || conn.isClosed()) {
+ throw new TajoSQLException(ResultCode.CLIENT_CONNECTION_DOES_NOT_EXIST);
}
}
@Override
public int executeUpdate(String sql) throws SQLException {
- checkConnection("Can't execute update");
- tajoClient.executeQuery(sql);
+ checkConnection();
+ try {
+ tajoClient.updateQuery(sql);
+ } catch (TajoException e) {
+ throw SQLExceptionUtil.toSQLException(e);
+ }
return 1;
}
@@ -203,19 +204,19 @@ public class TajoStatement implements Statement {
@Override
public Connection getConnection() throws SQLException {
- checkConnection("Can't get connection");
+ checkConnection();
return conn;
}
@Override
public int getFetchDirection() throws SQLException {
- checkConnection("Can't get fetch direction");
+ checkConnection();
return ResultSet.FETCH_FORWARD;
}
@Override
public int getFetchSize() throws SQLException {
- checkConnection("Can't get fetch size");
+ checkConnection();
return fetchSize;
}
@@ -252,7 +253,7 @@ public class TajoStatement implements Statement {
@Override
public ResultSet getResultSet() throws SQLException {
- checkConnection("Can't get result set");
+ checkConnection();
return resultSet;
}
@@ -282,7 +283,7 @@ public class TajoStatement implements Statement {
@Override
public SQLWarning getWarnings() throws SQLException {
- checkConnection("Can't get warnings");
+ checkConnection();
return warningChain;
}
@@ -321,7 +322,7 @@ public class TajoStatement implements Statement {
@Override
public void setFetchSize(int rows) throws SQLException {
- checkConnection("Can't set fetch size");
+ checkConnection();
fetchSize = rows;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
index e6d01fe..40d7e58 100644
--- a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
+++ b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
@@ -61,12 +61,6 @@ public class TestTajoJdbc extends QueryTestCaseBase {
assertFalse(driver.acceptsURL("jdbc:taju:"));
}
- @Test(expected = SQLException.class)
- public void testGetConnection() throws SQLException {
- DriverManager.getConnection("jdbc:taju://" + tajoMasterAddress.getHostName() + ":" + tajoMasterAddress.getPort()
- + "/default");
- }
-
@Test
public void testStatement() throws Exception {
String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbcNegative.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbcNegative.java b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbcNegative.java
new file mode 100644
index 0000000..232292b
--- /dev/null
+++ b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbcNegative.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.sql.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.exception.SQLExceptionUtil.toSQLState;
+import static org.apache.tajo.jdbc.TestTajoJdbc.buildConnectionUri;
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestTajoJdbcNegative extends QueryTestCaseBase {
+ private static InetSocketAddress tajoMasterAddress;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ tajoMasterAddress = testingCluster.getMaster().getTajoMasterClientService().getBindAddress();
+ Class.forName("org.apache.tajo.jdbc.TajoDriver").newInstance();
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetConnection() throws SQLException {
+ DriverManager.getConnection("jdbc:taju://" + tajoMasterAddress.getHostName() + ":" + tajoMasterAddress.getPort()
+ + "/default");
+ }
+
+ @Test
+ public void testUnresolvedError() throws SQLException {
+ try {
+ DriverManager.getConnection("jdbc:tajo://tajo-unknown-asdnkl213.asd:2002/default");
+ } catch (SQLException s) {
+ assertEquals(toSQLState(ResultCode.CLIENT_CONNECTION_EXCEPTION), s.getSQLState());
+ assertEquals("Can't resolve host name: tajo-unknown-asdnkl213.asd:2002", s.getMessage());
+ }
+ }
+
+ @Test
+ public void testConnectionRefused() throws SQLException, IOException {
+ Integer port = null;
+ try {
+ ServerSocket s = new ServerSocket(0);
+ port = s.getLocalPort();
+ s.close();
+ DriverManager.getConnection("jdbc:tajo://localhost:" + port + "/default");
+ fail("Must be failed.");
+ } catch (SQLException s) {
+ assertEquals(toSQLState(ResultCode.CLIENT_CONNECTION_EXCEPTION), s.getSQLState());
+ assertEquals("Connection refused: localhost/127.0.0.1:" + port, s.getMessage());
+ }
+ }
+
+ @Test
+ public void testConnectionClosedAtCreateStmt() throws SQLException, IOException {
+ String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+ DEFAULT_DATABASE_NAME);
+ Connection conn = DriverManager.getConnection(connUri);
+ assertTrue(conn.isValid(100));
+
+ conn.close();
+ try (Statement stmt = conn.createStatement()) {
+ fail("Must be failed.");
+ stmt.isClosed();
+ } catch (SQLException s) {
+ assertEquals(toSQLState(ResultCode.CLIENT_CONNECTION_DOES_NOT_EXIST), s.getSQLState());
+ assertEquals("This connection has been closed.", s.getMessage());
+ }
+ }
+
+ @Test
+ public void testConnectionClosed() throws SQLException, IOException {
+ String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+ DEFAULT_DATABASE_NAME);
+ Connection conn = DriverManager.getConnection(connUri);
+ assertTrue(conn.isValid(100));
+
+ try (Statement stmt = conn.createStatement()) {
+ conn.close();
+ stmt.executeUpdate("SELECT 1;");
+ fail("Must be failed.");
+ } catch (SQLException s) {
+ assertEquals(toSQLState(ResultCode.CLIENT_CONNECTION_DOES_NOT_EXIST), s.getSQLState());
+ assertEquals("This connection has been closed.", s.getMessage());
+ }
+ }
+
+ @Test
+ public void testImmediateException() throws Exception {
+ String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+ DEFAULT_DATABASE_NAME);
+ Connection conn = DriverManager.getConnection(connUri);
+ assertTrue(conn.isValid(100));
+
+ try (Statement stmt = conn.createStatement()) {
+ stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS TestTajoJdbcNegative");
+ stmt.executeUpdate("CREATE TABLE TestTajoJdbcNegative.table123u8sd ( name RECORD(last TEXT, first TEXT) )");
+
+ try (ResultSet resultSet = stmt.executeQuery("select name FROM TestTajoJdbcNegative.table123u8sd")) {
+ fail("Getting a record type field must be failed");
+ } catch (SQLException s) {
+ assertEquals(toSQLState(ResultCode.NOT_IMPLEMENTED), s.getSQLState());
+ } finally {
+ stmt.executeUpdate("DROP TABLE IF EXISTS TestTajoJdbcNegative.table12u79");
+ stmt.executeUpdate("DROP DATABASE IF EXISTS TestTajoJdbcNegative");
+ }
+ }
+ }
+
+ @Test
+ public void testExceptionDuringProcessing() throws Exception {
+ String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+ DEFAULT_DATABASE_NAME);
+ Connection conn = DriverManager.getConnection(connUri);
+ assertTrue(conn.isValid(100));
+
+ try (Statement stmt = conn.createStatement()) {
+ try (ResultSet resultSet =
+ stmt.executeQuery("select fail(3, l_orderkey, 'testQueryFailure') from default.lineitem")) {
+ fail("Failure must occur here.");
+ } catch (SQLException s) {
+ assertEquals(toSQLState(ResultCode.INTERNAL_ERROR), s.getSQLState());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/688bc5c1/tajo-rpc/tajo-rpc-protobuf/src/main/java/org/apache/tajo/rpc/NettyClientBase.java
----------------------------------------------------------------------
diff --git a/tajo-rpc/tajo-rpc-protobuf/src/main/java/org/apache/tajo/rpc/NettyClientBase.java b/tajo-rpc/tajo-rpc-protobuf/src/main/java/org/apache/tajo/rpc/NettyClientBase.java
index 0d86527..5f76bfc 100644
--- a/tajo-rpc/tajo-rpc-protobuf/src/main/java/org/apache/tajo/rpc/NettyClientBase.java
+++ b/tajo-rpc/tajo-rpc-protobuf/src/main/java/org/apache/tajo/rpc/NettyClientBase.java
@@ -39,6 +39,8 @@ import java.lang.reflect.Method;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.nio.channels.UnresolvedAddressException;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -195,7 +197,7 @@ public abstract class NettyClientBase<T> implements ProtoDeclaration, Closeable
if (maxRetries > retries) {
retries++;
- LOG.warn(getErrorMessage(ExceptionUtils.getMessage(future.cause())) + " Try to reconnect : " + getKey().addr);
+ LOG.warn(getErrorMessage(ExceptionUtils.getMessage(future.cause())) + "\nTry to reconnect : " + getKey().addr);
try {
Thread.sleep(RpcConstants.DEFAULT_PAUSE);
} catch (InterruptedException e) {
@@ -206,8 +208,13 @@ public abstract class NettyClientBase<T> implements ProtoDeclaration, Closeable
break;
}
} else {
- throw new ConnectTimeoutException("Max retry count has been exceeded. attempts=" + retries
- + " caused by: " + future.cause());
+ LOG.error("Max retry count has been exceeded. attempts=" + retries + " caused by: " + future.cause());
+
+ if (future.cause() instanceof UnresolvedAddressException) {
+ throw new ConnectException("Can't resolve host name: " + address.toString());
+ } else {
+ throw new ConnectTimeoutException(future.cause().getMessage());
+ }
}
}
}