From 47cc1d44fd1b038050745a08cfd2f18d1a1b5e2a Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Sun, 28 Jun 2015 22:40:06 -0700 Subject: [PATCH 01/30] Initial work --- .../org/apache/tajo/cli/tsql/TajoCli.java | 7 +- .../tajo/client/CatalogAdminClientImpl.java | 8 +- .../apache/tajo/client/QueryClientImpl.java | 18 +- .../apache/tajo/client/SessionConnection.java | 13 +- tajo-client/src/main/proto/ClientProtos.proto | 30 +-- tajo-common/pom.xml | 2 + tajo-common/src/main/proto/errors.proto | 195 ++++++++++++++++++ tajo-common/src/main/proto/stacktrace.proto | 33 +++ .../org/apache/tajo/master/GlobalEngine.java | 3 +- .../tajo/master/TajoMasterClientService.java | 28 +-- .../tajo/master/exec/QueryExecutor.java | 21 +- .../tajo/webapp/QueryExecutorServlet.java | 8 +- .../ws/rs/resources/SessionsResource.java | 15 +- .../ws/rs/responses/NewSessionResponse.java | 11 +- .../org/apache/tajo/jdbc/TajoStatement.java | 3 +- 15 files changed, 318 insertions(+), 77 deletions(-) create mode 100644 tajo-common/src/main/proto/errors.proto create mode 100644 tajo-common/src/main/proto/stacktrace.proto diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java index 86046c42a8..4b9eb2beff 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java @@ -33,6 +33,7 @@ import org.apache.tajo.client.*; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; +import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.service.ServiceTrackerFactory; import org.apache.tajo.util.FileUtil; @@ -43,6 +44,8 @@ import java.sql.SQLException; import java.util.*; +import static org.apache.tajo.exception.ErrorUtil.isOk; + public class TajoCli { public static final String ERROR_PREFIX = "ERROR: "; public static final String KILL_PREFIX = "KILL: "; @@ -490,7 +493,7 @@ private void executeJsonQuery(String json) throws ServiceException, IOException ClientProtos.SubmitQueryResponse response = client.executeQueryWithJson(json); if (response == null) { onError("response is null", null); - } else if (response.getResultCode() == ClientProtos.ResultCode.OK) { + } else if (isOk(response.getResultCode())) { if (response.getIsForwarded()) { QueryId queryId = new QueryId(response.getQueryId()); waitForQueryCompleted(queryId); @@ -521,7 +524,7 @@ private int executeQuery(String statement) throws ServiceException, IOException if (response == null) { onError("response is null", null); - } else if (response.getResultCode() == ClientProtos.ResultCode.OK) { + } else if (isOk(response.getResultCode())) { if (response.getIsForwarded()) { QueryId queryId = new QueryId(response.getQueryId()); waitForQueryCompleted(queryId); diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index 1fe856a393..3976d63a97 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -26,6 +26,7 @@ import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.SessionedStringProto; import org.apache.tajo.jdbc.SQLStates; @@ -37,6 +38,7 @@ import java.sql.SQLException; import java.util.List; +import static org.apache.tajo.exception.ErrorUtil.isOk; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; public class CatalogAdminClientImpl implements CatalogAdminClient { @@ -113,7 +115,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema builder.setPartition(partitionMethodDesc.getProto()); } ClientProtos.TableResponse res = tajoMasterService.createExternalTable(null, builder.build()); - if (res.getResultCode() == ClientProtos.ResultCode.OK) { + if (isOk(res.getResultCode())) { return CatalogUtil.newTableDesc(res.getTableDesc()); } else { throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState()); @@ -167,7 +169,7 @@ public TableDesc getTableDesc(final String tableName) throws ServiceException { builder.setSessionId(connection.sessionId); builder.setValue(tableName); ClientProtos.TableResponse res = tajoMasterService.getTableDesc(null, builder.build()); - if (res.getResultCode() == ClientProtos.ResultCode.OK) { + if (isOk(res.getResultCode())) { return CatalogUtil.newTableDesc(res.getTableDesc()); } else { throw new ServiceException(new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState())); @@ -184,7 +186,7 @@ public List getFunctions(final String functionN String paramFunctionName = functionName == null ? "" : functionName; ClientProtos.FunctionResponse res = tajoMasterService.getFunctionList(null, connection.convertSessionedString(paramFunctionName)); - if (res.getResultCode() == ClientProtos.ResultCode.OK) { + if (isOk(res.getResultCode())) { return res.getFunctionsList(); } else { throw new ServiceException(new SQLException(res.getErrorMessage())); 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 da10f55e14..7f6618f921 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 @@ -41,6 +41,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import static org.apache.tajo.exception.ErrorUtil.isFailed; +import static org.apache.tajo.exception.ErrorUtil.isOk; import static org.apache.tajo.ipc.ClientProtos.*; import static org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -164,7 +166,7 @@ public ClientProtos.SubmitQueryResponse executeQuery(final String sql) throws Se SubmitQueryResponse response = tajoMasterService.submitQuery(null, builder.build()); - if (response.getResultCode() == ResultCode.OK) { + if (isOk(response.getResultCode())) { connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); } return response; @@ -191,7 +193,7 @@ public ResultSet executeQueryAndGetResult(String sql) throws ServiceException, I ClientProtos.SubmitQueryResponse response = executeQuery(sql); - if (response.getResultCode() == ClientProtos.ResultCode.ERROR) { + if (isFailed(response.getResultCode())) { if (response.hasErrorMessage()) { throw new ServiceException(response.getErrorMessage()); } else if (response.hasErrorTrace()) { @@ -227,7 +229,7 @@ public ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceE ClientProtos.SubmitQueryResponse response = executeQueryWithJson(json); - if (response.getResultCode() == ClientProtos.ResultCode.ERROR) { + if (isFailed(response.getResultCode())) { throw new ServiceException(response.getErrorTrace()); } @@ -356,7 +358,7 @@ public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int builder.setFetchRowNum(fetchRowNum); GetQueryResultDataResponse response = tajoMasterService.getQueryResultData(null, builder.build()); - if (response.getResultCode() == ClientProtos.ResultCode.ERROR) { + if (isFailed(response.getResultCode())) { throw new ServiceException(response.getErrorMessage()); } @@ -387,7 +389,7 @@ public boolean updateQuery(final String sql) throws ServiceException { builder.setIsJson(false); ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - if (response.getResultCode() == ClientProtos.ResultCode.OK) { + if (isOk(response.getResultCode())) { connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return true; } else { @@ -410,7 +412,7 @@ public boolean updateQueryWithJson(final String json) throws ServiceException { builder.setQuery(json); builder.setIsJson(true); ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - if (response.getResultCode() == ClientProtos.ResultCode.OK) { + if (isOk(response.getResultCode())) { return true; } else { if (response.hasErrorMessage()) { @@ -518,7 +520,7 @@ public QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceExceptio TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); GetQueryInfoResponse res = tajoMasterService.getQueryInfo(null,builder.build()); - if (res.getResultCode() == ResultCode.OK) { + if (isOk(res.getResultCode())) { return res.getQueryInfo(); } else { throw new ServiceException(res.getErrorMessage()); @@ -552,7 +554,7 @@ public QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceEx QueryMasterClientProtocolService.BlockingInterface queryMasterService = queryMasterClient.getStub(); GetQueryHistoryResponse res = queryMasterService.getQueryHistory(null, builder.build()); - if (res.getResultCode() == ResultCode.OK) { + if (isOk(res.getResultCode())) { return res.getQueryHistory(); } else { throw new ServiceException(res.getErrorMessage()); 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 e1a3791ceb..0ae159bf6c 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 @@ -27,7 +27,6 @@ import org.apache.tajo.annotation.Nullable; import org.apache.tajo.auth.UserRoleInfo; import org.apache.tajo.ipc.ClientProtos; -import org.apache.tajo.ipc.ClientProtos.ResultCode; import org.apache.tajo.ipc.ClientProtos.SessionUpdateResponse; import org.apache.tajo.ipc.TajoMasterClientProtocol; import org.apache.tajo.rpc.NettyClientBase; @@ -50,6 +49,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.tajo.exception.ErrorUtil.isFailed; +import static org.apache.tajo.exception.ErrorUtil.isOk; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; import static org.apache.tajo.ipc.ClientProtos.CreateSessionResponse; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -178,7 +179,7 @@ public Map updateSessionVariables(final Map vari SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); - if (response.getResultCode() == ResultCode.OK) { + if (isOk(response.getResultCode())) { updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { @@ -197,7 +198,7 @@ public Map unsetSessionVariables(final List variables) t SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); - if (response.getResultCode() == ResultCode.OK) { + if (isOk(response.getResultCode())) { updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { @@ -307,7 +308,7 @@ protected void checkSessionAndGet(NettyClientBase client) throws ServiceExceptio CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); - if (response.getResultCode() == ResultCode.OK) { + if (isOk(response.getResultCode())) { sessionId = response.getSessionId(); updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); @@ -333,7 +334,7 @@ public boolean reconnect() throws Exception { // create new session TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); - if (response.getResultCode() != ResultCode.OK) { + if (isFailed(response.getResultCode())) { return false; } @@ -357,7 +358,7 @@ public boolean reconnect() throws Exception { .setSessionId(sessionId) .setSessionVars(keyValueSet.getProto()).build(); - if (tajoMasterService.updateSessionVariables(null, request).getResultCode() != ResultCode.OK) { + if (isFailed(tajoMasterService.updateSessionVariables(null, request).getResultCode())) { tajoMasterService.removeSession(null, sessionId); return false; } diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index 5497faade5..31137e8c69 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -26,10 +26,10 @@ import "TajoIdProtos.proto"; import "CatalogProtos.proto"; import "PrimitiveProtos.proto"; -enum ResultCode { - OK = 0; - ERROR = 1; -} +import "errors.proto"; // tajo-common +import "stacktrace.proto"; // tajo-common + + message CreateSessionRequest { required string username = 1; @@ -37,7 +37,7 @@ message CreateSessionRequest { } message CreateSessionResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional SessionIdProto sessionId = 2; optional KeyValueSetProto sessionVars = 3; optional string message = 4; @@ -50,7 +50,7 @@ message UpdateSessionVariableRequest { } message SessionUpdateResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional KeyValueSetProto sessionVars = 2; optional string message = 3; } @@ -61,7 +61,7 @@ message SessionedStringProto { } message ExplainQueryResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional string explain = 2; optional string errorMessage = 3; } @@ -74,7 +74,7 @@ message QueryRequest { } message UpdateQueryResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional string errorMessage = 2; optional KeyValueSetProto sessionVars = 3; } @@ -126,7 +126,7 @@ message SerializedResultSet { } message SubmitQueryResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; required QueryIdProto queryId = 2; required string userName = 3; optional bool isForwarded = 4 [default = false]; @@ -145,7 +145,7 @@ message SubmitQueryResponse { } message GetQueryStatusResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; required QueryIdProto queryId = 2; optional QueryState state = 3; optional float progress = 4; @@ -165,7 +165,7 @@ message GetQueryResultDataRequest { } message GetQueryResultDataResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; required SerializedResultSet resultSet = 2; optional string errorMessage = 3; optional string errorTrace = 4; @@ -212,13 +212,13 @@ message DropTableRequest { } message TableResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional TableDescProto tableDesc = 2; optional string errorMessage = 3; } message FunctionResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; repeated FunctionDescProto functions = 2; optional string errorMessage = 3; } @@ -273,13 +273,13 @@ message QueryHistoryProto { } message GetQueryHistoryResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional QueryHistoryProto queryHistory = 2; optional string errorMessage = 3; } message GetQueryInfoResponse { - required ResultCode resultCode = 1; + required tajo.error.ResultCode resultCode = 1; optional QueryInfoProto queryInfo = 2; optional string errorMessage = 3; } diff --git a/tajo-common/pom.xml b/tajo-common/pom.xml index 2f96a2cee3..68062657af 100644 --- a/tajo-common/pom.xml +++ b/tajo-common/pom.xml @@ -151,6 +151,8 @@ src/main/proto/DataTypes.proto src/main/proto/PrimitiveProtos.proto src/main/proto/tajo_protos.proto + src/main/proto/stacktrace.proto + src/main/proto/errors.proto diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto new file mode 100644 index 0000000000..8a755d1917 --- /dev/null +++ b/tajo-common/src/main/proto/errors.proto @@ -0,0 +1,195 @@ +/** + * 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 tajo.error; +option java_package = "org.apache.tajo.error"; + +import "stacktrace.proto"; + +enum ResultCode { + OK = 0; + + // Warnings + WARNING = 100; + + // General Errors + UNKNOWN_ERROR = 200; + INTERNAL_ERROR = 201; // error caused by internal bugs + NOT_IMPLEMENTED = 202; + ILLEGAL_STATE = 203; + + // Session Errors + SESSION_INVALIDATION = 251; + NO_SUCH_SESSION_VARIABLE = 252; + + // Query and Catalog Errors + NO_SUCH_DATABASE = 301; + NO_SUCH_TABLE = 302; + NO_SUCH_COLUMN = 303; + DATABASE_EXISTS = 305; + TABLE_EXISTS = 306; + COLUMN_EXISTS = 307; + + // Physical Executor Errors + INVALID_EXPRESSION = 401; + EXCEEDED_MEMORY = 402; + + // underlying system errors based on errno.h. + EPERM = 10001; // Operation not permitted + ENOENT = 10002; // No such file or directory + ESRCH = 10003; // No such process + EINTR = 10004; // Interrupted system call + EIO = 10005; // I/O error + ENXIO = 10006; // No such device or address + E2BIG = 10007; // Argument list too long + ENOEXEC = 10008; // Exec format error + EBADF = 10009; // Bad file number + ECHILD = 10010; // No child processes + EAGAIN = 10011; // Try again + ENOMEM = 10012; // Out of memory + EACCES = 10013; // Permission denied + EFAULT = 10014; // Bad address + ENOTBLK = 10015; // Block device required + EBUSY = 10016; // Device or resource busy + EEXIST = 10017; // File exists + EXDEV = 10018; // Cross-device link + ENODEV = 10019; // No such device + ENOTDIR = 10020; // Not a directory + EISDIR = 10021; // Is a directory + EINVAL = 10022; // Invalid argument + ENFILE = 10023; // File table overflow + EMFILE = 10024; // Too many open files + ENOTTY = 10025; // Not a typewriter + ETXTBSY = 10026; // Text file busy + EFBIG = 10027; // File too large + ENOSPC = 10028; // No space left on device + ESPIPE = 10029; // Illegal seek + EROFS = 10030; // Read-only file system + EMLINK = 10031; // Too many links + EPIPE = 10032; // Broken pipe + EDOM = 10033; // Math argument out of domain of func + ERANGE = 10034; // Math result not representable +; + EDEADLK = 10035; // Resource deadlock would occur + ENAMETOOLONG = 10036; // File name too long + ENOLCK = 10037; // No record locks available + ENOSYS = 10038; // Function not implemented + ENOTEMPTY = 10039; // Directory not empty + ELOOP = 10040; // Too many symbolic links encountered + // EWOULDBLOCK = 100EAGAIN // Operation would block + ENOMSG = 10042; // No message of desired type + EIDRM = 10043; // Identifier removed + ECHRNG = 10044; // Channel number out of range + EL2NSYNC = 10045; // Level 2 not synchronized + EL3HLT = 10046; // Level 3 halted + EL3RST = 10047; // Level 3 reset + ELNRNG = 10048; // Link number out of range + EUNATCH = 10049; // Protocol driver not attached + ENOCSI = 10050; // No CSI structure available + EL2HLT = 10051; // Level 2 halted + EBADE = 10052; // Invalid exchange + EBADR = 10053; // Invalid request descriptor + EXFULL = 10054; // Exchange full + ENOANO = 10055; // No anode + EBADRQC = 10056; // Invalid request code + EBADSLT = 10057; // Invalid slot + // EDEADLOCK EDEADLK + EBFONT = 10059; // Bad font file format + ENOSTR = 10060; // Device not a stream + ENODATA = 10061; // No data available + ETIME = 10062; // Timer expired + ENOSR = 10063; // Out of streams resources + ENONET = 10064; // Machine is not on the network + ENOPKG = 10065; // Package not installed + EREMOTE = 10066; // Object is remote + ENOLINK = 10067; // Link has been severed + EADV = 10068; // Advertise error + ESRMNT = 10069; // Srmount error + ECOMM = 10070; // Communication error on send + EPROTO = 10071; // Protocol error + EMULTIHOP = 10072; // Multihop attempted + EDOTDOT = 10073; // RFS specific error + EBADMSG = 10074; // Not a data message + EOVERFLOW = 10075; // Value too large for defined data type + ENOTUNIQ = 10076; // Name not unique on network + EBADFD = 10077; // File descriptor in bad state + EREMCHG = 10078; // Remote address changed + ELIBACC = 10079; // Can not access a needed shared library + ELIBBAD = 10080; // Accessing a corrupted shared library + ELIBSCN = 10081; // .lib section in a.out corrupted + ELIBMAX = 10082; // Attempting to link in too many shared libraries + ELIBEXEC = 10083; // Cannot exec a shared library directly + EILSEQ = 10084; // Illegal byte sequence + ERESTART = 10085; // Interrupted system call should be restarted + ESTRPIPE = 10086; // Streams pipe error + EUSERS = 10087; // Too many users + ENOTSOCK = 10088; // Socket operation on non-socket + EDESTADDRREQ = 10089; // Destination address required + EMSGSIZE = 10090; // Message too long + EPROTOTYPE = 10091; // Protocol wrong type for socket + ENOPROTOOPT = 10092; // Protocol not available + EPROTONOSUPPORT = 10093; // Protocol not supported + ESOCKTNOSUPPORT = 10094; // Socket type not supported + EOPNOTSUPP = 10095; // Operation not supported on transport endpoint + EPFNOSUPPORT = 10096; // Protocol family not supported + EAFNOSUPPORT = 10097; // Address family not supported by protocol + EADDRINUSE = 10098; // Address already in use + EADDRNOTAVAIL = 10099; // Cannot assign requested address + ENETDOWN = 10100; // Network is down + ENETUNREACH = 10101; // Network is unreachable + ENETRESET = 10102; // Network dropped connection because of reset + ECONNABORTED = 10103; // Software caused connection abort + ECONNRESET = 10104; // Connection reset by peer + ENOBUFS = 10105; // No buffer space available + EISCONN = 10106; // Transport endpoint is already connected + ENOTCONN = 10107; // Transport endpoint is not connected + ESHUTDOWN = 10108; // Cannot send after transport endpoint shutdown + ETOOMANYREFS = 10109; // Too many references: cannot splice + ETIMEDOUT = 10110; // Connection timed out + ECONNREFUSED = 10111; // Connection refused + EHOSTDOWN = 10112; // Host is down + EHOSTUNREACH = 10113; // No route to host + EALREADY = 10114; // Operation already in progress + EINPROGRESS = 10115; // Operation now in progress + ESTALE = 10116; // Stale NFS file handle + EUCLEAN = 10117; // Structure needs cleaning + ENOTNAM = 10118; // Not a XENIX named type file + ENAVAIL = 10119; // No XENIX semaphores available + EISNAM = 10120; // Is a named type file + EREMOTEIO = 10121; // Remote I/O error + EDQUOT = 10122; // Quota exceeded + ENOMEDIUM = 10123; // No medium found + EMEDIUMTYPE = 10124; // Wrong medium type + ECANCELED = 10125; // Operation Canceled + ENOKEY = 10126; // Required key not available + EKEYEXPIRED = 10127; // Key has expired + EKEYREVOKED = 10128; // Key has been revoked + EKEYREJECTED = 10129; // Key was rejected by service + + // for robust mutexes + EOWNERDEAD = 10130; // Owner died + ENOTRECOVERABLE = 10131; // State not recoverable +} + +message SerializedException { + required int64 timestamp = 1; // Microseconds since Epoch. + required ResultCode return_code = 2; + required string message = 3; + + optional StackTrace stack_trace = 4; +} \ No newline at end of file diff --git a/tajo-common/src/main/proto/stacktrace.proto b/tajo-common/src/main/proto/stacktrace.proto new file mode 100644 index 0000000000..04dca133c6 --- /dev/null +++ b/tajo-common/src/main/proto/stacktrace.proto @@ -0,0 +1,33 @@ +/** + * 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. + */ + +// Copyright 2011 Google Inc. All Rights Reserved. +// Support for serializing stack traces. + +package tajo.error; +option java_package = "org.apache.tajo.error"; + +message StackTrace { + message Element { + optional string function = 1; + optional string filename = 2; + optional int32 line = 3 [default = -1]; + optional string context = 4; + } + repeated Element element = 1; +} \ No newline at end of file diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java index 37b497ccd0..c3b7a3ffb4 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java @@ -39,6 +39,7 @@ import org.apache.tajo.engine.parser.SQLAnalyzer; import org.apache.tajo.engine.parser.SQLSyntaxError; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.error.Errors; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.master.exec.DDLExecutor; @@ -194,7 +195,7 @@ public SubmitQueryResponse executeQuery(Session session, String query, boolean i responseBuilder.setUserName(queryContext.get(SessionVars.USERNAME)); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); responseBuilder.setIsForwarded(true); - responseBuilder.setResultCode(ClientProtos.ResultCode.ERROR); + responseBuilder.setResultCode(Errors.ResultCode.UNKNOWN_ERROR); String errorMessage = t.getMessage(); if (t.getMessage() == null) { errorMessage = t.getClass().getName(); diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 7dbe81561d..6d23ecee6d 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -40,6 +40,8 @@ import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.error.Errors; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.*; import org.apache.tajo.ipc.TajoMasterClientProtocol; @@ -152,12 +154,12 @@ public CreateSessionResponse createSession(RpcController controller, CreateSessi return builder.build(); } catch (NoSuchDatabaseException nsde) { CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); builder.setMessage(nsde.getMessage()); return builder.build(); } catch (InvalidSessionException e) { CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); builder.setMessage(e.getMessage()); return builder.build(); } @@ -183,7 +185,7 @@ public SessionUpdateResponse buildSessionUpdateOnSuccess(Map var public SessionUpdateResponse buildSessionUpdateOnError(String message) { SessionUpdateResponse.Builder builder = SessionUpdateResponse.newBuilder(); - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); builder.setMessage(message); return builder.build(); } @@ -291,7 +293,7 @@ public SubmitQueryResponse submitQuery(RpcController controller, QueryRequest re responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); responseBuilder.setIsForwarded(true); responseBuilder.setUserName(context.getConf().getVar(ConfVars.USERNAME)); - responseBuilder.setResultCode(ResultCode.ERROR); + responseBuilder.setResultCode(ResultCode.UNKNOWN_ERROR); if (e.getMessage() != null) { responseBuilder.setErrorMessage(ExceptionUtils.getStackTrace(e)); } else { @@ -314,7 +316,7 @@ public UpdateQueryResponse updateQuery(RpcController controller, QueryRequest re builder.setResultCode(ResultCode.OK); return builder.build(); } catch (Exception e) { - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); if (e.getMessage() == null) { builder.setErrorMessage(ExceptionUtils.getStackTrace(e)); } @@ -496,7 +498,7 @@ public GetQueryStatusResponse getQueryStatus(RpcController controller, builder.setResultCode(ResultCode.OK); builder.setState(TajoProtos.QueryState.QUERY_SUCCEEDED); } else { - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); builder.setErrorMessage("No such query: " + queryId.toString()); } } @@ -557,7 +559,7 @@ public GetQueryResultDataResponse getQueryResultData(RpcController controller, G } catch (Throwable t) { LOG.error(t.getMessage(), t); builder.setResultSet(resultSetBuilder.build()); // required field - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); String errorMessage = t.getMessage() == null ? t.getClass().getName() : t.getMessage(); builder.setErrorMessage(errorMessage); builder.setErrorTrace(org.apache.hadoop.util.StringUtils.stringifyException(t)); @@ -603,7 +605,7 @@ public GetQueryInfoResponse getQueryInfo(RpcController controller, QueryIdReques builder.setResultCode(ResultCode.OK); } catch (Throwable t) { LOG.warn(t.getMessage(), t); - builder.setResultCode(ResultCode.ERROR); + builder.setResultCode(ResultCode.UNKNOWN_ERROR); builder.setErrorMessage(org.apache.hadoop.util.StringUtils.stringifyException(t)); } @@ -786,7 +788,7 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto if (!request.hasValue()) { return TableResponse.newBuilder() - .setResultCode(ResultCode.ERROR) + .setResultCode(ResultCode.UNKNOWN_ERROR) .setErrorMessage("table name is required.") .build(); } @@ -811,7 +813,7 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto .build(); } else { return TableResponse.newBuilder() - .setResultCode(ResultCode.ERROR) + .setResultCode(ResultCode.UNKNOWN_ERROR) .setErrorMessage("ERROR: no such a table: " + request.getValue()) .build(); } @@ -847,7 +849,7 @@ public TableResponse createExternalTable(RpcController controller, CreateTableRe null, meta.getStoreType(), schema, meta, path.toUri(), true, partitionDesc, false); } catch (Exception e) { return TableResponse.newBuilder() - .setResultCode(ResultCode.ERROR) + .setResultCode(ResultCode.UNKNOWN_ERROR) .setErrorMessage(e.getMessage()).build(); } @@ -856,11 +858,11 @@ public TableResponse createExternalTable(RpcController controller, CreateTableRe .setTableDesc(desc.getProto()).build(); } catch (InvalidSessionException ise) { return TableResponse.newBuilder() - .setResultCode(ResultCode.ERROR) + .setResultCode(ResultCode.UNKNOWN_ERROR) .setErrorMessage(ise.getMessage()).build(); } catch (IOException ioe) { return TableResponse.newBuilder() - .setResultCode(ResultCode.ERROR) + .setResultCode(ResultCode.UNKNOWN_ERROR) .setErrorMessage(ioe.getMessage()).build(); } } 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 5d42157217..ad41759df3 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 @@ -42,6 +42,7 @@ import org.apache.tajo.engine.planner.physical.EvalExprExec; import org.apache.tajo.engine.planner.physical.InsertRowsExec; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; import org.apache.tajo.master.QueryInfo; @@ -106,7 +107,7 @@ public SubmitQueryResponse execute(QueryContext queryContext, Session session, S context.getSystemMetrics().counter("Query", "numDDLQuery").inc(); ddlExecutor.execute(queryContext, plan); response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setResultCode(ClientProtos.ResultCode.OK); + response.setResultCode(ResultCode.OK); } else if (plan.isExplain()) { // explain query @@ -146,7 +147,7 @@ public void execSetSession(Session session, LogicalPlan plan, session.selectDatabase(setSessionNode.getValue()); } else { response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setResultCode(ClientProtos.ResultCode.ERROR); + response.setResultCode(ResultCode.NO_SUCH_DATABASE); response.setErrorMessage("database \"" + databaseName + "\" does not exists."); } @@ -161,7 +162,7 @@ public void execSetSession(Session session, LogicalPlan plan, context.getSystemMetrics().counter("Query", "numDDLQuery").inc(); response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setResultCode(ClientProtos.ResultCode.OK); + response.setResultCode(ResultCode.OK); } public void execExplain(LogicalPlan plan, QueryContext queryContext, boolean isGlobal, @@ -206,7 +207,7 @@ public void execExplain(LogicalPlan plan, QueryContext queryContext, boolean isG response.setResultSet(serializedResBuilder.build()); response.setMaxRowNum(lines.length); - response.setResultCode(ClientProtos.ResultCode.OK); + response.setResultCode(ResultCode.OK); response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); } @@ -228,7 +229,7 @@ public void execQueryOnVirtualTable(QueryContext queryContext, Session session, response.setQueryId(queryId.getProto()); response.setMaxRowNum(maxRow); response.setTableDesc(queryResultScanner.getTableDesc().getProto()); - response.setResultCode(ClientProtos.ResultCode.OK); + response.setResultCode(ResultCode.OK); } public void execSimpleQuery(QueryContext queryContext, Session session, String query, LogicalPlan plan, @@ -264,7 +265,7 @@ public void execSimpleQuery(QueryContext queryContext, Session session, String q response.setQueryId(queryInfo.getQueryId().getProto()); response.setMaxRowNum(maxRow); response.setTableDesc(desc.getProto()); - response.setResultCode(ClientProtos.ResultCode.OK); + response.setResultCode(ResultCode.OK); } public void execNonFromQuery(QueryContext queryContext, LogicalPlan plan, SubmitQueryResponse.Builder responseBuilder) @@ -301,7 +302,7 @@ public void execNonFromQuery(QueryContext queryContext, LogicalPlan plan, Submit responseBuilder.setResultSet(serializedResBuilder); responseBuilder.setMaxRowNum(1); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setResultCode(ClientProtos.ResultCode.OK); + responseBuilder.setResultCode(ResultCode.OK); } } finally { // stop script executor @@ -463,7 +464,7 @@ private void insertRowValues(QueryContext queryContext, // If queryId == NULL_QUERY_ID and MaxRowNum == -1, TajoCli prints only number of inserted rows. responseBuilder.setMaxRowNum(-1); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setResultCode(ClientProtos.ResultCode.OK); + responseBuilder.setResultCode(ResultCode.OK); } catch (Throwable t) { throw new RuntimeException(t); } @@ -499,13 +500,13 @@ public void executeDistributedQuery(QueryContext queryContext, Session session, if(queryInfo == null) { responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setResultCode(ClientProtos.ResultCode.ERROR); + responseBuilder.setResultCode(ResultCode.UNKNOWN_ERROR); responseBuilder.setErrorMessage("Fail starting QueryMaster."); LOG.error("Fail starting QueryMaster: " + sql); } else { responseBuilder.setIsForwarded(true); responseBuilder.setQueryId(queryInfo.getQueryId().getProto()); - responseBuilder.setResultCode(ClientProtos.ResultCode.OK); + responseBuilder.setResultCode(ResultCode.OK); if(queryInfo.getQueryMasterHost() != null) { responseBuilder.setQueryMasterHost(queryInfo.getQueryMasterHost()); } diff --git a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java index ae22d0d936..79aa0a108a 100644 --- a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java +++ b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java @@ -14,6 +14,7 @@ import org.apache.tajo.client.TajoClientImpl; import org.apache.tajo.client.TajoClientUtil; import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.jdbc.FetchResultSet; import org.apache.tajo.service.ServiceTrackerFactory; @@ -43,6 +44,9 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.tajo.exception.ErrorUtil.isFailed; +import static org.apache.tajo.exception.ErrorUtil.isOk; + /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -320,7 +324,7 @@ public void run() { LOG.error("Internal Error: SubmissionResponse is NULL"); error = new Exception("Internal Error: SubmissionResponse is NULL"); - } else if (response.getResultCode() == ClientProtos.ResultCode.OK) { + } else if (isOk(response.getResultCode())) { if (response.getIsForwarded()) { queryId = new QueryId(response.getQueryId()); getQueryResult(queryId); @@ -332,7 +336,7 @@ public void run() { progress.set(100); } - } else if (response.getResultCode() == ClientProtos.ResultCode.ERROR) { + } else if (isFailed(response.getResultCode())) { if (response.hasErrorMessage()) { StringBuffer errorMessage = new StringBuffer(response.getErrorMessage()); String modifiedMessage; diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java index 25aa7984b1..70a1fc628e 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java @@ -21,23 +21,18 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tajo.TajoConstants; -import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.master.TajoMaster; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.session.InvalidSessionException; import org.apache.tajo.session.Session; -import org.apache.tajo.ws.rs.JerseyResourceDelegate; -import org.apache.tajo.ws.rs.JerseyResourceDelegateContext; -import org.apache.tajo.ws.rs.JerseyResourceDelegateContextKey; -import org.apache.tajo.ws.rs.JerseyResourceDelegateUtil; -import org.apache.tajo.ws.rs.ResourcesUtil; +import org.apache.tajo.ws.rs.*; import org.apache.tajo.ws.rs.requests.NewSessionRequest; import org.apache.tajo.ws.rs.responses.ExceptionResponse; import org.apache.tajo.ws.rs.responses.NewSessionResponse; import javax.ws.rs.*; import javax.ws.rs.core.*; - import java.net.URI; import java.util.HashMap; import java.util.Iterator; @@ -132,7 +127,7 @@ public Response run(JerseyResourceDelegateContext context) { LOG.info("Session " + sessionId + " is created. "); sessionResponse.setId(sessionId); - sessionResponse.setResultCode(ClientProtos.ResultCode.OK); + sessionResponse.setResultCode(ResultCode.OK); sessionResponse.setVariables(masterContext.getSessionManager().getAllVariables(sessionId)); JerseyResourceDelegateContextKey uriInfoKey = @@ -147,7 +142,7 @@ public Response run(JerseyResourceDelegateContext context) { LOG.error(e.getMessage(), e); NewSessionResponse sessionResponse = new NewSessionResponse(); - sessionResponse.setResultCode(ClientProtos.ResultCode.ERROR); + sessionResponse.setResultCode(ResultCode.UNKNOWN_ERROR); sessionResponse.setMessage(e.getMessage()); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(sessionResponse).build(); @@ -155,7 +150,7 @@ public Response run(JerseyResourceDelegateContext context) { LOG.error(e.getMessage(), e); NewSessionResponse sessionResponse = new NewSessionResponse(); - sessionResponse.setResultCode(ClientProtos.ResultCode.ERROR); + sessionResponse.setResultCode(ResultCode.UNKNOWN_ERROR); sessionResponse.setMessage(e.getMessage()); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(sessionResponse).build(); diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/NewSessionResponse.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/NewSessionResponse.java index 67b5b33c59..cbc8f1df0f 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/NewSessionResponse.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/NewSessionResponse.java @@ -18,10 +18,9 @@ package org.apache.tajo.ws.rs.responses; -import org.apache.tajo.ipc.ClientProtos; -import org.apache.tajo.util.TUtil; - import com.google.gson.annotations.Expose; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.util.TUtil; import java.util.Map; @@ -29,7 +28,7 @@ public class NewSessionResponse { @Expose private String id; @Expose private String message; - @Expose private ClientProtos.ResultCode resultCode; + @Expose private ResultCode resultCode; @Expose private Map variables; public String getId() { @@ -48,11 +47,11 @@ public void setMessage(String message) { this.message = message; } - public ClientProtos.ResultCode getResultCode() { + public ResultCode getResultCode() { return resultCode; } - public void setResultCode(ClientProtos.ResultCode resultCode) { + public void setResultCode(ResultCode resultCode) { this.resultCode = resultCode; } 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 0f80ddfc9c..571ed1f594 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 @@ -23,6 +23,7 @@ import org.apache.tajo.SessionVars; import org.apache.tajo.client.TajoClient; import org.apache.tajo.client.TajoClientUtil; +import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import java.io.IOException; @@ -163,7 +164,7 @@ protected ResultSet executeSQL(String sql) throws SQLException, ServiceException } ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql); - if (response.getResultCode() == ClientProtos.ResultCode.ERROR) { + if (ErrorUtil.isFailed(response.getResultCode())) { if (response.hasErrorMessage()) { throw new ServiceException(response.getErrorMessage()); } From d58ffaded8b51f9d82837899343d5dc8b4fca971 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 29 Jun 2015 05:21:10 -0700 Subject: [PATCH 02/30] Add initial error code. --- tajo-common/src/main/proto/errors.proto | 122 +++++++++++++++++++++--- 1 file changed, 110 insertions(+), 12 deletions(-) diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index 8a755d1917..d6304d2152 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -22,16 +22,15 @@ option java_package = "org.apache.tajo.error"; import "stacktrace.proto"; enum ResultCode { - OK = 0; - // Warnings - WARNING = 100; + + WARNING = 100; // Warning // General Errors - UNKNOWN_ERROR = 200; - INTERNAL_ERROR = 201; // error caused by internal bugs - NOT_IMPLEMENTED = 202; - ILLEGAL_STATE = 203; + INTERNAL_ERROR = 200; // Error caused by internal bugs + ILLEGAL_STATE = 201; // Illegal state or unexpected state + NOT_IMPLEMENTED = 202; // Not implemented feature + NOT_SUPPORTED = 203; // Not supported feature // Session Errors SESSION_INVALIDATION = 251; @@ -45,11 +44,110 @@ enum ResultCode { TABLE_EXISTS = 306; COLUMN_EXISTS = 307; - // Physical Executor Errors + // Expressions INVALID_EXPRESSION = 401; - EXCEEDED_MEMORY = 402; + INVALID_CAST = 402; + UNKNOWN_DATA_TYPE = 403; + + NUMERIC_OVERFLOW = 403; // Numeric value overflow + VALUE_LARGER_THAN_PRECISION = 404; // Value larger than column precision + + // Physical Operator + EXCEEDED_MEMORY = 404; + + + // Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H + // are called "standard-defined classes". + + // Class + // 00 - Successful Completion + OK = 0; + + // 01 - Warning + // 02 - No Data + // 07 - Dynamic SQL Error + // 08 - Connection Exception + // 09 - Triggered Action Exception + // 0A - Feature Not Supported + // 0D - Invalid Target Type Specification + // 0F - Invalid Token + // 0K - Invalid RESIGNAL Statement + // 0N - SQL/XML mapping error + // 20 - Case Not Found for CASE Statement + // 21 - Cardinality Violation + // 22 - Data Exception + // 23 - Constraint Violation + // 24 - Invalid Cursor State + // 25 - Invalid Transaction State + // 26 - Invalid SQL Statement Identifier + // 28 - Invalid Authorization Specification + // 2D - Invalid Transaction Termination + // 2E - Invalid Connection Name + // 34 - Invalid Cursor Name + // 36 - Cursor Sensitivity Exception + // 38 - External Function Exception + // 39 - External Function Call Exception + // 3B - Invalid SAVEPOINT + // 40 - Transaction Rollback + + // Section: Class 42 - Syntax Error or Access Rule Violation + SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 42000; + + SYNTAX_ERROR = 42601; + INSUFFICIENT_PRIVILEGE = 42501; + CANNOT_COERCE = 42846; // Cast from source type to target type is not supported. + GROUPING_ERROR = 42803; + // WINDOWING_ERROR = 42P20; - PgSQL implementation-defined + // INVALID_RECURSION = 42P19; - PgSQL implementation-defined + + // INVALID_RECURSION = 42P19; - PgSQL implementation -defined + INVALID_FOREIGN_KEY = 42830; + INVALID_NAME = 42602; + NAME_TOO_LONG = 42622; + RESERVED_NAME = 42939; + DATATYPE_MISMATCH = 42804; + // INDETERMINATE_DATATYPE = 42P18; - PgSQL implementation -defined + + INVALID_COLUMN_DEFINITION = 42611; + DUPLICATE_COLUMN = 42701; + AMBIGUOUS_COLUMN = 42702; + UNDEFINED_COLUMN = 42703; + DUPLICATE_ALIAS = 42712; + DUPLICATE_FUNCTION = 42723; + AMBIGUOUS_FUNCTION = 42725; + UNDEFINED_FUNCTION = 42883; + + + + // 44 - WITH CHECK OPTION Violation + // 46 - Java DDL + // 51 - Invalid Application State + + // 53 - Invalid Operand or Inconsistent Specification + INSUFFICIENT_RESOURCE = 53000; + DISK_FULL = 53100; + OUT_OF_MEMORY = 53200; + + // 54 - SQL or Product Limit Exceeded + PROGRAM_LIMIT_EXCEEDED = 54000; + STATEMENT_TOO_COMPLEX = 54001; + STRING_CONSTANT_TOOL_LONG = 54002; + + TOO_MANY_TABLES = 54004; + TOO_MANY_COLUMNS = 54011; + TOO_MANY_ARGUMENTS = 54023; + + // 55 - Object Not in Prerequisite State + // 56 - Miscellaneous SQL or Product Error + // 57 - Resource Not Available or Operator Intervention + + // 58 - System Error + IO_ERROR = 58030; + + // 5U - Utilities Table + - // underlying system errors based on errno.h. + // underlying system errors based on errno.h. EPERM = 10001; // Operation not permitted ENOENT = 10002; // No such file or directory ESRCH = 10003; // No such process @@ -91,7 +189,7 @@ enum ResultCode { ENOSYS = 10038; // Function not implemented ENOTEMPTY = 10039; // Directory not empty ELOOP = 10040; // Too many symbolic links encountered - // EWOULDBLOCK = 100EAGAIN // Operation would block + // EWOULDBLOCK = EAGAIN // Operation would block ENOMSG = 10042; // No message of desired type EIDRM = 10043; // Identifier removed ECHRNG = 10044; // Channel number out of range @@ -108,7 +206,7 @@ enum ResultCode { ENOANO = 10055; // No anode EBADRQC = 10056; // Invalid request code EBADSLT = 10057; // Invalid slot - // EDEADLOCK EDEADLK + // EDEADLOCK = EDEADLK EBFONT = 10059; // Bad font file format ENOSTR = 10060; // Device not a stream ENODATA = 10061; // No data available From ec34cf8abb3ade2ad4caf27a2f6cbf74f7debc48 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 29 Jun 2015 05:29:19 -0700 Subject: [PATCH 03/30] Added ErrorUtil. --- .../org/apache/tajo/exception/ErrorUtil.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java new file mode 100644 index 0000000000..2d65ec38d9 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java @@ -0,0 +1,31 @@ +/** + * 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.exception; + +import org.apache.tajo.error.Errors.ResultCode; + +public class ErrorUtil { + public static boolean isOk(ResultCode code) { + return code == ResultCode.OK; + } + + public static boolean isFailed(ResultCode code) { + return code != ResultCode.OK; + } +} From f1a1e7d096e568cefa6f48f8ba7195eb3c7ffd05 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Tue, 30 Jun 2015 15:15:25 -0700 Subject: [PATCH 04/30] Initial work for new error propagation. --- .../org/apache/tajo/cli/tsql/TajoCli.java | 15 +- .../tajo/client/CatalogAdminClient.java | 24 +- .../tajo/client/CatalogAdminClientImpl.java | 25 +- .../apache/tajo/client/ClientErrorUtil.java | 126 ++++++++ .../tajo/client/ExceptionConvertor.java | 59 ++++ .../apache/tajo/client/QueryClientImpl.java | 35 +-- .../org/apache/tajo/client/QueryStatus.java | 2 +- .../apache/tajo/client/SQLExceptionUtil.java | 39 +++ .../apache/tajo/client/SessionConnection.java | 32 +- .../apache/tajo/client/TajoClientImpl.java | 2 +- .../apache/tajo/client/TajoClientUtil.java | 4 +- tajo-client/src/main/proto/ClientProtos.proto | 56 ++-- .../proto/QueryMasterClientProtocol.proto | 6 +- .../main/proto/TajoMasterClientProtocol.proto | 22 +- .../apache/tajo/exception/ErrorMessages.java | 89 ++++++ .../org/apache/tajo/exception/ErrorUtil.java | 5 + .../org/apache/tajo/exception/TajoError.java | 43 +++ .../apache/tajo/exception/TajoException.java | 40 +++ .../exception/TajoExceptionInterface.java | 27 ++ .../tajo/exception/TajoInternalError.java | 31 ++ .../tajo/exception/TajoRuntimeException.java | 40 +++ tajo-common/src/main/proto/errors.proto | 53 ++-- .../org/apache/tajo/master/GlobalEngine.java | 14 +- .../tajo/master/TajoMasterClientService.java | 278 +++++++++--------- .../tajo/master/exec/QueryExecutor.java | 44 ++- .../NoSuchSessionVariableException.java | 8 +- .../tajo/webapp/QueryExecutorServlet.java | 35 +-- .../tajo/worker/TajoWorkerClientService.java | 9 +- .../tajo/ws/rs/resources/QueryResource.java | 6 +- .../ws/rs/resources/QueryResultResource.java | 6 +- .../ws/rs/resources/SessionsResource.java | 4 +- .../responses/GetQueryResultDataResponse.java | 8 +- .../org/apache/tajo/QueryTestCaseBase.java | 12 +- .../tajo/engine/query/TestJoinQuery.java | 5 +- .../engine/query/TestTablePartitions.java | 9 +- .../ws/rs/resources/TestQueryResource.java | 4 +- .../rs/resources/TestQueryResultResource.java | 13 +- .../org/apache/tajo/jdbc/TajoStatement.java | 13 +- 38 files changed, 856 insertions(+), 387 deletions(-) create mode 100644 tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java create mode 100644 tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java create mode 100644 tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java index 4b9eb2beff..092a54fad5 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java @@ -33,7 +33,6 @@ import org.apache.tajo.client.*; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; -import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.service.ServiceTrackerFactory; import org.apache.tajo.util.FileUtil; @@ -44,8 +43,6 @@ import java.sql.SQLException; import java.util.*; -import static org.apache.tajo.exception.ErrorUtil.isOk; - public class TajoCli { public static final String ERROR_PREFIX = "ERROR: "; public static final String KILL_PREFIX = "KILL: "; @@ -493,7 +490,7 @@ private void executeJsonQuery(String json) throws ServiceException, IOException ClientProtos.SubmitQueryResponse response = client.executeQueryWithJson(json); if (response == null) { onError("response is null", null); - } else if (isOk(response.getResultCode())) { + } else if (ClientErrorUtil.isSuccess(response.getState())) { if (response.getIsForwarded()) { QueryId queryId = new QueryId(response.getQueryId()); waitForQueryCompleted(queryId); @@ -506,8 +503,8 @@ private void executeJsonQuery(String json) throws ServiceException, IOException } } } else { - if (response.hasErrorMessage()) { - onError(response.getErrorMessage(), null); + if (ClientErrorUtil.isError(response.getState())) { + onError(response.getState().getMessage(), null); } } } @@ -524,7 +521,7 @@ private int executeQuery(String statement) throws ServiceException, IOException if (response == null) { onError("response is null", null); - } else if (isOk(response.getResultCode())) { + } else if (ClientErrorUtil.isSuccess(response.getState())) { if (response.getIsForwarded()) { QueryId queryId = new QueryId(response.getQueryId()); waitForQueryCompleted(queryId); @@ -536,8 +533,8 @@ private int executeQuery(String statement) throws ServiceException, IOException } } } else { - if (response.hasErrorMessage()) { - onError(response.getErrorMessage(), null); + if (ClientErrorUtil.isError(response.getState())) { + onError(response.getState().getMessage(), null); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java index 1512b24a70..4d13abf728 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java @@ -39,7 +39,7 @@ public interface CatalogAdminClient extends Closeable { * @return True if created successfully. * @throws com.google.protobuf.ServiceException */ - public boolean createDatabase(final String databaseName) throws ServiceException; + boolean createDatabase(final String databaseName) throws ServiceException; /** * Does the database exist? * @@ -47,7 +47,7 @@ public interface CatalogAdminClient extends Closeable { * @return True if so. * @throws ServiceException */ - public boolean existDatabase(final String databaseName) throws ServiceException; + boolean existDatabase(final String databaseName) throws ServiceException; /** * Drop the database * @@ -55,9 +55,9 @@ public interface CatalogAdminClient extends Closeable { * @return True if the database is dropped successfully. * @throws ServiceException */ - public boolean dropDatabase(final String databaseName) throws ServiceException; + boolean dropDatabase(final String databaseName) throws ServiceException; - public List getAllDatabaseNames() throws ServiceException; + List getAllDatabaseNames() throws ServiceException; /** * Does the table exist? @@ -65,7 +65,7 @@ public interface CatalogAdminClient extends Closeable { * @param tableName The table name to be checked. This name is case sensitive. * @return True if so. */ - public boolean existTable(final String tableName) throws ServiceException; + boolean existTable(final String tableName) throws ServiceException; /** * Create an external table. @@ -79,7 +79,7 @@ public interface CatalogAdminClient extends Closeable { * @throws java.sql.SQLException * @throws ServiceException */ - public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, + TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, final TableMeta meta) throws SQLException, ServiceException; /** @@ -95,7 +95,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema * @throws SQLException * @throws ServiceException */ - public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, + TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, final TableMeta meta, final PartitionMethodDesc partitionMethodDesc) throws SQLException, ServiceException; @@ -105,7 +105,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema * @param tableName The table name to be dropped. This name is case sensitive. * @return True if the table is dropped successfully. */ - public boolean dropTable(final String tableName) throws ServiceException; + boolean dropTable(final String tableName) throws ServiceException; /** * Drop a table. @@ -114,7 +114,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema * @param purge If purge is true, this call will remove the entry in catalog as well as the table contents. * @return True if the table is dropped successfully. */ - public boolean dropTable(final String tableName, final boolean purge) throws ServiceException; + boolean dropTable(final String tableName, final boolean purge) throws ServiceException; /** * Get a list of table names. @@ -123,7 +123,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema * If it is null, this method will show all tables * in the current database of this session. */ - public List getTableList(@Nullable final String databaseName) throws ServiceException; + List getTableList(@Nullable final String databaseName) throws ServiceException; /** * Get a table description @@ -131,7 +131,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema * @param tableName The table name to get. This name is case sensitive. * @return Table description */ - public TableDesc getTableDesc(final String tableName) throws ServiceException; + TableDesc getTableDesc(final String tableName) throws ServiceException, SQLException; - public List getFunctions(final String functionName) throws ServiceException; + List getFunctions(final String functionName) throws ServiceException; } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index 3976d63a97..d1d5ce7a11 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -26,7 +26,6 @@ import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; -import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.SessionedStringProto; import org.apache.tajo.jdbc.SQLStates; @@ -38,7 +37,7 @@ import java.sql.SQLException; import java.util.List; -import static org.apache.tajo.exception.ErrorUtil.isOk; +import static org.apache.tajo.client.ClientErrorUtil.isSuccess; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; public class CatalogAdminClientImpl implements CatalogAdminClient { @@ -53,7 +52,7 @@ public boolean createDatabase(final String databaseName) throws ServiceException NettyClientBase client = connection.getTajoMasterConnection(); connection.checkSessionAndGet(client); BlockingInterface tajoMaster = client.getStub(); - return tajoMaster.createDatabase(null, connection.convertSessionedString(databaseName)).getValue(); + return isSuccess(tajoMaster.createDatabase(null, connection.convertSessionedString(databaseName))); } @Override @@ -62,7 +61,7 @@ public boolean existDatabase(final String databaseName) throws ServiceException NettyClientBase client = connection.getTajoMasterConnection(); connection.checkSessionAndGet(client); BlockingInterface tajoMaster = client.getStub(); - return tajoMaster.existDatabase(null, connection.convertSessionedString(databaseName)).getValue(); + return isSuccess(tajoMaster.existDatabase(null, connection.convertSessionedString(databaseName))); } @Override @@ -71,7 +70,7 @@ public boolean dropDatabase(final String databaseName) throws ServiceException { NettyClientBase client = connection.getTajoMasterConnection(); connection.checkSessionAndGet(client); BlockingInterface tajoMasterService = client.getStub(); - return tajoMasterService.dropDatabase(null, connection.convertSessionedString(databaseName)).getValue(); + return isSuccess(tajoMasterService.dropDatabase(null, connection.convertSessionedString(databaseName))); } @Override @@ -88,7 +87,7 @@ public boolean existTable(final String tableName) throws ServiceException { NettyClientBase client = connection.getTajoMasterConnection(); connection.checkSessionAndGet(client); BlockingInterface tajoMasterService = client.getStub(); - return tajoMasterService.existTable(null, connection.convertSessionedString(tableName)).getValue(); + return isSuccess(tajoMasterService.existTable(null, connection.convertSessionedString(tableName))); } @Override @@ -115,10 +114,10 @@ public TableDesc createExternalTable(final String tableName, final Schema schema builder.setPartition(partitionMethodDesc.getProto()); } ClientProtos.TableResponse res = tajoMasterService.createExternalTable(null, builder.build()); - if (isOk(res.getResultCode())) { + if (isSuccess(res.getState())) { return CatalogUtil.newTableDesc(res.getTableDesc()); } else { - throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState()); + throw SQLExceptionUtil.convert(res.getState()); } } @@ -138,7 +137,7 @@ public boolean dropTable(final String tableName, final boolean purge) throws Ser builder.setSessionId(connection.sessionId); builder.setName(tableName); builder.setPurge(purge); - return tajoMasterService.dropTable(null, builder.build()).getValue(); + return isSuccess(tajoMasterService.dropTable(null, builder.build())); } @@ -159,7 +158,7 @@ public List getTableList(@Nullable final String databaseName) throws Ser } @Override - public TableDesc getTableDesc(final String tableName) throws ServiceException { + public TableDesc getTableDesc(final String tableName) throws ServiceException, SQLException { NettyClientBase client = connection.getTajoMasterConnection(); connection.checkSessionAndGet(client); @@ -169,10 +168,10 @@ public TableDesc getTableDesc(final String tableName) throws ServiceException { builder.setSessionId(connection.sessionId); builder.setValue(tableName); ClientProtos.TableResponse res = tajoMasterService.getTableDesc(null, builder.build()); - if (isOk(res.getResultCode())) { + if (isSuccess(res.getState())) { return CatalogUtil.newTableDesc(res.getTableDesc()); } else { - throw new ServiceException(new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState())); + throw SQLExceptionUtil.convert(res.getState()); } } @@ -186,7 +185,7 @@ public List getFunctions(final String functionN String paramFunctionName = functionName == null ? "" : functionName; ClientProtos.FunctionResponse res = tajoMasterService.getFunctionList(null, connection.convertSessionedString(paramFunctionName)); - if (isOk(res.getResultCode())) { + if (isSuccess(res.getState())) { return res.getFunctionsList(); } else { throw new ServiceException(new SQLException(res.getErrorMessage())); diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java new file mode 100644 index 0000000000..3a6adad15c --- /dev/null +++ b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java @@ -0,0 +1,126 @@ +/* + * 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.client; + +import com.google.common.base.Preconditions; +import org.apache.tajo.QueryId; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.ErrorMessages; +import org.apache.tajo.exception.ErrorUtil; +import org.apache.tajo.exception.TajoExceptionInterface; +import org.apache.tajo.ipc.ClientProtos.ResponseState; + +public class ClientErrorUtil { + + public static final ResponseState OK; + + static { + ResponseState.Builder builder = ResponseState.newBuilder(); + builder.setReturnCode(ResultCode.OK); + OK = builder.build(); + } + + public static ResponseState returnOk() { + return OK; + } + + public static ResponseState returnError(ResultCode code) { + ResponseState.Builder builder = ResponseState.newBuilder(); + builder.setReturnCode(code); + builder.setMessage(ErrorMessages.getMessage(code)); + return builder.build(); + } + + private static ResponseState returnError(ResultCode code, String...args) { + Preconditions.checkNotNull(args); + + ResponseState.Builder builder = ResponseState.newBuilder(); + builder.setReturnCode(code); + builder.setMessage(ErrorMessages.getMessage(code, args)); + return builder.build(); + } + + public static ResponseState returnError(Throwable t) { + ResponseState.Builder builder = ResponseState.newBuilder(); + + if (t instanceof TajoExceptionInterface) { + TajoExceptionInterface tajoException = (TajoExceptionInterface) t; + builder.setReturnCode(tajoException.getErrorCode()); + builder.setMessage(tajoException.getMessage()); + } else { + builder.setReturnCode(ResultCode.INTERNAL_ERROR); + builder.setMessage(ErrorMessages.getInternalErrorMessage(t)); + builder.setStackTrace(ErrorUtil.convertStacktrace(t)); + } + + return builder.build(); + } + + /** + * This method check if the state is successful. + * + * @param state ResponseState to be checked + * @return True if ResponseState is success. + */ + public static boolean isSuccess(ResponseState state) { + return ErrorUtil.isOk(state.getReturnCode()); + } + + /** + * This method check if the state is failed. + * + * @param state ResponseState to be checked + * @return True if ResponseState is failed. + */ + public static boolean isError(ResponseState state) { + return ErrorUtil.isFailed(state.getReturnCode()); + } + + public static boolean isThisError(ResponseState state, ResultCode expected) { + return state.getReturnCode() == expected; + } + + public static ResponseState ERR_INVALID_RPC_CALL(String message) { + return returnError(ResultCode.INVALID_RPC_CALL, message); + } + + public static ResponseState ERR_NO_SUCH_QUERY_ID(QueryId queryId) { + return returnError(ResultCode.NO_SUCH_QUERYID, queryId.toString()); + } + + public static ResponseState ERR_INVALID_SESSION(String sessionId) { + return returnError(ResultCode.INVALID_SESSION, sessionId); + } + + public static ResponseState ERR_NO_SESSION_VARIABLE(String varName) { + return returnError(ResultCode.NO_SUCH_QUERYID, varName); + } + + public static ResponseState ERR_UNDEFIED_DATABASE(String dbName) { + return returnError(ResultCode.UNDEFINED_DATABASE, dbName); + } + + public static ResponseState ERR_UNDEFIED_TABLE(String tableName) { + return returnError(ResultCode.UNDEFINED_TABLE, tableName); + } + + public static ResponseState ERR_DUPLICATE_DATABASE(String dbName) { + return returnError(ResultCode.DUPLICATE_DATABASE, dbName); + } +} diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java b/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java new file mode 100644 index 0000000000..aa49d5eac0 --- /dev/null +++ b/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java @@ -0,0 +1,59 @@ +/* + * 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.client; + +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.ErrorUtil; +import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.TajoRuntimeException; +import org.apache.tajo.ipc.ClientProtos.ResponseState; + +/** + * + */ +public class ExceptionConvertor { + + private static boolean isManagedException(Throwable t) { + return t instanceof TajoException || t instanceof TajoRuntimeException; + } + + public ResponseState convert(Throwable t) { + + ResponseState.Builder builder = ResponseState.newBuilder(); + + if (isManagedException(t)) { + + + } else { + // uncaught Exception, RuntimeException, and Error are mostly bugs, + // and they should be handled as internal error. + + builder.setReturnCode(Errors.ResultCode.INTERNAL_ERROR); + + if (t.getMessage() != null) { + builder.setMessage(t.getMessage()); + } + + builder.setStackTrace(ErrorUtil.convertStacktrace(t)); + } + + return builder.build(); + } + +} 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 7f6618f921..486bcd9b51 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 @@ -41,8 +41,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import static org.apache.tajo.exception.ErrorUtil.isFailed; -import static org.apache.tajo.exception.ErrorUtil.isOk; +import static org.apache.tajo.client.ClientErrorUtil.isError; +import static org.apache.tajo.client.ClientErrorUtil.isSuccess; import static org.apache.tajo.ipc.ClientProtos.*; import static org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -166,7 +166,7 @@ public ClientProtos.SubmitQueryResponse executeQuery(final String sql) throws Se SubmitQueryResponse response = tajoMasterService.submitQuery(null, builder.build()); - if (isOk(response.getResultCode())) { + if (isSuccess(response.getState())) { connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); } return response; @@ -193,12 +193,8 @@ public ResultSet executeQueryAndGetResult(String sql) throws ServiceException, I ClientProtos.SubmitQueryResponse response = executeQuery(sql); - if (isFailed(response.getResultCode())) { - if (response.hasErrorMessage()) { - throw new ServiceException(response.getErrorMessage()); - } else if (response.hasErrorTrace()) { - throw new ServiceException(response.getErrorTrace()); - } + if (isError(response.getState())) { + throw new ServiceException(response.getState().getMessage()); } QueryId queryId = new QueryId(response.getQueryId()); @@ -229,8 +225,8 @@ public ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceE ClientProtos.SubmitQueryResponse response = executeQueryWithJson(json); - if (isFailed(response.getResultCode())) { - throw new ServiceException(response.getErrorTrace()); + if (isError(response.getState())) { + throw new ServiceException(response.getState().getMessage()); } QueryId queryId = new QueryId(response.getQueryId()); @@ -358,8 +354,9 @@ public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int builder.setFetchRowNum(fetchRowNum); GetQueryResultDataResponse response = tajoMasterService.getQueryResultData(null, builder.build()); - if (isFailed(response.getResultCode())) { - throw new ServiceException(response.getErrorMessage()); + + if (isError(response.getState())) { + throw new ServiceException(response.getState().getMessage()); } ClientProtos.SerializedResultSet resultSet = response.getResultSet(); @@ -389,7 +386,7 @@ public boolean updateQuery(final String sql) throws ServiceException { builder.setIsJson(false); ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - if (isOk(response.getResultCode())) { + if (isError(response.getState())) { connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return true; } else { @@ -412,7 +409,7 @@ public boolean updateQueryWithJson(final String json) throws ServiceException { builder.setQuery(json); builder.setIsJson(true); ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - if (isOk(response.getResultCode())) { + if (isSuccess(response.getState())) { return true; } else { if (response.hasErrorMessage()) { @@ -520,10 +517,10 @@ public QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceExceptio TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); GetQueryInfoResponse res = tajoMasterService.getQueryInfo(null,builder.build()); - if (isOk(res.getResultCode())) { + if (isSuccess(res.getState())) { return res.getQueryInfo(); } else { - throw new ServiceException(res.getErrorMessage()); + throw new ServiceException(res.getState().getMessage()); } } @@ -554,10 +551,10 @@ public QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceEx QueryMasterClientProtocolService.BlockingInterface queryMasterService = queryMasterClient.getStub(); GetQueryHistoryResponse res = queryMasterService.getQueryHistory(null, builder.build()); - if (isOk(res.getResultCode())) { + if (isSuccess(res.getState())) { return res.getQueryHistory(); } else { - throw new ServiceException(res.getErrorMessage()); + throw new ServiceException(res.getState().getMessage()); } } finally { queryMasterClient.close(); 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 4a38934222..809c675c38 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 @@ -36,7 +36,7 @@ public class QueryStatus { public QueryStatus(GetQueryStatusResponse proto) { queryId = new QueryId(proto.getQueryId()); - state = proto.getState(); + state = proto.getQueryState(); progress = proto.getProgress(); submitTime = proto.getSubmitTime(); finishTime = proto.getFinishTime(); diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java new file mode 100644 index 0000000000..c035c435bb --- /dev/null +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -0,0 +1,39 @@ +/* + * 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.client; + +import com.google.common.collect.Maps; +import org.apache.tajo.error.Errors; +import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.ResponseState; + +import java.sql.SQLException; +import java.util.Map; + +public class SQLExceptionUtil { + + private static final Map SQL_STATES = Maps.newHashMap(); + + public static SQLException convert(ResponseState state) { + return new SQLException( + state.getMessage(), + SQL_STATES.get(state.getReturnCode()), + state.getReturnCode().getNumber()); + } +} 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 0ae159bf6c..cf301bdbba 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 @@ -49,8 +49,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import static org.apache.tajo.exception.ErrorUtil.isFailed; -import static org.apache.tajo.exception.ErrorUtil.isOk; +import static org.apache.tajo.client.ClientErrorUtil.*; +import static org.apache.tajo.error.Errors.ResultCode.INVALID_SESSION; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; import static org.apache.tajo.ipc.ClientProtos.CreateSessionResponse; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -179,11 +179,11 @@ public Map updateSessionVariables(final Map vari SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); - if (isOk(response.getResultCode())) { + if (isSuccess(response.getState())) { updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { - throw new ServiceException(response.getMessage()); + throw new ServiceException(response.getState().getMessage()); } } @@ -198,11 +198,11 @@ public Map unsetSessionVariables(final List variables) t SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); - if (isOk(response.getResultCode())) { + if (isSuccess(response.getState())) { updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { - throw new ServiceException(response.getMessage()); + throw new ServiceException(response.getState().getMessage()); } } @@ -233,13 +233,7 @@ public Boolean existSessionVariable(final String varname) throws ServiceExceptio checkSessionAndGet(client); TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - return tajoMasterService.existSessionVariable(null, convertSessionedString(varname)).getValue(); - } - - public Map getCachedAllSessionVariables() { - synchronized (sessionVarsCache) { - return Collections.unmodifiableMap(sessionVarsCache); - } + return isSuccess(tajoMasterService.existSessionVariable(null, convertSessionedString(varname))); } public Map getAllSessionVariables() throws ServiceException { @@ -255,7 +249,7 @@ public Boolean selectDatabase(final String databaseName) throws ServiceException checkSessionAndGet(client); TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - boolean selected = tajoMasterService.selectDatabase(null, convertSessionedString(databaseName)).getValue(); + boolean selected = isSuccess(tajoMasterService.selectDatabase(null, convertSessionedString(databaseName))); if (selected) { this.baseDatabase = databaseName; @@ -308,7 +302,7 @@ protected void checkSessionAndGet(NettyClientBase client) throws ServiceExceptio CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); - if (isOk(response.getResultCode())) { + if (isSuccess(response.getState())) { sessionId = response.getSessionId(); updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); @@ -316,8 +310,10 @@ protected void checkSessionAndGet(NettyClientBase client) throws ServiceExceptio LOG.debug(String.format("Got session %s as a user '%s'.", sessionId.getId(), userInfo.getUserName())); } + } else if (isThisError(response.getState(), INVALID_SESSION)) { + throw new InvalidClientSessionException(response.getState().getMessage()); } else { - throw new InvalidClientSessionException(response.getMessage()); + throw new ServiceException(response.getState().getMessage()); } } } @@ -334,7 +330,7 @@ public boolean reconnect() throws Exception { // create new session TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); - if (isFailed(response.getResultCode())) { + if (isError(response.getState())) { return false; } @@ -358,7 +354,7 @@ public boolean reconnect() throws Exception { .setSessionId(sessionId) .setSessionVars(keyValueSet.getProto()).build(); - if (isFailed(tajoMasterService.updateSessionVariables(null, request).getResultCode())) { + if (isError(tajoMasterService.updateSessionVariables(null, request).getState())) { tajoMasterService.removeSession(null, sessionId); return false; } 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 612b56e528..3aa762215d 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 @@ -221,7 +221,7 @@ public List getTableList(@Nullable final String databaseName) throws Ser return catalogClient.getTableList(databaseName); } - public TableDesc getTableDesc(final String tableName) throws ServiceException { + public TableDesc getTableDesc(final String tableName) throws ServiceException, SQLException { return catalogClient.getTableDesc(tableName); } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java index bab699e0ce..1c832a17c8 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java @@ -26,11 +26,11 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.ResponseState; import org.apache.tajo.jdbc.FetchResultSet; import org.apache.tajo.jdbc.TajoMemoryResultSet; -import org.apache.tajo.jdbc.TajoResultSetBase; -import org.apache.tajo.rpc.RpcUtils; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; import java.io.IOException; diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index 31137e8c69..e2de4d66ce 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -16,6 +16,8 @@ * limitations under the License. */ +package tajo.client; + option java_package = "org.apache.tajo.ipc"; option java_outer_classname = "ClientProtos"; option java_generic_services = true; @@ -29,7 +31,11 @@ import "PrimitiveProtos.proto"; import "errors.proto"; // tajo-common import "stacktrace.proto"; // tajo-common - +message ResponseState { + required tajo.error.ResultCode return_code = 1; + required string message = 2; + optional tajo.error.StackTrace stack_trace = 3; +} message CreateSessionRequest { required string username = 1; @@ -37,10 +43,9 @@ message CreateSessionRequest { } message CreateSessionResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional SessionIdProto sessionId = 2; optional KeyValueSetProto sessionVars = 3; - optional string message = 4; } message UpdateSessionVariableRequest { @@ -50,9 +55,8 @@ message UpdateSessionVariableRequest { } message SessionUpdateResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional KeyValueSetProto sessionVars = 2; - optional string message = 3; } message SessionedStringProto { @@ -61,9 +65,8 @@ message SessionedStringProto { } message ExplainQueryResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional string explain = 2; - optional string errorMessage = 3; } message QueryRequest { @@ -74,7 +77,7 @@ message QueryRequest { } message UpdateQueryResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional string errorMessage = 2; optional KeyValueSetProto sessionVars = 3; } @@ -85,9 +88,10 @@ message GetQueryResultRequest { } message GetQueryResultResponse { - optional TableDescProto tableDesc = 1; - optional string errorMessage = 2; - optional string tajoUserName = 3; + required ResponseState state = 1; + optional TableDescProto tableDesc = 2; + optional string errorMessage = 3; + optional string tajoUserName = 4; } message QueryIdRequest { @@ -111,7 +115,8 @@ message BriefQueryInfo { } message GetQueryListResponse { - repeated BriefQueryInfo queryList = 1; + required ResponseState state = 1; + repeated BriefQueryInfo queryList = 2; } message GetQueryStatusRequest { @@ -126,7 +131,7 @@ message SerializedResultSet { } message SubmitQueryResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; required QueryIdProto queryId = 2; required string userName = 3; optional bool isForwarded = 4 [default = false]; @@ -138,16 +143,13 @@ message SubmitQueryResponse { optional TableDescProto tableDesc = 8; optional int32 maxRowNum = 9; - optional string errorMessage = 10; - optional string errorTrace = 11; - optional KeyValueSetProto sessionVars = 12; } message GetQueryStatusResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; required QueryIdProto queryId = 2; - optional QueryState state = 3; + optional QueryState query_state = 3; optional float progress = 4; optional int64 submitTime = 5; optional int64 finishTime = 7; @@ -165,10 +167,8 @@ message GetQueryResultDataRequest { } message GetQueryResultDataResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; required SerializedResultSet resultSet = 2; - optional string errorMessage = 3; - optional string errorTrace = 4; } message GetClusterInfoRequest { @@ -193,7 +193,8 @@ message WorkerResourceInfo { } message GetClusterInfoResponse { - repeated WorkerResourceInfo workerList = 1; + required ResponseState state = 1; + repeated WorkerResourceInfo workerList = 2; } message CreateTableRequest { @@ -212,13 +213,12 @@ message DropTableRequest { } message TableResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional TableDescProto tableDesc = 2; - optional string errorMessage = 3; } message FunctionResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; repeated FunctionDescProto functions = 2; optional string errorMessage = 3; } @@ -273,14 +273,12 @@ message QueryHistoryProto { } message GetQueryHistoryResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional QueryHistoryProto queryHistory = 2; - optional string errorMessage = 3; } message GetQueryInfoResponse { - required tajo.error.ResultCode resultCode = 1; + required ResponseState state = 1; optional QueryInfoProto queryInfo = 2; - optional string errorMessage = 3; } diff --git a/tajo-client/src/main/proto/QueryMasterClientProtocol.proto b/tajo-client/src/main/proto/QueryMasterClientProtocol.proto index 0b115667b0..eb0443d772 100644 --- a/tajo-client/src/main/proto/QueryMasterClientProtocol.proto +++ b/tajo-client/src/main/proto/QueryMasterClientProtocol.proto @@ -16,15 +16,13 @@ * limitations under the License. */ +package tajo.client; + option java_package = "org.apache.tajo.ipc"; option java_outer_classname = "QueryMasterClientProtocol"; option java_generic_services = true; option java_generate_equals_and_hash = true; -import "tajo_protos.proto"; -import "TajoIdProtos.proto"; -import "CatalogProtos.proto"; -import "PrimitiveProtos.proto"; import "ClientProtos.proto"; service QueryMasterClientProtocolService { diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto index 468a998d97..b48e01eb1a 100644 --- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto +++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto @@ -16,7 +16,9 @@ * limitations under the License. */ -//TajoClient -> TajoMaster Protocol +// TajoClient -> TajoMaster Protocol +package tajo.client; + option java_package = "org.apache.tajo.ipc"; option java_outer_classname = "TajoMasterClientProtocol"; option java_generic_services = true; @@ -34,7 +36,7 @@ service TajoMasterClientProtocolService { rpc createSession(CreateSessionRequest) returns (CreateSessionResponse); rpc removeSession(SessionIdProto) returns (BoolProto); rpc updateSessionVariables(UpdateSessionVariableRequest) returns (SessionUpdateResponse); - rpc existSessionVariable(SessionedStringProto) returns (BoolProto); + rpc existSessionVariable(SessionedStringProto) returns (ResponseState); rpc getSessionVariable(SessionedStringProto) returns (StringProto); rpc getAllSessionVariables(SessionIdProto) returns (KeyValueSetProto); @@ -48,23 +50,23 @@ service TajoMasterClientProtocolService { rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse); rpc getRunningQueryList(SessionIdProto) returns (GetQueryListResponse); rpc getFinishedQueryList(SessionIdProto) returns (GetQueryListResponse); - rpc killQuery(QueryIdRequest) returns (BoolProto); + rpc killQuery(QueryIdRequest) returns (ResponseState); rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse); - rpc closeNonForwardQuery(QueryIdRequest) returns (BoolProto); + rpc closeNonForwardQuery(QueryIdRequest) returns (ResponseState); rpc getQueryInfo(QueryIdRequest) returns (GetQueryInfoResponse); // Database Management APIs - rpc createDatabase(SessionedStringProto) returns (BoolProto); - rpc existDatabase(SessionedStringProto) returns (BoolProto); - rpc dropDatabase(SessionedStringProto) returns (BoolProto); + rpc createDatabase(SessionedStringProto) returns (ResponseState); + rpc existDatabase(SessionedStringProto) returns (ResponseState); + rpc dropDatabase(SessionedStringProto) returns (ResponseState); rpc getAllDatabases(SessionIdProto) returns (StringListProto); rpc getCurrentDatabase(SessionIdProto) returns (StringProto); - rpc selectDatabase(SessionedStringProto) returns (BoolProto); + rpc selectDatabase(SessionedStringProto) returns (ResponseState); // Table Management APIs rpc createExternalTable(CreateTableRequest) returns (TableResponse); - rpc existTable(SessionedStringProto) returns (BoolProto); - rpc dropTable(DropTableRequest) returns (BoolProto); + rpc existTable(SessionedStringProto) returns (ResponseState); + rpc dropTable(DropTableRequest) returns (ResponseState); rpc getTableList(SessionedStringProto) returns (StringListProto); rpc getTableDesc(SessionedStringProto) returns (TableResponse); rpc getFunctionList(SessionedStringProto) returns (FunctionResponse); 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 new file mode 100644 index 0000000000..938c654977 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java @@ -0,0 +1,89 @@ +/* + * 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.exception; + +import com.google.common.collect.Maps; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.util.Pair; + +import java.util.Collections; +import java.util.Map; + +public class ErrorMessages { + public static final Map> MESSAGES; + + static { + Map> msgs = Maps.newHashMap(); + + ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "Internal Error: %s", 1); + ADD_MESSAGE(ResultCode.INVALID_RPC_CALL, "Invalid RPC Call: %s", 1); + + ADD_MESSAGE(ResultCode.NO_SUCH_QUERYID, "Query id '%s' does not exist", 1); + + ADD_MESSAGE(ResultCode.INVALID_SESSION, "Invalid Session '%s'", 1); + ADD_MESSAGE(ResultCode.NO_SUCH_SESSION_VARIABLE, "No such session variable '%s", 1); + + ADD_MESSAGE(ResultCode.UNDEFINED_DATABASE, "Database '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "Table '%s' does not exist", 1); + + MESSAGES = Collections.unmodifiableMap(msgs); + } + + private static void ADD_MESSAGE(ResultCode code, String msgFormat) { + ADD_MESSAGE(code, msgFormat, 0); + } + + private static void ADD_MESSAGE(ResultCode code, String msgFormat, int argNum) { + MESSAGES.put(code, new Pair(msgFormat, argNum)); + } + + public static String getInternalErrorMessage() { + return MESSAGES.get(ResultCode.INTERNAL_ERROR).getFirst(); + } + + public static String getInternalErrorMessage(Throwable t) { + if (t.getMessage() != null) { + return MESSAGES.get(ResultCode.INTERNAL_ERROR).getFirst() + ": " + t.getMessage(); + } else { + return getInternalErrorMessage(); + } + + } + + public static String getMessage(ResultCode code, String...args) { + if (!MESSAGES.containsKey(code)) { + throw new TajoRuntimeException(code, args); + } else { + + Pair messageFormat = MESSAGES.get(code); + + if (messageFormat.getSecond() == args.length) { // if arguments are matched + + if (args.length == 0) { // no argument + return MESSAGES.get(code).getFirst(); + } else { + return String.format(MESSAGES.get(code).getFirst(), args); + } + + } else { + throw new TajoRuntimeException(code, args); + } + } + } +} diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java index 2d65ec38d9..f61243482a 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java @@ -19,6 +19,7 @@ package org.apache.tajo.exception; import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.error.Stacktrace; public class ErrorUtil { public static boolean isOk(ResultCode code) { @@ -28,4 +29,8 @@ public static boolean isOk(ResultCode code) { public static boolean isFailed(ResultCode code) { return code != ResultCode.OK; } + + public static Stacktrace.StackTrace convertStacktrace(Throwable t) { + return null; + } } diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java new file mode 100644 index 0000000000..dcd6a6596f --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.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.exception; + +import org.apache.tajo.error.Errors.ResultCode; + +/** + * Unrecoverable errors + */ +public class TajoError extends Error implements TajoExceptionInterface { + private ResultCode code; + + public TajoError(ResultCode code) { + super(ErrorMessages.getMessage(code)); + this.code = code; + } + + public TajoError(ResultCode code, String ... args) { + super(ErrorMessages.getMessage(code, args)); + this.code = code; + } + + @Override + public ResultCode getErrorCode() { + return code; + } +} 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 new file mode 100644 index 0000000000..8bd8c0910a --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java @@ -0,0 +1,40 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors.ResultCode; + +public class TajoException extends Exception implements TajoExceptionInterface { + private ResultCode code; + + public TajoException(ResultCode code) { + super(ErrorMessages.getMessage(code)); + this.code = code; + } + + public TajoException(ResultCode code, String ... args) { + super(ErrorMessages.getMessage(code, args)); + this.code = code; + } + + @Override + public ResultCode getErrorCode() { + return code; + } +} diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java new file mode 100644 index 0000000000..d92c094711 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java @@ -0,0 +1,27 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors.ResultCode; + +public interface TajoExceptionInterface { + ResultCode getErrorCode(); + + String getMessage(); +} diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java new file mode 100644 index 0000000000..81984d0d69 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java @@ -0,0 +1,31 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors.ResultCode; + +/** + * Exception Internal Bugs + */ +public class TajoInternalError extends TajoError { + + public TajoInternalError() { + super(ResultCode.INTERNAL_ERROR); + } +} diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java new file mode 100644 index 0000000000..e29ce888d6 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java @@ -0,0 +1,40 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors.ResultCode; + +public class TajoRuntimeException extends RuntimeException implements TajoExceptionInterface { + private ResultCode code; + + public TajoRuntimeException(ResultCode code) { + super(ErrorMessages.getMessage(code)); + this.code = code; + } + + public TajoRuntimeException(ResultCode code, String ... args) { + super(ErrorMessages.getMessage(code, args)); + this.code = code; + } + + @Override + public ResultCode getErrorCode() { + return code; + } +} diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index d6304d2152..dcccbfd2d9 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -22,46 +22,56 @@ option java_package = "org.apache.tajo.error"; import "stacktrace.proto"; enum ResultCode { - + // Class + // 00 - Successful Completion + OK = 0; WARNING = 100; // Warning // General Errors - INTERNAL_ERROR = 200; // Error caused by internal bugs - ILLEGAL_STATE = 201; // Illegal state or unexpected state - NOT_IMPLEMENTED = 202; // Not implemented feature - NOT_SUPPORTED = 203; // Not supported feature + INTERNAL_ERROR = 201; // Error caused by internal bugs + ILLEGAL_STATE = 202; // Illegal state or unexpected state + NOT_IMPLEMENTED = 203; // Not implemented feature + NOT_SUPPORTED = 204; // Not supported feature + INVALID_RPC_CALL = 205; // When invalid RPC call is invoked (e.g., wrong message and absent fields) + + // Query Management and Scheduler + NO_SUCH_QUERYID = 300; // No query id in TajoMaster + + // Session Errors - SESSION_INVALIDATION = 251; + INVALID_SESSION = 251; NO_SUCH_SESSION_VARIABLE = 252; // Query and Catalog Errors - NO_SUCH_DATABASE = 301; - NO_SUCH_TABLE = 302; - NO_SUCH_COLUMN = 303; - DATABASE_EXISTS = 305; - TABLE_EXISTS = 306; - COLUMN_EXISTS = 307; + // Section: Class 42 - Syntax Error or Access Rule Violation + UNDEFINED_DATABASE = 301; + UNDEFINED_TABLE = 302; + UNDEFINED_COLUMN = 303; // SQLState: 42703 + UNDEFINED_FUNCTION = 303; // SQLState: 42883 + + DUPLICATE_DATABASE = 305; + DUPLICATE_TABLE = 306; + DUPLICATE_COLUMN = 307; // SQLState: 42701 + DUPLICATE_ALIAS = 308; // SQLState: 42712 + DUPLICATE_FUNCTION = 309; // SQLState: 42723 // Expressions INVALID_EXPRESSION = 401; INVALID_CAST = 402; UNKNOWN_DATA_TYPE = 403; - NUMERIC_OVERFLOW = 403; // Numeric value overflow - VALUE_LARGER_THAN_PRECISION = 404; // Value larger than column precision + //NUMERIC_OVERFLOW = 403; // Numeric value overflow + //VALUE_LARGER_THAN_PRECISION = 404; // Value larger than column precision // Physical Operator - EXCEEDED_MEMORY = 404; // Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H // are called "standard-defined classes". - // Class - // 00 - Successful Completion - OK = 0; + // 01 - Warning // 02 - No Data @@ -109,15 +119,8 @@ enum ResultCode { // INDETERMINATE_DATATYPE = 42P18; - PgSQL implementation -defined INVALID_COLUMN_DEFINITION = 42611; - DUPLICATE_COLUMN = 42701; AMBIGUOUS_COLUMN = 42702; - UNDEFINED_COLUMN = 42703; - DUPLICATE_ALIAS = 42712; - DUPLICATE_FUNCTION = 42723; AMBIGUOUS_FUNCTION = 42725; - UNDEFINED_FUNCTION = 42883; - - // 44 - WITH CHECK OPTION Violation // 46 - Java DDL diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java index c3b7a3ffb4..a7f2e7b466 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java @@ -35,16 +35,14 @@ import org.apache.tajo.catalog.CatalogService; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.engine.parser.SQLAnalyzer; import org.apache.tajo.engine.parser.SQLSyntaxError; import org.apache.tajo.engine.query.QueryContext; -import org.apache.tajo.error.Errors; -import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.master.exec.DDLExecutor; import org.apache.tajo.master.exec.QueryExecutor; -import org.apache.tajo.session.Session; import org.apache.tajo.plan.*; import org.apache.tajo.plan.logical.InsertNode; import org.apache.tajo.plan.logical.LogicalRootNode; @@ -54,6 +52,7 @@ import org.apache.tajo.plan.verifier.PreLogicalPlanVerifier; import org.apache.tajo.plan.verifier.VerificationState; import org.apache.tajo.plan.verifier.VerifyException; +import org.apache.tajo.session.Session; import org.apache.tajo.storage.TablespaceManager; import org.apache.tajo.util.CommonTestingUtil; @@ -61,6 +60,7 @@ import java.sql.SQLException; import java.util.concurrent.TimeUnit; +import static org.apache.tajo.client.ClientErrorUtil.returnError; import static org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; public class GlobalEngine extends AbstractService { @@ -195,13 +195,7 @@ public SubmitQueryResponse executeQuery(Session session, String query, boolean i responseBuilder.setUserName(queryContext.get(SessionVars.USERNAME)); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); responseBuilder.setIsForwarded(true); - responseBuilder.setResultCode(Errors.ResultCode.UNKNOWN_ERROR); - String errorMessage = t.getMessage(); - if (t.getMessage() == null) { - errorMessage = t.getClass().getName(); - } - responseBuilder.setErrorMessage(errorMessage); - responseBuilder.setErrorTrace(StringUtils.stringifyException(t)); + responseBuilder.setState(ClientErrorUtil.returnError(t)); return responseBuilder.build(); } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 6d23ecee6d..94d6d61701 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -22,7 +22,6 @@ import com.google.protobuf.ByteString; import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; -import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.fs.FileSystem; @@ -32,7 +31,7 @@ import org.apache.tajo.QueryId; import org.apache.tajo.QueryIdFactory; import org.apache.tajo.TajoIdProtos; -import org.apache.tajo.TajoProtos; +import org.apache.tajo.TajoProtos.QueryState; import org.apache.tajo.catalog.*; import org.apache.tajo.catalog.exception.NoSuchDatabaseException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; @@ -40,8 +39,6 @@ import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; import org.apache.tajo.engine.query.QueryContext; -import org.apache.tajo.error.Errors; -import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.*; import org.apache.tajo.ipc.TajoMasterClientProtocol; @@ -59,8 +56,6 @@ import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto; -import org.apache.tajo.session.InvalidSessionException; -import org.apache.tajo.session.NoSuchSessionVariableException; import org.apache.tajo.session.Session; import org.apache.tajo.util.KeyValueSet; import org.apache.tajo.util.NetUtils; @@ -71,6 +66,7 @@ import java.util.*; import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; +import static org.apache.tajo.client.ClientErrorUtil.*; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueProto; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueSetProto; @@ -85,8 +81,6 @@ public class TajoMasterClientService extends AbstractService { private final BoolProto BOOL_TRUE = BoolProto.newBuilder().setValue(true).build(); - private final BoolProto BOOL_FALSE = - BoolProto.newBuilder().setValue(false).build(); public TajoMasterClientService(MasterContext context) { super(TajoMasterClientService.class.getName()); @@ -148,19 +142,14 @@ public CreateSessionResponse createSession(RpcController controller, CreateSessi String sessionId = context.getSessionManager().createSession(request.getUsername(), databaseName); CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setResultCode(ResultCode.OK); + builder.setState(OK); builder.setSessionId(TajoIdProtos.SessionIdProto.newBuilder().setId(sessionId).build()); builder.setSessionVars(ProtoUtil.convertFromMap(context.getSessionManager().getAllVariables(sessionId))); return builder.build(); - } catch (NoSuchDatabaseException nsde) { - CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - builder.setMessage(nsde.getMessage()); - return builder.build(); - } catch (InvalidSessionException e) { + + } catch (Throwable t) { CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - builder.setMessage(e.getMessage()); + builder.setState(returnError(t)); return builder.build(); } } @@ -176,23 +165,13 @@ public BoolProto removeSession(RpcController controller, TajoIdProtos.SessionIdP return BOOL_TRUE; } - public SessionUpdateResponse buildSessionUpdateOnSuccess(Map variables) { - SessionUpdateResponse.Builder builder = SessionUpdateResponse.newBuilder(); - builder.setResultCode(ResultCode.OK); - builder.setSessionVars(new KeyValueSet(variables).getProto()); - return builder.build(); - } + @Override + public SessionUpdateResponse updateSessionVariables(RpcController controller, + UpdateSessionVariableRequest request) + throws ServiceException { - public SessionUpdateResponse buildSessionUpdateOnError(String message) { SessionUpdateResponse.Builder builder = SessionUpdateResponse.newBuilder(); - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - builder.setMessage(message); - return builder.build(); - } - @Override - public SessionUpdateResponse updateSessionVariables(RpcController controller, UpdateSessionVariableRequest request) - throws ServiceException { try { String sessionId = request.getSessionId().getId(); for (KeyValueProto kv : request.getSessionVars().getKeyvalList()) { @@ -201,9 +180,15 @@ public SessionUpdateResponse updateSessionVariables(RpcController controller, Up for (String unsetVariable : request.getUnsetVariablesList()) { context.getSessionManager().removeVariable(sessionId, unsetVariable); } - return buildSessionUpdateOnSuccess(context.getSessionManager().getAllVariables(sessionId)); + + + builder.setState(OK); + builder.setSessionVars(new KeyValueSet(context.getSessionManager().getAllVariables(sessionId)).getProto()); + return builder.build(); + } catch (Throwable t) { - return buildSessionUpdateOnError("Invalid Session Id" + request.getSessionId()); + builder.setState(returnError(t)); + return builder.build(); } } @@ -220,19 +205,17 @@ public StringProto getSessionVariable(RpcController controller, SessionedStringP } @Override - public BoolProto existSessionVariable(RpcController controller, SessionedStringProto request) + public ResponseState existSessionVariable(RpcController controller, SessionedStringProto request) throws ServiceException { try { String value = context.getSessionManager().getVariable(request.getSessionId().getId(), request.getValue()); if (value != null) { - return ProtoUtil.TRUE; + return OK; } else { - return ProtoUtil.FALSE; + return ERR_NO_SESSION_VARIABLE(request.getValue()); } - } catch (NoSuchSessionVariableException nssv) { - return ProtoUtil.FALSE; } catch (Throwable t) { - throw new ServiceException(t); + return returnError(t); } } @@ -245,6 +228,7 @@ public KeyValueSetProto getAllSessionVariables(RpcController controller, KeyValueSet keyValueSet = new KeyValueSet(); keyValueSet.putAll(context.getSessionManager().getAllVariables(sessionId)); return keyValueSet.getProto(); + } catch (Throwable t) { throw new ServiceException(t); } @@ -256,25 +240,26 @@ public StringProto getCurrentDatabase(RpcController controller, TajoIdProtos.Ses try { String sessionId = request.getId(); return ProtoUtil.convertString(context.getSessionManager().getSession(sessionId).getCurrentDatabase()); + } catch (Throwable t) { throw new ServiceException(t); } } @Override - public BoolProto selectDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ResponseState selectDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { String sessionId = request.getSessionId().getId(); String databaseName = request.getValue(); if (context.getCatalog().existDatabase(databaseName)) { context.getSessionManager().getSession(sessionId).selectDatabase(databaseName); - return ProtoUtil.TRUE; + return OK; } else { - throw new ServiceException(new NoSuchDatabaseException(databaseName)); + return ERR_UNDEFIED_DATABASE(databaseName); } } catch (Throwable t) { - throw new ServiceException(t); + return returnError(t); } } @@ -286,45 +271,35 @@ public SubmitQueryResponse submitQuery(RpcController controller, QueryRequest re if(LOG.isDebugEnabled()) { LOG.debug("Query [" + request.getQuery() + "] is submitted"); } + return context.getGlobalEngine().executeQuery(session, request.getQuery(), request.getIsJson()); + } catch (Exception e) { - LOG.error(e.getMessage(), e); - SubmitQueryResponse.Builder responseBuilder = ClientProtos.SubmitQueryResponse.newBuilder(); - responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setIsForwarded(true); - responseBuilder.setUserName(context.getConf().getVar(ConfVars.USERNAME)); - responseBuilder.setResultCode(ResultCode.UNKNOWN_ERROR); - if (e.getMessage() != null) { - responseBuilder.setErrorMessage(ExceptionUtils.getStackTrace(e)); - } else { - responseBuilder.setErrorMessage("Internal Error"); - } - return responseBuilder.build(); + + return ClientProtos.SubmitQueryResponse.newBuilder() + .setState(returnError(e)) + .setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()) + .setIsForwarded(true) + .setUserName(context.getConf().getVar(ConfVars.USERNAME)) + .build(); + } } @Override public UpdateQueryResponse updateQuery(RpcController controller, QueryRequest request) throws ServiceException { + UpdateQueryResponse.Builder builder = UpdateQueryResponse.newBuilder(); try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); + context.getGlobalEngine().updateQuery(queryContext, request.getQuery(), request.getIsJson()); + builder.setState(OK); - UpdateQueryResponse.Builder builder = UpdateQueryResponse.newBuilder(); - try { - context.getGlobalEngine().updateQuery(queryContext, request.getQuery(), request.getIsJson()); - builder.setResultCode(ResultCode.OK); - return builder.build(); - } catch (Exception e) { - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - if (e.getMessage() == null) { - builder.setErrorMessage(ExceptionUtils.getStackTrace(e)); - } - return builder.build(); - } } catch (Throwable t) { - throw new ServiceException(t); + builder.setState(returnError(t)); } + return builder.build(); } @Override @@ -460,8 +435,8 @@ public GetQueryStatusResponse getQueryStatus(RpcController controller, builder.setQueryId(request.getQueryId()); if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) { - builder.setResultCode(ResultCode.OK); - builder.setState(TajoProtos.QueryState.QUERY_SUCCEEDED); + builder.setState(OK); + builder.setQueryState(QueryState.QUERY_SUCCEEDED); } else { QueryInProgress queryInProgress = context.getQueryJobManager().getQueryInProgress(queryId); @@ -474,8 +449,8 @@ public GetQueryStatusResponse getQueryStatus(RpcController controller, } if (queryInfo != null) { - builder.setResultCode(ResultCode.OK); - builder.setState(queryInfo.getQueryState()); + builder.setState(OK); + builder.setQueryState(queryInfo.getQueryState()); boolean isCreateTable = queryInfo.getQueryContext().isCreateTable(); boolean isInsert = queryInfo.getQueryContext().isInsert(); @@ -487,7 +462,7 @@ public GetQueryStatusResponse getQueryStatus(RpcController controller, builder.setQueryMasterHost(queryInfo.getQueryMasterHost()); builder.setQueryMasterPort(queryInfo.getQueryMasterClientPort()); } - if (queryInfo.getQueryState() == TajoProtos.QueryState.QUERY_SUCCEEDED) { + if (queryInfo.getQueryState() == QueryState.QUERY_SUCCEEDED) { builder.setFinishTime(queryInfo.getFinishTime()); } else { builder.setFinishTime(System.currentTimeMillis()); @@ -495,11 +470,10 @@ public GetQueryStatusResponse getQueryStatus(RpcController controller, } else { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); if (session.getNonForwardQueryResultScanner(queryId) != null) { - builder.setResultCode(ResultCode.OK); - builder.setState(TajoProtos.QueryState.QUERY_SUCCEEDED); + builder.setState(OK); + builder.setQueryState(QueryState.QUERY_SUCCEEDED); } else { - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - builder.setErrorMessage("No such query: " + queryId.toString()); + builder.setState(ERR_NO_SUCH_QUERY_ID(queryId)); } } } @@ -551,33 +525,33 @@ public GetQueryResultDataResponse getQueryResultData(RpcController controller, G resultSetBuilder.addAllSerializedTuples(rows); builder.setResultSet(resultSetBuilder.build()); - builder.setResultCode(ResultCode.OK); + builder.setState(OK); LOG.info("Send result to client for " + request.getSessionId().getId() + "," + queryId + ", " + rows.size() + " rows"); } catch (Throwable t) { - LOG.error(t.getMessage(), t); builder.setResultSet(resultSetBuilder.build()); // required field - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - String errorMessage = t.getMessage() == null ? t.getClass().getName() : t.getMessage(); - builder.setErrorMessage(errorMessage); - builder.setErrorTrace(org.apache.hadoop.util.StringUtils.stringifyException(t)); + builder.setState(returnError(t)); } + return builder.build(); } @Override - public BoolProto closeNonForwardQuery(RpcController controller, QueryIdRequest request) throws ServiceException { + public ResponseState closeNonForwardQuery(RpcController controller, QueryIdRequest request) + throws ServiceException { + try { context.getSessionManager().touch(request.getSessionId().getId()); Session session = context.getSessionManager().getSession(request.getSessionId().getId()); QueryId queryId = new QueryId(request.getQueryId()); session.closeNonForwardQueryResultScanner(queryId); - return BOOL_TRUE; + return OK; + } catch (Throwable t) { - throw new ServiceException(t); + return returnError(t); } } @@ -602,11 +576,10 @@ public GetQueryInfoResponse getQueryInfo(RpcController controller, QueryIdReques if (queryInfo != null) { builder.setQueryInfo(queryInfo.getProto()); } - builder.setResultCode(ResultCode.OK); + builder.setState(OK); + } catch (Throwable t) { - LOG.warn(t.getMessage(), t); - builder.setResultCode(ResultCode.UNKNOWN_ERROR); - builder.setErrorMessage(org.apache.hadoop.util.StringUtils.stringifyException(t)); + builder.setState(returnError(t)); } return builder.build(); @@ -616,23 +589,24 @@ public GetQueryInfoResponse getQueryInfo(RpcController controller, QueryIdReques * It is invoked by TajoContainerProxy. */ @Override - public BoolProto killQuery(RpcController controller, QueryIdRequest request) throws ServiceException { + public ResponseState killQuery(RpcController controller, QueryIdRequest request) throws ServiceException { try { context.getSessionManager().touch(request.getSessionId().getId()); QueryId queryId = new QueryId(request.getQueryId()); QueryInProgress progress = context.getQueryJobManager().getQueryInProgress(queryId); if (progress == null || progress.isFinishState() || progress.isKillWait()) { - return BOOL_TRUE; + return OK; } QueryManager queryManager = context.getQueryJobManager(); queryManager.getEventHandler().handle(new QueryJobEvent(QueryJobEvent.Type.QUERY_JOB_KILL, new QueryInfo(queryId))); - return BOOL_TRUE; + + return OK; + } catch (Throwable t) { - LOG.error(t.getMessage(), t); - throw new ServiceException(t); + return returnError(t); } } @@ -640,9 +614,11 @@ public BoolProto killQuery(RpcController controller, QueryIdRequest request) thr public GetClusterInfoResponse getClusterInfo(RpcController controller, GetClusterInfoRequest request) throws ServiceException { + + GetClusterInfoResponse.Builder builder = GetClusterInfoResponse.newBuilder(); + try { context.getSessionManager().touch(request.getSessionId().getId()); - GetClusterInfoResponse.Builder builder= GetClusterInfoResponse.newBuilder(); Map workers = context.getResourceManager().getWorkers(); @@ -673,71 +649,80 @@ public GetClusterInfoResponse getClusterInfo(RpcController controller, builder.addWorkerList(workerBuilder.build()); } - return builder.build(); + builder.setState(OK); + } catch (Throwable t) { - throw new ServiceException(t); + builder.setState(returnError(t)); } + + return builder.build(); } @Override - public BoolProto createDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ResponseState createDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); if (context.getGlobalEngine().getDDLExecutor().createDatabase(queryContext, request.getValue(), null, false)) { - return BOOL_TRUE; + return OK; } else { - return BOOL_FALSE; + return ERR_DUPLICATE_DATABASE(request.getValue()); } - } catch (Throwable e) { - throw new ServiceException(e); + + } catch (Throwable t) { + return returnError(t); } } @Override - public BoolProto existDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ResponseState existDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { context.getSessionManager().touch(request.getSessionId().getId()); if (catalog.existDatabase(request.getValue())) { - return BOOL_TRUE; + return OK; } else { - return BOOL_FALSE; + return ERR_UNDEFIED_DATABASE(request.getValue()); } - } catch (Throwable e) { - throw new ServiceException(e); + + } catch (Throwable t) { + return returnError(t); } } @Override - public BoolProto dropDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ResponseState dropDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); if (context.getGlobalEngine().getDDLExecutor().dropDatabase(queryContext, request.getValue(), false)) { - return BOOL_TRUE; + return OK; } else { - return BOOL_FALSE; + return ERR_UNDEFIED_DATABASE(request.getValue()); } - } catch (Throwable e) { - throw new ServiceException(e); + + } catch (Throwable t) { + return returnError(t); } } @Override public StringListProto getAllDatabases(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { + try { context.getSessionManager().touch(request.getId()); return ProtoUtil.convertStrings(catalog.getAllDatabaseNames()); + } catch (Throwable e) { throw new ServiceException(e); } } @Override - public BoolProto existTable(RpcController controller, SessionedStringProto request) throws ServiceException { + public ResponseState existTable(RpcController controller, SessionedStringProto request) throws ServiceException { + try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); @@ -753,12 +738,13 @@ public BoolProto existTable(RpcController controller, SessionedStringProto reque } if (catalog.existsTable(databaseName, tableName)) { - return BOOL_TRUE; + return OK; } else { - return BOOL_FALSE; + return ERR_UNDEFIED_TABLE(tableName); } - } catch (Throwable e) { - throw new ServiceException(e); + + } catch (Throwable t) { + return returnError(t); } } @@ -776,7 +762,9 @@ public StringListProto getTableList(RpcController controller, Collection tableNames = catalog.getAllTableNames(databaseName); StringListProto.Builder builder = StringListProto.newBuilder(); builder.addAllValues(tableNames); + return builder.build(); + } catch (Throwable t) { throw new ServiceException(t); } @@ -788,8 +776,7 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto if (!request.hasValue()) { return TableResponse.newBuilder() - .setResultCode(ResultCode.UNKNOWN_ERROR) - .setErrorMessage("table name is required.") + .setState(ERR_INVALID_RPC_CALL("Table name is required")) .build(); } @@ -808,13 +795,12 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto if (catalog.existsTable(databaseName, tableName)) { return TableResponse.newBuilder() - .setResultCode(ResultCode.OK) + .setState(OK) .setTableDesc(catalog.getTableDesc(databaseName, tableName).getProto()) .build(); } else { return TableResponse.newBuilder() - .setResultCode(ResultCode.UNKNOWN_ERROR) - .setErrorMessage("ERROR: no such a table: " + request.getValue()) + .setState(ERR_UNDEFIED_TABLE(request.getValue())) .build(); } } catch (Throwable t) { @@ -843,41 +829,42 @@ public TableResponse createExternalTable(RpcController controller, CreateTableRe partitionDesc = new PartitionMethodDesc(request.getPartition()); } - TableDesc desc; - try { - desc = context.getGlobalEngine().getDDLExecutor().createTable(queryContext, request.getName(), - null, meta.getStoreType(), schema, meta, path.toUri(), true, partitionDesc, false); - } catch (Exception e) { - return TableResponse.newBuilder() - .setResultCode(ResultCode.UNKNOWN_ERROR) - .setErrorMessage(e.getMessage()).build(); - } + TableDesc desc = context.getGlobalEngine().getDDLExecutor().createTable( + queryContext, + request.getName(), + null, + meta.getStoreType(), + schema, + meta, + path.toUri(), + true, + partitionDesc, + false + ); return TableResponse.newBuilder() - .setResultCode(ResultCode.OK) + .setState(OK) .setTableDesc(desc.getProto()).build(); - } catch (InvalidSessionException ise) { - return TableResponse.newBuilder() - .setResultCode(ResultCode.UNKNOWN_ERROR) - .setErrorMessage(ise.getMessage()).build(); - } catch (IOException ioe) { + + } catch (Throwable t) { return TableResponse.newBuilder() - .setResultCode(ResultCode.UNKNOWN_ERROR) - .setErrorMessage(ioe.getMessage()).build(); + .setState(returnError(t)) + .build(); } } @Override - public BoolProto dropTable(RpcController controller, DropTableRequest dropTable) throws ServiceException { + public ResponseState dropTable(RpcController controller, DropTableRequest dropTable) throws ServiceException { try { Session session = context.getSessionManager().getSession(dropTable.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); context.getGlobalEngine().getDDLExecutor().dropTable(queryContext, dropTable.getName(), false, dropTable.getPurge()); - return BOOL_TRUE; + return OK; + } catch (Throwable t) { - throw new ServiceException(t); + return returnError(t); } } @@ -903,11 +890,12 @@ public FunctionResponse getFunctionList(RpcController controller, SessionedStrin } } return FunctionResponse.newBuilder() - .setResultCode(ResultCode.OK) + .setState(OK) .addAllFunctions(functionProtos) .build(); + } catch (Throwable t) { - throw new ServiceException(t); + return FunctionResponse.newBuilder().setState(returnError(t)).build(); } } } 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 ad41759df3..7563d995a0 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 @@ -34,6 +34,7 @@ import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.statistics.TableStats; +import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.datum.DatumFactory; @@ -72,6 +73,9 @@ import java.util.ArrayList; import java.util.List; +import static org.apache.tajo.client.ClientErrorUtil.ERR_UNDEFIED_DATABASE; +import static org.apache.tajo.client.ClientErrorUtil.OK; + public class QueryExecutor { private static final Log LOG = LogFactory.getLog(QueryExecutor.class); @@ -107,7 +111,7 @@ public SubmitQueryResponse execute(QueryContext queryContext, Session session, S context.getSystemMetrics().counter("Query", "numDDLQuery").inc(); ddlExecutor.execute(queryContext, plan); response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setResultCode(ResultCode.OK); + response.setState(OK); } else if (plan.isExplain()) { // explain query @@ -147,8 +151,7 @@ public void execSetSession(Session session, LogicalPlan plan, session.selectDatabase(setSessionNode.getValue()); } else { response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setResultCode(ResultCode.NO_SUCH_DATABASE); - response.setErrorMessage("database \"" + databaseName + "\" does not exists."); + response.setState(ERR_UNDEFIED_DATABASE(databaseName)); } // others @@ -162,7 +165,7 @@ public void execSetSession(Session session, LogicalPlan plan, context.getSystemMetrics().counter("Query", "numDDLQuery").inc(); response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setResultCode(ResultCode.OK); + response.setState(OK); } public void execExplain(LogicalPlan plan, QueryContext queryContext, boolean isGlobal, @@ -205,9 +208,9 @@ public void execExplain(LogicalPlan plan, QueryContext queryContext, boolean isG serializedResBuilder.setSchema(schema.getProto()); serializedResBuilder.setBytesNum(bytesNum); + response.setState(OK); response.setResultSet(serializedResBuilder.build()); response.setMaxRowNum(lines.length); - response.setResultCode(ResultCode.OK); response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); } @@ -226,10 +229,10 @@ public void execQueryOnVirtualTable(QueryContext queryContext, Session session, queryResultScanner.init(); session.addNonForwardQueryResultScanner(queryResultScanner); + response.setState(OK); response.setQueryId(queryId.getProto()); response.setMaxRowNum(maxRow); response.setTableDesc(queryResultScanner.getTableDesc().getProto()); - response.setResultCode(ResultCode.OK); } public void execSimpleQuery(QueryContext queryContext, Session session, String query, LogicalPlan plan, @@ -262,10 +265,10 @@ public void execSimpleQuery(QueryContext queryContext, Session session, String q queryResultScanner.init(); session.addNonForwardQueryResultScanner(queryResultScanner); + response.setState(OK); response.setQueryId(queryInfo.getQueryId().getProto()); response.setMaxRowNum(maxRow); response.setTableDesc(desc.getProto()); - response.setResultCode(ResultCode.OK); } public void execNonFromQuery(QueryContext queryContext, LogicalPlan plan, SubmitQueryResponse.Builder responseBuilder) @@ -299,10 +302,10 @@ public void execNonFromQuery(QueryContext queryContext, LogicalPlan plan, Submit serializedResBuilder.setSchema(schema.getProto()); serializedResBuilder.setBytesNum(serializedBytes.length); + responseBuilder.setState(OK); responseBuilder.setResultSet(serializedResBuilder); responseBuilder.setMaxRowNum(1); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setResultCode(ResultCode.OK); } } finally { // stop script executor @@ -464,7 +467,7 @@ private void insertRowValues(QueryContext queryContext, // If queryId == NULL_QUERY_ID and MaxRowNum == -1, TajoCli prints only number of inserted rows. responseBuilder.setMaxRowNum(-1); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setResultCode(ResultCode.OK); + responseBuilder.setState(OK); } catch (Throwable t) { throw new RuntimeException(t); } @@ -498,22 +501,15 @@ public void executeDistributedQuery(QueryContext queryContext, Session session, queryInfo = queryManager.scheduleQuery(session, queryContext, sql, jsonExpr, rootNode); - if(queryInfo == null) { - responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - responseBuilder.setResultCode(ResultCode.UNKNOWN_ERROR); - responseBuilder.setErrorMessage("Fail starting QueryMaster."); - LOG.error("Fail starting QueryMaster: " + sql); - } else { - responseBuilder.setIsForwarded(true); - responseBuilder.setQueryId(queryInfo.getQueryId().getProto()); - responseBuilder.setResultCode(ResultCode.OK); - if(queryInfo.getQueryMasterHost() != null) { - responseBuilder.setQueryMasterHost(queryInfo.getQueryMasterHost()); - } - responseBuilder.setQueryMasterPort(queryInfo.getQueryMasterClientPort()); - LOG.info("Query " + queryInfo.getQueryId().toString() + "," + queryInfo.getSql() + "," + - " is forwarded to " + queryInfo.getQueryMasterHost() + ":" + queryInfo.getQueryMasterPort()); + responseBuilder.setIsForwarded(true); + responseBuilder.setQueryId(queryInfo.getQueryId().getProto()); + responseBuilder.setState(OK); + if (queryInfo.getQueryMasterHost() != null) { + responseBuilder.setQueryMasterHost(queryInfo.getQueryMasterHost()); } + responseBuilder.setQueryMasterPort(queryInfo.getQueryMasterClientPort()); + LOG.info("Query " + queryInfo.getQueryId().toString() + "," + queryInfo.getSql() + "," + + " is forwarded to " + queryInfo.getQueryMasterHost() + ":" + queryInfo.getQueryMasterPort()); } public MasterPlan compileMasterPlan(LogicalPlan plan, QueryContext context, GlobalPlanner planner) diff --git a/tajo-core/src/main/java/org/apache/tajo/session/NoSuchSessionVariableException.java b/tajo-core/src/main/java/org/apache/tajo/session/NoSuchSessionVariableException.java index be904490ca..a941b55517 100644 --- a/tajo-core/src/main/java/org/apache/tajo/session/NoSuchSessionVariableException.java +++ b/tajo-core/src/main/java/org/apache/tajo/session/NoSuchSessionVariableException.java @@ -18,8 +18,12 @@ package org.apache.tajo.session; -public class NoSuchSessionVariableException extends Exception { +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.TajoException; + +public class NoSuchSessionVariableException extends TajoException { + public NoSuchSessionVariableException(String varname) { - super("No such session variable \"" + varname + "\""); + super(Errors.ResultCode.NO_SUCH_SESSION_VARIABLE, varname); } } diff --git a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java index 79aa0a108a..463c85d504 100644 --- a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java +++ b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java @@ -9,10 +9,7 @@ import org.apache.tajo.TajoProtos; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.client.QueryStatus; -import org.apache.tajo.client.TajoClient; -import org.apache.tajo.client.TajoClientImpl; -import org.apache.tajo.client.TajoClientUtil; +import org.apache.tajo.client.*; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; @@ -44,6 +41,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.tajo.client.ClientErrorUtil.isError; +import static org.apache.tajo.client.ClientErrorUtil.isSuccess; import static org.apache.tajo.exception.ErrorUtil.isFailed; import static org.apache.tajo.exception.ErrorUtil.isOk; @@ -324,7 +323,7 @@ public void run() { LOG.error("Internal Error: SubmissionResponse is NULL"); error = new Exception("Internal Error: SubmissionResponse is NULL"); - } else if (isOk(response.getResultCode())) { + } else if (isSuccess(response.getState())) { if (response.getIsForwarded()) { queryId = new QueryId(response.getQueryId()); getQueryResult(queryId); @@ -336,22 +335,20 @@ public void run() { progress.set(100); } - } else if (isFailed(response.getResultCode())) { - if (response.hasErrorMessage()) { - StringBuffer errorMessage = new StringBuffer(response.getErrorMessage()); - String modifiedMessage; + } else if (isError(response.getState())) { + StringBuffer errorMessage = new StringBuffer(response.getState().getMessage()); + String modifiedMessage; - if (errorMessage.length() > 200) { - modifiedMessage = errorMessage.substring(0, 200); - } else { - modifiedMessage = errorMessage.toString(); - } - - String lineSeparator = System.getProperty("line.separator"); - modifiedMessage = modifiedMessage.replaceAll(lineSeparator, "
"); - - error = new Exception(modifiedMessage); + if (errorMessage.length() > 200) { + modifiedMessage = errorMessage.substring(0, 200); + } else { + modifiedMessage = errorMessage.toString(); } + + String lineSeparator = System.getProperty("line.separator"); + modifiedMessage = modifiedMessage.replaceAll(lineSeparator, "
"); + + error = new Exception(modifiedMessage); } } catch (Exception e) { LOG.error(e.getMessage(), e); diff --git a/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java b/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java index c0a6453a78..09d5d00966 100644 --- a/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java @@ -26,10 +26,10 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.service.AbstractService; import org.apache.tajo.QueryId; +import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.ipc.ClientProtos.GetQueryHistoryResponse; import org.apache.tajo.ipc.ClientProtos.QueryIdRequest; -import org.apache.tajo.ipc.ClientProtos.ResultCode; import org.apache.tajo.ipc.QueryMasterClientProtocol; import org.apache.tajo.querymaster.QueryMasterTask; import org.apache.tajo.rpc.BlockingRpcServer; @@ -129,11 +129,10 @@ public GetQueryHistoryResponse getQueryHistory(RpcController controller, QueryId if (queryHistory != null) { builder.setQueryHistory(queryHistory.getProto()); } - builder.setResultCode(ResultCode.OK); + builder.setState(ClientErrorUtil.OK); } catch (Throwable t) { - LOG.warn(t.getMessage(), t); - builder.setResultCode(ResultCode.ERROR); - builder.setErrorMessage(org.apache.hadoop.util.StringUtils.stringifyException(t)); + LOG.error(t.getMessage(), t); + builder.setState(ClientErrorUtil.returnError(t)); } return builder.build(); diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java index abecc3ad03..ae42bef263 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java @@ -22,7 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.tajo.QueryId; import org.apache.tajo.TajoProtos; -import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; import org.apache.tajo.master.QueryInProgress; import org.apache.tajo.master.QueryInfo; @@ -262,8 +262,8 @@ public Response run(JerseyResourceDelegateContext context) { SubmitQueryResponse response = masterContext.getGlobalEngine().executeQuery(session, request.getQuery(), false); - if (response.hasResultCode() && ClientProtos.ResultCode.ERROR.equals(response.getResultCode())) { - return ResourcesUtil.createExceptionResponse(LOG, response.getErrorMessage()); + if (ClientErrorUtil.isError(response.getState())) { + return ResourcesUtil.createExceptionResponse(LOG, response.getState().getMessage()); } else { JerseyResourceDelegateContextKey uriInfoKey = JerseyResourceDelegateContextKey.valueOf(JerseyResourceDelegateUtil.UriInfoKey, UriInfo.class); diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResultResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResultResource.java index 3384c90f84..ab45a5b33a 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResultResource.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResultResource.java @@ -24,7 +24,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.tajo.QueryId; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.ipc.ClientProtos.ResultCode; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.master.QueryInfo; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.master.exec.NonForwardQueryResultFileScanner; @@ -198,7 +198,7 @@ public Response run(JerseyResourceDelegateContext context) { GetQueryResultDataResponse response = new GetQueryResultDataResponse(); if (queryInfo == null) { - response.setResultCode(ResultCode.ERROR); + response.setResultCode(ResultCode.INTERNAL_ERROR); response.setErrorMessage("Unable to find a query info for requested id : " + queryId); return Response.status(Status.NOT_FOUND).entity(response).build(); } @@ -229,7 +229,7 @@ public Response run(JerseyResourceDelegateContext context) { LOG.error(e.getMessage(), e); GetQueryResultDataResponse response = new GetQueryResultDataResponse(); - response.setResultCode(ResultCode.ERROR); + response.setResultCode(ResultCode.INTERNAL_ERROR); response.setErrorMessage(e.getMessage()); response.setErrorTrace(org.apache.hadoop.util.StringUtils.stringifyException(e)); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(response).build(); diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java index 70a1fc628e..8456202d35 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/SessionsResource.java @@ -142,7 +142,7 @@ public Response run(JerseyResourceDelegateContext context) { LOG.error(e.getMessage(), e); NewSessionResponse sessionResponse = new NewSessionResponse(); - sessionResponse.setResultCode(ResultCode.UNKNOWN_ERROR); + sessionResponse.setResultCode(ResultCode.INTERNAL_ERROR); sessionResponse.setMessage(e.getMessage()); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(sessionResponse).build(); @@ -150,7 +150,7 @@ public Response run(JerseyResourceDelegateContext context) { LOG.error(e.getMessage(), e); NewSessionResponse sessionResponse = new NewSessionResponse(); - sessionResponse.setResultCode(ResultCode.UNKNOWN_ERROR); + sessionResponse.setResultCode(ResultCode.INTERNAL_ERROR); sessionResponse.setMessage(e.getMessage()); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(sessionResponse).build(); diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/GetQueryResultDataResponse.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/GetQueryResultDataResponse.java index 512f20ff6e..66884bfbd5 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/GetQueryResultDataResponse.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/responses/GetQueryResultDataResponse.java @@ -19,23 +19,25 @@ package org.apache.tajo.ws.rs.responses; import org.apache.tajo.catalog.Schema; +import org.apache.tajo.error.Errors; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; import com.google.gson.annotations.Expose; public class GetQueryResultDataResponse { - @Expose private ClientProtos.ResultCode resultCode; + @Expose private ResultCode resultCode; @Expose private Schema schema; @Expose private int bytesNum; @Expose private ResultSetInfoResponse resultset; @Expose private String errorMessage; @Expose private String errorTrace; - public ClientProtos.ResultCode getResultCode() { + public ResultCode getResultCode() { return resultCode; } - public void setResultCode(ClientProtos.ResultCode resultCode) { + public void setResultCode(ResultCode resultCode) { this.resultCode = resultCode; } public Schema getSchema() { diff --git a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java index a323f252f6..e6314d14fd 100644 --- a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java +++ b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java @@ -699,17 +699,19 @@ public void assertTableNotExists(String tableName) throws ServiceException { assertTrue(!client.existTable(tableName)); } - public void assertColumnExists(String tableName,String columnName) throws ServiceException { - TableDesc tableDesc = fetchTableMetaData(tableName); + public void assertColumnExists(String tableName,String columnName) throws ServiceException, SQLException { + TableDesc tableDesc = getTableDesc(tableName); assertTrue(tableDesc.getSchema().containsByName(columnName)); } - private TableDesc fetchTableMetaData(String tableName) throws ServiceException { + private TableDesc getTableDesc(String tableName) throws ServiceException, SQLException { return client.getTableDesc(tableName); } - public void assertTablePropertyEquals(String tableName, String key, String expectedValue) throws ServiceException { - TableDesc tableDesc = fetchTableMetaData(tableName); + public void assertTablePropertyEquals(String tableName, String key, String expectedValue) + throws ServiceException, SQLException { + + TableDesc tableDesc = getTableDesc(tableName); assertEquals(expectedValue, tableDesc.getMeta().getOption(key)); } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java index dd67e06496..ccbefc64f4 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java @@ -43,6 +43,7 @@ import java.io.File; import java.io.OutputStream; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -210,7 +211,7 @@ interface TupleCreator { Tuple createTuple(String[] columnDatas); } - private static String buildSchemaString(String tableName) throws ServiceException { + private static String buildSchemaString(String tableName) throws ServiceException, SQLException { TableDesc desc = client.getTableDesc(tableName); StringBuffer sb = new StringBuffer(); for (Column column : desc.getSchema().getRootColumns()) { @@ -225,7 +226,7 @@ private static String buildSchemaString(String tableName) throws ServiceExceptio return sb.toString(); } - private static String buildMultifileDDlString(String tableName) throws ServiceException { + private static String buildMultifileDDlString(String tableName) throws ServiceException, SQLException { String multiTableName = tableName + "_multifile"; StringBuilder sb = new StringBuilder("create table ").append(multiTableName).append(" ("); sb.append(buildSchemaString(tableName)).append(" )"); diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java index ef57356c80..903c72ca68 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java @@ -31,6 +31,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.engine.planner.global.DataChannel; @@ -864,8 +865,8 @@ public final void testColumnPartitionedTableWithSmallerExpressions1() throws Exc ClientProtos.SubmitQueryResponse response = client.executeQuery("insert overwrite into " + tableName + " select l_orderkey, l_partkey from lineitem"); - assertTrue(response.hasErrorMessage()); - assertEquals(response.getErrorMessage(), "INSERT has smaller expressions than target columns\n"); + assertTrue(ClientErrorUtil.isError(response.getState())); + assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns\n"); res = executeFile("case14.sql"); assertResultSet(res, "case14.result"); @@ -890,8 +891,8 @@ public final void testColumnPartitionedTableWithSmallerExpressions2() throws Exc response = client.executeQuery("insert overwrite into " + tableName + " select l_returnflag , l_orderkey, l_partkey from lineitem"); - assertTrue(response.hasErrorMessage()); - assertEquals(response.getErrorMessage(), "INSERT has smaller expressions than target columns\n"); + assertTrue(ClientErrorUtil.isError(response.getState())); + assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns\n"); res = executeFile("case15.sql"); assertResultSet(res, "case15.result"); diff --git a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java index 5d0b150c72..ff341d19a2 100644 --- a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java +++ b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java @@ -22,7 +22,7 @@ import org.apache.tajo.QueryTestCaseBase; import org.apache.tajo.TajoConstants; import org.apache.tajo.conf.TajoConf.ConfVars; -import org.apache.tajo.ipc.ClientProtos.ResultCode; +import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.master.QueryInfo; import org.apache.tajo.ws.rs.netty.gson.GsonFeature; import org.apache.tajo.ws.rs.requests.NewSessionRequest; @@ -94,7 +94,7 @@ private String generateNewSessionAndGetId() throws Exception { .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class); assertNotNull(response); - assertTrue(ResultCode.OK.equals(response.getResultCode())); + assertTrue(ErrorUtil.isOk(response.getResultCode())); assertTrue(response.getId() != null && !response.getId().isEmpty()); return response.getId(); diff --git a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java index d4f17855f2..9e7c48fcb8 100644 --- a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java +++ b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java @@ -22,7 +22,7 @@ import org.apache.tajo.QueryTestCaseBase; import org.apache.tajo.TajoConstants; import org.apache.tajo.conf.TajoConf.ConfVars; -import org.apache.tajo.ipc.ClientProtos.ResultCode; +import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.storage.RowStoreUtil; import org.apache.tajo.storage.Tuple; import org.apache.tajo.util.TUtil; @@ -52,6 +52,7 @@ import java.security.MessageDigest; import java.util.List; +import static org.apache.tajo.exception.ErrorUtil.isOk; import static org.junit.Assert.*; public class TestQueryResultResource extends QueryTestCaseBase { @@ -96,7 +97,7 @@ private String generateNewSessionAndGetId() throws Exception { .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class); assertNotNull(response); - assertTrue(ResultCode.OK.equals(response.getResultCode())); + assertTrue(isOk(response.getResultCode())); assertTrue(response.getId() != null && !response.getId().isEmpty()); return response.getId(); @@ -135,7 +136,7 @@ public void testGetQueryResult() throws Exception { assertNotNull(response); assertNotNull(response.getResultCode()); - assertEquals(ResultCode.OK, response.getResultCode()); + assertTrue(isOk(response.getResultCode())); assertNotNull(response.getSchema()); assertEquals(16, response.getSchema().getRootColumns().size()); assertNotNull(response.getResultset()); @@ -169,7 +170,7 @@ public void testGetQueryResultSet() throws Exception { assertNotNull(response); assertNotNull(response.getResultCode()); - assertEquals(ResultCode.OK, response.getResultCode()); + assertTrue(ErrorUtil.isOk(response.getResultCode())); assertNotNull(response.getSchema()); assertEquals(16, response.getSchema().getRootColumns().size()); assertNotNull(response.getResultset()); @@ -231,7 +232,7 @@ public void testGetQueryResultSetWithOffset() throws Exception { assertNotNull(response); assertNotNull(response.getResultCode()); - assertEquals(ResultCode.OK, response.getResultCode()); + assertTrue(isOk(response.getResultCode())); assertNotNull(response.getSchema()); assertEquals(16, response.getSchema().getRootColumns().size()); assertNotNull(response.getResultset()); @@ -294,7 +295,7 @@ public void testGetQueryResultSetWithDefaultCount() throws Exception { assertNotNull(response); assertNotNull(response.getResultCode()); - assertEquals(ResultCode.OK, response.getResultCode()); + assertTrue(isOk(response.getResultCode())); assertNotNull(response.getSchema()); assertEquals(16, response.getSchema().getRootColumns().size()); assertNotNull(response.getResultset()); 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 571ed1f594..2db9037560 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 @@ -23,7 +23,6 @@ import org.apache.tajo.SessionVars; import org.apache.tajo.client.TajoClient; import org.apache.tajo.client.TajoClientUtil; -import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import java.io.IOException; @@ -31,6 +30,8 @@ import java.util.HashMap; import java.util.Map; +import static org.apache.tajo.client.ClientErrorUtil.isError; + public class TajoStatement implements Statement { protected JdbcConnection conn; protected TajoClient tajoClient; @@ -164,14 +165,8 @@ protected ResultSet executeSQL(String sql) throws SQLException, ServiceException } ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql); - if (ErrorUtil.isFailed(response.getResultCode())) { - if (response.hasErrorMessage()) { - throw new ServiceException(response.getErrorMessage()); - } - if (response.hasErrorTrace()) { - throw new ServiceException(response.getErrorTrace()); - } - throw new ServiceException("Failed to submit query by unknown reason"); + if (isError(response.getState())) { + throw new ServiceException(response.getState().getMessage()); } QueryId queryId = new QueryId(response.getQueryId()); From 0f0ffd80fefb20a77b69be2bae619161d461fb60 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Wed, 1 Jul 2015 10:16:33 -0700 Subject: [PATCH 05/30] Fixed many exceptions. --- .../tajo/catalog/AbstractCatalogClient.java | 8 +- .../java/org/apache/tajo/catalog/Schema.java | 4 +- .../AlreadyExistsIndexException.java | 39 ---- .../AlreadyExistsPartitionException.java | 33 ---- .../AlreadyExistsTableException.java | 35 ---- .../catalog/exception/CatalogException.java | 33 +--- .../exception/CatalogExceptionUtil.java | 59 +++++++ ...ion.java => DuplicateColumnException.java} | 11 +- ...n.java => DuplicateDatabaseException.java} | 10 +- ...n.java => DuplicateFunctionException.java} | 8 +- .../exception/DuplicateIndexException.java | 29 +++ .../DuplicatePartitionException.java | 30 ++++ .../exception/DuplicateTableException.java | 30 ++++ ...java => DuplicateTablespaceException.java} | 10 +- .../NoPartitionedTableException.java | 2 - .../exception/NoSuchColumnException.java | 34 ---- .../exception/NoSuchPartitionException.java | 39 ---- .../exception/TMCConnectionException.java | 32 ++++ ...ion.java => UndefinedColumnException.java} | 10 +- ...n.java => UndefinedDatabaseException.java} | 11 +- ...n.java => UndefinedFunctionException.java} | 18 +- ...tion.java => UndefinedIndexException.java} | 15 +- ....java => UndefinedPartitionException.java} | 13 +- .../UndefinedTablespaceException.java | 29 +++ ...ption.java => UndefinedTbleException.java} | 15 +- .../org/apache/tajo/catalog/TestSchema.java | 4 +- .../tajo/catalog/store/HiveCatalogStore.java | 65 ++++--- .../apache/tajo/catalog/CatalogServer.java | 73 ++++---- .../InfoSchemaMetadataDictionary.java | 10 +- .../tajo/catalog/store/AbstractDBStore.java | 166 +++++++++--------- .../apache/tajo/catalog/store/DerbyStore.java | 3 +- .../apache/tajo/catalog/store/MemStore.java | 40 ++--- .../store/XMLCatalogSchemaManager.java | 39 ++-- .../org/apache/tajo/catalog/TestCatalog.java | 12 +- .../apache/tajo/client/QueryClientImpl.java | 5 +- tajo-client/src/main/proto/ClientProtos.proto | 2 +- .../exception/NotImplementedException.java | 49 ------ .../apache/tajo/exception/ErrorMessages.java | 48 +++-- .../org/apache/tajo/exception/ErrorUtil.java | 10 +- .../apache/tajo/exception/ExceptionUtil.java | 28 +++ .../org/apache/tajo/exception/TajoError.java | 10 ++ .../tajo/exception/TajoInternalError.java | 14 +- .../exception/UndefinedOperatorException.java | 28 +++ .../exception/UnimplementedException.java | 18 +- .../tajo/exception/UnsupportedException.java | 19 +- tajo-common/src/main/proto/errors.proto | 107 ++++++----- .../org/apache/tajo/master/GlobalEngine.java | 25 ++- .../tajo/master/TajoMasterClientService.java | 16 +- .../apache/tajo/master/exec/DDLExecutor.java | 23 +-- .../tajo/master/rm/TajoResourceTracker.java | 2 - .../org/apache/tajo/QueryTestCaseBase.java | 8 +- .../apache/tajo/engine/eval/ExprTestBase.java | 12 +- .../tajo/engine/eval/TestSQLExpression.java | 8 +- .../function/TestConditionalExpressions.java | 10 +- .../org/apache/tajo/plan/ExprAnnotator.java | 49 +++--- .../org/apache/tajo/plan/ExprNormalizer.java | 4 +- .../tajo/plan/LogicalPlanPreprocessor.java | 6 +- .../apache/tajo/plan/PlanningException.java | 12 +- .../org/apache/tajo/plan/TypeDeterminant.java | 10 +- .../tajo/plan/expr/GeneralFunctionEval.java | 6 +- .../tajo/plan/nameresolver/NameResolver.java | 8 +- .../ResolverByRelsAndSubExprs.java | 4 +- .../rules/PartitionedTableRewriter.java | 2 +- .../plan/serder/EvalNodeDeserializer.java | 12 +- .../tajo/plan/verifier/ExprsVerifier.java | 12 +- .../plan/verifier/LogicalPlanVerifier.java | 29 +-- .../plan/verifier/PreLogicalPlanVerifier.java | 39 ++-- .../plan/verifier/SyntaxErrorException.java | 29 +++ .../tajo/plan/verifier/SyntaxErrorUtil.java | 54 ++++++ .../tajo/plan/verifier/VerificationState.java | 16 +- .../storage/json/JsonLineDeserializer.java | 7 +- .../tajo/storage/json/JsonLineSerializer.java | 5 +- .../storage/text/DelimitedLineReader.java | 4 +- 73 files changed, 943 insertions(+), 776 deletions(-) delete mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java delete mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsPartitionException.java delete mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{AlreadyExistsFieldException.java => DuplicateColumnException.java} (81%) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{AlreadyExistsDatabaseException.java => DuplicateDatabaseException.java} (78%) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{AlreadyExistsFunctionException.java => DuplicateFunctionException.java} (81%) create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateIndexException.java create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicatePartitionException.java create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTableException.java rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{AlreadyExistsTablespaceException.java => DuplicateTablespaceException.java} (77%) delete mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchColumnException.java delete mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchPartitionException.java create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{NoSuchDatabaseException.java => UndefinedColumnException.java} (80%) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{NoSuchTablespaceException.java => UndefinedDatabaseException.java} (80%) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{NoSuchFunctionException.java => UndefinedFunctionException.java} (57%) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{NoSuchIndexException.java => UndefinedIndexException.java} (71%) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{ColumnNameAlreadyExistException.java => UndefinedPartitionException.java} (73%) create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{NoSuchTableException.java => UndefinedTbleException.java} (70%) delete mode 100644 tajo-common/src/main/java/org/apache/tajo/common/exception/NotImplementedException.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java create mode 100644 tajo-common/src/main/java/org/apache/tajo/exception/UndefinedOperatorException.java create mode 100644 tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorException.java create mode 100644 tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index 766f6c2627..a628199a2f 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.*; @@ -578,21 +578,21 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT try { CatalogProtocolService.BlockingInterface stub = getStub(); descProto = stub.getFunctionMeta(null, builder.build()); - } catch (NoSuchFunctionException e) { + } catch (UndefinedFunctionException e) { LOG.debug(e.getMessage()); } catch (ServiceException e) { LOG.error(e.getMessage(), e); } if (descProto == null) { - throw new NoSuchFunctionException(signature, paramTypes); + throw new UndefinedFunctionException(signature, paramTypes); } try { return new FunctionDesc(descProto); } catch (ClassNotFoundException e) { LOG.error(e, e); - throw new NoSuchFunctionException(signature, paramTypes); + throw new UndefinedFunctionException(signature, paramTypes); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java index 80c4d833ad..424861b1bf 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java @@ -24,7 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tajo.catalog.SchemaUtil.ColumnVisitor; -import org.apache.tajo.catalog.exception.AlreadyExistsFieldException; +import org.apache.tajo.catalog.exception.DuplicateColumnException; import org.apache.tajo.catalog.json.CatalogGsonHelper; import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto; import org.apache.tajo.catalog.proto.CatalogProtos.SchemaProto; @@ -420,7 +420,7 @@ public synchronized Schema addColumn(String name, TypeDesc typeDesc) { String normalized = name; if(fieldsByQualifiedName.containsKey(normalized)) { LOG.error("Already exists column " + normalized); - throw new AlreadyExistsFieldException(normalized); + throw new DuplicateColumnException(normalized); } Column newCol = new Column(normalized, typeDesc); diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java deleted file mode 100644 index 22c8172231..0000000000 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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.catalog.exception; - -import org.apache.tajo.annotation.Nullable; - -public class AlreadyExistsIndexException extends CatalogException { - private static final long serialVersionUID = 3705839985189534673L; - - /** - * - */ - public AlreadyExistsIndexException() { - } - - public AlreadyExistsIndexException(String databaseName, @Nullable String namespace, String indexName) { - super(String.format("index \" %s \" already exists in %s.%s", indexName, databaseName, namespace)); - } - - public AlreadyExistsIndexException(String indexName) { - super("index \"" + indexName + "\" exists table"); - } -} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsPartitionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsPartitionException.java deleted file mode 100644 index ab6144f26a..0000000000 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsPartitionException.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 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.catalog.exception; - -public class AlreadyExistsPartitionException extends RuntimeException { - - private static final long serialVersionUID = 277182608283894930L; - - public AlreadyExistsPartitionException(String message) { - super(message); - } - - public AlreadyExistsPartitionException(String databaseName, String tableName, String partitionName) { - super(String.format("ERROR: \"%s already exist in \"%s.%s\"", partitionName, databaseName, tableName)); - } - -} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java deleted file mode 100644 index ec4cf67d56..0000000000 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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.catalog.exception; - - -public class AlreadyExistsTableException extends CatalogException { - private static final long serialVersionUID = -641623770742392865L; - - public AlreadyExistsTableException() { - } - - public AlreadyExistsTableException(String databaseName, String relName) { - super(String.format("relation \" %s \" already exists in %s", relName, databaseName)); - } - - public AlreadyExistsTableException(String tableName) { - super("relation \"" + tableName + "\" exists table"); - } -} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java index 760bb71df3..7098800541 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java @@ -18,34 +18,13 @@ package org.apache.tajo.catalog.exception; -public class CatalogException extends RuntimeException { - private static final long serialVersionUID = -26362412527118618L; - - /** - * - */ - public CatalogException() { - } +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.TajoRuntimeException; - /** - * @param message - */ - public CatalogException(String message) { - super(message); - } - - /** - * @param cause - */ - public CatalogException(Throwable cause) { - super(cause); - } +public class CatalogException extends TajoRuntimeException { + private static final long serialVersionUID = -26362412527118618L; - /** - * @param message - * @param cause - */ - public CatalogException(String message, Throwable cause) { - super(message, cause); + public CatalogException(ResultCode code, String...args) { + super(code, args); } } \ No newline at end of file diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java new file mode 100644 index 0000000000..ce967050a7 --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java @@ -0,0 +1,59 @@ +/* + * 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.catalog.exception; + +import org.apache.tajo.common.TajoDataTypes; +import org.apache.tajo.error.Errors; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.function.FunctionUtil; + +import java.util.Collection; + +public class CatalogExceptionUtil { + + public static CatalogException makeUndefinedDatabase(String dbName) { + return new CatalogException(ResultCode.UNDEFINED_DATABASE, dbName); + } + + public static CatalogException makeUndefinedFunction(String signature) { + return new CatalogException(ResultCode.UNDEFINED_FUNCTION, signature); + } + + public static CatalogException makeUndefinedFunction(String funcName, TajoDataTypes.DataType[] parameters) { + return new CatalogException(ResultCode.UNDEFINED_FUNCTION, + FunctionUtil.buildSimpleFunctionSignature(funcName, parameters)); + } + + public static CatalogException makeUndefinedFunction(String funcName, Collection parameters) { + return new CatalogException( + ResultCode.UNDEFINED_FUNCTION, FunctionUtil.buildSimpleFunctionSignature(funcName, parameters)); + } + + public static CatalogException makeUndefinedTable(String tbName) { + return new CatalogException(ResultCode.UNDEFINED_TABLE, tbName); + } + + public static CatalogException makeDuplicateTable(String tbName) { + return new CatalogException(ResultCode.DUPLICATE_TABLE, tbName); + } + + public static CatalogException makeCatalogUpgrade() { + return new CatalogException(ResultCode.CAT_UPGRADE_REQUIRED); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateColumnException.java similarity index 81% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateColumnException.java index ee90278129..121a289228 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateColumnException.java @@ -18,13 +18,12 @@ package org.apache.tajo.catalog.exception; -public class AlreadyExistsFieldException extends CatalogException { - private static final long serialVersionUID = 6766228091940775275L; +import org.apache.tajo.error.Errors; - public AlreadyExistsFieldException() { - } +public class DuplicateColumnException extends CatalogException { + private static final long serialVersionUID = 6766228091940775275L; - public AlreadyExistsFieldException(String fieldName) { - super("Already Exists Field: "+fieldName); + public DuplicateColumnException(String columnName) { + super(Errors.ResultCode.DUPLICATE_COLUMN, columnName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsDatabaseException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateDatabaseException.java similarity index 78% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsDatabaseException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateDatabaseException.java index f811689784..69e37d323b 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsDatabaseException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateDatabaseException.java @@ -19,12 +19,10 @@ package org.apache.tajo.catalog.exception; -public class AlreadyExistsDatabaseException extends CatalogException { +import org.apache.tajo.error.Errors; - public AlreadyExistsDatabaseException() { - } - - public AlreadyExistsDatabaseException(String dbName) { - super(String.format("Already exists database \"%s\"", dbName)); +public class DuplicateDatabaseException extends CatalogException { + public DuplicateDatabaseException(String dbName) { + super(Errors.ResultCode.DUPLICATE_DATABASE, dbName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java similarity index 81% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java index 4bf70ae7c6..4daa7c711b 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java @@ -18,10 +18,12 @@ package org.apache.tajo.catalog.exception; -public class AlreadyExistsFunctionException extends CatalogException { +import org.apache.tajo.error.Errors; + +public class DuplicateFunctionException extends CatalogException { private static final long serialVersionUID = 3224521585413794703L; - public AlreadyExistsFunctionException(String funcName) { - super("Already Exists Function: "+funcName); + public DuplicateFunctionException(String funcName) { + super(Errors.ResultCode.DUPLICATE_FUNCTION, funcName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateIndexException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateIndexException.java new file mode 100644 index 0000000000..c510b162a0 --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateIndexException.java @@ -0,0 +1,29 @@ +/** + * 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.catalog.exception; + +import org.apache.tajo.error.Errors; + +public class DuplicateIndexException extends CatalogException { + private static final long serialVersionUID = 3705839985189534673L; + + public DuplicateIndexException(String indexName) { + super(Errors.ResultCode.DUPLICATE_INDEX, indexName); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicatePartitionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicatePartitionException.java new file mode 100644 index 0000000000..bdec4fc148 --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicatePartitionException.java @@ -0,0 +1,30 @@ +/** + * 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.catalog.exception; + +import org.apache.tajo.error.Errors; + +public class DuplicatePartitionException extends CatalogException { + private static final long serialVersionUID = 277182608283894930L; + + public DuplicatePartitionException(String partitionName) { + super(Errors.ResultCode.DUPLICATE_PARTITION, partitionName); + } + +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTableException.java new file mode 100644 index 0000000000..74fa39fb2d --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTableException.java @@ -0,0 +1,30 @@ +/** + * 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.catalog.exception; + + +import org.apache.tajo.error.Errors; + +public class DuplicateTableException extends CatalogException { + private static final long serialVersionUID = -641623770742392865L; + + public DuplicateTableException(String relName) { + super(Errors.ResultCode.DUPLICATE_TABLE, relName); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTablespaceException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTablespaceException.java similarity index 77% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTablespaceException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTablespaceException.java index 49c5bf9203..2e03e3c422 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTablespaceException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateTablespaceException.java @@ -19,12 +19,10 @@ package org.apache.tajo.catalog.exception; -public class AlreadyExistsTablespaceException extends CatalogException { +import org.apache.tajo.error.Errors; - public AlreadyExistsTablespaceException() { - } - - public AlreadyExistsTablespaceException(String dbName) { - super(String.format("Already exists tablespace \"%s\"", dbName)); +public class DuplicateTablespaceException extends CatalogException { + public DuplicateTablespaceException(String spaceName) { + super(Errors.ResultCode.DUPLICATE_TABLESPACE, spaceName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java index faa8bc407a..62cc9a8c4b 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java @@ -20,8 +20,6 @@ public class NoPartitionedTableException extends Exception { - public NoPartitionedTableException() {} - public NoPartitionedTableException(String databaseName, String relName) { super(String.format("ERROR: \"%s.%s\" is not a partitioned table", databaseName, relName)); } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchColumnException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchColumnException.java deleted file mode 100644 index 4af3f70db8..0000000000 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchColumnException.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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.catalog.exception; - - -public class NoSuchColumnException extends CatalogException { - private static final long serialVersionUID = 277182608283894937L; - - public NoSuchColumnException() {} - - public NoSuchColumnException(String databaseName, String relName, String columnName) { - super(String.format("ERROR: column \" %s.%s \" in %s does not exist", relName, columnName, databaseName)); - } - - public NoSuchColumnException(String columnName) { - super("ERROR: column \"" + columnName + "\" does not exist"); - } -} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchPartitionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchPartitionException.java deleted file mode 100644 index 45c92990bf..0000000000 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchPartitionException.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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.catalog.exception; - -import org.apache.tajo.common.TajoDataTypes; -import org.apache.tajo.function.FunctionUtil; -import org.codehaus.jackson.schema.JsonSerializableSchema; - -import java.util.Collection; - -public class NoSuchPartitionException extends RuntimeException { - - private static final long serialVersionUID = 277182608283894938L; - - public NoSuchPartitionException(String message) { - super(message); - } - - public NoSuchPartitionException(String databaseName, String tableName, String partitionName) { - super(String.format("ERROR: \"%s\" does not exist in \"%s.%s\".", partitionName, databaseName, tableName)); - } - -} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java new file mode 100644 index 0000000000..b3a536e5fb --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java @@ -0,0 +1,32 @@ +/* + * 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.catalog.exception; + +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.TajoError; + +/** + * Tajo Metadata Connector's connection error + */ +public class TMCConnectionException extends TajoError { + + public TMCConnectionException(String uri, Throwable t) { + super(ResultCode.CAT_CANNOT_CONNECT, t, uri, t.getMessage()); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchDatabaseException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedColumnException.java similarity index 80% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchDatabaseException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedColumnException.java index 757cad5f77..43b74104d7 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchDatabaseException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedColumnException.java @@ -19,12 +19,12 @@ package org.apache.tajo.catalog.exception; -public class NoSuchDatabaseException extends CatalogException { - private static final long serialVersionUID = 277182608283894937L; +import org.apache.tajo.error.Errors.ResultCode; - public NoSuchDatabaseException() {} +public class UndefinedColumnException extends CatalogException { + private static final long serialVersionUID = 277182608283894937L; - public NoSuchDatabaseException(String databaseName) { - super("ERROR: database \"" + databaseName + "\" does not exist"); + public UndefinedColumnException(String columnName) { + super(ResultCode.UNDEFINED_COLUMN, columnName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTablespaceException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedDatabaseException.java similarity index 80% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTablespaceException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedDatabaseException.java index 8b7d80beb6..8294addf15 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTablespaceException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedDatabaseException.java @@ -18,12 +18,13 @@ package org.apache.tajo.catalog.exception; -public class NoSuchTablespaceException extends CatalogException { - private static final long serialVersionUID = 277182608283894937L; - public NoSuchTablespaceException() {} +import org.apache.tajo.error.Errors; + +public class UndefinedDatabaseException extends CatalogException { + private static final long serialVersionUID = 277182608283894937L; - public NoSuchTablespaceException(String spaceName) { - super("ERROR: tablespace \"" + spaceName + "\" does not exist"); + public UndefinedDatabaseException(String dbName) { + super(Errors.ResultCode.UNDEFINED_DATABASE, dbName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedFunctionException.java similarity index 57% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedFunctionException.java index e91e41da7b..175b59751b 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedFunctionException.java @@ -19,22 +19,26 @@ package org.apache.tajo.catalog.exception; import org.apache.tajo.common.TajoDataTypes; +import org.apache.tajo.error.Errors; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.TajoRuntimeException; import org.apache.tajo.function.FunctionUtil; import java.util.Collection; -public class NoSuchFunctionException extends RuntimeException { +public class UndefinedFunctionException extends CatalogException { private static final long serialVersionUID = 5062193018697228028L; - public NoSuchFunctionException(String message) { - super(message); + public UndefinedFunctionException(String signature) { + super(ResultCode.UNDEFINED_FUNCTION, signature); } - public NoSuchFunctionException(String funcName, TajoDataTypes.DataType [] parameters) { - super("function " + FunctionUtil.buildSimpleFunctionSignature(funcName, parameters) + " does not exist"); + public UndefinedFunctionException(String funcName, TajoDataTypes.DataType[] parameters) { + super(ResultCode.UNDEFINED_FUNCTION, FunctionUtil.buildSimpleFunctionSignature(funcName, parameters)); } - public NoSuchFunctionException(String funcName, Collection parameters) { - super("function " + FunctionUtil.buildSimpleFunctionSignature(funcName, parameters) + " does not exist"); + public UndefinedFunctionException(String funcName, Collection parameters) { + super(ResultCode.UNDEFINED_FUNCTION, FunctionUtil.buildSimpleFunctionSignature(funcName, parameters)); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java similarity index 71% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java index 0bb7e32465..d228a40caf 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java @@ -18,17 +18,16 @@ package org.apache.tajo.catalog.exception; -public class NoSuchIndexException extends CatalogException { - private static final long serialVersionUID = 3705839985189534673L; +import org.apache.tajo.error.Errors.ResultCode; - public NoSuchIndexException() { - } +public class UndefinedIndexException extends CatalogException { + private static final long serialVersionUID = 3705839985189534673L; - public NoSuchIndexException(String databaseName, String columnName) { - super(String.format("ERROR: index \" %s \" in %s does not exist", columnName, databaseName)); + public UndefinedIndexException(String tableName, String columnName) { + super(ResultCode.UNDEFINED_INDEX, tableName, columnName); } - public NoSuchIndexException(String indexName) { - super("ERROR: index \"" + indexName + "\" does not exist"); + public UndefinedIndexException(String indexName) { + super(ResultCode.UNDEFINED_INDEX_NAME, indexName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedPartitionException.java similarity index 73% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedPartitionException.java index 1c026d7b44..282f0a22cc 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedPartitionException.java @@ -15,17 +15,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.tajo.catalog.exception; +package org.apache.tajo.catalog.exception; -public class ColumnNameAlreadyExistException extends CatalogException { +import org.apache.tajo.error.Errors.ResultCode; - private static final long serialVersionUID = -4863862140874083282L; +public class UndefinedPartitionException extends CatalogException { - public ColumnNameAlreadyExistException() { - } + private static final long serialVersionUID = 277182608283894938L; - public ColumnNameAlreadyExistException(String columnName) { - super("Column already exists : " + columnName); + public UndefinedPartitionException(String partitionName) { + super(ResultCode.UNDEFINED_PARTITION, partitionName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java new file mode 100644 index 0000000000..ab6282c1da --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java @@ -0,0 +1,29 @@ +/** + * 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.catalog.exception; + +import org.apache.tajo.error.Errors; + +public class UndefinedTablespaceException extends CatalogException { + private static final long serialVersionUID = 277182608283894937L; + + public UndefinedTablespaceException(String spaceName) { + super(Errors.ResultCode.UNDEFINED_PARTITION, spaceName); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTbleException.java similarity index 70% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTbleException.java index cc1144443b..1d3f2bac76 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTbleException.java @@ -19,16 +19,17 @@ package org.apache.tajo.catalog.exception; -public class NoSuchTableException extends CatalogException { - private static final long serialVersionUID = 277182608283894937L; +import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.error.Errors.ResultCode; - public NoSuchTableException() {} +public class UndefinedTbleException extends CatalogException { + private static final long serialVersionUID = 277182608283894937L; - public NoSuchTableException(String databaseName, String relName) { - super(String.format("ERROR: relation \" %s \" in %s does not exist", relName, databaseName)); + public UndefinedTbleException(String dbName, String tbName) { + super(ResultCode.UNDEFINED_TABLE, CatalogUtil.buildFQName(dbName, tbName)); } - public NoSuchTableException(String relName) { - super("ERROR: relation \"" + relName + "\" does not exist"); + public UndefinedTbleException(String relName) { + super(ResultCode.UNDEFINED_TABLE, relName); } } diff --git a/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestSchema.java b/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestSchema.java index edd0f3e5b1..cf1a24a19c 100644 --- a/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestSchema.java +++ b/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestSchema.java @@ -18,7 +18,7 @@ package org.apache.tajo.catalog; -import org.apache.tajo.catalog.exception.AlreadyExistsFieldException; +import org.apache.tajo.catalog.exception.DuplicateColumnException; import org.apache.tajo.catalog.json.CatalogGsonHelper; import org.apache.tajo.catalog.proto.CatalogProtos.SchemaProto; import org.apache.tajo.common.TajoDataTypes.Type; @@ -191,7 +191,7 @@ public final void testClone() throws CloneNotSupportedException { assertEquals(schema.size(), schema3.size()); } - @Test(expected = AlreadyExistsFieldException.class) + @Test(expected = DuplicateColumnException.class) public final void testAddExistColumn() { Schema schema = new Schema(); schema.addColumn("abc", Type.FLOAT8); diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java index 8f23db4c13..dcbc9dcee1 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java @@ -49,9 +49,10 @@ import org.apache.tajo.catalog.proto.CatalogProtos.TablespaceProto; import org.apache.tajo.catalog.statistics.TableStats; import org.apache.tajo.common.TajoDataTypes; -import org.apache.tajo.common.exception.NotImplementedException; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.exception.InternalException; +import org.apache.tajo.exception.TajoInternalError; +import org.apache.tajo.exception.UnsupportedException; import org.apache.tajo.storage.StorageConstants; import org.apache.tajo.util.KeyValueSet; import org.apache.thrift.TException; @@ -73,7 +74,7 @@ public class HiveCatalogStore extends CatalogConstants implements CatalogStore { public HiveCatalogStore(final Configuration conf) throws InternalException { if (!(conf instanceof TajoConf)) { - throw new CatalogException("Invalid Configuration Type:" + conf.getClass().getSimpleName()); + throw new TajoInternalError("Invalid Configuration Type:" + conf.getClass().getSimpleName()); } this.conf = conf; this.defaultTableSpaceUri = TajoConf.getWarehouseDir((TajoConf) conf).toString(); @@ -96,7 +97,7 @@ public boolean existTable(final String databaseName, final String tableName) thr } catch (NoSuchObjectException nsoe) { exist = false; } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -127,9 +128,9 @@ public final CatalogProtos.TableDescProto getTable(String databaseName, final St table = HiveCatalogUtil.getTable(client.getHiveClient(), databaseName, tableName); path = table.getPath(); } catch (NoSuchObjectException nsoe) { - throw new CatalogException("Table not found. - tableName:" + tableName, nsoe); + throw new UndefinedTbleException(tableName); } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } // convert HiveCatalogStore field schema into tajo field schema. @@ -221,7 +222,7 @@ public final CatalogProtos.TableDescProto getTable(String databaseName, final St totalSize = fs.getContentSummary(path).getLength(); } } catch (IOException ioe) { - throw new CatalogException("Fail to get path. - path:" + path.toString(), ioe); + throw new TajoInternalError(ioe); } } stats.setNumBytes(totalSize); @@ -288,7 +289,7 @@ public final List getAllTableNames(String databaseName) throws CatalogEx client = clientPool.getClient(); return client.getHiveClient().getAllTables(databaseName); } catch (TException e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if(client != null) client.release(); } @@ -323,7 +324,7 @@ public TablespaceProto getTablespace(String spaceName) throws CatalogException { builder.setUri(defaultTableSpaceUri); return builder.build(); } else { - throw new CatalogException("tablespace concept is not supported in HiveCatalogStore"); + throw new UnsupportedException("Tablespace in HiveMeta"); } } @@ -335,7 +336,7 @@ public void updateTableStats(CatalogProtos.UpdateTableStatsProto statsProto) thr @Override public void alterTablespace(CatalogProtos.AlterTablespaceProto alterProto) throws CatalogException { - throw new CatalogException("tablespace concept is not supported in HiveCatalogStore"); + throw new UnsupportedException("Tablespace in HiveMeta"); } @Override @@ -351,9 +352,9 @@ public void createDatabase(String databaseName, String tablespaceName) throws Ca client = clientPool.getClient(); client.getHiveClient().createDatabase(database); } catch (AlreadyExistsException e) { - throw new AlreadyExistsDatabaseException(databaseName); + throw new DuplicateDatabaseException(databaseName); } catch (Throwable t) { - throw new CatalogException(t); + throw new TajoInternalError(t); } finally { if (client != null) { client.release(); @@ -370,7 +371,7 @@ public boolean existDatabase(String databaseName) throws CatalogException { List databaseNames = client.getHiveClient().getAllDatabases(); return databaseNames.contains(databaseName); } catch (Throwable t) { - throw new CatalogException(t); + throw new TajoInternalError(t); } finally { if (client != null) { client.release(); @@ -386,9 +387,9 @@ public void dropDatabase(String databaseName) throws CatalogException { client = clientPool.getClient(); client.getHiveClient().dropDatabase(databaseName); } catch (NoSuchObjectException e) { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } catch (Throwable t) { - throw new CatalogException(databaseName); + throw new TajoInternalError(t); } finally { if (client != null) { client.release(); @@ -404,7 +405,7 @@ public Collection getAllDatabaseNames() throws CatalogException { client = clientPool.getClient(); return client.getHiveClient().getAllDatabases(); } catch (TException e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -549,7 +550,7 @@ public final void createTable(final CatalogProtos.TableDescProto tableDescProto) sd.setOutputFormat(parquet.hive.DeprecatedParquetOutputFormat.class.getName()); sd.getSerdeInfo().setSerializationLib(parquet.hive.serde.ParquetHiveSerDe.class.getName()); } else { - throw new CatalogException(new NotImplementedException(tableDesc.getMeta().getStoreType())); + throw new UnsupportedException(tableDesc.getMeta().getStoreType() + " in HivecatalogStore"); } } @@ -557,10 +558,8 @@ public final void createTable(final CatalogProtos.TableDescProto tableDescProto) table.setSd(sd); client.getHiveClient().createTable(table); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new CatalogException(e); + } catch (Throwable t) { + throw new TajoInternalError(t); } finally { if(client != null) client.release(); } @@ -575,7 +574,7 @@ public final void dropTable(String databaseName, final String tableName) throws client.getHiveClient().dropTable(databaseName, tableName, false, false); } catch (NoSuchObjectException nsoe) { } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -601,19 +600,19 @@ public void alterTable(final CatalogProtos.AlterTableDescProto alterTableDescPro switch (alterTableDescProto.getAlterTableType()) { case RENAME_TABLE: if (existTable(databaseName,alterTableDescProto.getNewTableName().toLowerCase())) { - throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName()); + throw new DuplicateTableException(alterTableDescProto.getNewTableName()); } renameTable(databaseName, tableName, alterTableDescProto.getNewTableName().toLowerCase()); break; case RENAME_COLUMN: if (existColumn(databaseName,tableName, alterTableDescProto.getAlterColumnName().getNewColumnName())) { - throw new ColumnNameAlreadyExistException(alterTableDescProto.getAlterColumnName().getNewColumnName()); + throw new DuplicateColumnException(alterTableDescProto.getAlterColumnName().getNewColumnName()); } renameColumn(databaseName, tableName, alterTableDescProto.getAlterColumnName()); break; case ADD_COLUMN: if (existColumn(databaseName,tableName, alterTableDescProto.getAddColumn().getName())) { - throw new ColumnNameAlreadyExistException(alterTableDescProto.getAddColumn().getName()); + throw new DuplicateColumnException(alterTableDescProto.getAddColumn().getName()); } addNewColumn(databaseName, tableName, alterTableDescProto.getAddColumn()); break; @@ -621,7 +620,7 @@ public void alterTable(final CatalogProtos.AlterTableDescProto alterTableDescPro partitionName = alterTableDescProto.getPartitionDesc().getPartitionName(); partitionDesc = getPartition(databaseName, tableName, partitionName); if(partitionDesc != null) { - throw new AlreadyExistsPartitionException(databaseName, tableName, partitionName); + throw new DuplicatePartitionException(partitionName); } addPartition(databaseName, tableName, alterTableDescProto.getPartitionDesc()); break; @@ -629,7 +628,7 @@ public void alterTable(final CatalogProtos.AlterTableDescProto alterTableDescPro partitionName = alterTableDescProto.getPartitionDesc().getPartitionName(); partitionDesc = getPartition(databaseName, tableName, partitionName); if(partitionDesc == null) { - throw new NoSuchPartitionException(databaseName, tableName, partitionName); + throw new UndefinedPartitionException(partitionName); } dropPartition(databaseName, tableName, partitionDesc); break; @@ -652,7 +651,7 @@ private void renameTable(String databaseName, String tableName, String newTableN } catch (NoSuchObjectException nsoe) { } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -677,7 +676,7 @@ private void renameColumn(String databaseName, String tableName, CatalogProtos.A } catch (NoSuchObjectException nsoe) { } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -700,7 +699,7 @@ private void addNewColumn(String databaseName, String tableName, CatalogProtos.C } catch (NoSuchObjectException nsoe) { } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -732,7 +731,7 @@ private void addPartition(String databaseName, String tableName, CatalogProtos.P client.getHiveClient().add_partition(partition); } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -753,7 +752,7 @@ private void dropPartition(String databaseName, String tableName, CatalogProtos. } client.getHiveClient().dropPartition(databaseName, tableName, values, true); } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -817,7 +816,7 @@ public CatalogProtos.PartitionDescProto getPartition(String databaseName, String } catch (NoSuchObjectException e) { return null; } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); @@ -912,7 +911,7 @@ private boolean existColumn(final String databaseName ,final String tableName , } catch (NoSuchObjectException nsoe) { } catch (Exception e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { if (client != null) { client.release(); diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java index f2e9795537..18eec78f8a 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java @@ -40,6 +40,9 @@ import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; +import org.apache.tajo.error.Errors; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.rpc.BlockingRpcServer; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; @@ -123,7 +126,7 @@ public void serviceInit(Configuration conf) throws Exception { if (conf instanceof TajoConf) { this.conf = (TajoConf) conf; } else { - throw new CatalogException("conf must be a TajoConf instance"); + throw new TajoInternalError("conf must be a TajoConf instance"); } Class storeClass = this.conf.getClass(CatalogConstants.STORE_CLASS, DerbyStore.class); @@ -137,7 +140,7 @@ public void serviceInit(Configuration conf) throws Exception { initBuiltinFunctions(builtingFuncs); } catch (Throwable t) { LOG.error("CatalogServer initialization failed", t); - throw new CatalogException(t); + throw new TajoInternalError(t); } super.serviceInit(conf); @@ -185,7 +188,7 @@ public void start() { conf.setVar(ConfVars.CATALOG_ADDRESS, bindAddressStr); } catch (Exception e) { LOG.error("CatalogServer startup failed", e); - throw new CatalogException(e); + throw new TajoInternalError(e); } LOG.info("Catalog Server startup (" + bindAddressStr + ")"); @@ -228,7 +231,7 @@ public BoolProto createTablespace(RpcController controller, CreateTablespaceRequ wlock.lock(); try { if (store.existTablespace(tablespaceName)) { - throw new AlreadyExistsDatabaseException(tablespaceName); + throw new DuplicateDatabaseException(tablespaceName); } store.createTablespace(tablespaceName, uri); @@ -250,11 +253,11 @@ public BoolProto dropTablespace(RpcController controller, StringProto request) t wlock.lock(); try { if (tablespaceName.equals(TajoConstants.DEFAULT_TABLESPACE_NAME)) { - throw new CatalogException("default tablespace cannot be dropped."); + throw new CatalogException(ResultCode.INSUFFICIENT_PRIVILEGE, "drop to default tablespace"); } if (!store.existTablespace(tablespaceName)) { - throw new NoSuchTablespaceException(tablespaceName); + throw new UndefinedTablespaceException(tablespaceName); } store.dropTablespace(tablespaceName); @@ -330,7 +333,7 @@ public BoolProto alterTablespace(RpcController controller, AlterTablespaceProto wlock.lock(); try { if (!store.existTablespace(request.getSpaceName())) { - throw new NoSuchTablespaceException(request.getSpaceName()); + throw new UndefinedTablespaceException(request.getSpaceName()); } if (request.getCommandList().size() > 0) { @@ -369,7 +372,7 @@ public BoolProto createDatabase(RpcController controller, CreateDatabaseRequest wlock.lock(); try { if (store.existDatabase(databaseName)) { - throw new AlreadyExistsDatabaseException(databaseName); + throw new DuplicateDatabaseException(databaseName); } store.createDatabase(databaseName, tablespaceName); @@ -390,7 +393,7 @@ public BoolProto updateTableStats(RpcController controller, UpdateTableStatsProt try { String [] split = CatalogUtil.splitTableName(proto.getTableName()); if (!store.existTable(split[0], split[1])) { - throw new NoSuchTableException(proto.getTableName()); + throw new UndefinedTbleException(proto.getTableName()); } store.updateTableStats(proto); } catch (Exception e) { @@ -415,7 +418,7 @@ public BoolProto alterTable(RpcController controller, AlterTableDescProto proto) wlock.lock(); try { if (!store.existTable(split[0], split[1])) { - throw new NoSuchTableException(proto.getTableName()); + throw new UndefinedTbleException(proto.getTableName()); } store.alterTable(proto); } catch (Exception e) { @@ -440,7 +443,7 @@ public BoolProto dropDatabase(RpcController controller, StringProto request) thr wlock.lock(); try { if (!store.existDatabase(databaseName)) { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } store.dropDatabase(databaseName); @@ -525,10 +528,10 @@ public TableDescProto getTableDesc(RpcController controller, if (contain) { return store.getTable(databaseName, tableName); } else { - throw new NoSuchTableException(tableName); + throw new UndefinedTbleException(tableName); } } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -553,7 +556,7 @@ public StringListProto getAllTableNames(RpcController controller, StringProto re if (store.existDatabase(databaseName)) { return ProtoUtil.convertStrings(store.getAllTableNames(databaseName)); } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -596,14 +599,14 @@ public BoolProto createTable(RpcController controller, TableDescProto request)th if (contain) { if (store.existTable(databaseName, tableName)) { - throw new AlreadyExistsTableException(databaseName, tableName); + throw new DuplicateTableException(tableName); } store.createTable(request); LOG.info(String.format("relation \"%s\" is added to the catalog (%s)", CatalogUtil.getCanonicalTableName(databaseName, tableName), bindAddressStr)); } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e.getMessage(), e); @@ -631,14 +634,14 @@ public BoolProto dropTable(RpcController controller, TableIdentifierProto reques if (contain) { if (!store.existTable(databaseName, tableName)) { - throw new NoSuchTableException(databaseName, tableName); + throw new UndefinedTbleException(databaseName, tableName); } store.dropTable(databaseName, tableName); LOG.info(String.format("relation \"%s\" is deleted from the catalog (%s)", CatalogUtil.getCanonicalTableName(databaseName, tableName), bindAddressStr)); } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e.getMessage(), e); @@ -669,7 +672,7 @@ public BoolProto existsTable(RpcController controller, TableIdentifierProto requ return BOOL_FALSE; } } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -761,10 +764,10 @@ public PartitionMethodProto getPartitionMethodByTableName(RpcController controll throw new NoPartitionedTableException(databaseName, tableName); } } else { - throw new NoSuchTableException(databaseName); + throw new UndefinedTbleException(databaseName); } } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -799,10 +802,10 @@ public BoolProto existPartitionMethod(RpcController controller, TableIdentifierP return ProtoUtil.FALSE; } } else { - throw new NoSuchTableException(databaseName); + throw new UndefinedTbleException(databaseName); } } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -842,16 +845,16 @@ public PartitionDescProto getPartitionByPartitionName(RpcController controller, if (partitionDesc != null) { return partitionDesc; } else { - throw new NoSuchPartitionException(databaseName, tableName, partitionName); + throw new UndefinedPartitionException(partitionName); } } else { throw new NoPartitionedTableException(databaseName, tableName); } } else { - throw new NoSuchTableException(tableName); + throw new UndefinedTbleException(tableName); } } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -890,10 +893,10 @@ public PartitionsProto getPartitionsByTableName(RpcController controller, Partit throw new NoPartitionedTableException(databaseName, tableName); } } else { - throw new NoSuchTableException(tableName); + throw new UndefinedTbleException(tableName); } } else { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } catch (Exception e) { LOG.error(e); @@ -925,7 +928,7 @@ public BoolProto createIndex(RpcController controller, IndexDescProto indexDesc) if (store.existIndexByName( databaseName, indexDesc.getIndexName())) { - throw new AlreadyExistsIndexException(indexDesc.getIndexName()); + throw new DuplicateIndexException(indexDesc.getIndexName()); } store.createIndex(indexDesc); } catch (Exception e) { @@ -987,7 +990,7 @@ public IndexDescProto getIndexByName(RpcController controller, IndexNameProto re rlock.lock(); try { if (!store.existIndexByName(databaseName, indexName)) { - throw new NoSuchIndexException(databaseName, indexName); + throw new UndefinedIndexException(indexName); } return store.getIndexByName(databaseName, indexName); } catch (Exception e) { @@ -1010,7 +1013,7 @@ public IndexDescProto getIndexByColumn(RpcController controller, GetIndexByColum rlock.lock(); try { if (!store.existIndexByColumn(databaseName, tableName, columnName)) { - throw new NoSuchIndexException(databaseName, columnName); + throw new UndefinedIndexException(columnName); } return store.getIndexByColumn(databaseName, tableName, columnName); } catch (Exception e) { @@ -1031,7 +1034,7 @@ public BoolProto dropIndex(RpcController controller, IndexNameProto request) wlock.lock(); try { if (!store.existIndexByName(databaseName, indexName)) { - throw new NoSuchIndexException(indexName); + throw new UndefinedIndexException(indexName); } store.dropIndex(databaseName, indexName); } catch (Exception e) { @@ -1190,7 +1193,7 @@ public BoolProto createFunction(RpcController controller, FunctionDescProto func if (functions.containsKey(funcDesc.getSignature())) { FunctionDescProto found = findFunctionStrictType(funcDesc, true); if (found != null) { - throw new ServiceException(new AlreadyExistsFunctionException(signature.toString())); + throw new ServiceException(new DuplicateFunctionException(signature.toString())); } } @@ -1207,7 +1210,7 @@ public BoolProto dropFunction(RpcController controller, UnregisterFunctionReques throws ServiceException { if (!containFunction(request.getSignature())) { - throw new ServiceException(new NoSuchFunctionException(request.getSignature(), new DataType[]{})); + throw new ServiceException(new UndefinedFunctionException(request.getSignature(), new DataType[]{})); } functions.remove(request.getSignature()); @@ -1229,7 +1232,7 @@ public FunctionDescProto getFunctionMeta(RpcController controller, GetFunctionMe } if (function == null) { - throw new ServiceException(new NoSuchFunctionException(request.getSignature(), request.getParameterTypesList())); + throw new ServiceException(new UndefinedFunctionException(request.getSignature(), request.getParameterTypesList())); } else { return function; } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java index 8312e0e962..bf3d1036a0 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java @@ -22,7 +22,7 @@ import java.util.Collections; import java.util.List; -import org.apache.tajo.catalog.exception.NoSuchTableException; +import org.apache.tajo.catalog.exception.UndefinedTbleException; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.StoreType; import org.apache.tajo.util.TUtil; @@ -31,7 +31,7 @@ public class InfoSchemaMetadataDictionary { private static final String DATABASE_NAME = "information_schema"; - private static enum DEFINED_TABLES { + private enum DEFINED_TABLES { TABLESPACES, DATABASES, TABLES, @@ -43,7 +43,7 @@ private static enum DEFINED_TABLES { PARTITION_KEYS, CLUSTER, SESSION, - MAX_TABLE; + MAX_TABLE } private List schemaInfoTableDescriptors = new ArrayList( @@ -95,7 +95,7 @@ private TableDescriptor getTableDescriptor(String tableName) { TableDescriptor tableDescriptor = null; if (tableName == null || tableName.isEmpty()) { - throw new NoSuchTableException(tableName); + throw new UndefinedTbleException(tableName); } tableName = tableName.toUpperCase(); @@ -115,7 +115,7 @@ public CatalogProtos.TableDescProto getTableDesc(String tableName) { tableDescriptor = getTableDescriptor(tableName); if (tableDescriptor == null) { - throw new NoSuchTableException(DATABASE_NAME, tableName); + throw new UndefinedTbleException(DATABASE_NAME, tableName); } return tableDescriptor.getTableDescription(); diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java index 043c8bc03d..fc884d7d99 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java @@ -36,7 +36,7 @@ import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.common.TajoDataTypes.Type; import org.apache.tajo.exception.InternalException; -import org.apache.tajo.exception.UnimplementedException; +import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.util.FileUtil; import org.apache.tajo.util.Pair; import org.apache.tajo.util.TUtil; @@ -49,6 +49,7 @@ import java.sql.Statement; import java.util.*; +import static org.apache.tajo.catalog.exception.CatalogExceptionUtil.makeCatalogUpgrade; import static org.apache.tajo.catalog.proto.CatalogProtos.AlterTablespaceProto.AlterTablespaceCommand; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueProto; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueSetProto; @@ -128,7 +129,7 @@ public AbstractDBStore(Configuration conf) throws InternalException { Class.forName(getCatalogDriverName()).newInstance(); LOG.info("Loaded the Catalog driver (" + catalogDriver + ")"); } catch (Exception e) { - throw new CatalogException("Cannot load Catalog driver " + catalogDriver, e); + throw new TajoInternalError(e); } try { @@ -136,8 +137,7 @@ public AbstractDBStore(Configuration conf) throws InternalException { conn = createConnection(conf); LOG.info("Connected to database (" + catalogUri + ")"); } catch (SQLException e) { - throw new CatalogException("Cannot connect to database (" + catalogUri - + ")", e); + throw new TMCConnectionException(catalogUri , e); } String schemaPath = getCatalogSchemaPath(); @@ -168,7 +168,7 @@ public AbstractDBStore(Configuration conf) throws InternalException { } } } catch (Exception se) { - throw new CatalogException("Cannot initialize the persistent storage of Catalog", se); + throw new TajoInternalError(se); } } @@ -180,7 +180,7 @@ public String readSchemaFile(String path) throws CatalogException { try { return FileUtil.readTextFileFromResource("schemas/" + path); } catch (IOException e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } } @@ -232,7 +232,7 @@ private int getSchemaVersion() { schemaVersion = result.getInt("VERSION"); } } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } finally { CatalogUtil.closeQuietly(pstmt, result); } @@ -256,7 +256,7 @@ private void verifySchemaVersion() throws CatalogException { LOG.error("| In order to learn how to migration Apache Tajo instance, |"); LOG.error("| please refer http://tajo.apache.org/docs/current/backup_and_restore/catalog.html |"); LOG.error("========================================================================="); - throw new CatalogException("Migration Needed. Please refer http://s.apache.org/0_8_migration."); + throw makeCatalogUpgrade(); } LOG.info(String.format("The compatibility of the catalog schema (version: %d) has been verified.", @@ -267,7 +267,7 @@ private void verifySchemaVersion() throws CatalogException { * Insert the version of the current catalog schema */ protected void insertSchemaVersion() throws CatalogException { - Connection conn = null; + Connection conn; PreparedStatement pstmt = null; try { conn = getConnection(); @@ -275,7 +275,7 @@ protected void insertSchemaVersion() throws CatalogException { pstmt.setInt(1, getDriverVersion()); pstmt.executeUpdate(); } catch (SQLException se) { - throw new CatalogException("cannot insert catalog schema version", se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -310,7 +310,7 @@ public void createTablespace(String spaceName, String spaceUri) throws CatalogEx LOG.error(e, e); } } - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -336,7 +336,7 @@ public boolean existTablespace(String tableSpaceName) throws CatalogException { res = pstmt.executeQuery(); exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -374,7 +374,7 @@ public void dropTablespace(String tableSpaceName) throws CatalogException { LOG.error(e, e); } } - throw new CatalogException(String.format("Failed to drop tablespace \"%s\"", tableSpaceName), se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -406,7 +406,7 @@ private Collection getAllTablespaceNamesInternal(@Nullable String whereC tablespaceNames.add(resultSet.getString(1)); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, resultSet); } @@ -439,7 +439,7 @@ public List getTablespaces() throws CatalogException { return tablespaces; } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -459,7 +459,7 @@ public TablespaceProto getTablespace(String spaceName) throws CatalogException { resultSet = pstmt.executeQuery(); if (!resultSet.next()) { - throw new NoSuchTablespaceException(spaceName); + throw new UndefinedTablespaceException(spaceName); } String retrieveSpaceName = resultSet.getString("SPACE_NAME"); @@ -471,7 +471,7 @@ public TablespaceProto getTablespace(String spaceName) throws CatalogException { return builder.build(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, resultSet); } @@ -495,7 +495,7 @@ public void alterTablespace(AlterTablespaceProto alterProto) throws CatalogExcep pstmt.setString(2, alterProto.getSpaceName()); pstmt.executeUpdate(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -534,7 +534,7 @@ public void createDatabase(String databaseName, String tablespaceName) throws Ca LOG.error(e, e); } } - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -560,7 +560,7 @@ public boolean existDatabase(String databaseName) throws CatalogException { res = pstmt.executeQuery(); exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -595,7 +595,7 @@ public void dropDatabase(String databaseName) throws CatalogException { LOG.error(e, e); } } - throw new CatalogException(String.format("Failed to drop database \"%s\"", databaseName), se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -627,7 +627,7 @@ private Collection getAllDatabaseNamesInternal(@Nullable String whereCon databaseNames.add(resultSet.getString(1)); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, resultSet); } @@ -659,7 +659,7 @@ public List getAllDatabases() throws CatalogException { databases.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -703,11 +703,11 @@ private TableSpaceInternal getTableSpaceInfo(String spaceName) { pstmt.setString(1, spaceName); res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("ERROR: there is no SPACE_ID matched to the space name \"" + spaceName + "\""); + throw new TajoInternalError("There is no SPACE_ID matched to the space name '" + spaceName + "'"); } return new TableSpaceInternal(res.getInt(1), res.getString(2), res.getString(3)); } catch (SQLException se) { - throw new NoSuchTablespaceException(spaceName); + throw new UndefinedTablespaceException(spaceName); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -726,11 +726,11 @@ private int getTableId(int databaseId, String databaseName, String tableName) { pstmt.setString(2, tableName); res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("ERROR: there is no tid matched to " + tableName); + throw new TajoInternalError("There is no tid matched to '" + tableName + "'"); } return res.getInt(1); } catch (SQLException se) { - throw new NoSuchTableException(databaseName, tableName); + throw new UndefinedTbleException(databaseName, tableName); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -753,8 +753,8 @@ public void createTable(final CatalogProtos.TableDescProto table) throws Catalog String[] splitted = CatalogUtil.splitTableName(table.getTableName()); if (splitted.length == 1) { - throw new IllegalArgumentException("createTable() requires a qualified table name, but it is \"" - + table.getTableName() + "\"."); + throw new TajoInternalError( + "createTable() requires a qualified table name, but it is '" + table.getTableName() + "'"); } String databaseName = splitted[0]; String tableName = splitted[1]; @@ -789,7 +789,7 @@ public void createTable(final CatalogProtos.TableDescProto table) throws Catalog res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("ERROR: there is no TID matched to " + table.getTableName()); + throw new TajoInternalError("There is no TID matched to '" + table.getTableName() + '"'); } int tableId = res.getInt("TID"); @@ -885,7 +885,7 @@ public void createTable(final CatalogProtos.TableDescProto table) throws Catalog LOG.error(e, e); } } - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -920,7 +920,7 @@ public void updateTableStats(final CatalogProtos.UpdateTableStatsProto statsProt res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("ERROR: there is no TID matched to " + statsProto.getTableName()); + throw new TajoInternalError("There is no TID matched to '" + statsProto.getTableName() + "'"); } int tableId = res.getInt("TID"); @@ -953,7 +953,7 @@ public void updateTableStats(final CatalogProtos.UpdateTableStatsProto statsProt LOG.error(e, e); } } - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -979,19 +979,19 @@ public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) th switch (alterTableDescProto.getAlterTableType()) { case RENAME_TABLE: if (existTable(databaseName,alterTableDescProto.getNewTableName())) { - throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName()); + throw new DuplicateTableException(alterTableDescProto.getNewTableName()); } renameTable(tableId, alterTableDescProto.getNewTableName()); break; case RENAME_COLUMN: if (existColumn(tableId, alterTableDescProto.getAlterColumnName().getNewColumnName())) { - throw new ColumnNameAlreadyExistException(alterTableDescProto.getAlterColumnName().getNewColumnName()); + throw new DuplicateColumnException(alterTableDescProto.getAlterColumnName().getNewColumnName()); } renameColumn(tableId, alterTableDescProto.getAlterColumnName()); break; case ADD_COLUMN: if (existColumn(tableId, alterTableDescProto.getAddColumn().getName())) { - throw new ColumnNameAlreadyExistException(alterTableDescProto.getAddColumn().getName()); + throw new DuplicateColumnException(alterTableDescProto.getAddColumn().getName()); } addNewColumn(tableId, alterTableDescProto.getAddColumn()); break; @@ -999,7 +999,7 @@ public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) th partitionName = alterTableDescProto.getPartitionDesc().getPartitionName(); partitionDesc = getPartition(databaseName, tableName, partitionName); if(partitionDesc != null) { - throw new AlreadyExistsPartitionException(databaseName, tableName, partitionName); + throw new DuplicatePartitionException(partitionName); } addPartition(tableId, alterTableDescProto.getPartitionDesc()); break; @@ -1007,7 +1007,7 @@ public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) th partitionName = alterTableDescProto.getPartitionDesc().getPartitionName(); partitionDesc = getPartition(databaseName, tableName, partitionName); if(partitionDesc == null) { - throw new NoSuchPartitionException(databaseName, tableName, partitionName); + throw new UndefinedPartitionException(partitionName); } dropPartition(tableId, alterTableDescProto.getPartitionDesc().getPartitionName()); break; @@ -1017,7 +1017,7 @@ public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) th default: } } catch (SQLException sqlException) { - throw new CatalogException(sqlException); + throw new TajoInternalError(sqlException); } } @@ -1040,7 +1040,7 @@ private Map getTableOptions(final int tableId) throws CatalogExc options.put(res.getString("KEY_"), res.getString("VALUE_")); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -1084,8 +1084,8 @@ private void setProperties(final int tableId, final KeyValueSetProto properties) } conn.commit(); - } catch (SQLException sqlException) { - throw new CatalogException(sqlException); + } catch (Throwable sqlException) { + throw new TajoInternalError(sqlException); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -1110,8 +1110,8 @@ private void renameTable(final int tableId, final String tableName) throws Catal pstmt.setInt(2, tableId); pstmt.executeUpdate(); - } catch (SQLException sqlException) { - throw new CatalogException(sqlException); + } catch (SQLException se) { + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -1161,7 +1161,7 @@ private void renameColumn(final int tableId, final CatalogProtos.AlterColumnProt ordinalPosition = resultSet.getInt("ORDINAL_POSITION"); nestedFieldNum = resultSet.getInt("NESTED_FIELD_NUM"); } else { - throw new NoSuchColumnException(alterColumnProto.getOldColumnName()); + throw new UndefinedColumnException(alterColumnProto.getOldColumnName()); } resultSet.close(); @@ -1189,7 +1189,7 @@ private void renameColumn(final int tableId, final CatalogProtos.AlterColumnProt } catch (SQLException sqlException) { - throw new CatalogException(sqlException); + throw new TajoInternalError(sqlException); } finally { CatalogUtil.closeQuietly(pstmt,resultSet); } @@ -1237,7 +1237,7 @@ private void addNewColumn(int tableId, CatalogProtos.ColumnProto columnProto) th pstmt.executeUpdate(); } catch (SQLException sqlException) { - throw new CatalogException(sqlException); + throw new TajoInternalError(sqlException); } finally { CatalogUtil.closeQuietly(pstmt,resultSet); } @@ -1275,7 +1275,7 @@ public void addPartition(int tableId, CatalogProtos.PartitionDescProto partition pstmt.executeBatch(); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -1305,7 +1305,7 @@ public int getPartitionId(int tableId, String partitionName) throws CatalogExcep retValue = res.getInt(1); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -1352,7 +1352,7 @@ private void dropPartition(int tableId, String partitionName) throws CatalogExce pstmt.executeUpdate(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -1375,7 +1375,7 @@ private int getDatabaseId(String databaseName) throws SQLException { pstmt.setString(1, databaseName); res = pstmt.executeQuery(); if (!res.next()) { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } return res.getInt("DB_ID"); @@ -1408,7 +1408,7 @@ public boolean existTable(String databaseName, final String tableName) throws Ca res = pstmt.executeQuery(); exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -1548,7 +1548,7 @@ public Pair getDatabaseIdAndUri(String databaseName) throws SQL pstmt.setString(1, databaseName); res = pstmt.executeQuery(); if (!res.next()) { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } return new Pair(res.getInt(1), res.getString(2) + "/" + databaseName); @@ -1691,10 +1691,8 @@ public CatalogProtos.TableDescProto getTable(String databaseName, String tableNa if (res.next()) { tableBuilder.setPartition(resultToPartitionMethodProto(databaseName, tableName, res)); } - } catch (InvalidProtocolBufferException e) { - throw new CatalogException(e); - } catch (SQLException se) { - throw new CatalogException(se); + } catch (Throwable se) { + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -1737,7 +1735,7 @@ public List getAllTableNames(String databaseName) throws CatalogExceptio tables.add(res.getString(COL_TABLES_NAME).trim()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -1785,7 +1783,7 @@ public List getAllTables() throws CatalogException { tables.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -1820,7 +1818,7 @@ public List getAllTableOptions() throws CatalogException { options.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -1852,7 +1850,7 @@ public List getAllTableStats() throws CatalogException { stats.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -1898,7 +1896,7 @@ public List getAllColumns() throws CatalogException { columns.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -1933,7 +1931,7 @@ public void addPartitionMethod(CatalogProtos.PartitionMethodProto proto) throws pstmt.setBytes(4, proto.getExpressionSchema().toByteArray()); pstmt.executeUpdate(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -1959,7 +1957,7 @@ public void dropPartitionMethod(String databaseName, String tableName) throws Ca pstmt.setInt(1, tableId); pstmt.executeUpdate(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -1991,10 +1989,8 @@ public CatalogProtos.PartitionMethodProto getPartitionMethod(String databaseName if (res.next()) { return resultToPartitionMethodProto(databaseName, tableName, res); } - } catch (InvalidProtocolBufferException e) { - throw new CatalogException(e); - } catch (SQLException se) { - throw new CatalogException(se); + } catch (Throwable se) { + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2026,7 +2022,7 @@ public boolean existPartitionMethod(String databaseName, String tableName) throw exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2067,7 +2063,7 @@ public CatalogProtos.PartitionDescProto getPartition(String databaseName, String return null; } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2096,7 +2092,7 @@ private void setPartitionKeys(int pid, PartitionDescProto.Builder partitionDesc) partitionDesc.addPartitionKeys(builder); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2134,7 +2130,7 @@ public List getPartitions(String databaseName, String tableN partitions.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2167,7 +2163,7 @@ public List getAllPartitions() throws CatalogException { partitions.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -2214,7 +2210,7 @@ public void createIndex(final IndexDescProto proto) throws CatalogException { pstmt.executeUpdate(); conn.commit(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -2239,7 +2235,7 @@ public void dropIndex(String databaseName, final String indexName) throws Catalo pstmt.setString(2, indexName); pstmt.executeUpdate(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt); } @@ -2255,7 +2251,7 @@ public static String getTableName(Connection conn, int tableId) throws SQLExcept pstmt.setInt(1, tableId); res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("Cannot get any table name from TID"); + throw new TajoInternalError("Cannot get any table name from TID"); } return res.getString(1); } finally { @@ -2291,7 +2287,7 @@ public IndexDescProto getIndexByName(String databaseName, final String indexName pstmt.setString(2, indexName); res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("ERROR: there is no index matched to " + indexName); + throw new TajoInternalError("There is no index matched to " + indexName); } IndexDescProto.Builder builder = IndexDescProto.newBuilder(); resultToIndexDescProtoBuilder(builder, res); @@ -2299,7 +2295,7 @@ public IndexDescProto getIndexByName(String databaseName, final String indexName builder.setTableIdentifier(CatalogUtil.buildTableIdentifier(databaseName, tableName)); proto = builder.build(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2332,14 +2328,14 @@ public IndexDescProto getIndexByColumn(final String databaseName, pstmt.setString(2, columnName); res = pstmt.executeQuery(); if (!res.next()) { - throw new CatalogException("ERROR: there is no index matched to " + columnName); + throw new TajoInternalError("ERROR: there is no index matched to " + columnName); } IndexDescProto.Builder builder = IndexDescProto.newBuilder(); resultToIndexDescProtoBuilder(builder, res); builder.setTableIdentifier(CatalogUtil.buildTableIdentifier(databaseName, tableName)); proto = builder.build(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2372,7 +2368,7 @@ public boolean existIndexByName(String databaseName, final String indexName) thr res = pstmt.executeQuery(); exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2406,7 +2402,7 @@ public boolean existIndexByColumn(String databaseName, String tableName, String res = pstmt.executeQuery(); exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2447,7 +2443,7 @@ public IndexDescProto[] getIndexes(String databaseName, final String tableName) protos.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } @@ -2486,7 +2482,7 @@ public List getAllIndexes() throws CatalogException { indexes.add(builder.build()); } } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(stmt, resultSet); } @@ -2620,7 +2616,7 @@ private boolean existColumn(final int tableId, final String columnName) throws C res = pstmt.executeQuery(); exist = res.next(); } catch (SQLException se) { - throw new CatalogException(se); + throw new TajoInternalError(se); } finally { CatalogUtil.closeQuietly(pstmt, res); } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/DerbyStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/DerbyStore.java index c209ce5fb3..d9ec3d357b 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/DerbyStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/DerbyStore.java @@ -25,6 +25,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.exception.CatalogException; import org.apache.tajo.exception.InternalException; +import org.apache.tajo.exception.TajoInternalError; import java.sql.*; @@ -80,7 +81,7 @@ protected void createDatabaseDependants() throws CatalogException { stmt = getConnection().createStatement(); stmt.executeUpdate("CREATE SCHEMA " + schemaName); } catch (SQLException e) { - throw new CatalogException(e); + throw new TajoInternalError(e); } finally { CatalogUtil.closeQuietly(stmt); } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java index 55c43367a4..2697ab2839 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java @@ -76,7 +76,7 @@ public void close() throws IOException { @Override public void createTablespace(String spaceName, String spaceUri) throws CatalogException { if (tablespaces.containsKey(spaceName)) { - throw new AlreadyExistsTablespaceException(spaceName); + throw new DuplicateTablespaceException(spaceName); } tablespaces.put(spaceName, spaceUri); @@ -90,7 +90,7 @@ public boolean existTablespace(String spaceName) throws CatalogException { @Override public void dropTablespace(String spaceName) throws CatalogException { if (!tablespaces.containsKey(spaceName)) { - throw new NoSuchTablespaceException(spaceName); + throw new UndefinedTablespaceException(spaceName); } tablespaces.remove(spaceName); } @@ -119,7 +119,7 @@ public List getTablespaces() throws CatalogException { @Override public TablespaceProto getTablespace(String spaceName) throws CatalogException { if (!tablespaces.containsKey(spaceName)) { - throw new NoSuchTablespaceException(spaceName); + throw new UndefinedTablespaceException(spaceName); } TablespaceProto.Builder builder = TablespaceProto.newBuilder(); @@ -131,7 +131,7 @@ public TablespaceProto getTablespace(String spaceName) throws CatalogException { @Override public void alterTablespace(CatalogProtos.AlterTablespaceProto alterProto) throws CatalogException { if (!tablespaces.containsKey(alterProto.getSpaceName())) { - throw new NoSuchTablespaceException(alterProto.getSpaceName()); + throw new UndefinedTablespaceException(alterProto.getSpaceName()); } if (alterProto.getCommandList().size() > 0) { @@ -147,7 +147,7 @@ public void alterTablespace(CatalogProtos.AlterTablespaceProto alterProto) throw @Override public void createDatabase(String databaseName, String tablespaceName) throws CatalogException { if (databases.containsKey(databaseName)) { - throw new AlreadyExistsDatabaseException(databaseName); + throw new DuplicateDatabaseException(databaseName); } databases.put(databaseName, new HashMap()); @@ -161,7 +161,7 @@ public boolean existDatabase(String databaseName) throws CatalogException { @Override public void dropDatabase(String databaseName) throws CatalogException { if (!databases.containsKey(databaseName)) { - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } databases.remove(databaseName); } @@ -197,7 +197,7 @@ private Map checkAndGetDatabaseNS(final Map indexByColumn = checkAndGetDatabaseNS(indexesByColumn, databaseName); if (index.containsKey(proto.getIndexName())) { - throw new AlreadyExistsIndexException(proto.getIndexName()); + throw new DuplicateIndexException(proto.getIndexName()); } index.put(proto.getIndexName(), proto); @@ -631,7 +631,7 @@ public void createIndex(IndexDescProto proto) throws CatalogException { public void dropIndex(String databaseName, String indexName) throws CatalogException { Map index = checkAndGetDatabaseNS(indexes, databaseName); if (!index.containsKey(indexName)) { - throw new NoSuchIndexException(indexName); + throw new UndefinedIndexException(indexName); } index.remove(indexName); } @@ -643,7 +643,7 @@ public void dropIndex(String databaseName, String indexName) throws CatalogExcep public IndexDescProto getIndexByName(String databaseName, String indexName) throws CatalogException { Map index = checkAndGetDatabaseNS(indexes, databaseName); if (!index.containsKey(indexName)) { - throw new NoSuchIndexException(indexName); + throw new UndefinedIndexException(indexName); } return index.get(indexName); @@ -658,7 +658,7 @@ public IndexDescProto getIndexByColumn(String databaseName, String tableName, St Map indexByColumn = checkAndGetDatabaseNS(indexesByColumn, databaseName); if (!indexByColumn.containsKey(columnName)) { - throw new NoSuchIndexException(columnName); + throw new UndefinedIndexException(CatalogUtil.buildFQName(databaseName, tableName), columnName); } return indexByColumn.get(columnName); diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/XMLCatalogSchemaManager.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/XMLCatalogSchemaManager.java index 9173cb8105..dd8e2a278a 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/XMLCatalogSchemaManager.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/XMLCatalogSchemaManager.java @@ -55,6 +55,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.exception.CatalogException; import org.apache.tajo.catalog.store.object.*; +import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.util.TUtil; public class XMLCatalogSchemaManager { @@ -71,7 +72,7 @@ public XMLCatalogSchemaManager(String schemaPath) throws CatalogException { loadFromXmlFiles(); } catch (Exception e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } } @@ -102,7 +103,7 @@ protected String getDropSQL(DatabaseObjectType type, String name) public void dropBaseSchema(Connection conn) throws CatalogException { if (!isLoaded()) { - throw new CatalogException("Schema files are not loaded yet."); + throw new TajoInternalError("Schema files are not loaded yet."); } List failedObjects = new ArrayList(); @@ -111,7 +112,7 @@ public void dropBaseSchema(Connection conn) throws CatalogException { try { stmt = conn.createStatement(); } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } for (DatabaseObject object: catalogStore.getSchema().getObjects()) { @@ -230,7 +231,7 @@ protected boolean checkExistence(Connection conn, DatabaseObjectType type, Strin pstmt = getExistQuery(conn, type); if (pstmt == null) { - throw new CatalogException("Finding " + type + throw new TajoInternalError("Finding " + type + " type of database object is not supported on this database system."); } @@ -274,13 +275,13 @@ public void createBaseSchema(Connection conn) throws CatalogException { Statement stmt; if (!isLoaded()) { - throw new CatalogException("Database schema files are not loaded."); + throw new TajoInternalError("Database schema files are not loaded."); } try { stmt = conn.createStatement(); } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } for (DatabaseObject object: catalogStore.getSchema().getObjects()) { @@ -304,7 +305,7 @@ public void createBaseSchema(Connection conn) throws CatalogException { LOG.info(object.getName() + " " + object.getType() + " is created."); } } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } } @@ -313,7 +314,7 @@ public void createBaseSchema(Connection conn) throws CatalogException { public void upgradeBaseSchema(Connection conn, int currentVersion) { if (!isLoaded()) { - throw new CatalogException("Database schema files are not loaded."); + throw new TajoInternalError("Database schema files are not loaded."); } final List candidatePatches = new ArrayList(); @@ -329,7 +330,7 @@ public void upgradeBaseSchema(Connection conn, int currentVersion) { try { stmt = conn.createStatement(); } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } for (SchemaPatch patch: candidatePatches) { @@ -338,7 +339,7 @@ public void upgradeBaseSchema(Connection conn, int currentVersion) { stmt.executeUpdate(object.getSql()); LOG.info(object.getName() + " " + object.getType() + " was created or altered."); } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } } } @@ -369,14 +370,14 @@ public boolean catalogAlreadyExists(Connection conn) throws CatalogException { } } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } return result; } public boolean isInitialized(Connection conn) throws CatalogException { if (!isLoaded()) { - throw new CatalogException("Database schema files are not loaded."); + throw new TajoInternalError("Database schema files are not loaded."); } boolean result = true; @@ -390,7 +391,7 @@ public boolean isInitialized(Connection conn) throws CatalogException { result &= checkExistence(conn, object.getType(), object.getName()); } } catch (SQLException e) { - throw new CatalogException(e.getMessage(), e); + throw new TajoInternalError(e); } if (!result) { @@ -490,7 +491,7 @@ public boolean accept(File dir, String name) { protected void mergeXmlSchemas(final List storeObjects) throws CatalogException { if (storeObjects.size() <= 0) { - throw new CatalogException("Unable to find a schema file."); + throw new TajoInternalError("Unable to find a schema file."); } this.catalogStore = new StoreObjectsMerger(storeObjects).merge(); @@ -571,7 +572,7 @@ protected void copySchemaInfo(StoreObject sourceStore) { !targetStore.getSchema().getSchemaName().isEmpty() && !targetStore.getSchema().getSchemaName().equalsIgnoreCase( sourceStore.getSchema().getSchemaName())) { - throw new CatalogException("different schema names are specified. One is " + + throw new TajoInternalError("different schema names are specified. One is " + sourceStore.getSchema().getSchemaName() + " and other is " + targetStore.getSchema().getSchemaName()); } @@ -610,7 +611,7 @@ protected List mergeDatabaseObjects(List objects int objIdx = object.getOrder(); if (objIdx < orderedObjects.size() && orderedObjects.get(objIdx) != null) { - throw new CatalogException("This catalog configuration contains duplicated order of DatabaseObject"); + throw new TajoInternalError("This catalog configuration contains duplicated order of DatabaseObject"); } orderedObjects.add(objIdx, object); @@ -637,7 +638,7 @@ protected List mergeDatabaseObjects(List objects protected void validatePatch(List patches, SchemaPatch testPatch) { if (testPatch.getPriorVersion() > testPatch.getNextVersion()) { - throw new CatalogException("Prior version cannot proceed to next version of patch."); + throw new TajoInternalError("Prior version cannot proceed to next version of patch."); } for (SchemaPatch patch: patches) { @@ -649,7 +650,7 @@ protected void validatePatch(List patches, SchemaPatch testPatch) { LOG.warn("It has the same prior version (" + testPatch.getPriorVersion() + ") of patch."); if (testPatch.getNextVersion() == patch.getNextVersion()) { - throw new CatalogException("Duplicate versions of patch found. It will terminate Catalog Store. "); + throw new TajoInternalError("Duplicate versions of patch found. It will terminate Catalog Store. "); } } @@ -687,7 +688,7 @@ protected void validateSQLObject(List queries, SQLObject testQuery) { } if (occurredCount > 1) { - throw new CatalogException("Duplicate Query type (" + testQuery.getType() + ") has found."); + throw new TajoInternalError("Duplicate Query type (" + testQuery.getType() + ") has found."); } } diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java index cbcec83f5a..9cee17a85a 100644 --- a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java +++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java @@ -24,7 +24,7 @@ import org.apache.tajo.TajoConstants; import org.apache.tajo.catalog.dictionary.InfoSchemaMetadataDictionary; import org.apache.tajo.catalog.exception.CatalogException; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionDesc; import org.apache.tajo.catalog.partition.PartitionKey; import org.apache.tajo.catalog.store.PostgreSQLStore; @@ -32,7 +32,6 @@ import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType; import org.apache.tajo.catalog.proto.CatalogProtos.IndexMethod; -import org.apache.tajo.catalog.proto.CatalogProtos.StoreType; import org.apache.tajo.catalog.store.DerbyStore; import org.apache.tajo.catalog.store.MySQLStore; import org.apache.tajo.catalog.store.MariaDBStore; @@ -40,6 +39,7 @@ import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.common.TajoDataTypes.Type; import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.function.Function; import org.apache.tajo.util.CommonTestingUtil; import org.apache.tajo.util.KeyValueSet; @@ -94,7 +94,7 @@ public static void setUp() throws Exception { // MySQLStore/MariaDB/PostgreSQL requires username (and password). if (isConnectionIdRequired(driverClass)) { if (connectionId == null) { - throw new CatalogException(String.format("%s driver requires %s", driverClass, CatalogConstants.CONNECTION_ID)); + throw new TajoInternalError(String.format("%s driver requires %s", driverClass, CatalogConstants.CONNECTION_ID)); } conf.set(CatalogConstants.CONNECTION_ID, connectionId); if (password != null) { @@ -695,7 +695,7 @@ public final void testSuchFunctionException() throws Exception { assertFalse(catalog.containFunction("test123", CatalogUtil.newSimpleDataTypeArray(Type.INT4))); catalog.getFunction("test123", CatalogUtil.newSimpleDataTypeArray(Type.INT4)); fail(); - } catch (NoSuchFunctionException nsfe) { + } catch (UndefinedFunctionException nsfe) { // succeed test } catch (Throwable e) { fail(e.getMessage()); @@ -1098,7 +1098,7 @@ public final void testFindIntFunc() throws Exception { assertEquals(retrieved.getParamTypes()[1] , CatalogUtil.newSimpleDataType(Type.INT4)); } - @Test(expected=NoSuchFunctionException.class) + @Test(expected=UndefinedFunctionException.class) public final void testFindIntInvalidFunc() throws Exception { assertFalse(catalog.containFunction("testintinvalid", FunctionType.GENERAL)); FunctionDesc meta = new FunctionDesc("testintinvalid", TestIntFunc.class, FunctionType.GENERAL, @@ -1127,7 +1127,7 @@ public final void testFindFloatFunc() throws Exception { assertEquals(retrieved.getParamTypes()[1] , CatalogUtil.newSimpleDataType(Type.INT4)); } - @Test(expected=NoSuchFunctionException.class) + @Test(expected=UndefinedFunctionException.class) public final void testFindFloatInvalidFunc() throws Exception { assertFalse(catalog.containFunction("testfloatinvalid", FunctionType.GENERAL)); FunctionDesc meta = new FunctionDesc("testfloatinvalid", TestFloatFunc.class, FunctionType.GENERAL, 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 486bcd9b51..37afba6e78 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 @@ -43,6 +43,7 @@ import static org.apache.tajo.client.ClientErrorUtil.isError; import static org.apache.tajo.client.ClientErrorUtil.isSuccess; +import static org.apache.tajo.client.ClientErrorUtil.returnError; import static org.apache.tajo.ipc.ClientProtos.*; import static org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -334,8 +335,8 @@ public GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceE return response; - } catch (Exception e) { - throw new ServiceException(e.getMessage(), e); + } catch (Exception t) { + return GetQueryResultResponse.newBuilder().setState(returnError(t)).build(); } } diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index e2de4d66ce..207c7cb106 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -33,7 +33,7 @@ import "stacktrace.proto"; // tajo-common message ResponseState { required tajo.error.ResultCode return_code = 1; - required string message = 2; + optional string message = 2; optional tajo.error.StackTrace stack_trace = 3; } diff --git a/tajo-common/src/main/java/org/apache/tajo/common/exception/NotImplementedException.java b/tajo-common/src/main/java/org/apache/tajo/common/exception/NotImplementedException.java deleted file mode 100644 index 2690b4735d..0000000000 --- a/tajo-common/src/main/java/org/apache/tajo/common/exception/NotImplementedException.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * 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.common.exception; - -public class NotImplementedException extends RuntimeException { - - private static final long serialVersionUID = 8515328809349325243L; - - public NotImplementedException() { - } - - /** - * @param message - */ - public NotImplementedException(String message) { - super(message); - } - - /** - * @param cause - */ - public NotImplementedException(Throwable cause) { - super(cause); - } - - /** - * @param message - * @param cause - */ - public NotImplementedException(String message, Throwable cause) { - super(message, cause); - } -} 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 938c654977..bfbdfce028 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 @@ -22,27 +22,55 @@ import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.util.Pair; -import java.util.Collections; import java.util.Map; public class ErrorMessages { public static final Map> MESSAGES; static { - Map> msgs = Maps.newHashMap(); + MESSAGES = Maps.newHashMap(); - ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "Internal Error: %s", 1); - ADD_MESSAGE(ResultCode.INVALID_RPC_CALL, "Invalid RPC Call: %s", 1); + ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "internal Error: %s", 1); + ADD_MESSAGE(ResultCode.INVALID_RPC_CALL, "invalid RPC Call: %s", 1); - ADD_MESSAGE(ResultCode.NO_SUCH_QUERYID, "Query id '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.NO_SUCH_QUERYID, "query id '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.NO_DATA, "no data due to query failure or error"); + ADD_MESSAGE(ResultCode.INCOMPLETE_QUERY, "query '%s' is stilling running", 1); - ADD_MESSAGE(ResultCode.INVALID_SESSION, "Invalid Session '%s'", 1); - ADD_MESSAGE(ResultCode.NO_SUCH_SESSION_VARIABLE, "No such session variable '%s", 1); + ADD_MESSAGE(ResultCode.INVALID_SESSION, "invalid Session '%s'", 1); + ADD_MESSAGE(ResultCode.NO_SUCH_SESSION_VARIABLE, "no such session variable '%s", 1); + ADD_MESSAGE(ResultCode.INVALID_SESSION_VARIABLE, "invalid session variable '%s': %s", 2); - ADD_MESSAGE(ResultCode.UNDEFINED_DATABASE, "Database '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "Table '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s"); - MESSAGES = Collections.unmodifiableMap(msgs); + ADD_MESSAGE(ResultCode.SYNTAX_ERROR, "%s", 1); + + ADD_MESSAGE(ResultCode.UNDEFINED_DATABASE, "database '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "table '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_COLUMN, "column '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_FUNCTION, "function does not exist: %s", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_OPERATOR, "operator does not exist: '%s'", 1); + + ADD_MESSAGE(ResultCode.DUPLICATE_DATABASE, "database '%s' already exists", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_SCHEMA, "schema '%s' already exists", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_TABLE, "table '%s' already exists", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_COLUMN, "column '%s' already exists", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_ALIAS, "table name '%s' specified more than once", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_INDEX, "index '%s' already exists", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_PARTITION, "partition '%s' already exists", 1); + + ADD_MESSAGE(ResultCode.DIVISION_BY_ZERO, "Division by zero: %s", 1); + + ADD_MESSAGE(ResultCode.DATATYPE_MISMATCH, + "column \"%s\" is of type %s but expression %s is of type %s", 4); + + ADD_MESSAGE(ResultCode.SET_OPERATION_SCHEMA_MISMATCH, "each %s query must have the same number of columns", 1); + ADD_MESSAGE(ResultCode.SET_OPERATION_DATATYPE_MISMATCH, "%s types %s and %s cannot be matched"); + + ADD_MESSAGE(ResultCode.CAT_UPGRADE_REQUIRED, "Catalog must be upgraded"); + ADD_MESSAGE(ResultCode.CAT_CANNOT_CONNECT, "Cannot connect metadata store '%s': %s", 2); + + ADD_MESSAGE(ResultCode.UNKNOWN_DATAFORMAT, "Unknown data format: '%s'", 1); } private static void ADD_MESSAGE(ResultCode code, String msgFormat) { diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java index f61243482a..025a20cac1 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java @@ -31,6 +31,14 @@ public static boolean isFailed(ResultCode code) { } public static Stacktrace.StackTrace convertStacktrace(Throwable t) { - return null; + Stacktrace.StackTrace.Builder builder = Stacktrace.StackTrace.newBuilder(); + for (StackTraceElement element: t.getStackTrace()) { + builder.addElement(Stacktrace.StackTrace.Element.newBuilder() + .setFilename(element.getFileName()) + .setFunction(element.getClassName() + "::" + element.getMethodName()) + .setLine(element.getLineNumber()) + ); + } + return builder.build(); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java new file mode 100644 index 0000000000..da381660aa --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java @@ -0,0 +1,28 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors; + +public class ExceptionUtil { + + public static TajoRuntimeException makeNotSupported(String feature) { + return new TajoRuntimeException(Errors.ResultCode.NOT_SUPPORTED, feature); + } +} diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java index dcd6a6596f..dbb2748965 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java @@ -31,11 +31,21 @@ public TajoError(ResultCode code) { this.code = code; } + public TajoError(ResultCode code, Throwable t) { + super(ErrorMessages.getMessage(code), t); + this.code = code; + } + public TajoError(ResultCode code, String ... args) { super(ErrorMessages.getMessage(code, args)); this.code = code; } + public TajoError(ResultCode code, Throwable t, String ... args) { + super(ErrorMessages.getMessage(code, args), t); + this.code = code; + } + @Override public ResultCode getErrorCode() { return code; diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java index 81984d0d69..34ead32974 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java @@ -21,11 +21,19 @@ import org.apache.tajo.error.Errors.ResultCode; /** - * Exception Internal Bugs + * Exception for Internal Bugs and Unexpected exception + * + * When should we use TajoInternalError? + * * Cases that must not be happened + * * Developer bugs */ public class TajoInternalError extends TajoError { - public TajoInternalError() { - super(ResultCode.INTERNAL_ERROR); + public TajoInternalError(String message) { + super(ResultCode.INTERNAL_ERROR, message); + } + + public TajoInternalError(Throwable t) { + super(ResultCode.INTERNAL_ERROR, t.getMessage()); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/UndefinedOperatorException.java b/tajo-common/src/main/java/org/apache/tajo/exception/UndefinedOperatorException.java new file mode 100644 index 0000000000..9d91946785 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/exception/UndefinedOperatorException.java @@ -0,0 +1,28 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors; + +public class UndefinedOperatorException extends TajoException { + + public UndefinedOperatorException(String operation) { + super(Errors.ResultCode.UNDEFINED_OPERATOR, operation); + } +} diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/UnimplementedException.java b/tajo-common/src/main/java/org/apache/tajo/exception/UnimplementedException.java index 3e4555d8bb..b32079fedb 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/UnimplementedException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/UnimplementedException.java @@ -18,21 +18,17 @@ package org.apache.tajo.exception; -public class UnimplementedException extends RuntimeException { +import org.apache.tajo.error.Errors; + +public class UnimplementedException extends TajoRuntimeException { private static final long serialVersionUID = -5467580471721530536L; public UnimplementedException() { + super(Errors.ResultCode.NOT_IMPLEMENTED, + Thread.currentThread().getStackTrace()[1].getClassName()); } - public UnimplementedException(String message) { - super(message); - } - - public UnimplementedException(Throwable cause) { - super(cause); - } - - public UnimplementedException(String message, Throwable cause) { - super(message, cause); + public UnimplementedException(String featureName) { + super(Errors.ResultCode.NOT_IMPLEMENTED, featureName); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java b/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java index 1e19622131..590c2ec931 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java @@ -18,21 +18,16 @@ package org.apache.tajo.exception; -public class UnsupportedException extends RuntimeException { - private static final long serialVersionUID = 6702291354858193578L; - - public UnsupportedException() { - } +import org.apache.tajo.error.Errors; - public UnsupportedException(String message) { - super(message); - } +public class UnsupportedException extends TajoRuntimeException { + private static final long serialVersionUID = 6702291354858193578L; - public UnsupportedException(Throwable cause) { - super(cause); + public UnsupportedException(String featureName) { + super(Errors.ResultCode.NOT_SUPPORTED, featureName); } - public UnsupportedException(String message, Throwable cause) { - super(message, cause); + public UnsupportedException() { + super(Errors.ResultCode.NOT_SUPPORTED, Thread.currentThread().getStackTrace()[1].getClassName()); } } diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index dcccbfd2d9..9b9e1bd271 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -31,41 +31,85 @@ enum ResultCode { // General Errors INTERNAL_ERROR = 201; // Error caused by internal bugs ILLEGAL_STATE = 202; // Illegal state or unexpected state - NOT_IMPLEMENTED = 203; // Not implemented feature + NOT_IMPLEMENTED = 203; // Not implemented method NOT_SUPPORTED = 204; // Not supported feature INVALID_RPC_CALL = 205; // When invalid RPC call is invoked (e.g., wrong message and absent fields) // Query Management and Scheduler NO_SUCH_QUERYID = 300; // No query id in TajoMaster - - + NO_DATA = 301; // No data due to query fail or error + INCOMPLETE_QUERY = 302; // It occurs when a client requests something of a completed query. // Session Errors - INVALID_SESSION = 251; - NO_SUCH_SESSION_VARIABLE = 252; + INVALID_SESSION = 401; + NO_SUCH_SESSION_VARIABLE = 402; + INVALID_SESSION_VARIABLE = 403; + + // Data Exception (SQLState Class - 22) + DIVISION_BY_ZERO = 451; // SQLState: 22012 - Division by zero // Query and Catalog Errors // Section: Class 42 - Syntax Error or Access Rule Violation - UNDEFINED_DATABASE = 301; - UNDEFINED_TABLE = 302; - UNDEFINED_COLUMN = 303; // SQLState: 42703 - UNDEFINED_FUNCTION = 303; // SQLState: 42883 - - DUPLICATE_DATABASE = 305; - DUPLICATE_TABLE = 306; - DUPLICATE_COLUMN = 307; // SQLState: 42701 - DUPLICATE_ALIAS = 308; // SQLState: 42712 - DUPLICATE_FUNCTION = 309; // SQLState: 42723 + UNDEFINED_TABLESPACE = 500; // ? + UNDEFINED_DATABASE = 501; // ? + UNDEFINED_SCHEMA = 502; // ? + UNDEFINED_TABLE = 503; // ? + UNDEFINED_COLUMN = 504; // SQLState: 42703 + UNDEFINED_FUNCTION = 505; // SQLState: 42883 + UNDEFINED_INDEX = 506; // ? + UNDEFINED_INDEX_NAME = 507; // ? + UNDEFINED_PARTITION = 508; // ? + UNDEFINED_OPERATOR = 509; // SQLState: 42883 (=UNDEFINED_FUNCTION) + + DUPLICATE_TABLESPACE = 510; + DUPLICATE_DATABASE = 511; // SQLState: 42P04 + DUPLICATE_SCHEMA = 512; // SQLState: 42P06 + DUPLICATE_TABLE = 513; // SQLState: 42P07 + DUPLICATE_COLUMN = 514; // SQLState: 42701 + DUPLICATE_ALIAS = 515; // SQLState: 42712 + DUPLICATE_FUNCTION = 516; // SQLState: 42723 + DUPLICATE_INDEX = 517; // SQLState: ? + DUPLICATE_PARTITION = 518; // SQLState: ? + + AMBIGUOUS_TABLE = 521; // ? + AMBIGUOUS_COLUMN = 522; // SQLState: 42702; + AMBIGUOUS_FUNCTION = 523; // SQLState: 42725; + + + // Section: Syntax Error or Access Rule Violation + SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 601; // SQLState: 42000 + SYNTAX_ERROR = 602; // SQLState: 42601 + INSUFFICIENT_PRIVILEGE = 603; // SQLState: 42501 + CANNOT_CAST = 604; // SQLState: 42846 - Cast from source type to target type is not supported. + GROUPING_ERROR = 605; // SQLState: 42803 + WINDOWING_ERROR = 606; // SQLState: 42P20 - PgSQL implementation-defined + INVALID_RECURSION = 607; // SQLState: 42P19 - PgSQL implementation-defined + SET_OPERATION_SCHEMA_MISMATCH = 608; // SQLState: 42601 (=SYNTAX_ERROR) + SET_OPERATION_DATATYPE_MISMATCH = 609; // SQLState: 42601 (=SYNTAX_ERROR) + + INVALID_FOREIGN_KEY = 621; // SQLState: 42830 + INVALID_NAME = 622; // SQLState: 42602 + NAME_TOO_LONG = 623; // SQLState: 42622 + RESERVED_NAME = 624; // SQLState: 42939 + DATATYPE_MISMATCH = 625; // SQLState: 42804; + INDETERMINATE_DATATYPE = 626; // SQLState: 42P18; - PgSQL implementation -defined + + INVALID_COLUMN_DEFINITION = 631; // SQLState: 42611; // Expressions - INVALID_EXPRESSION = 401; - INVALID_CAST = 402; - UNKNOWN_DATA_TYPE = 403; + INVALID_EXPRESSION = 701; + INVALID_CAST = 702; + UNKNOWN_DATATYPE = 703; + + //NUMERIC_OVERFLOW = 803; // Numeric value overflow + //VALUE_LARGER_THAN_PRECISION = 804; // Value larger than column precision - //NUMERIC_OVERFLOW = 403; // Numeric value overflow - //VALUE_LARGER_THAN_PRECISION = 404; // Value larger than column precision + // Metadata Connector + CAT_UPGRADE_REQUIRED = 901; // Migration + CAT_CANNOT_CONNECT = 902; // Cannot connect metadata server - // Physical Operator + // Storage and Data Format + UNKNOWN_DATAFORMAT = 1001; // Unknown Data Format // Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H @@ -100,27 +144,6 @@ enum ResultCode { // 3B - Invalid SAVEPOINT // 40 - Transaction Rollback - // Section: Class 42 - Syntax Error or Access Rule Violation - SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 42000; - - SYNTAX_ERROR = 42601; - INSUFFICIENT_PRIVILEGE = 42501; - CANNOT_COERCE = 42846; // Cast from source type to target type is not supported. - GROUPING_ERROR = 42803; - // WINDOWING_ERROR = 42P20; - PgSQL implementation-defined - // INVALID_RECURSION = 42P19; - PgSQL implementation-defined - - // INVALID_RECURSION = 42P19; - PgSQL implementation -defined - INVALID_FOREIGN_KEY = 42830; - INVALID_NAME = 42602; - NAME_TOO_LONG = 42622; - RESERVED_NAME = 42939; - DATATYPE_MISMATCH = 42804; - // INDETERMINATE_DATATYPE = 42P18; - PgSQL implementation -defined - - INVALID_COLUMN_DEFINITION = 42611; - AMBIGUOUS_COLUMN = 42702; - AMBIGUOUS_FUNCTION = 42725; // 44 - WITH CHECK OPTION Violation // 46 - Java DDL diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java index a7f2e7b466..a6347f1900 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java @@ -40,6 +40,7 @@ import org.apache.tajo.engine.parser.SQLAnalyzer; import org.apache.tajo.engine.parser.SQLSyntaxError; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.exception.TajoException; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.master.exec.DDLExecutor; import org.apache.tajo.master.exec.QueryExecutor; @@ -48,10 +49,7 @@ import org.apache.tajo.plan.logical.LogicalRootNode; import org.apache.tajo.plan.logical.NodeType; import org.apache.tajo.plan.util.PlannerUtil; -import org.apache.tajo.plan.verifier.LogicalPlanVerifier; -import org.apache.tajo.plan.verifier.PreLogicalPlanVerifier; -import org.apache.tajo.plan.verifier.VerificationState; -import org.apache.tajo.plan.verifier.VerifyException; +import org.apache.tajo.plan.verifier.*; import org.apache.tajo.session.Session; import org.apache.tajo.storage.TablespaceManager; import org.apache.tajo.util.CommonTestingUtil; @@ -222,8 +220,7 @@ public Expr buildExpressionFromSql(String sql, Session session) throws Interrupt } } - public QueryId updateQuery(QueryContext queryContext, String sql, boolean isJson) throws IOException, - SQLException, PlanningException { + public QueryId updateQuery(QueryContext queryContext, String sql, boolean isJson) throws Throwable { try { LOG.info("SQL: " + sql); @@ -250,16 +247,16 @@ public QueryId updateQuery(QueryContext queryContext, String sql, boolean isJson } } - private LogicalPlan createLogicalPlan(QueryContext queryContext, Expr expression) throws PlanningException { + private LogicalPlan createLogicalPlan(QueryContext queryContext, Expr expression) throws Throwable { VerificationState state = new VerificationState(); preVerifier.verify(queryContext, state, expression); if (!state.verified()) { StringBuilder sb = new StringBuilder(); - for (String error : state.getErrorMessages()) { - sb.append(error).append("\n"); + + for (Throwable error : state.getErrors()) { + throw error; } - throw new VerifyException(sb.toString()); } LogicalPlan plan = planner.createPlan(queryContext, expression); @@ -278,11 +275,9 @@ private LogicalPlan createLogicalPlan(QueryContext queryContext, Expr expression verifyInsertTableSchema(queryContext, state, plan); if (!state.verified()) { - StringBuilder sb = new StringBuilder(); - for (String error : state.getErrorMessages()) { - sb.append(error).append("\n"); + for (Throwable error : state.getErrors()) { + throw error; } - throw new VerifyException(sb.toString()); } return plan; @@ -301,7 +296,7 @@ private void verifyInsertTableSchema(QueryContext queryContext, VerificationStat TablespaceManager.get(tableDesc.getUri()).get().verifySchemaToWrite(tableDesc, outSchema); } catch (Throwable t) { - state.addVerification(t.getMessage()); + state.addVerification(SyntaxErrorUtil.makeSyntaxError(t.getMessage())); } } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 94d6d61701..bf116e51b9 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -33,12 +33,14 @@ import org.apache.tajo.TajoIdProtos; import org.apache.tajo.TajoProtos.QueryState; import org.apache.tajo.catalog.*; -import org.apache.tajo.catalog.exception.NoSuchDatabaseException; +import org.apache.tajo.catalog.exception.UndefinedDatabaseException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.error.Errors; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.*; import org.apache.tajo.ipc.TajoMasterClientProtocol; @@ -136,7 +138,7 @@ public CreateSessionResponse createSession(RpcController controller, CreateSessi if (!context.getCatalog().existDatabase(databaseName)) { LOG.info("Session creation is canceled due to absent base database \"" + databaseName + "\"."); - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } String sessionId = @@ -305,6 +307,9 @@ public UpdateQueryResponse updateQuery(RpcController controller, QueryRequest re @Override public GetQueryResultResponse getQueryResult(RpcController controller, GetQueryResultRequest request) throws ServiceException { + + GetQueryResultResponse.Builder builder = GetQueryResultResponse.newBuilder(); + try { context.getSessionManager().touch(request.getSessionId().getId()); QueryId queryId = new QueryId(request.getQueryId()); @@ -319,7 +324,6 @@ public GetQueryResultResponse getQueryResult(RpcController controller, queryInfo = queryInProgress.getQueryInfo(); } - GetQueryResultResponse.Builder builder = GetQueryResultResponse.newBuilder(); builder.setTajoUserName(UserGroupInformation.getCurrentUser().getUserName()); // If we cannot the QueryInfo instance from the finished list, @@ -333,15 +337,17 @@ public GetQueryResultResponse getQueryResult(RpcController controller, switch (queryInfo.getQueryState()) { case QUERY_SUCCEEDED: if (queryInfo.hasResultdesc()) { + builder.setState(OK); builder.setTableDesc(queryInfo.getResultDesc().getProto()); } break; case QUERY_FAILED: case QUERY_ERROR: - builder.setErrorMessage("Query " + queryId + " is failed"); + builder.setState(ClientErrorUtil.returnError(Errors.ResultCode.NO_DATA)); break; + default: - builder.setErrorMessage("Query " + queryId + " is still running"); + builder.setState(ClientErrorUtil.returnError(Errors.ResultCode.INCOMPLETE_QUERY)); } return builder.build(); 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 7104412db2..0f78597dfa 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 @@ -32,6 +32,7 @@ import org.apache.tajo.catalog.proto.CatalogProtos.AlterTablespaceProto; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.master.TajoMaster; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.logical.*; @@ -152,7 +153,7 @@ public boolean createDatabase(@Nullable QueryContext queryContext, String databa LOG.info("database \"" + databaseName + "\" is already exists." ); return true; } else { - throw new AlreadyExistsDatabaseException(databaseName); + throw new DuplicateDatabaseException(databaseName); } } @@ -173,7 +174,7 @@ public boolean dropDatabase(QueryContext queryContext, String databaseName, bool LOG.info("database \"" + databaseName + "\" does not exists." ); return true; } else { // Otherwise, it causes an exception. - throw new NoSuchDatabaseException(databaseName); + throw new UndefinedDatabaseException(databaseName); } } @@ -245,7 +246,7 @@ public TableDesc createTable(QueryContext queryContext, LOG.info("relation \"" + qualifiedName + "\" is already exists." ); return catalog.getTableDesc(databaseName, simpleTableName); } else { - throw new AlreadyExistsTableException(qualifiedName); + throw new DuplicateTableException(qualifiedName); } } @@ -273,7 +274,7 @@ public TableDesc createTable(QueryContext queryContext, return desc; } else { LOG.info("Table creation " + tableName + " is failed."); - throw new CatalogException("Cannot create table \"" + tableName + "\"."); + throw new TajoInternalError("Cannot create table \"" + tableName + "\""); } } @@ -304,7 +305,7 @@ public boolean dropTable(QueryContext queryContext, String tableName, boolean if LOG.info("relation \"" + qualifiedName + "\" is already exists." ); return true; } else { // Otherwise, it causes an exception. - throw new NoSuchTableException(qualifiedName); + throw new UndefinedTbleException(qualifiedName); } } @@ -347,7 +348,7 @@ public void truncateTable(final QueryContext queryContext, final TruncateTableNo final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName); if (!catalog.existsTable(databaseName, simpleTableName)) { - throw new NoSuchTableException(qualifiedName); + throw new UndefinedTbleException(qualifiedName); } Path warehousePath = new Path(TajoConf.getWarehouseDir(context.getConf()), databaseName); @@ -397,16 +398,16 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName); if (!catalog.existsTable(databaseName, simpleTableName)) { - throw new NoSuchTableException(qualifiedName); + throw new UndefinedTbleException(qualifiedName); } switch (alterTable.getAlterTableOpType()) { case RENAME_TABLE: if (!catalog.existsTable(databaseName, simpleTableName)) { - throw new NoSuchTableException(alterTable.getTableName()); + throw new UndefinedTbleException(alterTable.getTableName()); } if (catalog.existsTable(databaseName, alterTable.getNewTableName())) { - throw new AlreadyExistsTableException(alterTable.getNewTableName()); + throw new DuplicateTableException(alterTable.getNewTableName()); } TableDesc desc = catalog.getTableDesc(databaseName, simpleTableName); @@ -432,14 +433,14 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer break; case RENAME_COLUMN: if (existColumnName(qualifiedName, alterTable.getNewColumnName())) { - throw new ColumnNameAlreadyExistException(alterTable.getNewColumnName()); + throw new DuplicateColumnException(alterTable.getNewColumnName()); } catalog.alterTable(CatalogUtil.renameColumn(qualifiedName, alterTable.getColumnName(), alterTable.getNewColumnName(), AlterTableType.RENAME_COLUMN)); break; case ADD_COLUMN: if (existColumnName(qualifiedName, alterTable.getAddNewColumn().getSimpleName())) { - throw new ColumnNameAlreadyExistException(alterTable.getAddNewColumn().getSimpleName()); + throw new DuplicateColumnException(alterTable.getAddNewColumn().getSimpleName()); } catalog.alterTable(CatalogUtil.addNewColumn(qualifiedName, alterTable.getAddNewColumn(), AlterTableType.ADD_COLUMN)); break; diff --git a/tajo-core/src/main/java/org/apache/tajo/master/rm/TajoResourceTracker.java b/tajo-core/src/main/java/org/apache/tajo/master/rm/TajoResourceTracker.java index 2a18de7ecb..3bff9b1d0c 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/rm/TajoResourceTracker.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/rm/TajoResourceTracker.java @@ -20,12 +20,10 @@ import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcController; -import com.google.protobuf.ServiceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.service.AbstractService; -import org.apache.tajo.common.exception.NotImplementedException; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.ipc.QueryCoordinatorProtocol.TajoHeartbeatResponse; import org.apache.tajo.ipc.TajoResourceTrackerProtocol; diff --git a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java index e6314d14fd..9cc1407156 100644 --- a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java +++ b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java @@ -296,7 +296,7 @@ private static VerificationState verify(String query) throws PlanningException { Expr expr = sqlParser.parse(query); verifier.verify(context, state, expr); - if (state.getErrorMessages().size() > 0) { + if (state.getErrors().size() > 0) { return state; } LogicalPlan plan = planner.createPlan(context, expr); @@ -308,8 +308,8 @@ private static VerificationState verify(String query) throws PlanningException { public void assertValidSQL(String query) throws PlanningException, IOException { VerificationState state = verify(query); - if (state.getErrorMessages().size() > 0) { - fail(state.getErrorMessages().get(0)); + if (state.getErrors().size() > 0) { + fail(state.getErrors().get(0).getMessage()); } } @@ -321,7 +321,7 @@ public void assertValidSQLFromFile(String fileName) throws PlanningException, IO public void assertInvalidSQL(String query) throws PlanningException, IOException { VerificationState state = verify(query); - if (state.getErrorMessages().size() == 0) { + if (state.getErrors().size() == 0) { fail(PreLogicalPlanVerifier.class.getSimpleName() + " cannot catch any verification error: " + query); } } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java index 07a09ad363..a8efb7dc7a 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java @@ -142,18 +142,18 @@ private static Target[] getRawTargets(QueryContext context, String query, boolea Expr expr = analyzer.parse(parsedResults.get(0).getHistoryStatement()); VerificationState state = new VerificationState(); preLogicalPlanVerifier.verify(context, state, expr); - if (state.getErrorMessages().size() > 0) { - if (!condition && state.getErrorMessages().size() > 0) { - throw new PlanningException(state.getErrorMessages().get(0)); + if (state.getErrors().size() > 0) { + if (!condition && state.getErrors().size() > 0) { + throw new PlanningException(state.getErrors().get(0)); } - assertFalse(state.getErrorMessages().get(0), true); + assertFalse(state.getErrors().get(0), true); } LogicalPlan plan = planner.createPlan(context, expr, true); optimizer.optimize(context, plan); annotatedPlanVerifier.verify(context, state, plan); - if (state.getErrorMessages().size() > 0) { - assertFalse(state.getErrorMessages().get(0), true); + if (state.getErrors().size() > 0) { + assertFalse(state.getErrors().get(0), true); } Target [] targets = plan.getRootBlock().getRawTargets(); diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java index b04d544862..8d81ae8c16 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java @@ -21,7 +21,7 @@ import org.apache.tajo.SessionVars; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.datum.DatumFactory; import org.apache.tajo.datum.TimestampDatum; @@ -53,11 +53,11 @@ public void testQuotedIdentifiers() throws IOException { public void testNoSuchFunction() throws IOException { try { testSimpleEval("select test123('abc') col1 ", new String[]{"abc"}); - fail("This test should throw NoSuchFunctionException"); - } catch (NoSuchFunctionException e) { + fail("This test should throw UndefinedFunctionException"); + } catch (UndefinedFunctionException e) { //success } catch (Exception e) { - fail("This test should throw NoSuchFunctionException: " + e); + fail("This test should throw UndefinedFunctionException: " + e); } } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java index bec8cd37e9..1d35139488 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java @@ -20,7 +20,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.engine.eval.ExprTestBase; import org.junit.Test; @@ -151,7 +151,7 @@ public void testCoalesceText() throws Exception { try { testSimpleEval("select coalesce(null, 2, 'value3');", new String[]{"2"}); fail("coalesce(NULL, INT, TEXT) not defined. So should throw exception."); - } catch (NoSuchFunctionException e) { + } catch (UndefinedFunctionException e) { //success } } @@ -170,7 +170,7 @@ public void testCoalesceLong() throws Exception { try { testSimpleEval("select coalesce(null, 'value2', 3);", new String[]{"2"}); fail("coalesce(NULL, TEXT, INT) not defined. So should throw exception."); - } catch (NoSuchFunctionException e) { + } catch (UndefinedFunctionException e) { //success } } @@ -189,14 +189,14 @@ public void testCoalesceDouble() throws Exception { try { testSimpleEval("select coalesce('value1', null, 3.0);", new String[]{"1.0"}); fail("coalesce(TEXT, NULL, FLOAT8) not defined. So should throw exception."); - } catch (NoSuchFunctionException e) { + } catch (UndefinedFunctionException e) { // success } try { testSimpleEval("select coalesce(null, 'value2', 3.0);", new String[]{"2.0"}); fail("coalesce(NULL, TEXT, FLOAT8) not defined. So should throw exception."); - } catch (NoSuchFunctionException e) { + } catch (UndefinedFunctionException e) { //success } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java index 7467dcd676..0ec485085c 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java @@ -27,14 +27,12 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.FunctionDesc; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.datum.*; -import org.apache.tajo.exception.InternalException; import org.apache.tajo.exception.InvalidOperationException; import org.apache.tajo.plan.algebra.BaseAlgebraVisitor; import org.apache.tajo.plan.expr.*; -import org.apache.tajo.plan.function.AggFunction; import org.apache.tajo.plan.logical.NodeType; import org.apache.tajo.plan.nameresolver.NameResolver; import org.apache.tajo.plan.nameresolver.NameResolvingMode; @@ -43,7 +41,6 @@ import org.apache.tajo.util.datetime.DateTimeUtil; import org.apache.tajo.util.datetime.TimeMeta; -import java.io.IOException; import java.util.Set; import java.util.Stack; import java.util.TimeZone; @@ -579,7 +576,7 @@ public EvalNode visitFunction(Context ctx, Stack stack, FunctionExpr expr) stack.pop(); // <--- Pop if (!catalog.containFunction(expr.getSignature(), paramTypes)) { - throw new NoSuchFunctionException(expr.getSignature(), paramTypes); + throw new UndefinedFunctionException(expr.getSignature(), paramTypes); } FunctionDesc funcDesc = catalog.getFunction(expr.getSignature(), paramTypes); @@ -605,27 +602,21 @@ public EvalNode visitFunction(Context ctx, Stack stack, FunctionExpr expr) } - try { - FunctionType functionType = funcDesc.getFuncType(); - if (functionType == FunctionType.GENERAL - || functionType == FunctionType.UDF) { - return new GeneralFunctionEval(ctx.queryContext, funcDesc, givenArgs); - } else if (functionType == FunctionType.AGGREGATION - || functionType == FunctionType.UDA) { - if (!ctx.currentBlock.hasNode(NodeType.GROUP_BY)) { - ctx.currentBlock.setAggregationRequire(); - } - return new AggregationFunctionCallEval(funcDesc, givenArgs); - } else if (functionType == FunctionType.DISTINCT_AGGREGATION - || functionType == FunctionType.DISTINCT_UDA) { - throw new PlanningException("Unsupported function: " + funcDesc.toString()); - } else { - throw new PlanningException("Unsupported Function Type: " + functionType.name()); + FunctionType functionType = funcDesc.getFuncType(); + if (functionType == FunctionType.GENERAL + || functionType == FunctionType.UDF) { + return new GeneralFunctionEval(ctx.queryContext, funcDesc, givenArgs); + } else if (functionType == FunctionType.AGGREGATION + || functionType == FunctionType.UDA) { + if (!ctx.currentBlock.hasNode(NodeType.GROUP_BY)) { + ctx.currentBlock.setAggregationRequire(); } - } catch (InternalException e) { - throw new PlanningException(e); - } catch (IOException e) { - throw new PlanningException(e); + return new AggregationFunctionCallEval(funcDesc, givenArgs); + } else if (functionType == FunctionType.DISTINCT_AGGREGATION + || functionType == FunctionType.DISTINCT_UDA) { + throw new PlanningException("Unsupported function: " + funcDesc.toString()); + } else { + throw new PlanningException("Unsupported Function Type: " + functionType.name()); } } @@ -635,7 +626,7 @@ public EvalNode visitCountRowsFunction(Context ctx, Stack stack, CountRows FunctionDesc countRows = catalog.getFunction("count", FunctionType.AGGREGATION, new DataType[] {}); if (countRows == null) { - throw new NoSuchFunctionException(expr.getSignature(), new DataType[]{}); + throw new UndefinedFunctionException(expr.getSignature(), new DataType[]{}); } ctx.currentBlock.setAggregationRequire(); @@ -660,7 +651,7 @@ public EvalNode visitGeneralSetFunction(Context ctx, Stack stack, GeneralS } if (!catalog.containFunction(setFunction.getSignature(), functionType, paramTypes)) { - throw new NoSuchFunctionException(setFunction.getSignature(), paramTypes); + throw new UndefinedFunctionException(setFunction.getSignature(), paramTypes); } FunctionDesc funcDesc = catalog.getFunction(setFunction.getSignature(), functionType, paramTypes); @@ -741,7 +732,7 @@ public EvalNode visitWindowFunction(Context ctx, Stack stack, WindowFuncti // the below checking against WINDOW_FUNCTIONS is a workaround code for the above problem. if (WINDOW_FUNCTIONS.contains(funcName.toLowerCase())) { if (distinct) { - throw new NoSuchFunctionException("row_number() does not support distinct keyword."); + throw new UndefinedFunctionException("row_number() does not support distinct keyword."); } functionType = FunctionType.WINDOW; } else { @@ -749,7 +740,7 @@ public EvalNode visitWindowFunction(Context ctx, Stack stack, WindowFuncti } if (!catalog.containFunction(windowFunc.getSignature(), functionType, paramTypes)) { - throw new NoSuchFunctionException(funcName, paramTypes); + throw new UndefinedFunctionException(funcName, paramTypes); } FunctionDesc funcDesc = catalog.getFunction(funcName, functionType, paramTypes); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java index 2a6cb0bbe8..d61049edf0 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java @@ -21,7 +21,7 @@ import com.google.common.collect.Sets; import org.apache.tajo.algebra.*; import org.apache.tajo.catalog.CatalogUtil; -import org.apache.tajo.catalog.exception.NoSuchColumnException; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.plan.nameresolver.NameResolver; import org.apache.tajo.plan.nameresolver.NameResolvingMode; import org.apache.tajo.plan.visitor.SimpleAlgebraVisitor; @@ -344,7 +344,7 @@ public Expr visitColumnReference(ExprNormalizedResult ctx, Stack stack, Co String normalized = NameResolver.resolve(ctx.plan, ctx.block, expr, NameResolvingMode.LEGACY).getQualifiedName(); expr.setName(normalized); - } catch (NoSuchColumnException nsc) { + } catch (UndefinedColumnException nsc) { } } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java index dced4d32c8..2aae055b91 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java @@ -21,7 +21,7 @@ import org.apache.tajo.SessionVars; import org.apache.tajo.algebra.*; import org.apache.tajo.catalog.*; -import org.apache.tajo.catalog.exception.NoSuchColumnException; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.plan.LogicalPlan.QueryBlock; import org.apache.tajo.plan.algebra.BaseAlgebraVisitor; @@ -109,7 +109,7 @@ public static Column[] getColumns(LogicalPlanner.PlanContext ctx, QualifiedAster // If we cannot find any relation against a qualified column name if (relationOp == null) { - throw new NoSuchColumnException(CatalogUtil.buildFQName(qualifier, "*")); + throw new UndefinedColumnException(CatalogUtil.buildFQName(qualifier, "*")); } Schema schema = relationOp.getLogicalSchema(); @@ -128,7 +128,7 @@ public static Column[] getColumns(LogicalPlanner.PlanContext ctx, QualifiedAster } if (resolvedColumns.size() == 0) { - throw new NoSuchColumnException(asteriskExpr.toString()); + throw new UndefinedColumnException(asteriskExpr.toString()); } return resolvedColumns.toArray(new Column[resolvedColumns.size()]); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java b/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java index 2a52401aa7..d63f4b6ef8 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java @@ -18,12 +18,16 @@ package org.apache.tajo.plan; -public class PlanningException extends Exception { +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.TajoException; + +public class PlanningException extends TajoException { + public PlanningException(String message) { - super(message); + super(ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION, message); } - public PlanningException(Exception e) { - super(e); + public PlanningException(Throwable e) { + super(ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION, e.getMessage()); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java b/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java index 7c468bb385..83542ec393 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java @@ -25,7 +25,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.FunctionDesc; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.plan.visitor.SimpleAlgebraVisitor; @@ -169,7 +169,7 @@ public DataType visitFunction(LogicalPlanner.PlanContext ctx, Stack stack, stack.pop(); // <--- Pop if (!catalog.containFunction(expr.getSignature(), paramTypes)) { - throw new NoSuchFunctionException(expr.getSignature(), paramTypes); + throw new UndefinedFunctionException(expr.getSignature(), paramTypes); } FunctionDesc funcDesc = catalog.getFunction(expr.getSignature(), paramTypes); @@ -205,7 +205,7 @@ public DataType visitGeneralSetFunction(LogicalPlanner.PlanContext ctx, Stack // the below checking against WINDOW_FUNCTIONS is a workaround code for the above problem. if (ExprAnnotator.WINDOW_FUNCTIONS.contains(funcName.toLowerCase())) { if (distinct) { - throw new NoSuchFunctionException("row_number() does not support distinct keyword."); + throw new UndefinedFunctionException("row_number() does not support distinct keyword."); } functionType = CatalogProtos.FunctionType.WINDOW; } else { @@ -255,7 +255,7 @@ public DataType visitWindowFunction(LogicalPlanner.PlanContext ctx, Stack } if (!catalog.containFunction(windowFunc.getSignature(), functionType, paramTypes)) { - throw new NoSuchFunctionException(funcName, paramTypes); + throw new UndefinedFunctionException(funcName, paramTypes); } FunctionDesc funcDesc = catalog.getFunction(funcName, functionType, paramTypes); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java index 30fbe910f5..c7b900eeaa 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java @@ -33,8 +33,7 @@ public class GeneralFunctionEval extends FunctionEval { protected FunctionInvoke funcInvoke; @Expose protected FunctionInvokeContext invokeContext; - public GeneralFunctionEval(OverridableConf queryContext, FunctionDesc desc, EvalNode[] givenArgs) - throws IOException { + public GeneralFunctionEval(OverridableConf queryContext, FunctionDesc desc, EvalNode[] givenArgs) { super(EvalType.FUNCTION, desc, givenArgs); this.invokeContext = new FunctionInvokeContext(queryContext, getParamType()); } @@ -58,8 +57,7 @@ public EvalNode bind(EvalContext evalContext, Schema schema) { @SuppressWarnings("unchecked") public Datum eval(Tuple tuple) { super.eval(tuple); - Datum res = funcInvoke.eval(evalParams(tuple)); - return res; + return funcInvoke.eval(evalParams(tuple)); } @Override diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/NameResolver.java b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/NameResolver.java index 633b30e8b3..dfcff9d6d1 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/NameResolver.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/NameResolver.java @@ -22,12 +22,10 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.tajo.algebra.ColumnReferenceExpr; -import org.apache.tajo.algebra.Relation; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Column; -import org.apache.tajo.catalog.NestedPathUtil; import org.apache.tajo.catalog.Schema; -import org.apache.tajo.catalog.exception.NoSuchColumnException; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.plan.algebra.AmbiguousFieldException; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.PlanningException; @@ -192,7 +190,7 @@ static Column resolveFromRelsWithinBlock(LogicalPlan plan, LogicalPlan.QueryBloc * @return The found column */ static Column resolveFromCurrentAndChildNode(LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef) - throws NoSuchColumnException { + throws UndefinedColumnException { if (block.getCurrentNode() != null && block.getCurrentNode().getInSchema() != null) { Column found = block.getCurrentNode().getInSchema().getColumn(columnRef.getCanonicalName()); @@ -355,7 +353,7 @@ static Pair lookupQualifierAndCanonicalName(LogicalPlan.QueryBlo // throw exception if no column cannot be founded or two or more than columns are founded if (guessedRelations.size() == 0) { - throw new NoSuchColumnException(columnRef.getQualifier()); + throw new UndefinedColumnException(columnRef.getQualifier()); } else if (guessedRelations.size() > 1) { throw new AmbiguousFieldException(columnRef.getCanonicalName()); } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRelsAndSubExprs.java b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRelsAndSubExprs.java index f48611745c..2a8319cdcb 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRelsAndSubExprs.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRelsAndSubExprs.java @@ -20,7 +20,7 @@ import org.apache.tajo.algebra.ColumnReferenceExpr; import org.apache.tajo.catalog.Column; -import org.apache.tajo.catalog.exception.NoSuchColumnException; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.PlanningException; @@ -35,7 +35,7 @@ public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnRefe } if (column == null) { - throw new NoSuchColumnException(columnRef.getCanonicalName()); + throw new UndefinedColumnException(columnRef.getCanonicalName()); } return column; } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java b/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java index 3b1f1a8fc5..cd56a51323 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java @@ -323,7 +323,7 @@ private void updateTableStat(OverridableConf queryContext, PartitionedTableScanN totalVolume += summary.getFileCount(); } scanNode.getTableDesc().getStats().setNumBytes(totalVolume); - } catch (IOException e) { + } catch (Throwable e) { throw new PlanningException(e); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/EvalNodeDeserializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/EvalNodeDeserializer.java index 72373cfac7..05f95df8b8 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/EvalNodeDeserializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/EvalNodeDeserializer.java @@ -27,7 +27,7 @@ import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.FunctionDesc; import org.apache.tajo.catalog.SortSpec; -import org.apache.tajo.catalog.exception.NoSuchFunctionException; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionSignatureProto; import org.apache.tajo.common.TajoDataTypes.DataType; @@ -229,19 +229,15 @@ public int compare(PlanProto.EvalNode o1, PlanProto.EvalNode o2) { DataType[] parameterTypes = new DataType[0]; if (funcProto.getFuncion() != null && funcProto.getFuncion().getSignature() != null) { FunctionSignatureProto funcSignatureProto = funcProto.getFuncion().getSignature(); - + if (funcSignatureProto.hasName()) { functionName = funcSignatureProto.getName(); } - + parameterTypes = funcSignatureProto.getParameterTypesList().toArray( new DataType[funcSignatureProto.getParameterTypesCount()]); } - throw new NoSuchFunctionException(functionName, parameterTypes); - } catch (InternalException ie) { - throw new NoSuchFunctionException(funcDesc.getFunctionName(), funcDesc.getParamTypes()); - } catch (IOException e) { - throw new NoSuchFunctionException(e.getMessage()); + throw new UndefinedFunctionException(functionName, parameterTypes); } } else { throw new RuntimeException("Unknown EvalType: " + type.name()); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/ExprsVerifier.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/ExprsVerifier.java index bc6e69601a..212fa9e69d 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/ExprsVerifier.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/ExprsVerifier.java @@ -19,6 +19,10 @@ package org.apache.tajo.plan.verifier; import org.apache.tajo.catalog.Column; +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.TajoInternalError; +import org.apache.tajo.exception.UndefinedOperatorException; import org.apache.tajo.plan.PlanningException; import org.apache.tajo.plan.expr.*; import org.apache.tajo.plan.logical.LogicalNode; @@ -49,7 +53,7 @@ public static VerificationState verify(VerificationState state, LogicalNode curr Set referredColumns = EvalTreeUtil.findUniqueColumns(expression); for (Column referredColumn : referredColumns) { if (!currentNode.getInSchema().contains(referredColumn)) { - throw new PlanningException("Invalid State: " + referredColumn + " cannot be accessible at Node (" + throw new TajoInternalError("Invalid State: " + referredColumn + " cannot be accessible at Node (" + currentNode.getPID() + ")"); } } @@ -86,7 +90,7 @@ private static void verifyComparisonOperator(VerificationState state, BinaryEval DataType leftType = expr.getLeftExpr().getValueType(); DataType rightType = expr.getRightExpr().getValueType(); if (!isCompatibleType(leftType, rightType)) { - state.addVerification("No operator matches the given name and argument type(s): " + expr.toString()); + state.addVerification(new UndefinedOperatorException(expr.toString())); } } @@ -134,7 +138,7 @@ private static void checkDivisionByZero(VerificationState state, BinaryEval eval if (evalNode.getRightExpr().getType() == EvalType.CONST) { ConstEval constEval = evalNode.getRightExpr(); if (constEval.getValue().asFloat8() == 0) { - state.addVerification("division by zero"); + state.addVerification(new TajoException(Errors.ResultCode.DIVISION_BY_ZERO, evalNode.toString())); } } } @@ -173,7 +177,7 @@ private static void checkArithmeticOperand(VerificationState state, BinaryEval e } if (!(checkNumericType(leftDataType) && checkNumericType(rightDataType))) { - state.addVerification("No operator matches the given name and argument type(s): " + evalNode.toString()); + state.addVerification(new UndefinedOperatorException(evalNode.toString())); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/LogicalPlanVerifier.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/LogicalPlanVerifier.java index c5ef8efa20..c6062e9091 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/LogicalPlanVerifier.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/LogicalPlanVerifier.java @@ -23,9 +23,11 @@ import org.apache.tajo.catalog.CatalogService; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.Schema; -import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.common.TajoDataTypes.Type; import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.UnsupportedException; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.util.PlannerUtil; import org.apache.tajo.plan.PlanningException; @@ -35,6 +37,10 @@ import java.util.Stack; +import static org.apache.tajo.plan.verifier.SyntaxErrorUtil.makeDataTypeMisMatch; +import static org.apache.tajo.plan.verifier.SyntaxErrorUtil.makeSetOpDataTypeMisMatch; +import static org.apache.tajo.plan.verifier.SyntaxErrorUtil.makeSyntaxError; + public class LogicalPlanVerifier extends BasicLogicalPlanVisitor { public LogicalPlanVerifier(TajoConf conf, CatalogService catalog) { } @@ -71,16 +77,13 @@ private static void verifyProjectableOutputSchema(Context context, Projectable n Column outputColumn = outputSchema.getColumn(i); if (outputColumn.getDataType().getType() == Type.RECORD) { - context.state.addVerification("Projecting RECORD fields is not supported yet."); + context.state.addVerification(new UnsupportedException("RECORD field projection")); } if (!outputColumn.getDataType().equals(targetSchema.getColumn(i).getDataType())) { Column targetColumn = targetSchema.getColumn(i); Column insertColumn = outputColumn; - throw new PlanningException("ERROR: " + - insertColumn.getSimpleName() + " is of type " + insertColumn.getDataType().getType().name() + - ", but target column '" + targetColumn.getSimpleName() + "' is of type " + - targetColumn.getDataType().getType().name()); + throw new PlanningException(SyntaxErrorUtil.makeDataTypeMisMatch(insertColumn, targetColumn)); } } } @@ -105,7 +108,7 @@ public LogicalNode visitLimit(Context context, LogicalPlan plan, LogicalPlan.Que super.visitLimit(context, plan, block, node, stack); if (node.getFetchFirstNum() < 0) { - context.state.addVerification("LIMIT must not be negative"); + context.state.addVerification(makeSyntaxError("LIMIT must not be negative")); } return node; @@ -151,7 +154,7 @@ private void verifySetStatement(VerificationState state, BinaryNode setNode) { NodeType type = setNode.getType(); if (left.size() != right.size()) { - state.addVerification("each " + type.name() + " query must have the same number of columns"); + state.addVerification(new TajoException(Errors.ResultCode.AMBIGUOUS_FUNCTION)); return; } @@ -160,8 +163,9 @@ private void verifySetStatement(VerificationState state, BinaryNode setNode) { for (int i = 0; i < leftColumns.length; i++) { if (!leftColumns[i].getDataType().equals(rightColumns[i].getDataType())) { - state.addVerification(type + " types " + leftColumns[i].getDataType().getType() + " and " - + rightColumns[i].getDataType().getType() + " cannot be matched"); + state.addVerification( + makeSetOpDataTypeMisMatch(type, leftColumns[i].getDataType(), rightColumns[i].getDataType()) + ); } } } @@ -245,10 +249,7 @@ private static void ensureDomains(VerificationState state, Schema targetTableSch if (!schema.getColumn(i).getDataType().equals(targetTableScheme.getColumn(i).getDataType())) { Column targetColumn = targetTableScheme.getColumn(i); Column insertColumn = schema.getColumn(i); - state.addVerification("ERROR: " + - insertColumn.getSimpleName() + " is of type " + insertColumn.getDataType().getType().name() + - ", but target column '" + targetColumn.getSimpleName() + "' is of type " + - targetColumn.getDataType().getType().name()); + state.addVerification(makeDataTypeMisMatch(insertColumn, targetColumn)); } } } 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 09160abc1d..92813fdad3 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 @@ -26,7 +26,9 @@ import org.apache.tajo.catalog.CatalogService; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.catalog.exception.*; +import org.apache.tajo.exception.ExceptionUtil; +import org.apache.tajo.exception.UnimplementedException; import org.apache.tajo.plan.util.ExprFinder; import org.apache.tajo.plan.PlanningException; import org.apache.tajo.plan.algebra.BaseAlgebraVisitor; @@ -37,6 +39,9 @@ import java.util.Set; import java.util.Stack; +import static org.apache.tajo.catalog.exception.CatalogExceptionUtil.makeUndefinedTable; +import static org.apache.tajo.plan.verifier.SyntaxErrorUtil.makeSyntaxError; + public class PreLogicalPlanVerifier extends BaseAlgebraVisitor { private CatalogService catalog; @@ -71,7 +76,7 @@ public Expr visitSetSession(Context ctx, Stack stack, SetSession expr) thr Collection violations = var.validator().validate(expr.getValue()); for (ConstraintViolation violation : violations) { - ctx.state.addVerification(violation.getMessage()); + ctx.state.addVerification(SyntaxErrorUtil.makeInvalidSessionVar(var.keyname(), violation.getMessage())); } } } @@ -88,8 +93,7 @@ public Expr visitProjection(Context context, Stack stack, Projection expr) if (namedExpr.hasAlias()) { if (names.contains(namedExpr.getAlias())) { - context.state.addVerification(String.format("column name \"%s\" specified more than once", - namedExpr.getAlias())); + context.state.addVerification(SyntaxErrorUtil.makeDuplicateAlias(namedExpr.getAlias())); } else { names.add(namedExpr.getAlias()); } @@ -103,7 +107,7 @@ public Expr visitLimit(Context context, Stack stack, Limit expr) throws Pl stack.push(expr); if (ExprFinder.finds(expr.getFetchFirstNum(), OpType.Column).size() > 0) { - context.state.addVerification("argument of LIMIT must not contain variables"); + context.state.addVerification(SyntaxErrorUtil.makeSyntaxError("argument of LIMIT must not contain variables")); } visit(context, stack, expr.getFetchFirstNum()); @@ -119,7 +123,7 @@ public Expr visitGroupBy(Context context, Stack stack, Aggregation expr) t // Enforcer only ordinary grouping set. for (Aggregation.GroupElement groupingElement : expr.getGroupSet()) { if (groupingElement.getType() != Aggregation.GroupType.OrdinaryGroup) { - context.state.addVerification(groupingElement.getType() + " is not supported yet"); + context.state.addVerification(ExceptionUtil.makeNotSupported(groupingElement.getType().name())); } } @@ -154,7 +158,7 @@ private boolean assertRelationExistence(Context context, String tableName) { } if (!catalog.existsTable(qualifiedName)) { - context.state.addVerification(String.format("relation \"%s\" does not exist", qualifiedName)); + context.state.addVerification(makeUndefinedTable(qualifiedName)); return false; } return true; @@ -172,7 +176,7 @@ private boolean assertRelationNoExistence(Context context, String tableName) { System.out.println("A"); } if (catalog.existsTable(qualifiedName)) { - context.state.addVerification(String.format("relation \"%s\" already exists", qualifiedName)); + context.state.addVerification(CatalogExceptionUtil.makeDuplicateTable(qualifiedName)); return false; } return true; @@ -182,7 +186,7 @@ private boolean assertSupportedStoreType(VerificationState state, String name) { Preconditions.checkNotNull(name); if (name.equalsIgnoreCase("RAW")) { - state.addVerification(String.format("Store format %s is not supported.", name)); + state.addVerification(SyntaxErrorUtil.makeUnknownDataformat(name)); return false; } return true; @@ -190,7 +194,7 @@ private boolean assertSupportedStoreType(VerificationState state, String name) { private boolean assertDatabaseExistence(VerificationState state, String name) { if (!catalog.existDatabase(name)) { - state.addVerification(String.format("database \"%s\" does not exist", name)); + state.addVerification(new UndefinedDatabaseException(name)); return false; } return true; @@ -198,7 +202,7 @@ private boolean assertDatabaseExistence(VerificationState state, String name) { private boolean assertDatabaseNoExistence(VerificationState state, String name) { if (catalog.existDatabase(name)) { - state.addVerification(String.format("database \"%s\" already exists", name)); + state.addVerification(new DuplicateDatabaseException(name)); return false; } return true; @@ -283,9 +287,9 @@ public Expr visitInsert(Context context, Stack stack, Insert expr) throws int targetColumnNum = expr.getTargetColumns().length; if (targetColumnNum > projectColumnNum) { - context.state.addVerification("INSERT has more target columns than expressions"); + context.state.addVerification(makeSyntaxError("INSERT has more target columns than expressions")); } else if (targetColumnNum < projectColumnNum) { - context.state.addVerification("INSERT has more expressions than target columns"); + context.state.addVerification(makeSyntaxError("INSERT has more expressions than target columns")); } } else { if (expr.hasTableName()) { @@ -297,16 +301,17 @@ public Expr visitInsert(Context context, Stack stack, Insert expr) throws TableDesc table = catalog.getTableDesc(qualifiedName); if (table == null) { - context.state.addVerification(String.format("relation \"%s\" does not exist", qualifiedName)); + context.state.addVerification(new UndefinedTbleException(qualifiedName)); return null; } if (table.hasPartition()) { int columnSize = table.getSchema().getRootColumns().size(); columnSize += table.getPartitionMethod().getExpressionSchema().getRootColumns().size(); + if (projectColumnNum < columnSize) { - context.state.addVerification("INSERT has smaller expressions than target columns"); + context.state.addVerification(makeSyntaxError("INSERT has smaller expressions than target columns")); } else if (projectColumnNum > columnSize) { - context.state.addVerification("INSERT has more expressions than target columns"); + context.state.addVerification(makeSyntaxError("INSERT has more expressions than target columns")); } } } @@ -323,7 +328,7 @@ public Expr visitAlterTable(Context context, Stack stack, AlterTable expr) if (expr.getAlterTableOpType() == AlterTableOpType.ADD_PARTITION || expr.getAlterTableOpType() == AlterTableOpType.DROP_PARTITION) { - context.state.addVerification(expr.getAlterTableOpType().name() + " is not supported yet"); + context.state.addVerification(new UnimplementedException(expr.getAlterTableOpType().name())); } return expr; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorException.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorException.java new file mode 100644 index 0000000000..ff556c19af --- /dev/null +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorException.java @@ -0,0 +1,29 @@ +/* + * 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.plan.verifier; + +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.TajoException; + +public class SyntaxErrorException extends TajoException { + + public SyntaxErrorException(Errors.ResultCode code, String ... args) { + super(code, args); + } +} diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java new file mode 100644 index 0000000000..98fb290a7f --- /dev/null +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java @@ -0,0 +1,54 @@ +/* + * 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.plan.verifier; + +import org.apache.tajo.catalog.Column; +import org.apache.tajo.common.TajoDataTypes.DataType; +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.plan.logical.NodeType; + +public class SyntaxErrorUtil { + + public static SyntaxErrorException makeSyntaxError(String message) { + return new SyntaxErrorException(ResultCode.SYNTAX_ERROR, message); + } + + public static SyntaxErrorException makeDataTypeMisMatch(Column src, Column target) { + return new SyntaxErrorException(ResultCode.DATATYPE_MISMATCH, + src.getSimpleName(), src.getDataType().getType().name(), + target.getSimpleName(), target.getDataType().getType().name()); + } + + public static SyntaxErrorException makeSetOpDataTypeMisMatch(NodeType type, DataType src, DataType target) { + return new SyntaxErrorException(ResultCode.SET_OPERATION_DATATYPE_MISMATCH, + type.name(), src.getType().name(), target.getType().name()); + } + + public static SyntaxErrorException makeDuplicateAlias(String name) { + return new SyntaxErrorException(ResultCode.DUPLICATE_ALIAS, name); + } + + public static SyntaxErrorException makeUnknownDataformat(String format) { + return new SyntaxErrorException(ResultCode.UNKNOWN_DATAFORMAT, format); + } + + public static SyntaxErrorException makeInvalidSessionVar(String varName, String message) { + return new SyntaxErrorException(ResultCode.INVALID_SESSION_VARIABLE, varName, message); + } +} diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/VerificationState.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/VerificationState.java index a27b2007d7..d20f8f92d8 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/VerificationState.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/VerificationState.java @@ -21,16 +21,24 @@ import com.google.common.collect.Lists; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.TajoExceptionInterface; +import org.apache.tajo.exception.TajoRuntimeException; import org.apache.tajo.util.TUtil; import java.util.List; public class VerificationState { private static final Log LOG = LogFactory.getLog(VerificationState.class); - List errorMessages = Lists.newArrayList(); + List errorMessages = Lists.newArrayList(); - public void addVerification(String error) { - LOG.warn(TUtil.getCurrentCodePoint(1) + " causes: " + error); + public void addVerification(TajoException error) { + LOG.warn(TUtil.getCurrentCodePoint(1) + " causes: " + error.getMessage()); + errorMessages.add(error); + } + + public void addVerification(TajoRuntimeException error) { + LOG.warn(TUtil.getCurrentCodePoint(1) + " causes: " + error.getMessage()); errorMessages.add(error); } @@ -38,7 +46,7 @@ public boolean verified() { return errorMessages.size() == 0; } - public List getErrorMessages() { + public List getErrors() { return errorMessages; } } diff --git a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineDeserializer.java b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineDeserializer.java index 0d1c94af54..73b7592182 100644 --- a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineDeserializer.java +++ b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineDeserializer.java @@ -26,21 +26,18 @@ import org.apache.tajo.catalog.*; import org.apache.commons.net.util.Base64; import org.apache.tajo.catalog.Schema; -import org.apache.tajo.catalog.SchemaUtil; import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.common.TajoDataTypes.Type; -import org.apache.tajo.common.exception.NotImplementedException; import org.apache.tajo.datum.DatumFactory; import org.apache.tajo.datum.NullDatum; import org.apache.tajo.datum.TextDatum; +import org.apache.tajo.exception.UnimplementedException; import org.apache.tajo.storage.Tuple; import org.apache.tajo.storage.text.TextLineDeserializer; import org.apache.tajo.storage.text.TextLineParsingError; -import org.apache.tajo.util.StringUtils; import org.apache.tajo.util.TUtil; import java.io.IOException; -import java.util.Iterator; import java.util.Map; public class JsonLineDeserializer extends TextLineDeserializer { @@ -238,7 +235,7 @@ private void getValue(JSONObject object, break; default: - throw new NotImplementedException(types.get(fullPath).name() + " is not supported."); + throw new UnimplementedException(types.get(fullPath).name() + " is not supported."); } } diff --git a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineSerializer.java b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineSerializer.java index 60c32a7756..4d5d2e6bf0 100644 --- a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineSerializer.java +++ b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/json/JsonLineSerializer.java @@ -25,9 +25,8 @@ import org.apache.tajo.catalog.SchemaUtil; import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.common.TajoDataTypes.Type; -import org.apache.tajo.common.exception.NotImplementedException; import org.apache.tajo.datum.TextDatum; -import org.apache.tajo.datum.protobuf.ProtobufJsonFormat; +import org.apache.tajo.exception.UnimplementedException; import org.apache.tajo.storage.Tuple; import org.apache.tajo.storage.text.TextLineSerializer; @@ -112,7 +111,7 @@ public int serialize(OutputStream out, Tuple input) throws IOException { break; default: - throw new NotImplementedException(types[i].name() + " is not supported."); + throw new UnimplementedException(types[i].name() + " is not supported."); } } diff --git a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/text/DelimitedLineReader.java b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/text/DelimitedLineReader.java index f15861c7c9..b73f96b621 100644 --- a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/text/DelimitedLineReader.java +++ b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/text/DelimitedLineReader.java @@ -30,8 +30,8 @@ import org.apache.hadoop.io.compress.CompressionCodecFactory; import org.apache.hadoop.io.compress.Decompressor; import org.apache.hadoop.io.compress.SplittableCompressionCodec; -import org.apache.tajo.common.exception.NotImplementedException; import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.exception.UnimplementedException; import org.apache.tajo.exception.UnsupportedException; import org.apache.tajo.storage.*; import org.apache.tajo.storage.compress.CodecPool; @@ -72,7 +72,7 @@ public DelimitedLineReader(Configuration conf, final FileFragment fragment, int this.bufferSize = bufferSize; if (this.codec instanceof SplittableCompressionCodec) { // bzip2 does not support multi-thread model - throw new NotImplementedException(this.getClass() + " does not support " + this.codec.getDefaultExtension()); + throw new UnimplementedException(this.getClass() + " does not support " + this.codec.getDefaultExtension()); } } From 4402c6818e9986650c4cec763b5ecc3ae5eab572 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Wed, 1 Jul 2015 16:15:17 -0700 Subject: [PATCH 06/30] Fixed many bugs. --- .../exception/CatalogExceptionUtil.java | 4 ++ .../tajo/catalog/store/HiveCatalogUtil.java | 40 ++++++++++--------- .../apache/tajo/client/ClientErrorUtil.java | 10 ++++- .../apache/tajo/client/QueryClientImpl.java | 10 ++--- tajo-client/src/main/proto/ClientProtos.proto | 6 +-- .../apache/tajo/exception/ErrorMessages.java | 27 +++++++++---- .../apache/tajo/exception/ExceptionUtil.java | 24 ++++++++++- .../exception/InvalidDataTypeException.java | 20 ++++------ .../tajo/exception/UnsupportedException.java | 4 +- tajo-common/src/main/proto/errors.proto | 24 ++++++----- .../org/apache/tajo/master/GlobalEngine.java | 14 +++++-- .../tajo/master/TajoMasterClientService.java | 18 ++++----- .../apache/tajo/engine/eval/ExprTestBase.java | 4 +- .../testAlterTableAddPartition.result | 2 +- .../testAlterTableDropPartition.result | 2 +- .../TestTajoCli/testStopWhenError.result | 2 +- .../testStopWhenErrorDeprecated.result | 2 +- .../org/apache/tajo/plan/LogicalPlanner.java | 20 +++++----- .../apache/tajo/plan/PlanningException.java | 9 ++--- .../plan/nameresolver/ResolverByLegacy.java | 6 +-- .../plan/nameresolver/ResolverByRels.java | 4 +- .../ResolverBySubExprsAndRels.java | 4 +- .../plan/verifier/PreLogicalPlanVerifier.java | 2 +- .../tajo/plan/verifier/SyntaxErrorUtil.java | 8 ++-- 24 files changed, 155 insertions(+), 111 deletions(-) rename tajo-plan/src/main/java/org/apache/tajo/plan/logical/NoSuchColumnException.java => tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java (59%) diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java index ce967050a7..5a3c73c1ec 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java @@ -56,4 +56,8 @@ public static CatalogException makeDuplicateTable(String tbName) { public static CatalogException makeCatalogUpgrade() { return new CatalogException(ResultCode.CAT_UPGRADE_REQUIRED); } + + public static CatalogException makeTMCNoMatchedDataType(String dataType) { + return new CatalogException(ResultCode.TMC_NO_MATCHED_DATATYPE, dataType); + } } diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java index 59910b84f9..06ff6b8f30 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java @@ -26,50 +26,54 @@ import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.tajo.catalog.exception.CatalogException; +import org.apache.tajo.catalog.exception.CatalogExceptionUtil; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.common.TajoDataTypes; +import org.apache.tajo.exception.ExceptionUtil; import org.apache.thrift.TException; import parquet.hadoop.mapred.DeprecatedParquetOutputFormat; +import static org.apache.tajo.exception.ExceptionUtil.makeNotSupported; + public class HiveCatalogUtil { public static void validateSchema(Table tblSchema) throws CatalogException { for (FieldSchema fieldSchema : tblSchema.getCols()) { String fieldType = fieldSchema.getType(); if (fieldType.equalsIgnoreCase("ARRAY") || fieldType.equalsIgnoreCase("STRUCT") || fieldType.equalsIgnoreCase("MAP")) { - throw new CatalogException("Unsupported field type :" + fieldType.toUpperCase()); + throw makeNotSupported(fieldType.toUpperCase()); } } } - public static TajoDataTypes.Type getTajoFieldType(String fieldType) { - Preconditions.checkNotNull(fieldType); + public static TajoDataTypes.Type getTajoFieldType(String dataType) { + Preconditions.checkNotNull(dataType); - if(fieldType.equalsIgnoreCase(serdeConstants.INT_TYPE_NAME)) { + if(dataType.equalsIgnoreCase(serdeConstants.INT_TYPE_NAME)) { return TajoDataTypes.Type.INT4; - } else if(fieldType.equalsIgnoreCase(serdeConstants.TINYINT_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.TINYINT_TYPE_NAME)) { return TajoDataTypes.Type.INT1; - } else if(fieldType.equalsIgnoreCase(serdeConstants.SMALLINT_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.SMALLINT_TYPE_NAME)) { return TajoDataTypes.Type.INT2; - } else if(fieldType.equalsIgnoreCase(serdeConstants.BIGINT_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.BIGINT_TYPE_NAME)) { return TajoDataTypes.Type.INT8; - } else if(fieldType.equalsIgnoreCase(serdeConstants.BOOLEAN_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.BOOLEAN_TYPE_NAME)) { return TajoDataTypes.Type.BOOLEAN; - } else if(fieldType.equalsIgnoreCase(serdeConstants.FLOAT_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.FLOAT_TYPE_NAME)) { return TajoDataTypes.Type.FLOAT4; - } else if(fieldType.equalsIgnoreCase(serdeConstants.DOUBLE_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.DOUBLE_TYPE_NAME)) { return TajoDataTypes.Type.FLOAT8; - } else if(fieldType.equalsIgnoreCase(serdeConstants.STRING_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.STRING_TYPE_NAME)) { return TajoDataTypes.Type.TEXT; - } else if(fieldType.equalsIgnoreCase(serdeConstants.BINARY_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.BINARY_TYPE_NAME)) { return TajoDataTypes.Type.BLOB; - } else if(fieldType.equalsIgnoreCase(serdeConstants.TIMESTAMP_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.TIMESTAMP_TYPE_NAME)) { return TajoDataTypes.Type.TIMESTAMP; - } else if(fieldType.equalsIgnoreCase(serdeConstants.DATE_TYPE_NAME)) { + } else if(dataType.equalsIgnoreCase(serdeConstants.DATE_TYPE_NAME)) { return TajoDataTypes.Type.DATE; } else { - throw new CatalogException("Cannot find a matched type against from '" + fieldType + "'"); + throw CatalogExceptionUtil.makeTMCNoMatchedDataType(dataType); } } @@ -95,7 +99,7 @@ public static String getHiveFieldType(TajoDataTypes.DataType dataType) { case DATE: return serdeConstants.DATE_TYPE_NAME; case TIMESTAMP: return serdeConstants.TIMESTAMP_TYPE_NAME; default: - throw new CatalogException(dataType + " is not supported."); + throw ExceptionUtil.makeInvalidDataType(dataType); } } @@ -104,7 +108,7 @@ public static String getStoreType(String fileFormat) { String[] fileFormatArrary = fileFormat.split("\\."); if(fileFormatArrary.length < 1) { - throw new CatalogException("Hive file output format is wrong. - file output format:" + fileFormat); + throw makeNotSupported(fileFormat); } String outputFormatClass = fileFormatArrary[fileFormatArrary.length-1]; @@ -117,7 +121,7 @@ public static String getStoreType(String fileFormat) { } else if(outputFormatClass.equals(DeprecatedParquetOutputFormat.class.getSimpleName())) { return CatalogProtos.StoreType.PARQUET.name(); } else { - throw new CatalogException("Not supported file output format. - file output format:" + fileFormat); + throw makeNotSupported(fileFormat); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java index 3a6adad15c..90628c0746 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java @@ -47,7 +47,7 @@ public static ResponseState returnError(ResultCode code) { return builder.build(); } - private static ResponseState returnError(ResultCode code, String...args) { + public static ResponseState returnError(ResultCode code, String...args) { Preconditions.checkNotNull(args); ResponseState.Builder builder = ResponseState.newBuilder(); @@ -104,6 +104,14 @@ public static ResponseState ERR_NO_SUCH_QUERY_ID(QueryId queryId) { return returnError(ResultCode.NO_SUCH_QUERYID, queryId.toString()); } + public static ResponseState ERR_NO_DATA(QueryId queryId) { + return returnError(ResultCode.NO_DATA, queryId.toString()); + } + + public static ResponseState ERR_INCOMPLETE_QUERY(QueryId queryId) { + return returnError(ResultCode.INCOMPLETE_QUERY, queryId.toString()); + } + public static ResponseState ERR_INVALID_SESSION(String sessionId) { return returnError(ResultCode.INVALID_SESSION, sessionId); } 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 37afba6e78..da7849373f 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 @@ -387,13 +387,11 @@ public boolean updateQuery(final String sql) throws ServiceException { builder.setIsJson(false); ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - if (isError(response.getState())) { + if (isSuccess(response.getState())) { connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return true; } else { - if (response.hasErrorMessage()) { - LOG.error("ERROR: " + response.getErrorMessage()); - } + LOG.error("ERROR: " + response.getState().getMessage()); return false; } } @@ -413,9 +411,7 @@ public boolean updateQueryWithJson(final String json) throws ServiceException { if (isSuccess(response.getState())) { return true; } else { - if (response.hasErrorMessage()) { - LOG.error("ERROR: " + response.getErrorMessage()); - } + LOG.error("ERROR: " + response.getState().getMessage()); return false; } } diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index 207c7cb106..73f9882cc3 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -78,8 +78,7 @@ message QueryRequest { message UpdateQueryResponse { required ResponseState state = 1; - optional string errorMessage = 2; - optional KeyValueSetProto sessionVars = 3; + optional KeyValueSetProto sessionVars = 2; } message GetQueryResultRequest { @@ -90,8 +89,7 @@ message GetQueryResultRequest { message GetQueryResultResponse { required ResponseState state = 1; optional TableDescProto tableDesc = 2; - optional string errorMessage = 3; - optional string tajoUserName = 4; + optional string tajoUserName = 3; } message QueryIdRequest { 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 bfbdfce028..10517c8e7e 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 @@ -30,23 +30,32 @@ public class ErrorMessages { static { MESSAGES = Maps.newHashMap(); - ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "internal Error: %s", 1); + // Warnings + + // General Errors + ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "internal error: %s", 1); + ADD_MESSAGE(ResultCode.NOT_IMPLEMENTED, "not implemented feature: %s", 1); + ADD_MESSAGE(ResultCode.UNSUPPORTED, "unsupported feature: %s", 1); ADD_MESSAGE(ResultCode.INVALID_RPC_CALL, "invalid RPC Call: %s", 1); - ADD_MESSAGE(ResultCode.NO_SUCH_QUERYID, "query id '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.NO_DATA, "no data due to query failure or error"); - ADD_MESSAGE(ResultCode.INCOMPLETE_QUERY, "query '%s' is stilling running", 1); + // Query Management and Scheduler + ADD_MESSAGE(ResultCode.NO_SUCH_QUERYID, "query %s does not exist", 1); + ADD_MESSAGE(ResultCode.NO_DATA, "no data for %s due to query failure or error", 1); + ADD_MESSAGE(ResultCode.INCOMPLETE_QUERY, "query %s is stilling running", 1); + // Session ADD_MESSAGE(ResultCode.INVALID_SESSION, "invalid Session '%s'", 1); ADD_MESSAGE(ResultCode.NO_SUCH_SESSION_VARIABLE, "no such session variable '%s", 1); ADD_MESSAGE(ResultCode.INVALID_SESSION_VARIABLE, "invalid session variable '%s': %s", 2); + ADD_MESSAGE(ResultCode.INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s"); ADD_MESSAGE(ResultCode.SYNTAX_ERROR, "%s", 1); ADD_MESSAGE(ResultCode.UNDEFINED_DATABASE, "database '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "table '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_SCHEMA, "schema '%s' does not exist", 1); + ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "relation '%s' does not exist", 1); ADD_MESSAGE(ResultCode.UNDEFINED_COLUMN, "column '%s' does not exist", 1); ADD_MESSAGE(ResultCode.UNDEFINED_FUNCTION, "function does not exist: %s", 1); ADD_MESSAGE(ResultCode.UNDEFINED_OPERATOR, "operator does not exist: '%s'", 1); @@ -67,8 +76,10 @@ public class ErrorMessages { ADD_MESSAGE(ResultCode.SET_OPERATION_SCHEMA_MISMATCH, "each %s query must have the same number of columns", 1); ADD_MESSAGE(ResultCode.SET_OPERATION_DATATYPE_MISMATCH, "%s types %s and %s cannot be matched"); - ADD_MESSAGE(ResultCode.CAT_UPGRADE_REQUIRED, "Catalog must be upgraded"); - ADD_MESSAGE(ResultCode.CAT_CANNOT_CONNECT, "Cannot connect metadata store '%s': %s", 2); + ADD_MESSAGE(ResultCode.CAT_UPGRADE_REQUIRED, "catalog must be upgraded"); + ADD_MESSAGE(ResultCode.CAT_CANNOT_CONNECT, "cannot connect metadata store '%s': %s", 2); + + ADD_MESSAGE(ResultCode.TMC_NO_MATCHED_DATATYPE, "no matched type for %s", 1); ADD_MESSAGE(ResultCode.UNKNOWN_DATAFORMAT, "Unknown data format: '%s'", 1); } @@ -96,7 +107,7 @@ public static String getInternalErrorMessage(Throwable t) { public static String getMessage(ResultCode code, String...args) { if (!MESSAGES.containsKey(code)) { - throw new TajoRuntimeException(code, args); + throw new TajoInternalError("no error message for " + code); } else { Pair messageFormat = MESSAGES.get(code); diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java index da381660aa..9da78c38a7 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java @@ -18,11 +18,31 @@ package org.apache.tajo.exception; -import org.apache.tajo.error.Errors; +import org.apache.commons.logging.Log; +import org.apache.hadoop.util.StringUtils; +import org.apache.tajo.common.TajoDataTypes.DataType; public class ExceptionUtil { public static TajoRuntimeException makeNotSupported(String feature) { - return new TajoRuntimeException(Errors.ResultCode.NOT_SUPPORTED, feature); + return new UnsupportedException(feature); + } + + public static boolean isManagedException(Throwable t) { + return t instanceof TajoException || t instanceof TajoRuntimeException; + } + + public static InvalidDataTypeException makeInvalidDataType(DataType dataType) { + return new InvalidDataTypeException(dataType); + } + + private static void printStackTrace(Log log, Throwable t) { + log.error("\nStack Trace:\n" + StringUtils.stringifyException(t)); + } + + public static void printStackTraceIfError(Log log, Throwable t) { + if (!ExceptionUtil.isManagedException(t)) { + ExceptionUtil.printStackTrace(log, t); + } } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NoSuchColumnException.java b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java similarity index 59% rename from tajo-plan/src/main/java/org/apache/tajo/plan/logical/NoSuchColumnException.java rename to tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java index 94cef1efaf..9f470f293d 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NoSuchColumnException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -16,19 +16,15 @@ * limitations under the License. */ -package org.apache.tajo.plan.logical; +package org.apache.tajo.exception; +import org.apache.tajo.common.TajoDataTypes; +import org.apache.tajo.common.TajoDataTypes.DataType; +import org.apache.tajo.error.Errors; -import org.apache.tajo.plan.verifier.VerifyException; +public class InvalidDataTypeException extends TajoRuntimeException { -public class NoSuchColumnException extends VerifyException { - private static final long serialVersionUID = 277182608283894937L; - - public NoSuchColumnException(String databaseName, String relName, String columnName) { - super(String.format("ERROR: column \" %s.%s \" in %s does not exist", relName, columnName, databaseName)); - } - - public NoSuchColumnException(String columnName) { - super("ERROR: column \"" + columnName + "\" does not exist"); + public InvalidDataTypeException(DataType dataType) { + super(Errors.ResultCode.INVALID_DATATYPE, dataType.getType().name()); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java b/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java index 590c2ec931..a4d9977119 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java @@ -24,10 +24,10 @@ public class UnsupportedException extends TajoRuntimeException { private static final long serialVersionUID = 6702291354858193578L; public UnsupportedException(String featureName) { - super(Errors.ResultCode.NOT_SUPPORTED, featureName); + super(Errors.ResultCode.UNSUPPORTED, featureName); } public UnsupportedException() { - super(Errors.ResultCode.NOT_SUPPORTED, Thread.currentThread().getStackTrace()[1].getClassName()); + super(Errors.ResultCode.UNSUPPORTED, Thread.currentThread().getStackTrace()[1].getClassName()); } } diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index 9b9e1bd271..1e9b326cca 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -29,21 +29,20 @@ enum ResultCode { WARNING = 100; // Warning // General Errors - INTERNAL_ERROR = 201; // Error caused by internal bugs - ILLEGAL_STATE = 202; // Illegal state or unexpected state - NOT_IMPLEMENTED = 203; // Not implemented method - NOT_SUPPORTED = 204; // Not supported feature - INVALID_RPC_CALL = 205; // When invalid RPC call is invoked (e.g., wrong message and absent fields) + INTERNAL_ERROR = 201; // Error caused by internal bugs (See also TajoInternalException.java) + NOT_IMPLEMENTED = 202; // Planned, but not implemented yet. + UNSUPPORTED = 203; // Unsupported feature (usually for unreasonable feature) + INVALID_RPC_CALL = 204; // When invalid RPC call is invoked (e.g., wrong message and absent fields) // Query Management and Scheduler NO_SUCH_QUERYID = 300; // No query id in TajoMaster NO_DATA = 301; // No data due to query fail or error INCOMPLETE_QUERY = 302; // It occurs when a client requests something of a completed query. - // Session Errors - INVALID_SESSION = 401; - NO_SUCH_SESSION_VARIABLE = 402; - INVALID_SESSION_VARIABLE = 403; + // 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) // Data Exception (SQLState Class - 22) DIVISION_BY_ZERO = 451; // SQLState: 22012 - Division by zero @@ -99,15 +98,18 @@ enum ResultCode { // Expressions INVALID_EXPRESSION = 701; INVALID_CAST = 702; - UNKNOWN_DATATYPE = 703; + INVALID_DATATYPE = 703; //NUMERIC_OVERFLOW = 803; // Numeric value overflow //VALUE_LARGER_THAN_PRECISION = 804; // Value larger than column precision - // Metadata Connector + // Meta Catalog CAT_UPGRADE_REQUIRED = 901; // Migration CAT_CANNOT_CONNECT = 902; // Cannot connect metadata server + // Metadata Connector + TMC_NO_MATCHED_DATATYPE = 910; // No matched data type between Tajo and connector + // Storage and Data Format UNKNOWN_DATAFORMAT = 1001; // Unknown Data Format diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java index a6347f1900..c3788072ce 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java @@ -40,7 +40,10 @@ import org.apache.tajo.engine.parser.SQLAnalyzer; import org.apache.tajo.engine.parser.SQLSyntaxError; import org.apache.tajo.engine.query.QueryContext; +import org.apache.tajo.exception.ExceptionUtil; import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.TajoInternalError; +import org.apache.tajo.exception.TajoRuntimeException; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.master.exec.DDLExecutor; import org.apache.tajo.master.exec.QueryExecutor; @@ -186,9 +189,12 @@ public SubmitQueryResponse executeQuery(Session session, String query, boolean i LogicalPlan plan = createLogicalPlan(queryContext, planningContext); SubmitQueryResponse response = queryExecutor.execute(queryContext, session, query, jsonExpr, plan); return response; + + } catch (Throwable t) { + ExceptionUtil.printStackTraceIfError(LOG, t); + context.getSystemMetrics().counter("Query", "errorQuery").inc(); - LOG.error("\nStack Trace:\n" + StringUtils.stringifyException(t)); SubmitQueryResponse.Builder responseBuilder = SubmitQueryResponse.newBuilder(); responseBuilder.setUserName(queryContext.get(SessionVars.USERNAME)); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); @@ -241,9 +247,9 @@ public QueryId updateQuery(QueryContext queryContext, String sql, boolean isJson ddlExecutor.execute(queryContext, plan); return QueryIdFactory.NULL_QUERY_ID; } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - throw new IOException(e.getMessage(), e); + } catch (Throwable e) { + ExceptionUtil.printStackTraceIfError(LOG, e); + throw e; } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index bf116e51b9..bf224f360c 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -36,11 +36,9 @@ import org.apache.tajo.catalog.exception.UndefinedDatabaseException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; -import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; import org.apache.tajo.engine.query.QueryContext; -import org.apache.tajo.error.Errors; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.*; import org.apache.tajo.ipc.TajoMasterClientProtocol; @@ -330,7 +328,7 @@ public GetQueryResultResponse getQueryResult(RpcController controller, // the query result was expired due to timeout. // In this case, we will result in error. if (queryInfo == null) { - builder.setErrorMessage("No such query: " + queryId.toString()); + builder.setState(ERR_NO_SUCH_QUERY_ID(queryId)); return builder.build(); } @@ -343,11 +341,11 @@ public GetQueryResultResponse getQueryResult(RpcController controller, break; case QUERY_FAILED: case QUERY_ERROR: - builder.setState(ClientErrorUtil.returnError(Errors.ResultCode.NO_DATA)); + builder.setState(ERR_NO_DATA(queryId)); break; default: - builder.setState(ClientErrorUtil.returnError(Errors.ResultCode.INCOMPLETE_QUERY)); + builder.setState(ERR_INCOMPLETE_QUERY(queryId)); } return builder.build(); @@ -397,9 +395,10 @@ public GetQueryListResponse getRunningQueryList(RpcController controller, TajoId public GetQueryListResponse getFinishedQueryList(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { + GetQueryListResponse.Builder builder = GetQueryListResponse.newBuilder(); + try { context.getSessionManager().touch(request.getId()); - GetQueryListResponse.Builder builder = GetQueryListResponse.newBuilder(); Collection queries = context.getQueryJobManager().getFinishedQueries(); @@ -421,11 +420,12 @@ public GetQueryListResponse getFinishedQueryList(RpcController controller, TajoI builder.addQueryList(infoBuilder.build()); } - GetQueryListResponse result = builder.build(); - return result; + builder.setState(OK); } catch (Throwable t) { - throw new ServiceException(t); + builder.setState(returnError(t)); } + + return builder.build(); } @Override diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java index a8efb7dc7a..b9bdbf5938 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java @@ -146,14 +146,14 @@ private static Target[] getRawTargets(QueryContext context, String query, boolea if (!condition && state.getErrors().size() > 0) { throw new PlanningException(state.getErrors().get(0)); } - assertFalse(state.getErrors().get(0), true); + assertFalse(state.getErrors().get(0).getMessage(), true); } LogicalPlan plan = planner.createPlan(context, expr, true); optimizer.optimize(context, plan); annotatedPlanVerifier.verify(context, state, plan); if (state.getErrors().size() > 0) { - assertFalse(state.getErrors().get(0), true); + assertFalse(state.getErrors().get(0).getMessage(), true); } Target [] targets = plan.getRootBlock().getRawTargets(); diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddPartition.result b/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddPartition.result index 31f46bc4f3..595d9693da 100644 --- a/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddPartition.result +++ b/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddPartition.result @@ -1,2 +1,2 @@ OK -ERROR: ADD_PARTITION is not supported yet \ No newline at end of file +ERROR: not implemented feature: ADD_PARTITION \ No newline at end of file diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableDropPartition.result b/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableDropPartition.result index 1fadcea500..6af407d63f 100644 --- a/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableDropPartition.result +++ b/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableDropPartition.result @@ -1,2 +1,2 @@ OK -ERROR: DROP_PARTITION is not supported yet \ No newline at end of file +ERROR: not implemented feature: DROP_PARTITION \ No newline at end of file diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenError.result b/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenError.result index 183e6c5d79..e2e6b34143 100644 --- a/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenError.result +++ b/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenError.result @@ -2,4 +2,4 @@ ------------------------------- 5 (1 rows, , 2 B selected) -ERROR: relation "default.lineitem2" does not exist +ERROR: relation 'default.lineitem2' does not exist \ No newline at end of file diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenErrorDeprecated.result b/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenErrorDeprecated.result index 5c49139d0b..17b4d5662f 100644 --- a/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenErrorDeprecated.result +++ b/tajo-core/src/test/resources/results/TestTajoCli/testStopWhenErrorDeprecated.result @@ -3,4 +3,4 @@ Warning: deprecated to directly use config key in TajoConf.ConfVars. Please exec ------------------------------- 5 (1 rows, , 2 B selected) -ERROR: relation "default.lineitem2" does not exist +ERROR: relation 'default.lineitem2' does not exist \ No newline at end of file diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java index c51d068f90..825a34283f 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java @@ -35,10 +35,12 @@ import org.apache.tajo.algebra.*; import org.apache.tajo.algebra.WindowSpec; import org.apache.tajo.catalog.*; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.datum.NullDatum; +import org.apache.tajo.exception.ExceptionUtil; import org.apache.tajo.plan.LogicalPlan.QueryBlock; import org.apache.tajo.plan.algebra.BaseAlgebraVisitor; import org.apache.tajo.plan.expr.*; @@ -634,7 +636,7 @@ private LogicalNode insertWindowAggNode(PlanContext context, LogicalNode child, // TODO - Later, we also consider the possibility that a window function contains only a window name. rawWindowSpecs.add(((WindowFunctionExpr) (rawTarget.getExpr())).getWindowSpec()); } - } catch (VerifyException ve) { + } catch (UndefinedColumnException uc) { } } @@ -768,7 +770,7 @@ private LogicalNode insertGroupbyNode(PlanContext context, LogicalNode child, St aggEvals.add((AggregationFunctionCallEval) evalNode); block.namedExprsMgr.markAsEvaluated(rawTarget.getAlias(), evalNode); } - } catch (VerifyException ve) { + } catch (UndefinedColumnException ve) { } } @@ -1008,7 +1010,7 @@ public LogicalNode visitGroupBy(PlanContext context, Stack stack, Aggregat aggEvalNames.add(namedExpr.getAlias()); aggEvalNodes.add((AggregationFunctionCallEval) evalNode); } - } catch (VerifyException ve) { + } catch (UndefinedColumnException ve) { } } // if there is at least one distinct aggregation function @@ -1182,7 +1184,7 @@ private List getNewlyEvaluatedExprsForJoin(PlanContext context, JoinNode block.namedExprsMgr.markAsEvaluated(namedExpr.getAlias(), evalNode); newlyEvaluatedExprs.add(namedExpr.getAlias()); } - } catch (VerifyException ve) { + } catch (UndefinedColumnException ve) { } catch (PlanningException e) { } } @@ -1253,7 +1255,7 @@ private LogicalNode createCartesianProduct(PlanContext context, LogicalNode left block.namedExprsMgr.markAsEvaluated(namedExpr.getAlias(), evalNode); newlyEvaluatedExprs.add(namedExpr.getAlias()); } - } catch (VerifyException ve) {} + } catch (UndefinedColumnException ve) {} } List targets = TUtil.newList(PlannerUtil.schemaToTargets(merged)); @@ -1306,7 +1308,7 @@ public ScanNode visitRelation(PlanContext context, Stack stack, Relation e block.namedExprsMgr.markAsEvaluated(rawTarget.getAlias(), evalNode); newlyEvaluatedExprsReferences.add(rawTarget.getAlias()); // newly added exr } - } catch (VerifyException ve) { + } catch (UndefinedColumnException ve) { } } @@ -1391,7 +1393,7 @@ public TableSubQueryNode visitTableSubQuery(PlanContext context, Stack sta block.namedExprsMgr.markAsEvaluated(rawTarget.getAlias(), evalNode); newlyEvaluatedExprs.add(rawTarget.getAlias()); // newly added exr } - } catch (VerifyException ve) { + } catch (UndefinedColumnException ve) { } } @@ -1811,8 +1813,8 @@ public LogicalNode visitCreateTable(PlanContext context, Stack stack, Crea if (expr.getPartitionMethod().getPartitionType().equals(PartitionType.COLUMN)) { createTableNode.setPartitionMethod(getPartitionMethod(context, expr.getTableName(), expr.getPartitionMethod())); } else { - throw new PlanningException(String.format("Not supported PartitonType: %s", - expr.getPartitionMethod().getPartitionType())); + throw ExceptionUtil.makeNotSupported( + String.format("PartitonType " + expr.getPartitionMethod().getPartitionType())); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java b/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java index d63f4b6ef8..8f496005cc 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/PlanningException.java @@ -18,16 +18,13 @@ package org.apache.tajo.plan; -import org.apache.tajo.error.Errors.ResultCode; -import org.apache.tajo.exception.TajoException; - -public class PlanningException extends TajoException { +public class PlanningException extends Exception { public PlanningException(String message) { - super(ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION, message); + super(message); } public PlanningException(Throwable e) { - super(ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION, e.getMessage()); + super(e); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByLegacy.java b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByLegacy.java index 0a665ab68b..a94c29611e 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByLegacy.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByLegacy.java @@ -22,10 +22,10 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.Schema; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.PlanningException; import org.apache.tajo.plan.logical.LogicalNode; -import org.apache.tajo.plan.logical.NoSuchColumnException; import org.apache.tajo.plan.logical.NodeType; import org.apache.tajo.plan.logical.RelationNode; import org.apache.tajo.util.Pair; @@ -56,7 +56,7 @@ private static Column resolveColumnWithQualifier(LogicalPlan plan, LogicalPlan.Q Column found = resolveFromRelsWithinBlock(plan, block, columnRef); if (found == null) { - throw new NoSuchColumnException(columnRef.getCanonicalName()); + throw new UndefinedColumnException(columnRef.getCanonicalName()); } // If code reach here, a column is found. @@ -119,6 +119,6 @@ static Column resolveColumnWithoutQualifier(LogicalPlan plan, LogicalPlan.QueryB return found; } - throw new NoSuchColumnException("ERROR: no such a column name "+ columnRef.getCanonicalName()); + throw new UndefinedColumnException(columnRef.getCanonicalName()); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRels.java b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRels.java index a67a1caecd..1045ccef18 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRels.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverByRels.java @@ -20,9 +20,9 @@ import org.apache.tajo.algebra.ColumnReferenceExpr; import org.apache.tajo.catalog.Column; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.PlanningException; -import org.apache.tajo.plan.logical.NoSuchColumnException; public class ResolverByRels extends NameResolver { @Override @@ -31,7 +31,7 @@ public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnRefe Column column = resolveFromRelsWithinBlock(plan, block, columnRef); if (column == null) { - throw new NoSuchColumnException(columnRef.getCanonicalName()); + throw new UndefinedColumnException(columnRef.getCanonicalName()); } return column; } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverBySubExprsAndRels.java b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverBySubExprsAndRels.java index 3064fdee47..5de720e840 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverBySubExprsAndRels.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/nameresolver/ResolverBySubExprsAndRels.java @@ -20,9 +20,9 @@ import org.apache.tajo.algebra.ColumnReferenceExpr; import org.apache.tajo.catalog.Column; +import org.apache.tajo.catalog.exception.UndefinedColumnException; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.PlanningException; -import org.apache.tajo.plan.logical.NoSuchColumnException; public class ResolverBySubExprsAndRels extends NameResolver { @Override @@ -35,7 +35,7 @@ public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnRefe } if (column == null) { - throw new NoSuchColumnException(columnRef.getCanonicalName()); + throw new UndefinedColumnException(columnRef.getCanonicalName()); } return column; } 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 92813fdad3..87122e8d68 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 @@ -186,7 +186,7 @@ private boolean assertSupportedStoreType(VerificationState state, String name) { Preconditions.checkNotNull(name); if (name.equalsIgnoreCase("RAW")) { - state.addVerification(SyntaxErrorUtil.makeUnknownDataformat(name)); + state.addVerification(SyntaxErrorUtil.makeUnknownDataFormat(name)); return false; } return true; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java index 98fb290a7f..3c11b8ce6e 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/SyntaxErrorUtil.java @@ -44,11 +44,11 @@ public static SyntaxErrorException makeDuplicateAlias(String name) { return new SyntaxErrorException(ResultCode.DUPLICATE_ALIAS, name); } - public static SyntaxErrorException makeUnknownDataformat(String format) { - return new SyntaxErrorException(ResultCode.UNKNOWN_DATAFORMAT, format); - } - public static SyntaxErrorException makeInvalidSessionVar(String varName, String message) { return new SyntaxErrorException(ResultCode.INVALID_SESSION_VARIABLE, varName, message); } + + public static SyntaxErrorException makeUnknownDataFormat(String dataFormat) { + return new SyntaxErrorException(ResultCode.UNKNOWN_DATAFORMAT, dataFormat); + } } From 5c55013511433452ae8751ae4fd669696bea218a Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Wed, 1 Jul 2015 16:46:52 -0700 Subject: [PATCH 07/30] Fixed all unit tests. --- .../org/apache/tajo/engine/query/TestTablePartitions.java | 4 ++-- .../src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java index 903c72ca68..f9002ff770 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java @@ -866,7 +866,7 @@ public final void testColumnPartitionedTableWithSmallerExpressions1() throws Exc + " select l_orderkey, l_partkey from lineitem"); assertTrue(ClientErrorUtil.isError(response.getState())); - assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns\n"); + assertEquals("INSERT has smaller expressions than target columns", response.getState().getMessage()); res = executeFile("case14.sql"); assertResultSet(res, "case14.result"); @@ -892,7 +892,7 @@ public final void testColumnPartitionedTableWithSmallerExpressions2() throws Exc + " select l_returnflag , l_orderkey, l_partkey from lineitem"); assertTrue(ClientErrorUtil.isError(response.getState())); - assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns\n"); + assertEquals("INSERT has smaller expressions than target columns", response.getState().getMessage()); res = executeFile("case15.sql"); assertResultSet(res, "case15.result"); diff --git a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java index ad74046712..31d19f35c0 100644 --- a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java +++ b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java @@ -620,7 +620,7 @@ public void testAlterTableAddPartition() throws Exception { } catch (SQLException e) { errorMessage = e.getMessage(); } finally { - assertEquals(errorMessage, "ADD_PARTITION is not supported yet\n"); + assertEquals("not implemented feature: ADD_PARTITION", errorMessage); cleanupQuery(resultSet); if (stmt != null) { stmt.close(); From 2beb04bbd1ef7f4ccff4cd5555c6126369d28c4d Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Wed, 1 Jul 2015 17:09:47 -0700 Subject: [PATCH 08/30] Add SQLExceptionUtil and SQLState system. --- .../apache/tajo/client/SQLExceptionUtil.java | 18 +++- .../tajo/engine/parser/SQLAnalyzer.java | 1 - .../tajo/engine/parser/SQLSyntaxError.java | 9 +- .../engine/query/TestTablePartitions.java | 4 +- .../org/apache/tajo/jdbc/TestSQLState.java | 91 +++++++++++++++++++ .../org/apache/tajo/jdbc/TestTajoJdbc.java | 2 +- .../org/apache/tajo/jdbc/TajoStatement.java | 44 ++++----- 7 files changed, 135 insertions(+), 34 deletions(-) create mode 100644 tajo-core/src/test/java/org/apache/tajo/jdbc/TestSQLState.java diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java index c035c435bb..ab8738d9a6 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -20,7 +20,7 @@ import com.google.common.collect.Maps; import org.apache.tajo.error.Errors; -import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos.ResponseState; import java.sql.SQLException; @@ -28,12 +28,22 @@ public class SQLExceptionUtil { - private static final Map SQL_STATES = Maps.newHashMap(); + private static final Map SQLSTATES = Maps.newHashMap(); - public static SQLException convert(ResponseState state) { + static { + SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601"); + } + + public static void throwIfError(ResponseState state) throws SQLException { + if (ClientErrorUtil.isError(state)) { + throw convert(state); + } + } + + public static SQLException convert(ResponseState state) throws SQLException { return new SQLException( state.getMessage(), - SQL_STATES.get(state.getReturnCode()), + SQLSTATES.get(state.getReturnCode()), state.getReturnCode().getNumber()); } } diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java index 62bb0f9533..34775deb3f 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java @@ -64,7 +64,6 @@ public Expr parse(String sql) { try { context = parser.sql(); } catch (SQLParseError e) { - e.printStackTrace(); throw new SQLSyntaxError(e); } return visitSql(context); diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java index 4c3b0fd844..0249daf2c4 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java @@ -19,19 +19,20 @@ package org.apache.tajo.engine.parser; -import org.apache.tajo.plan.InvalidQueryException; +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.TajoRuntimeException; -public class SQLSyntaxError extends InvalidQueryException { +public class SQLSyntaxError extends TajoRuntimeException { private static final long serialVersionUID = 5388279335175632067L; private transient String detailedMessage; public SQLSyntaxError(String errorMessage) { - super(errorMessage); + super(Errors.ResultCode.SYNTAX_ERROR, errorMessage); } public SQLSyntaxError(SQLParseError e) { - super(e.getMessageHeader(), e); + super(Errors.ResultCode.SYNTAX_ERROR, e.getMessageHeader()); } @Override diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java index f9002ff770..b5d52fbfe5 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java @@ -866,7 +866,7 @@ public final void testColumnPartitionedTableWithSmallerExpressions1() throws Exc + " select l_orderkey, l_partkey from lineitem"); assertTrue(ClientErrorUtil.isError(response.getState())); - assertEquals("INSERT has smaller expressions than target columns", response.getState().getMessage()); + assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns"); res = executeFile("case14.sql"); assertResultSet(res, "case14.result"); @@ -892,7 +892,7 @@ public final void testColumnPartitionedTableWithSmallerExpressions2() throws Exc + " select l_returnflag , l_orderkey, l_partkey from lineitem"); assertTrue(ClientErrorUtil.isError(response.getState())); - assertEquals("INSERT has smaller expressions than target columns", response.getState().getMessage()); + assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns"); res = executeFile("case15.sql"); assertResultSet(res, "case15.result"); diff --git a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestSQLState.java b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestSQLState.java new file mode 100644 index 0000000000..e711524c14 --- /dev/null +++ b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestSQLState.java @@ -0,0 +1,91 @@ +/* + * 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 com.google.common.collect.Maps; +import org.apache.hadoop.io.IOUtils; +import org.apache.tajo.*; +import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.catalog.Column; +import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.client.QueryClient; +import org.apache.tajo.client.QueryStatus; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.net.InetSocketAddress; +import java.sql.*; +import java.util.*; + +import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; +import static org.junit.Assert.*; + +@Category(IntegrationTest.class) +public class TestSQLState 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 { + } + + static String buildConnectionUri(String hostName, int port, String databaseName) { + return "jdbc:tajo://" + hostName + ":" + port + "/" + databaseName; + } + + private Connection makeConnection() throws SQLException { + String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(), + DEFAULT_DATABASE_NAME); + Connection conn = DriverManager.getConnection(connUri); + assertTrue(conn.isValid(100)); + + return conn; + } + + public void assertSQLState(String sql, String sqlState) throws SQLException { + Connection conn = null; + Statement stmt = null; + ResultSet res = null; + + try { + conn = makeConnection(); + stmt = conn.createStatement(); + res = stmt.executeQuery(sql); + } catch (SQLException se) { + assertEquals(sqlState, se.getSQLState()); + } catch (Throwable t) { + fail(t.getMessage()); + } finally { + CatalogUtil.closeQuietly(stmt, res); + CatalogUtil.closeQuietly(conn); + } + } + + @Test + public void testSyntaxError() throws Exception { + assertSQLState("selec x,y,x from lineitem", "42601"); + } +} diff --git a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java index 31d19f35c0..e3a46c669d 100644 --- a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java +++ b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java @@ -620,7 +620,7 @@ public void testAlterTableAddPartition() throws Exception { } catch (SQLException e) { errorMessage = e.getMessage(); } finally { - assertEquals("not implemented feature: ADD_PARTITION", errorMessage); + assertEquals(errorMessage, "not implemented feature: ADD_PARTITION"); cleanupQuery(resultSet); if (stmt != null) { stmt.close(); 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 2db9037560..13c74f03fa 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 @@ -21,6 +21,7 @@ import com.google.protobuf.ServiceException; import org.apache.tajo.QueryId; import org.apache.tajo.SessionVars; +import org.apache.tajo.client.SQLExceptionUtil; import org.apache.tajo.client.TajoClient; import org.apache.tajo.client.TajoClientUtil; import org.apache.tajo.ipc.ClientProtos; @@ -30,8 +31,6 @@ import java.util.HashMap; import java.util.Map; -import static org.apache.tajo.client.ClientErrorUtil.isError; - public class TajoStatement implements Statement { protected JdbcConnection conn; protected TajoClient tajoClient; @@ -148,15 +147,11 @@ public int[] executeBatch() throws SQLException { @Override public ResultSet executeQuery(String sql) throws SQLException { checkConnection("Can't execute"); + return executeSQL(sql); - try { - return executeSQL(sql); - } catch (Exception e) { - throw new SQLException(e.getMessage(), e); - } } - protected ResultSet executeSQL(String sql) throws SQLException, ServiceException, IOException { + protected ResultSet executeSQL(String sql) throws SQLException { if (isSetVariableQuery(sql)) { return setSessionVariable(tajoClient, sql); } @@ -164,24 +159,29 @@ protected ResultSet executeSQL(String sql) throws SQLException, ServiceException return unSetSessionVariable(tajoClient, sql); } - ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql); - if (isError(response.getState())) { - throw new ServiceException(response.getState().getMessage()); - } - QueryId queryId = new QueryId(response.getQueryId()); - if (response.getIsForwarded() && !queryId.isNull()) { - WaitingResultSet result = new WaitingResultSet(tajoClient, queryId, fetchSize); - if (blockWait) { - result.getSchema(); + try { + ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql); + SQLExceptionUtil.throwIfError(response.getState()); + + QueryId queryId = new QueryId(response.getQueryId()); + if (response.getIsForwarded() && !queryId.isNull()) { + WaitingResultSet result = new WaitingResultSet(tajoClient, queryId, fetchSize); + if (blockWait) { + result.getSchema(); + } + return result; } - return result; - } - if (response.hasResultSet() || response.hasTableDesc()) { - return TajoClientUtil.createResultSet(tajoClient, response, fetchSize); + if (response.hasResultSet() || response.hasTableDesc()) { + return TajoClientUtil.createResultSet(tajoClient, response, fetchSize); + } + return TajoClientUtil.createNullResultSet(queryId); + } catch (SQLException s) { + throw s; + } catch (Throwable t) { + throw new SQLException(t.getMessage(), t); } - return TajoClientUtil.createNullResultSet(queryId); } protected void checkConnection(String errorMsg) throws SQLException { From 305ed51f58c3590a4dccb67cbe307a9afb6549cd Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Wed, 1 Jul 2015 21:22:56 -0700 Subject: [PATCH 09/30] Improved client API. --- .../tajo/client/CatalogAdminClient.java | 2 +- .../tajo/client/CatalogAdminClientImpl.java | 3 +- .../org/apache/tajo/client/QueryClient.java | 71 +++++++++---------- .../apache/tajo/client/SQLExceptionUtil.java | 20 ++++-- .../apache/tajo/client/SessionConnection.java | 3 +- .../apache/tajo/client/TajoClientImpl.java | 2 +- .../java/org/apache/tajo/jdbc/SQLStates.java | 33 --------- tajo-common/src/main/proto/errors.proto | 3 + 8 files changed, 59 insertions(+), 78 deletions(-) delete mode 100644 tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java index 4d13abf728..89fa4c0299 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java @@ -131,7 +131,7 @@ TableDesc createExternalTable(final String tableName, final Schema schema, final * @param tableName The table name to get. This name is case sensitive. * @return Table description */ - TableDesc getTableDesc(final String tableName) throws ServiceException, SQLException; + TableDesc getTableDesc(final String tableName) throws SQLException; List getFunctions(final String functionName) throws ServiceException; } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index d1d5ce7a11..eac1585cd7 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -28,7 +28,6 @@ import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.SessionedStringProto; -import org.apache.tajo.jdbc.SQLStates; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; @@ -158,7 +157,7 @@ public List getTableList(@Nullable final String databaseName) throws Ser } @Override - public TableDesc getTableDesc(final String tableName) throws ServiceException, SQLException { + public TableDesc getTableDesc(final String tableName) throws SQLException { NettyClientBase client = connection.getTajoMasterConnection(); connection.checkSessionAndGet(client); diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java index 39b5fc3782..97cd7ca464 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java @@ -24,6 +24,7 @@ import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.QueryHistoryProto; import org.apache.tajo.ipc.ClientProtos.QueryInfoProto; +import org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; import org.apache.tajo.jdbc.TajoMemoryResultSet; import java.io.Closeable; @@ -36,55 +37,53 @@ public interface QueryClient extends Closeable { - public void setSessionId(SessionIdProto sessionId); + boolean isConnected(); - public boolean isConnected(); + SessionIdProto getSessionId(); - public SessionIdProto getSessionId(); + Map getClientSideSessionVars(); - public Map getClientSideSessionVars(); - - public String getBaseDatabase(); + String getBaseDatabase(); - public void setMaxRows(int maxRows); + void setMaxRows(int maxRows); - public int getMaxRows(); + int getMaxRows(); @Override - public void close(); + void close(); - public UserRoleInfo getUserInfo(); + UserRoleInfo getUserInfo(); /** * Call to QueryMaster closing query resources * @param queryId */ - public void closeQuery(final QueryId queryId); + void closeQuery(final QueryId queryId); - public void closeNonForwardQuery(final QueryId queryId); + void closeNonForwardQuery(final QueryId queryId); - public String getCurrentDatabase() throws ServiceException; + String getCurrentDatabase() throws ServiceException; - public Boolean selectDatabase(final String databaseName) throws ServiceException; + Boolean selectDatabase(final String databaseName) throws ServiceException; - public Map updateSessionVariables(final Map variables) throws ServiceException; + Map updateSessionVariables(final Map variables) throws ServiceException; - public Map unsetSessionVariables(final List variables) throws ServiceException; + Map unsetSessionVariables(final List variables) throws ServiceException; - public String getSessionVariable(final String varname) throws ServiceException; + String getSessionVariable(final String varname) throws ServiceException; - public Boolean existSessionVariable(final String varname) throws ServiceException; + Boolean existSessionVariable(final String varname) throws ServiceException; - public Map getAllSessionVariables() throws ServiceException; + Map getAllSessionVariables() throws ServiceException; /** * It submits a query statement and get a response immediately. * The response only contains a query id, and submission status. * In order to get the result, you should use {@link #getQueryResult(org.apache.tajo.QueryId)}. */ - public ClientProtos.SubmitQueryResponse executeQuery(final String sql) throws ServiceException; + SubmitQueryResponse executeQuery(final String sql) throws ServiceException; - public ClientProtos.SubmitQueryResponse executeQueryWithJson(final String json) throws ServiceException; + SubmitQueryResponse executeQueryWithJson(final String json) throws ServiceException; /** * It submits a query statement and get a response. @@ -94,33 +93,33 @@ public interface QueryClient extends Closeable { * * @return If failed, return null. */ - public ResultSet executeQueryAndGetResult(final String sql) throws ServiceException, IOException; + ResultSet executeQueryAndGetResult(final String sql) throws ServiceException, IOException; - public ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceException, IOException; + ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceException, IOException; - public QueryStatus getQueryStatus(QueryId queryId) throws ServiceException; + QueryStatus getQueryStatus(QueryId queryId) throws ServiceException; - public ResultSet getQueryResult(QueryId queryId) throws ServiceException, IOException; + ResultSet getQueryResult(QueryId queryId) throws ServiceException, IOException; - public ResultSet createNullResultSet(QueryId queryId) throws IOException; + ResultSet createNullResultSet(QueryId queryId) throws IOException; - public ClientProtos.GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException; + ClientProtos.GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException; - public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws ServiceException; + TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws ServiceException; - public boolean updateQuery(final String sql) throws ServiceException; + boolean updateQuery(final String sql) throws ServiceException; - public boolean updateQueryWithJson(final String json) throws ServiceException; + boolean updateQueryWithJson(final String json) throws ServiceException; - public List getRunningQueryList() throws ServiceException; + List getRunningQueryList() throws ServiceException; - public List getFinishedQueryList() throws ServiceException; + List getFinishedQueryList() throws ServiceException; - public List getClusterInfo() throws ServiceException; + List getClusterInfo() throws ServiceException; - public QueryStatus killQuery(final QueryId queryId) throws ServiceException, IOException; + QueryStatus killQuery(final QueryId queryId) throws ServiceException, IOException; - public QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceException; + QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceException; - public QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceException; + QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceException; } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java index ab8738d9a6..bf75b3f5f7 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -31,6 +31,7 @@ public class SQLExceptionUtil { private static final Map SQLSTATES = Maps.newHashMap(); static { + // TODO - All SQLState should be be filled SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601"); } @@ -41,9 +42,20 @@ public static void throwIfError(ResponseState state) throws SQLException { } public static SQLException convert(ResponseState state) throws SQLException { - return new SQLException( - state.getMessage(), - SQLSTATES.get(state.getReturnCode()), - state.getReturnCode().getNumber()); + if (SQLSTATES.containsKey(state.getReturnCode())) { + return new SQLException( + state.getMessage(), + SQLSTATES.get(state.getReturnCode()), + state.getReturnCode().getNumber()); + } else { + // If there is no SQLState corresponding to error code, + // It will make SQLState '42000' (Syntax Error Or Access Rule Violation). + return new SQLException( + state.getMessage(), + "42000", + ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_VALUE); + } } + + public static SQLException makeCon } 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 cf301bdbba..1247e3aecb 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 @@ -41,6 +41,7 @@ import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; +import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -110,7 +111,7 @@ public Map getClientSideSessionVars() { return Collections.unmodifiableMap(sessionVarsCache); } - public synchronized NettyClientBase getTajoMasterConnection() throws ServiceException { + public synchronized NettyClientBase getTajoMasterConnection() throws SQLException { if (client != null && client.isConnected()) return client; else { try { 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 3aa762215d..735126f3a0 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 @@ -221,7 +221,7 @@ public List getTableList(@Nullable final String databaseName) throws Ser return catalogClient.getTableList(databaseName); } - public TableDesc getTableDesc(final String tableName) throws ServiceException, SQLException { + public TableDesc getTableDesc(final String tableName) throws SQLException { return catalogClient.getTableDesc(tableName); } diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java deleted file mode 100644 index 32ab19c17d..0000000000 --- a/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 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; - -public enum SQLStates { - ER_NO_SUCH_TABLE("42S02"); - - private String state; - - SQLStates(String state) { - this.state = state; - } - - public String getState() { - return state; - } -} diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index 1e9b326cca..895d1dcd3c 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -114,6 +114,9 @@ enum ResultCode { UNKNOWN_DATAFORMAT = 1001; // Unknown Data Format + CLIENT_CONNECTION_EXCEPTION = 1101; // SQLState: 08000 - Client connection error + CLIENT_UNABLE_TO_ESTABLISH_CONNECTION = 1102; // SQLState: 08001 - + // Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H // are called "standard-defined classes". From 16a8d25acf49d93848c5b3fc16beecf8c1759dab Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 02:14:02 -0700 Subject: [PATCH 10/30] Refactor client APIs to throw SQLException and fixed all unit tests. --- .../org/apache/tajo/cli/tools/TajoAdmin.java | 20 +- .../org/apache/tajo/cli/tsql/TajoCli.java | 44 +- .../tsql/commands/ConnectDatabaseCommand.java | 4 +- .../tajo/cli/tsql/commands/SetCommand.java | 9 +- .../tajo/client/CatalogAdminClient.java | 37 +- .../tajo/client/CatalogAdminClientImpl.java | 180 ++++--- .../apache/tajo/client/ClientErrorUtil.java | 2 + .../org/apache/tajo/client/QueryClient.java | 55 +- .../apache/tajo/client/QueryClientImpl.java | 506 +++++++++--------- .../apache/tajo/client/SQLExceptionUtil.java | 27 +- .../apache/tajo/client/SessionConnection.java | 145 +++-- .../org/apache/tajo/client/TajoClient.java | 2 +- .../apache/tajo/client/TajoClientImpl.java | 71 ++- .../apache/tajo/client/TajoClientUtil.java | 6 +- .../apache/tajo/exception/ErrorMessages.java | 2 +- .../tajo/exception/UnsupportedException.java | 4 +- tajo-common/src/main/proto/errors.proto | 3 +- .../apache/tajo/benchmark/BenchmarkSet.java | 7 +- .../java/org/apache/tajo/benchmark/TPCH.java | 13 +- .../tajo/webapp/QueryExecutorServlet.java | 10 +- .../apache/tajo/LocalTajoTestingUtility.java | 3 +- .../org/apache/tajo/QueryTestCaseBase.java | 12 +- .../org/apache/tajo/TajoTestingCluster.java | 3 +- .../apache/tajo/client/TestTajoClient.java | 85 +-- .../tajo/engine/query/TestInnerJoinQuery.java | 3 +- .../query/TestInnerJoinWithSubQuery.java | 3 +- .../query/TestJoinOnPartitionedTables.java | 3 +- .../tajo/engine/query/TestJoinQuery.java | 4 +- .../engine/query/TestMultipleJoinTypes.java | 4 +- .../tajo/engine/query/TestOuterJoinQuery.java | 3 +- .../query/TestOuterJoinWithSubQuery.java | 4 +- .../org/apache/tajo/worker/TestHistory.java | 5 +- .../org/apache/tajo/jdbc/JdbcConnection.java | 40 +- .../tajo/jdbc/TajoDatabaseMetaData.java | 21 +- .../org/apache/tajo/jdbc/TajoStatement.java | 55 +- 35 files changed, 744 insertions(+), 651 deletions(-) diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java index 739cd541d0..5ba0dc5716 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java @@ -406,13 +406,19 @@ private void processList(Writer writer) throws ParseException, IOException, public void processKill(Writer writer, String queryIdStr) throws IOException, ServiceException { - QueryStatus status = tajoClient.killQuery(TajoIdUtils.parseQueryId(queryIdStr)); - if (status.getState() == TajoProtos.QueryState.QUERY_KILLED) { - writer.write(queryIdStr + " is killed successfully.\n"); - } else if (status.getState() == TajoProtos.QueryState.QUERY_KILL_WAIT) { - writer.write(queryIdStr + " will be finished after a while.\n"); - } else { - writer.write("ERROR:" + status.getErrorMessage()); + + try { + QueryStatus status = tajoClient.killQuery(TajoIdUtils.parseQueryId(queryIdStr)); + + if (status.getState() == TajoProtos.QueryState.QUERY_KILLED) { + writer.write(queryIdStr + " is killed successfully.\n"); + } else if (status.getState() == TajoProtos.QueryState.QUERY_KILL_WAIT) { + writer.write(queryIdStr + " will be finished after a while.\n"); + } else { + writer.write("ERROR:" + status.getErrorMessage()); + } + } catch (SQLException e) { + writer.write("ERROR:" + e.getMessage()); } } diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java index 092a54fad5..abc56d9fc1 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java @@ -279,7 +279,7 @@ public TajoCli(TajoConf c, String [] args, InputStream in, OutputStream out) thr addShutdownHook(); } - private void processConfVarCommand(String[] confCommands) throws ServiceException { + private void processConfVarCommand(String[] confCommands) throws SQLException { for (String eachParam: confCommands) { String[] tokens = eachParam.split("="); if (tokens.length != 2) { @@ -292,7 +292,7 @@ private void processConfVarCommand(String[] confCommands) throws ServiceExceptio } } - private void processSessionVarCommand(String[] confCommands) throws ServiceException { + private void processSessionVarCommand(String[] confCommands) throws SQLException { for (String eachParam: confCommands) { String[] tokens = eachParam.split("="); if (tokens.length != 2) { @@ -484,7 +484,7 @@ public int executeMetaCommand(String line) throws Exception { return 0; } - private void executeJsonQuery(String json) throws ServiceException, IOException { + private void executeJsonQuery(String json) throws SQLException { long startTime = System.currentTimeMillis(); ClientProtos.SubmitQueryResponse response = client.executeQueryWithJson(json); @@ -509,7 +509,7 @@ private void executeJsonQuery(String json) throws ServiceException, IOException } } - private int executeQuery(String statement) throws ServiceException, IOException { + private int executeQuery(String statement) throws SQLException { long startTime = System.currentTimeMillis(); ClientProtos.SubmitQueryResponse response = null; @@ -519,22 +519,22 @@ private int executeQuery(String statement) throws ServiceException, IOException onError(null, te); } - if (response == null) { - onError("response is null", null); - } else if (ClientErrorUtil.isSuccess(response.getState())) { - if (response.getIsForwarded()) { - QueryId queryId = new QueryId(response.getQueryId()); - waitForQueryCompleted(queryId); - } else { - if (!response.hasTableDesc() && !response.hasResultSet()) { - displayFormatter.printMessage(sout, "OK"); + if (response != null) { + if (ClientErrorUtil.isSuccess(response.getState())) { + if (response.getIsForwarded()) { + QueryId queryId = new QueryId(response.getQueryId()); + waitForQueryCompleted(queryId); } else { - localQueryCompleted(response, startTime); + if (!response.hasTableDesc() && !response.hasResultSet()) { + displayFormatter.printMessage(sout, "OK"); + } else { + localQueryCompleted(response, startTime); + } + } + } else { + if (ClientErrorUtil.isError(response.getState())) { + onError(response.getState().getMessage(), null); } - } - } else { - if (ClientErrorUtil.isError(response.getState())) { - onError(response.getState().getMessage(), null); } } @@ -570,7 +570,7 @@ private void localQueryCompleted(ClientProtos.SubmitQueryResponse response, long } } - private void waitForQueryCompleted(QueryId queryId) { + private void waitForQueryCompleted(QueryId queryId) throws SQLException { // if query is empty string if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) { return; @@ -661,7 +661,11 @@ private void onError(String message, Throwable t) { if (t == null) { displayFormatter.printErrorMessage(sout, message); } else { - displayFormatter.printErrorMessage(sout, t); + if (t instanceof SQLException) { + displayFormatter.printErrorMessage(sout, t.getMessage()); + } else { + displayFormatter.printErrorMessage(sout, t); + } } if (reconnect && (t instanceof InvalidClientSessionException || (message != null && message.startsWith("org.apache.tajo.session.InvalidSessionException")))) { diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/ConnectDatabaseCommand.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/ConnectDatabaseCommand.java index ae644bdd3b..e75171d4ed 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/ConnectDatabaseCommand.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/ConnectDatabaseCommand.java @@ -21,6 +21,8 @@ import com.google.protobuf.ServiceException; import org.apache.tajo.cli.tsql.TajoCli; +import java.sql.SQLException; + public class ConnectDatabaseCommand extends TajoShellCommand { public ConnectDatabaseCommand(TajoCli.TajoCliContext context) { @@ -49,7 +51,7 @@ public void invoke(String[] cmd) throws Exception { context.getOutput().write(String.format("You are now connected to database \"%s\" as user \"%s\".%n", context.getCurrentDatabase(), client.getUserInfo().getUserName())); } - } catch (ServiceException se) { + } catch (SQLException se) { if (se.getMessage() != null) { context.getOutput().write(se.getMessage()); } else { diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/SetCommand.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/SetCommand.java index 21c4be51b5..c1c286d761 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/SetCommand.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/commands/SetCommand.java @@ -23,6 +23,7 @@ import org.apache.tajo.cli.tsql.TajoCli; import org.apache.tajo.util.StringUtils; +import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @@ -39,20 +40,20 @@ public String getCommand() { return "\\set"; } - private void showAllSessionVars() throws ServiceException { + private void showAllSessionVars() throws SQLException { for (Map.Entry entry: client.getAllSessionVariables().entrySet()) { context.getOutput().println(StringUtils.quote(entry.getKey()) + "=" + StringUtils.quote(entry.getValue())); } } - private void updateSessionVariable(String key, String val) throws ServiceException { + private void updateSessionVariable(String key, String val) throws SQLException { Map variables = new HashMap(); variables.put(key, val); client.updateSessionVariables(variables); } - public void set(String key, String val) throws ServiceException { - SessionVars sessionVar = null; + public void set(String key, String val) throws SQLException { + SessionVars sessionVar; if (SessionVars.exists(key)) { // if the variable is one of the session variables sessionVar = SessionVars.get(key); diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java index 89fa4c0299..c020ef542e 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClient.java @@ -18,7 +18,6 @@ package org.apache.tajo.client; -import com.google.protobuf.ServiceException; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; @@ -37,27 +36,27 @@ public interface CatalogAdminClient extends Closeable { * * @param databaseName The database name to be created. This name is case sensitive. * @return True if created successfully. - * @throws com.google.protobuf.ServiceException + * @throws java.sql.SQLException */ - boolean createDatabase(final String databaseName) throws ServiceException; + boolean createDatabase(final String databaseName) throws SQLException; /** * Does the database exist? * * @param databaseName The database name to be checked. This name is case sensitive. * @return True if so. - * @throws ServiceException + * @throws java.sql.SQLException */ - boolean existDatabase(final String databaseName) throws ServiceException; + boolean existDatabase(final String databaseName) throws SQLException; /** * Drop the database * * @param databaseName The database name to be dropped. This name is case sensitive. * @return True if the database is dropped successfully. - * @throws ServiceException + * @throws java.sql.SQLException */ - boolean dropDatabase(final String databaseName) throws ServiceException; + boolean dropDatabase(final String databaseName) throws SQLException; - List getAllDatabaseNames() throws ServiceException; + List getAllDatabaseNames() throws SQLException; /** * Does the table exist? @@ -65,7 +64,7 @@ public interface CatalogAdminClient extends Closeable { * @param tableName The table name to be checked. This name is case sensitive. * @return True if so. */ - boolean existTable(final String tableName) throws ServiceException; + boolean existTable(final String tableName) throws SQLException; /** * Create an external table. @@ -77,10 +76,9 @@ public interface CatalogAdminClient extends Closeable { * @param meta Table meta * @return the created table description. * @throws java.sql.SQLException - * @throws ServiceException */ TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, - final TableMeta meta) throws SQLException, ServiceException; + final TableMeta meta) throws SQLException; /** * Create an external table. @@ -92,20 +90,20 @@ TableDesc createExternalTable(final String tableName, final Schema schema, final * @param meta Table meta * @param partitionMethodDesc Table partition description * @return the created table description. - * @throws SQLException - * @throws ServiceException + * @throws java.sql.SQLException */ TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, final TableMeta meta, final PartitionMethodDesc partitionMethodDesc) - throws SQLException, ServiceException; + throws SQLException; /** * Drop a table * * @param tableName The table name to be dropped. This name is case sensitive. * @return True if the table is dropped successfully. + * @throws java.sql.SQLException */ - boolean dropTable(final String tableName) throws ServiceException; + boolean dropTable(final String tableName) throws SQLException; /** * Drop a table. @@ -113,8 +111,9 @@ TableDesc createExternalTable(final String tableName, final Schema schema, final * @param tableName The table name to be dropped. This name is case sensitive. * @param purge If purge is true, this call will remove the entry in catalog as well as the table contents. * @return True if the table is dropped successfully. + * @throws java.sql.SQLException */ - boolean dropTable(final String tableName, final boolean purge) throws ServiceException; + boolean dropTable(final String tableName, final boolean purge) throws SQLException; /** * Get a list of table names. @@ -122,16 +121,18 @@ TableDesc createExternalTable(final String tableName, final Schema schema, final * @param databaseName The database name to show all tables. This name is case sensitive. * If it is null, this method will show all tables * in the current database of this session. + * @throws java.sql.SQLException */ - List getTableList(@Nullable final String databaseName) throws ServiceException; + List getTableList(@Nullable final String databaseName) throws SQLException; /** * Get a table description * * @param tableName The table name to get. This name is case sensitive. * @return Table description + * @throws java.sql.SQLException */ TableDesc getTableDesc(final String tableName) throws SQLException; - List getFunctions(final String functionName) throws ServiceException; + List getFunctions(final String functionName) throws SQLException; } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index eac1585cd7..5b77f16309 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -26,7 +26,9 @@ import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.catalog.proto.CatalogProtos.FunctionDescProto; import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.DropTableRequest; import org.apache.tajo.ipc.ClientProtos.SessionedStringProto; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; @@ -37,82 +39,107 @@ import java.util.List; import static org.apache.tajo.client.ClientErrorUtil.isSuccess; +import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; public class CatalogAdminClientImpl implements CatalogAdminClient { - private final SessionConnection connection; + private final SessionConnection conn; - public CatalogAdminClientImpl(SessionConnection connection) { - this.connection = connection; + public CatalogAdminClientImpl(SessionConnection conn) { + this.conn = conn; } @Override - public boolean createDatabase(final String databaseName) throws ServiceException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMaster = client.getStub(); - return isSuccess(tajoMaster.createDatabase(null, connection.convertSessionedString(databaseName))); + public boolean createDatabase(final String databaseName) throws SQLException { + + final BlockingInterface stub = conn.getTMStub(); + + try { + return isSuccess(stub.createDatabase(null, conn.getSessionedString(databaseName))); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } @Override - public boolean existDatabase(final String databaseName) throws ServiceException { + public boolean existDatabase(final String databaseName) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMaster = client.getStub(); - return isSuccess(tajoMaster.existDatabase(null, connection.convertSessionedString(databaseName))); + final BlockingInterface stub = conn.getTMStub(); + + try { + return isSuccess(stub.existDatabase(null, conn.getSessionedString(databaseName))); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } @Override - public boolean dropDatabase(final String databaseName) throws ServiceException { + public boolean dropDatabase(final String databaseName) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); - return isSuccess(tajoMasterService.dropDatabase(null, connection.convertSessionedString(databaseName))); + final BlockingInterface stub = conn.getTMStub(); + + try { + return isSuccess(stub.dropDatabase(null, conn.getSessionedString(databaseName))); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } @Override - public List getAllDatabaseNames() throws ServiceException { + public List getAllDatabaseNames() throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); - return tajoMasterService.getAllDatabases(null, connection.sessionId).getValuesList(); + final BlockingInterface stub = conn.getTMStub(); + + try { + return stub.getAllDatabases(null, conn.sessionId).getValuesList(); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } - public boolean existTable(final String tableName) throws ServiceException { + public boolean existTable(final String tableName) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); - return isSuccess(tajoMasterService.existTable(null, connection.convertSessionedString(tableName))); + final BlockingInterface stub = conn.getTMStub(); + + try { + return isSuccess(stub.existTable(null, conn.getSessionedString(tableName))); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } @Override public TableDesc createExternalTable(String tableName, Schema schema, URI path, TableMeta meta) - throws SQLException, ServiceException { + throws SQLException { return createExternalTable(tableName, schema, path, meta, null); } public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, final TableMeta meta, final PartitionMethodDesc partitionMethodDesc) - throws SQLException, ServiceException { + throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); + NettyClientBase client = conn.getTajoMasterConnection(); + conn.checkSessionAndGet(client); BlockingInterface tajoMasterService = client.getStub(); ClientProtos.CreateTableRequest.Builder builder = ClientProtos.CreateTableRequest.newBuilder(); - builder.setSessionId(connection.sessionId); + builder.setSessionId(conn.sessionId); builder.setName(tableName); builder.setSchema(schema.getProto()); builder.setMeta(meta.getProto()); builder.setPath(path.toString()); + if (partitionMethodDesc != null) { builder.setPartition(partitionMethodDesc.getProto()); } - ClientProtos.TableResponse res = tajoMasterService.createExternalTable(null, builder.build()); + + ClientProtos.TableResponse res; + try { + res = tajoMasterService.createExternalTable(null, builder.build()); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + if (isSuccess(res.getState())) { return CatalogUtil.newTableDesc(res.getTableDesc()); } else { @@ -121,74 +148,73 @@ public TableDesc createExternalTable(final String tableName, final Schema schema } @Override - public boolean dropTable(String tableName) throws ServiceException { + public boolean dropTable(String tableName) throws SQLException { return dropTable(tableName, false); } @Override - public boolean dropTable(final String tableName, final boolean purge) throws ServiceException { - - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); - - ClientProtos.DropTableRequest.Builder builder = ClientProtos.DropTableRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setName(tableName); - builder.setPurge(purge); - return isSuccess(tajoMasterService.dropTable(null, builder.build())); - + public boolean dropTable(final String tableName, final boolean purge) throws SQLException { + + final BlockingInterface stub = conn.getTMStub(); + final DropTableRequest request = DropTableRequest.newBuilder() + .setSessionId(conn.sessionId) + .setName(tableName) + .setPurge(purge) + .build(); + + try { + return isSuccess(stub.dropTable(null, request)); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } @Override - public List getTableList(@Nullable final String databaseName) throws ServiceException { + public List getTableList(@Nullable final String databaseName) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); - SessionedStringProto.Builder builder = SessionedStringProto.newBuilder(); - builder.setSessionId(connection.sessionId); - if (databaseName != null) { - builder.setValue(databaseName); + PrimitiveProtos.StringListProto res; + try { + res = stub.getTableList(null, conn.getSessionedString(databaseName)); + } catch (ServiceException e) { + throw new RuntimeException(e); } - PrimitiveProtos.StringListProto res = tajoMasterService.getTableList(null, builder.build()); + return res.getValuesList(); } @Override public TableDesc getTableDesc(final String tableName) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); - SessionedStringProto.Builder builder = SessionedStringProto.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setValue(tableName); - ClientProtos.TableResponse res = tajoMasterService.getTableDesc(null, builder.build()); - if (isSuccess(res.getState())) { - return CatalogUtil.newTableDesc(res.getTableDesc()); - } else { - throw SQLExceptionUtil.convert(res.getState()); + ClientProtos.TableResponse res; + try { + res = stub.getTableDesc(null, conn.getSessionedString(tableName)); + } catch (ServiceException e) { + throw new RuntimeException(e); } + + throwIfError(res.getState()); + return CatalogUtil.newTableDesc(res.getTableDesc()); } @Override - public List getFunctions(final String functionName) throws ServiceException { + public List getFunctions(final String functionName) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); String paramFunctionName = functionName == null ? "" : functionName; - ClientProtos.FunctionResponse res = tajoMasterService.getFunctionList(null, - connection.convertSessionedString(paramFunctionName)); - if (isSuccess(res.getState())) { - return res.getFunctionsList(); - } else { - throw new ServiceException(new SQLException(res.getErrorMessage())); + ClientProtos.FunctionResponse res; + try { + res = stub.getFunctionList(null, conn.getSessionedString(paramFunctionName)); + } catch (ServiceException e) { + throw new RuntimeException(e); } + + throwIfError(res.getState()); + return res.getFunctionsList(); } @Override diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java index 90628c0746..8934a9076d 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java @@ -26,6 +26,8 @@ import org.apache.tajo.exception.TajoExceptionInterface; import org.apache.tajo.ipc.ClientProtos.ResponseState; +import java.sql.SQLException; + public class ClientErrorUtil { public static final ResponseState OK; diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java index 97cd7ca464..ffe3d960ad 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java @@ -30,6 +30,7 @@ import java.io.Closeable; import java.io.IOException; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import java.util.Map; @@ -39,7 +40,7 @@ public interface QueryClient extends Closeable { boolean isConnected(); - SessionIdProto getSessionId(); + String getSessionId(); Map getClientSideSessionVars(); @@ -58,32 +59,32 @@ public interface QueryClient extends Closeable { * Call to QueryMaster closing query resources * @param queryId */ - void closeQuery(final QueryId queryId); + void closeQuery(final QueryId queryId) throws SQLException; - void closeNonForwardQuery(final QueryId queryId); + void closeNonForwardQuery(final QueryId queryId) throws SQLException; - String getCurrentDatabase() throws ServiceException; + String getCurrentDatabase() throws SQLException; - Boolean selectDatabase(final String databaseName) throws ServiceException; + Boolean selectDatabase(final String databaseName) throws SQLException; - Map updateSessionVariables(final Map variables) throws ServiceException; + Map updateSessionVariables(final Map variables) throws SQLException; - Map unsetSessionVariables(final List variables) throws ServiceException; + Map unsetSessionVariables(final List variables) throws SQLException; - String getSessionVariable(final String varname) throws ServiceException; + String getSessionVariable(final String varname) throws SQLException; - Boolean existSessionVariable(final String varname) throws ServiceException; + Boolean existSessionVariable(final String varname) throws SQLException; - Map getAllSessionVariables() throws ServiceException; + Map getAllSessionVariables() throws SQLException; /** * It submits a query statement and get a response immediately. * The response only contains a query id, and submission status. * In order to get the result, you should use {@link #getQueryResult(org.apache.tajo.QueryId)}. */ - SubmitQueryResponse executeQuery(final String sql) throws ServiceException; + SubmitQueryResponse executeQuery(final String sql) throws SQLException; - SubmitQueryResponse executeQueryWithJson(final String json) throws ServiceException; + SubmitQueryResponse executeQueryWithJson(final String json) throws SQLException; /** * It submits a query statement and get a response. @@ -93,33 +94,33 @@ public interface QueryClient extends Closeable { * * @return If failed, return null. */ - ResultSet executeQueryAndGetResult(final String sql) throws ServiceException, IOException; + ResultSet executeQueryAndGetResult(final String sql) throws SQLException; - ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceException, IOException; + ResultSet executeJsonQueryAndGetResult(final String json) throws SQLException; - QueryStatus getQueryStatus(QueryId queryId) throws ServiceException; + QueryStatus getQueryStatus(QueryId queryId) throws SQLException; - ResultSet getQueryResult(QueryId queryId) throws ServiceException, IOException; + ResultSet getQueryResult(QueryId queryId) throws SQLException; - ResultSet createNullResultSet(QueryId queryId) throws IOException; + ResultSet createNullResultSet(QueryId queryId) throws SQLException; - ClientProtos.GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException; + ClientProtos.GetQueryResultResponse getResultResponse(QueryId queryId) throws SQLException; - TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws ServiceException; + TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws SQLException; - boolean updateQuery(final String sql) throws ServiceException; + boolean updateQuery(final String sql) throws SQLException; - boolean updateQueryWithJson(final String json) throws ServiceException; + boolean updateQueryWithJson(final String json) throws SQLException; - List getRunningQueryList() throws ServiceException; + List getRunningQueryList() throws SQLException; - List getFinishedQueryList() throws ServiceException; + List getFinishedQueryList() throws SQLException; - List getClusterInfo() throws ServiceException; + List getClusterInfo() throws SQLException; - QueryStatus killQuery(final QueryId queryId) throws ServiceException, IOException; + QueryStatus killQuery(final QueryId queryId) throws SQLException; - QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceException; + QueryInfoProto getQueryInfo(final QueryId queryId) throws SQLException; - QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceException; + QueryHistoryProto getQueryHistory(final QueryId queryId) throws SQLException; } 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 da7849373f..3c720c0453 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 @@ -22,21 +22,24 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tajo.*; +import org.apache.tajo.TajoIdProtos.SessionIdProto; import org.apache.tajo.auth.UserRoleInfo; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.QueryMasterClientProtocol; +import org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; import org.apache.tajo.jdbc.FetchResultSet; import org.apache.tajo.jdbc.TajoMemoryResultSet; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.RpcClientManager; import org.apache.tajo.util.ProtoUtil; -import java.io.IOException; +import java.net.ConnectException; import java.net.InetSocketAddress; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -44,47 +47,42 @@ import static org.apache.tajo.client.ClientErrorUtil.isError; import static org.apache.tajo.client.ClientErrorUtil.isSuccess; import static org.apache.tajo.client.ClientErrorUtil.returnError; +import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.*; import static org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService; -import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; public class QueryClientImpl implements QueryClient { private static final Log LOG = LogFactory.getLog(QueryClientImpl.class); - private final SessionConnection connection; + private final SessionConnection conn; private final int defaultFetchRows; -//maxRows number is limit value of resultSet. The value must be >= 0, and 0 means there is not limit. + // maxRows number is limit value of resultSet. The value must be >= 0, and 0 means there is not limit. private int maxRows; - public QueryClientImpl(SessionConnection connection) { - this.connection = connection; - this.defaultFetchRows = this.connection.getProperties().getInt(SessionVars.FETCH_ROWNUM.getConfVars().keyname(), + public QueryClientImpl(SessionConnection conn) { + this.conn = conn; + this.defaultFetchRows = this.conn.getProperties().getInt(SessionVars.FETCH_ROWNUM.getConfVars().keyname(), SessionVars.FETCH_ROWNUM.getConfVars().defaultIntVal); this.maxRows = 0; } - @Override - public void setSessionId(TajoIdProtos.SessionIdProto sessionId) { - connection.setSessionId(sessionId); - } - @Override public boolean isConnected() { - return connection.isConnected(); + return conn.isConnected(); } @Override - public TajoIdProtos.SessionIdProto getSessionId() { - return connection.getSessionId(); + public String getSessionId() { + return conn.getSessionId(); } @Override public Map getClientSideSessionVars() { - return connection.getClientSideSessionVars(); + return conn.getClientSideSessionVars(); } @Override public String getBaseDatabase() { - return connection.getBaseDatabase(); + return conn.getBaseDatabase(); } @Override @@ -93,110 +91,95 @@ public void close() { @Override public UserRoleInfo getUserInfo() { - return connection.getUserInfo(); + return conn.getUserInfo(); } @Override - public void closeQuery(QueryId queryId) { + public void closeQuery(QueryId queryId) throws SQLException { closeNonForwardQuery(queryId); } @Override - public void closeNonForwardQuery(QueryId queryId) { - NettyClientBase tmClient = null; + public void closeNonForwardQuery(QueryId queryId) throws SQLException { try { - tmClient = connection.getTajoMasterConnection(); - TajoMasterClientProtocolService.BlockingInterface tajoMaster = tmClient.getStub(); - connection.checkSessionAndGet(tmClient); - - ClientProtos.QueryIdRequest.Builder builder = ClientProtos.QueryIdRequest.newBuilder(); - - builder.setSessionId(getSessionId()); - builder.setQueryId(queryId.getProto()); - tajoMaster.closeNonForwardQuery(null, builder.build()); - } catch (Exception e) { - LOG.warn("Fail to close a TajoMaster connection (qid=" + queryId + ", msg=" + e.getMessage() + ")", e); + throwIfError(conn.getTMStub().closeNonForwardQuery(null, buildQueryIdRequest(queryId))); + } catch (ServiceException e) { + throw new RuntimeException(e); } } @Override - public String getCurrentDatabase() throws ServiceException { - return connection.getCurrentDatabase(); + public String getCurrentDatabase() throws SQLException { + return conn.getCurrentDatabase(); } @Override - public Boolean selectDatabase(String databaseName) throws ServiceException { - return connection.selectDatabase(databaseName); + public Boolean selectDatabase(String databaseName) throws SQLException { + return conn.selectDatabase(databaseName); } @Override - public Map updateSessionVariables(Map variables) throws ServiceException { - return connection.updateSessionVariables(variables); + public Map updateSessionVariables(Map variables) throws SQLException { + return conn.updateSessionVariables(variables); } @Override - public Map unsetSessionVariables(List variables) throws ServiceException { - return connection.unsetSessionVariables(variables); + public Map unsetSessionVariables(List variables) throws SQLException { + return conn.unsetSessionVariables(variables); } @Override - public String getSessionVariable(String varname) throws ServiceException { - return connection.getSessionVariable(varname); + public String getSessionVariable(String varname) throws SQLException { + return conn.getSessionVariable(varname); } @Override - public Boolean existSessionVariable(String varname) throws ServiceException { - return connection.existSessionVariable(varname); + public Boolean existSessionVariable(String varname) throws SQLException { + return conn.existSessionVariable(varname); } @Override - public Map getAllSessionVariables() throws ServiceException { - return connection.getAllSessionVariables(); + public Map getAllSessionVariables() throws SQLException { + return conn.getAllSessionVariables(); } @Override - public ClientProtos.SubmitQueryResponse executeQuery(final String sql) throws ServiceException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); + public ClientProtos.SubmitQueryResponse executeQuery(final String sql) throws SQLException { - final QueryRequest.Builder builder = QueryRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQuery(sql); - builder.setIsJson(false); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); + final QueryRequest request = buildQueryRequest(sql, false); + SubmitQueryResponse response; + try { + response = stub.submitQuery(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); + } - SubmitQueryResponse response = tajoMasterService.submitQuery(null, builder.build()); if (isSuccess(response.getState())) { - connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); + conn.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); } + return response; } @Override - public ClientProtos.SubmitQueryResponse executeQueryWithJson(final String json) throws ServiceException { - - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - - final QueryRequest.Builder builder = QueryRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQuery(json); - builder.setIsJson(true); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + public ClientProtos.SubmitQueryResponse executeQueryWithJson(final String json) throws SQLException { + final BlockingInterface tajoMasterService = conn.getTMStub(); + final QueryRequest request = buildQueryRequest(json, true); - - return tajoMasterService.submitQuery(null, builder.build()); + try { + return tajoMasterService.submitQuery(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } @Override - public ResultSet executeQueryAndGetResult(String sql) throws ServiceException, IOException { + public ResultSet executeQueryAndGetResult(String sql) throws SQLException { ClientProtos.SubmitQueryResponse response = executeQuery(sql); - - if (isError(response.getState())) { - throw new ServiceException(response.getState().getMessage()); - } + throwIfError(response.getState()); QueryId queryId = new QueryId(response.getQueryId()); @@ -222,16 +205,12 @@ public ResultSet executeQueryAndGetResult(String sql) throws ServiceException, I } @Override - public ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceException, IOException { + public ResultSet executeJsonQueryAndGetResult(final String json) throws SQLException { ClientProtos.SubmitQueryResponse response = executeQueryWithJson(json); - - if (isError(response.getState())) { - throw new ServiceException(response.getState().getMessage()); - } + throwIfError(response.getState()); QueryId queryId = new QueryId(response.getQueryId()); - if (response.getIsForwarded()) { if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) { @@ -251,7 +230,7 @@ public ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceE } } - private ResultSet getQueryResultAndWait(QueryId queryId) throws ServiceException, IOException { + private ResultSet getQueryResultAndWait(QueryId queryId) throws SQLException { if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) { return createNullResultSet(queryId); @@ -275,222 +254,210 @@ private ResultSet getQueryResultAndWait(QueryId queryId) throws ServiceException } @Override - public QueryStatus getQueryStatus(QueryId queryId) throws ServiceException { + public QueryStatus getQueryStatus(QueryId queryId) throws SQLException { - ClientProtos.GetQueryStatusRequest.Builder builder = ClientProtos.GetQueryStatusRequest.newBuilder(); - builder.setQueryId(queryId.getProto()); + final BlockingInterface stub = conn.getTMStub(); + final GetQueryStatusRequest request = GetQueryStatusRequest.newBuilder() + .setSessionId(conn.sessionId) + .setQueryId(queryId.getProto()) + .build(); - GetQueryStatusResponse res = null; - - NettyClientBase tmClient = null; + GetQueryStatusResponse res; try { - tmClient = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(tmClient); - builder.setSessionId(connection.sessionId); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub(); - - res = tajoMasterService.getQueryStatus(null, builder.build()); - - } catch (Exception e) { - throw new ServiceException(e.getMessage(), e); + res = stub.getQueryStatus(null, request); + } catch (ServiceException t) { + throw new RuntimeException(t); } + + throwIfError(res.getState()); return new QueryStatus(res); } @Override - public ResultSet getQueryResult(QueryId queryId) throws ServiceException, IOException { + public ResultSet getQueryResult(QueryId queryId) throws SQLException { if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) { return createNullResultSet(queryId); } GetQueryResultResponse response = getResultResponse(queryId); + throwIfError(response.getState()); TableDesc tableDesc = CatalogUtil.newTableDesc(response.getTableDesc()); return new FetchResultSet(this, tableDesc.getLogicalSchema(), queryId, defaultFetchRows); } @Override - public ResultSet createNullResultSet(QueryId queryId) throws IOException { + public ResultSet createNullResultSet(QueryId queryId) { return TajoClientUtil.createNullResultSet(queryId); } @Override - public GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException { + public GetQueryResultResponse getResultResponse(QueryId queryId) throws SQLException { if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) { return null; } - NettyClientBase tmClient = null; + final BlockingInterface stub = conn.getTMStub(); + final GetQueryResultRequest request = GetQueryResultRequest.newBuilder() + .setQueryId(queryId.getProto()) + .setSessionId(conn.sessionId) + .build(); + GetQueryResultResponse response; try { - - tmClient = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(tmClient); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub(); - - GetQueryResultRequest.Builder builder = GetQueryResultRequest.newBuilder(); - builder.setQueryId(queryId.getProto()); - builder.setSessionId(connection.sessionId); - GetQueryResultResponse response = tajoMasterService.getQueryResult(null,builder.build()); - - return response; - - } catch (Exception t) { - return GetQueryResultResponse.newBuilder().setState(returnError(t)).build(); + response = stub.getQueryResult(null, request); + } catch (ServiceException t) { + throw new RuntimeException(t); } + + throwIfError(response.getState()); + return response; } @Override - public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) - throws ServiceException { - - try { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - - GetQueryResultDataRequest.Builder builder = GetQueryResultDataRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQueryId(queryId.getProto()); - builder.setFetchRowNum(fetchRowNum); + public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws SQLException { - GetQueryResultDataResponse response = tajoMasterService.getQueryResultData(null, builder.build()); + final BlockingInterface stub = conn.getTMStub(); + final GetQueryResultDataRequest request = GetQueryResultDataRequest.newBuilder() + .setSessionId(conn.sessionId) + .setQueryId(queryId.getProto()) + .setFetchRowNum(fetchRowNum) + .build(); - if (isError(response.getState())) { - throw new ServiceException(response.getState().getMessage()); - } - - ClientProtos.SerializedResultSet resultSet = response.getResultSet(); - return new TajoMemoryResultSet(queryId, - new Schema(resultSet.getSchema()), - resultSet.getSerializedTuplesList(), - resultSet.getSerializedTuplesCount(), - getClientSideSessionVars()); + GetQueryResultDataResponse response; + try { + response = stub.getQueryResultData(null, request); } catch (ServiceException e) { - throw e; - } catch (Throwable e) { - throw new ServiceException(e.getMessage(), e); + throw new RuntimeException(e); } + + throwIfError(response.getState()); + + ClientProtos.SerializedResultSet resultSet = response.getResultSet(); + return new TajoMemoryResultSet(queryId, + new Schema(resultSet.getSchema()), + resultSet.getSerializedTuplesList(), + resultSet.getSerializedTuplesCount(), + getClientSideSessionVars()); } @Override - public boolean updateQuery(final String sql) throws ServiceException { + public boolean updateQuery(final String sql) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); + final QueryRequest request = buildQueryRequest(sql, false); - QueryRequest.Builder builder = QueryRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQuery(sql); - builder.setIsJson(false); - ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - - if (isSuccess(response.getState())) { - connection.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); - return true; - } else { - LOG.error("ERROR: " + response.getState().getMessage()); - return false; + UpdateQueryResponse response; + try { + response = stub.updateQuery(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); } + + throwIfError(response.getState()); + conn.updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); + + return true; } @Override - public boolean updateQueryWithJson(final String json) throws ServiceException { + public boolean updateQueryWithJson(final String json) throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); + final QueryRequest request = buildQueryRequest(json, true); - QueryRequest.Builder builder = QueryRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQuery(json); - builder.setIsJson(true); - ClientProtos.UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build()); - if (isSuccess(response.getState())) { - return true; - } else { - LOG.error("ERROR: " + response.getState().getMessage()); - return false; + UpdateQueryResponse response; + try { + response = stub.updateQuery(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); } + + throwIfError(response.getState()); + return true; } @Override - public List getRunningQueryList() throws ServiceException { + public List getRunningQueryList() throws SQLException { + + final BlockingInterface stmb = conn.getTMStub(); - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + GetQueryListResponse res; + try { + res = stmb.getRunningQueryList(null, conn.sessionId); + } catch (ServiceException e) { + throw new RuntimeException(e); + } - TajoIdProtos.SessionIdProto.Builder builder = TajoIdProtos.SessionIdProto.newBuilder(); - builder.setId(connection.sessionId.getId()); - ClientProtos.GetQueryListResponse res = tajoMasterService.getRunningQueryList(null, builder.build()); + throwIfError(res.getState()); return res.getQueryListList(); } @Override - public List getFinishedQueryList() throws ServiceException { + public List getFinishedQueryList() throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); - TajoIdProtos.SessionIdProto.Builder builder = TajoIdProtos.SessionIdProto.newBuilder(); - builder.setId(connection.sessionId.getId()); - ClientProtos.GetQueryListResponse res = tajoMasterService.getFinishedQueryList(null, builder.build()); + GetQueryListResponse res; + try { + res = stub.getFinishedQueryList(null, conn.sessionId); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + throwIfError(res.getState()); return res.getQueryListList(); } @Override - public List getClusterInfo() throws ServiceException { + public List getClusterInfo() throws SQLException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + final BlockingInterface stub = conn.getTMStub(); + final GetClusterInfoRequest request = GetClusterInfoRequest.newBuilder() + .setSessionId(conn.sessionId) + .build(); - ClientProtos.GetClusterInfoRequest.Builder builder = ClientProtos.GetClusterInfoRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - ClientProtos.GetClusterInfoResponse res = tajoMasterService.getClusterInfo(null, builder.build()); + GetClusterInfoResponse res; + try { + res = stub.getClusterInfo(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + throwIfError(res.getState()); return res.getWorkerListList(); } @Override - public QueryStatus killQuery(final QueryId queryId) - throws ServiceException, IOException { + public QueryStatus killQuery(final QueryId queryId) throws SQLException { + final BlockingInterface stub = conn.getTMStub(); QueryStatus status = getQueryStatus(queryId); - NettyClientBase tmClient = null; + /* send a kill to the TM */ + QueryIdRequest request = buildQueryIdRequest(queryId); try { - /* send a kill to the TM */ - tmClient = connection.getTajoMasterConnection(); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub(); - - connection.checkSessionAndGet(tmClient); - - ClientProtos.QueryIdRequest.Builder builder = ClientProtos.QueryIdRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQueryId(queryId.getProto()); - tajoMasterService.killQuery(null, builder.build()); - - long currentTimeMillis = System.currentTimeMillis(); - long timeKillIssued = currentTimeMillis; - while ((currentTimeMillis < timeKillIssued + 10000L) - && ((status.getState() != TajoProtos.QueryState.QUERY_KILLED) - || (status.getState() == TajoProtos.QueryState.QUERY_KILL_WAIT))) { - try { - Thread.sleep(100L); - } catch(InterruptedException ie) { - break; - } - currentTimeMillis = System.currentTimeMillis(); - status = getQueryStatus(queryId); - } + stub.killQuery(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + - } catch(Exception e) { - LOG.debug("Error when checking for application status", e); + long currentTimeMillis = System.currentTimeMillis(); + long timeKillIssued = currentTimeMillis; + while ((currentTimeMillis < timeKillIssued + 10000L) + && ((status.getState() != TajoProtos.QueryState.QUERY_KILLED) + || (status.getState() == TajoProtos.QueryState.QUERY_KILL_WAIT))) { + try { + Thread.sleep(100L); + } catch (InterruptedException ie) { + break; + } + currentTimeMillis = System.currentTimeMillis(); + status = getQueryStatus(queryId); } + return status; } @@ -504,57 +471,90 @@ public int getMaxRows() { return this.maxRows; } - public QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceException { - NettyClientBase client = connection.getTajoMasterConnection(); - connection.checkSessionAndGet(client); - - QueryIdRequest.Builder builder = QueryIdRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQueryId(queryId.getProto()); - - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - GetQueryInfoResponse res = tajoMasterService.getQueryInfo(null,builder.build()); - if (isSuccess(res.getState())) { - return res.getQueryInfo(); - } else { - throw new ServiceException(res.getState().getMessage()); + public QueryInfoProto getQueryInfo(final QueryId queryId) throws SQLException { + + final BlockingInterface stub = conn.getTMStub(); + final QueryIdRequest request = buildQueryIdRequest(queryId); + + GetQueryInfoResponse res; + try { + res = stub.getQueryInfo(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); } + + throwIfError(res.getState()); + return res.getQueryInfo(); } - public QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceException { + public QueryHistoryProto getQueryHistory(final QueryId queryId) throws SQLException { final QueryInfoProto queryInfo = getQueryInfo(queryId); if (queryInfo.getHostNameOfQM() == null || queryInfo.getQueryMasterClientPort() == 0) { return null; } + InetSocketAddress qmAddress = new InetSocketAddress( queryInfo.getHostNameOfQM(), queryInfo.getQueryMasterClientPort()); RpcClientManager manager = RpcClientManager.getInstance(); - NettyClientBase queryMasterClient; - try { - queryMasterClient = manager.newClient(qmAddress, QueryMasterClientProtocol.class, false, - manager.getRetries(), manager.getTimeoutSeconds(), TimeUnit.SECONDS, false); - } catch (Exception e) { - throw new ServiceException(e); - } + NettyClientBase qmClient = null; try { - connection.checkSessionAndGet(connection.getTajoMasterConnection()); - - QueryIdRequest.Builder builder = QueryIdRequest.newBuilder(); - builder.setSessionId(connection.sessionId); - builder.setQueryId(queryId.getProto()); - QueryMasterClientProtocolService.BlockingInterface queryMasterService = queryMasterClient.getStub(); - GetQueryHistoryResponse res = queryMasterService.getQueryHistory(null, builder.build()); - if (isSuccess(res.getState())) { - return res.getQueryHistory(); - } else { - throw new ServiceException(res.getState().getMessage()); + qmClient = manager.newClient( + qmAddress, + QueryMasterClientProtocol.class, + false, + manager.getRetries(), + manager.getTimeoutSeconds(), + TimeUnit.SECONDS, + false + ); + + conn.checkSessionAndGet(conn.getTajoMasterConnection()); + + QueryIdRequest request = QueryIdRequest.newBuilder() + .setSessionId(conn.sessionId) + .setQueryId(queryId.getProto()) + .build(); + + QueryMasterClientProtocolService.BlockingInterface stub = qmClient.getStub(); + GetQueryHistoryResponse res; + try { + res = stub.getQueryHistory(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); } + + throwIfError(res.getState()); + return res.getQueryHistory(); + + } catch (ConnectException e) { + throw SQLExceptionUtil.makeUnableToEstablishConnection(e); + } catch (ClassNotFoundException e) { + throw SQLExceptionUtil.makeUnableToEstablishConnection(e); + } catch (NoSuchMethodException e) { + throw SQLExceptionUtil.makeUnableToEstablishConnection(e); + } catch (SQLException e) { + throw e; } finally { - queryMasterClient.close(); + qmClient.close(); } } + + private QueryIdRequest buildQueryIdRequest(QueryId queryId) { + return ClientProtos.QueryIdRequest.newBuilder() + .setSessionId(SessionIdProto.newBuilder().setId(getSessionId())) + .setQueryId(queryId.getProto()) + .build(); + } + + private QueryRequest buildQueryRequest(String query, boolean json) { + return QueryRequest.newBuilder() + .setSessionId(conn.sessionId) + .setQuery(query) + .setIsJson(json) + .build(); + } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java index bf75b3f5f7..5880375d61 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -19,8 +19,8 @@ package org.apache.tajo.client; import com.google.common.collect.Maps; -import org.apache.tajo.error.Errors; import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.ErrorMessages; import org.apache.tajo.ipc.ClientProtos.ResponseState; import java.sql.SQLException; @@ -32,6 +32,9 @@ public class SQLExceptionUtil { 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"); } @@ -57,5 +60,25 @@ public static SQLException convert(ResponseState state) throws SQLException { } } - public static SQLException makeCon + public static SQLException makeSQLException(ResultCode code, String ...args) { + if (SQLSTATES.containsKey(code)) { + return new SQLException( + ErrorMessages.getMessage(code, args), + SQLSTATES.get(code), + code.getNumber()); + } else { + // If there is no SQLState corresponding to error code, + // It will make SQLState '42000' (Syntax Error Or Access Rule Violation). + return new SQLException( + code.name(), + "42000", + code.getNumber()); + } + + } + + public static SQLException makeUnableToEstablishConnection(Throwable t) { + return makeSQLException( + ResultCode.CLIENT_UNABLE_TO_ESTABLISH_CONNECTION, t.getMessage()); + } } 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 1247e3aecb..db1742bd2a 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 @@ -39,7 +39,6 @@ import org.apache.tajo.util.ProtoUtil; import java.io.Closeable; -import java.io.IOException; import java.net.InetSocketAddress; import java.sql.SQLException; import java.util.Collections; @@ -51,7 +50,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.apache.tajo.client.ClientErrorUtil.*; -import static org.apache.tajo.error.Errors.ResultCode.INVALID_SESSION; +import static org.apache.tajo.client.SQLExceptionUtil.convert; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; import static org.apache.tajo.ipc.ClientProtos.CreateSessionResponse; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -91,7 +90,7 @@ public class SessionConnection implements Closeable { * @throws java.io.IOException */ public SessionConnection(@NotNull ServiceTracker tracker, @Nullable String baseDatabase, - @NotNull KeyValueSet properties) throws IOException { + @NotNull KeyValueSet properties) throws SQLException { this.serviceTracker = tracker; this.baseDatabase = baseDatabase; this.properties = properties; @@ -100,11 +99,7 @@ public SessionConnection(@NotNull ServiceTracker tracker, @Nullable String baseD this.manager.setRetries(properties.getInt(RpcConstants.RPC_CLIENT_RETRY_MAX, RpcConstants.DEFAULT_RPC_RETRIES)); this.userInfo = UserRoleInfo.getCurrentUser(); - try { - this.client = getTajoMasterConnection(); - } catch (ServiceException e) { - throw new IOException(e); - } + this.client = getTajoMasterConnection(); } public Map getClientSideSessionVars() { @@ -112,21 +107,41 @@ public Map getClientSideSessionVars() { } public synchronized NettyClientBase getTajoMasterConnection() throws SQLException { - if (client != null && client.isConnected()) return client; - else { + + if (client != null && client.isConnected()) { + return client; + } else { + try { RpcClientManager.cleanup(client); + // Client do not closed on idle state for support high available - this.client = manager.newClient(getTajoMasterAddr(), TajoMasterClientProtocol.class, false, - manager.getRetries(), 0, TimeUnit.SECONDS, false); + this.client = manager.newClient( + getTajoMasterAddr(), + TajoMasterClientProtocol.class, + false, + manager.getRetries(), + 0, + TimeUnit.SECONDS, + false); connections.incrementAndGet(); - } catch (Exception e) { - throw new ServiceException(e); + + } catch (Throwable t) { + throw SQLExceptionUtil.makeUnableToEstablishConnection(t); } + return client; } } + protected TajoMasterClientProtocolService.BlockingInterface getTMStub() throws SQLException { + NettyClientBase tmClient; + tmClient = getTajoMasterConnection(); + TajoMasterClientProtocolService.BlockingInterface stub = tmClient.getStub(); + checkSessionAndGet(tmClient); + return stub; + } + public KeyValueSet getProperties() { return properties; } @@ -136,8 +151,8 @@ public void setSessionId(TajoIdProtos.SessionIdProto sessionId) { this.sessionId = sessionId; } - public TajoIdProtos.SessionIdProto getSessionId() { - return sessionId; + public String getSessionId() { + return sessionId.getId(); } public String getBaseDatabase() { @@ -159,15 +174,20 @@ public UserRoleInfo getUserInfo() { return userInfo; } - public String getCurrentDatabase() throws ServiceException { + public String getCurrentDatabase() throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - return tajoMasterService.getCurrentDatabase(null, sessionId).getValue(); + + try { + return tajoMasterService.getCurrentDatabase(null, sessionId).getValue(); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } - public Map updateSessionVariables(final Map variables) throws ServiceException { + public Map updateSessionVariables(final Map variables) throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); @@ -178,17 +198,23 @@ public Map updateSessionVariables(final Map vari .setSessionId(sessionId) .setSessionVars(keyValueSet.getProto()).build(); - SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); + SessionUpdateResponse response; + + try { + response = tajoMasterService.updateSessionVariables(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); + } if (isSuccess(response.getState())) { updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { - throw new ServiceException(response.getState().getMessage()); + throw convert(response.getState()); } } - public Map unsetSessionVariables(final List variables) throws ServiceException { + public Map unsetSessionVariables(final List variables) throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); @@ -197,13 +223,19 @@ public Map unsetSessionVariables(final List variables) t .setSessionId(sessionId) .addAllUnsetVariables(variables).build(); - SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); + SessionUpdateResponse response; + + try { + response = tajoMasterService.updateSessionVariables(null, request); + } catch (ServiceException e) { + throw new RuntimeException(e); + } if (isSuccess(response.getState())) { updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { - throw new ServiceException(response.getState().getMessage()); + throw convert(response.getState()); } } @@ -214,7 +246,7 @@ void updateSessionVarsCache(Map variables) { } } - public String getSessionVariable(final String varname) throws ServiceException { + public String getSessionVariable(final String varname) throws SQLException { synchronized (sessionVarsCache) { // If a desired variable is client side one and exists in the cache, immediately return the variable. if (sessionVarsCache.containsKey(varname)) { @@ -225,32 +257,51 @@ public String getSessionVariable(final String varname) throws ServiceException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - return tajoMasterService.getSessionVariable(null, convertSessionedString(varname)).getValue(); + TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + + try { + return stub.getSessionVariable(null, getSessionedString(varname)).getValue(); + + } catch (ServiceException e) { + throw new RuntimeException(e); + } } - public Boolean existSessionVariable(final String varname) throws ServiceException { + public Boolean existSessionVariable(final String varname) throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - return isSuccess(tajoMasterService.existSessionVariable(null, convertSessionedString(varname))); + TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + try { + return isSuccess(stub.existSessionVariable(null, getSessionedString(varname))); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } - public Map getAllSessionVariables() throws ServiceException { + public Map getAllSessionVariables() throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - return ProtoUtil.convertToMap(tajoMasterService.getAllSessionVariables(null, sessionId)); + TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + try { + return ProtoUtil.convertToMap(stub.getAllSessionVariables(null, sessionId)); + } catch (ServiceException e) { + throw new RuntimeException(e); + } } - public Boolean selectDatabase(final String databaseName) throws ServiceException { + public Boolean selectDatabase(final String databaseName) throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - boolean selected = isSuccess(tajoMasterService.selectDatabase(null, convertSessionedString(databaseName))); + TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + boolean selected = false; + try { + selected = isSuccess(stub.selectDatabase(null, getSessionedString(databaseName))); + } catch (ServiceException e) { + throw new RuntimeException(e); + } if (selected) { this.baseDatabase = databaseName; @@ -289,7 +340,7 @@ protected InetSocketAddress getTajoMasterAddr() { return serviceTracker.getClientServiceAddress(); } - protected void checkSessionAndGet(NettyClientBase client) throws ServiceException { + protected void checkSessionAndGet(NettyClientBase client) throws SQLException { if (sessionId == null) { @@ -301,7 +352,14 @@ protected void checkSessionAndGet(NettyClientBase client) throws ServiceExceptio builder.setBaseDatabaseName(baseDatabase); } - CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); + + CreateSessionResponse response = null; + + try { + response = tajoMasterService.createSession(null, builder.build()); + } catch (ServiceException se) { + throw new RuntimeException(se); + } if (isSuccess(response.getState())) { @@ -310,11 +368,8 @@ protected void checkSessionAndGet(NettyClientBase client) throws ServiceExceptio if (LOG.isDebugEnabled()) { LOG.debug(String.format("Got session %s as a user '%s'.", sessionId.getId(), userInfo.getUserName())); } - - } else if (isThisError(response.getState(), INVALID_SESSION)) { - throw new InvalidClientSessionException(response.getState().getMessage()); } else { - throw new ServiceException(response.getState().getMessage()); + throw SQLExceptionUtil.convert(response.getState()); } } } @@ -374,10 +429,12 @@ public boolean reconnect() throws Exception { SessionVars.SESSION_ID, SessionVars.SESSION_LAST_ACCESS_TIME, SessionVars.CLIENT_HOST }; - ClientProtos.SessionedStringProto convertSessionedString(String str) { + ClientProtos.SessionedStringProto getSessionedString(String str) { ClientProtos.SessionedStringProto.Builder builder = ClientProtos.SessionedStringProto.newBuilder(); builder.setSessionId(sessionId); - builder.setValue(str); + if (str != null) { + builder.setValue(str); + } return builder.build(); } 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 85929e8d84..d2b688a265 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 @@ -24,7 +24,7 @@ import java.io.Closeable; @ThreadSafe -public interface TajoClient extends QueryClient, CatalogAdminClient, Closeable { +public interface TajoClient extends QueryClient, CatalogAdminClient, Closeable { KeyValueSet getProperties(); } 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 735126f3a0..e005974c3c 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 @@ -18,7 +18,6 @@ package org.apache.tajo.client; -import com.google.protobuf.ServiceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tajo.QueryId; @@ -34,7 +33,6 @@ import org.apache.tajo.service.ServiceTracker; import org.apache.tajo.util.KeyValueSet; -import java.io.IOException; import java.net.InetSocketAddress; import java.net.URI; import java.sql.ResultSet; @@ -58,7 +56,8 @@ public class TajoClientImpl extends SessionConnection implements TajoClient, Que * @throws java.io.IOException */ public TajoClientImpl(ServiceTracker tracker, @Nullable String baseDatabase, KeyValueSet properties) - throws IOException { + throws SQLException { + super(tracker, baseDatabase, properties); this.queryClient = new QueryClientImpl(this); @@ -75,94 +74,94 @@ public TajoClientImpl(ServiceTracker tracker, @Nullable String baseDatabase, Key * @throws java.io.IOException */ public TajoClientImpl(InetSocketAddress addr, @Nullable String baseDatabase, KeyValueSet properties) - throws IOException { + throws SQLException { this(new DummyServiceTracker(addr), baseDatabase, properties); } - public TajoClientImpl(ServiceTracker serviceTracker) throws IOException { + public TajoClientImpl(ServiceTracker serviceTracker) throws SQLException { this(serviceTracker, null); } - public TajoClientImpl(ServiceTracker serviceTracker, @Nullable String baseDatabase) throws IOException { + public TajoClientImpl(ServiceTracker serviceTracker, @Nullable String baseDatabase) throws SQLException { this(serviceTracker, baseDatabase, new KeyValueSet()); } /*------------------------------------------------------------------------*/ // QueryClient wrappers /*------------------------------------------------------------------------*/ - public void closeQuery(final QueryId queryId) { + public void closeQuery(final QueryId queryId) throws SQLException { queryClient.closeQuery(queryId); } - public void closeNonForwardQuery(final QueryId queryId) { + public void closeNonForwardQuery(final QueryId queryId) throws SQLException { queryClient.closeNonForwardQuery(queryId); } - public SubmitQueryResponse executeQuery(final String sql) throws ServiceException { + public SubmitQueryResponse executeQuery(final String sql) throws SQLException { return queryClient.executeQuery(sql); } - public SubmitQueryResponse executeQueryWithJson(final String json) throws ServiceException { + public SubmitQueryResponse executeQueryWithJson(final String json) throws SQLException { return queryClient.executeQueryWithJson(json); } - public ResultSet executeQueryAndGetResult(final String sql) throws ServiceException, IOException { + public ResultSet executeQueryAndGetResult(final String sql) throws SQLException { return queryClient.executeQueryAndGetResult(sql); } - public ResultSet executeJsonQueryAndGetResult(final String json) throws ServiceException, IOException { + public ResultSet executeJsonQueryAndGetResult(final String json) throws SQLException { return queryClient.executeJsonQueryAndGetResult(json); } - public QueryStatus getQueryStatus(QueryId queryId) throws ServiceException { + public QueryStatus getQueryStatus(QueryId queryId) throws SQLException { return queryClient.getQueryStatus(queryId); } - public ResultSet getQueryResult(QueryId queryId) throws ServiceException, IOException { + public ResultSet getQueryResult(QueryId queryId) throws SQLException { return queryClient.getQueryResult(queryId); } - public ResultSet createNullResultSet(QueryId queryId) throws IOException { + public ResultSet createNullResultSet(QueryId queryId) throws SQLException { return TajoClientUtil.createNullResultSet(queryId); } - public GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException { + public GetQueryResultResponse getResultResponse(QueryId queryId) throws SQLException { return queryClient.getResultResponse(queryId); } - public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws ServiceException { + public TajoMemoryResultSet fetchNextQueryResult(final QueryId queryId, final int fetchRowNum) throws SQLException { return queryClient.fetchNextQueryResult(queryId, fetchRowNum); } - public boolean updateQuery(final String sql) throws ServiceException { + public boolean updateQuery(final String sql) throws SQLException { return queryClient.updateQuery(sql); } - public boolean updateQueryWithJson(final String json) throws ServiceException { + public boolean updateQueryWithJson(final String json) throws SQLException { return queryClient.updateQueryWithJson(json); } - public QueryStatus killQuery(final QueryId queryId) throws ServiceException, IOException { + public QueryStatus killQuery(final QueryId queryId) throws SQLException { return queryClient.killQuery(queryId); } - public List getRunningQueryList() throws ServiceException { + public List getRunningQueryList() throws SQLException { return queryClient.getRunningQueryList(); } - public List getFinishedQueryList() throws ServiceException { + public List getFinishedQueryList() throws SQLException { return queryClient.getFinishedQueryList(); } - public List getClusterInfo() throws ServiceException { + public List getClusterInfo() throws SQLException { return queryClient.getClusterInfo(); } - public QueryInfoProto getQueryInfo(final QueryId queryId) throws ServiceException { + public QueryInfoProto getQueryInfo(final QueryId queryId) throws SQLException { return queryClient.getQueryInfo(queryId); } - public QueryHistoryProto getQueryHistory(final QueryId queryId) throws ServiceException { + public QueryHistoryProto getQueryHistory(final QueryId queryId) throws SQLException { return queryClient.getQueryHistory(queryId); } @@ -178,46 +177,46 @@ public int getMaxRows() { // CatalogClient wrappers /*------------------------------------------------------------------------*/ - public boolean createDatabase(final String databaseName) throws ServiceException { + public boolean createDatabase(final String databaseName) throws SQLException { return catalogClient.createDatabase(databaseName); } - public boolean existDatabase(final String databaseName) throws ServiceException { + public boolean existDatabase(final String databaseName) throws SQLException { return catalogClient.existDatabase(databaseName); } - public boolean dropDatabase(final String databaseName) throws ServiceException { + public boolean dropDatabase(final String databaseName) throws SQLException { return catalogClient.dropDatabase(databaseName); } - public List getAllDatabaseNames() throws ServiceException { + public List getAllDatabaseNames() throws SQLException { return catalogClient.getAllDatabaseNames(); } - public boolean existTable(final String tableName) throws ServiceException { + public boolean existTable(final String tableName) throws SQLException { return catalogClient.existTable(tableName); } public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, - final TableMeta meta) throws SQLException, ServiceException { + final TableMeta meta) throws SQLException, SQLException { return catalogClient.createExternalTable(tableName, schema, path, meta); } public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, final TableMeta meta, final PartitionMethodDesc partitionMethodDesc) - throws SQLException, ServiceException { + throws SQLException, SQLException { return catalogClient.createExternalTable(tableName, schema, path, meta, partitionMethodDesc); } - public boolean dropTable(final String tableName) throws ServiceException { + public boolean dropTable(final String tableName) throws SQLException { return dropTable(tableName, false); } - public boolean dropTable(final String tableName, final boolean purge) throws ServiceException { + public boolean dropTable(final String tableName, final boolean purge) throws SQLException { return catalogClient.dropTable(tableName, purge); } - public List getTableList(@Nullable final String databaseName) throws ServiceException { + public List getTableList(@Nullable final String databaseName) throws SQLException { return catalogClient.getTableList(databaseName); } @@ -225,7 +224,7 @@ public TableDesc getTableDesc(final String tableName) throws SQLException { return catalogClient.getTableDesc(tableName); } - public List getFunctions(final String functionName) throws ServiceException { + public List getFunctions(final String functionName) throws SQLException { return catalogClient.getFunctions(functionName); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java index 1c832a17c8..a4f7c7ebc6 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.sql.ResultSet; +import java.sql.SQLException; public class TajoClientUtil { @@ -60,7 +61,7 @@ public static boolean isQueryComplete(TajoProtos.QueryState state) { return !isQueryWaitingForSchedule(state) && !isQueryRunning(state); } - public static QueryStatus waitCompletion(QueryClient client, QueryId queryId) throws ServiceException { + public static QueryStatus waitCompletion(QueryClient client, QueryId queryId) throws SQLException { QueryStatus status = client.getQueryStatus(queryId); while(!isQueryComplete(status.getState())) { @@ -82,8 +83,7 @@ public static ResultSet createResultSet(TajoClient client, QueryId queryId, return new FetchResultSet(client, desc.getLogicalSchema(), queryId, fetchRows); } - public static ResultSet createResultSet(QueryClient client, ClientProtos.SubmitQueryResponse response, int fetchRows) - throws IOException { + public static ResultSet createResultSet(QueryClient client, ClientProtos.SubmitQueryResponse response, int fetchRows) { if (response.hasTableDesc()) { // non-forward query // select * from table1 [limit 10] 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 10517c8e7e..df4f3d118b 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 @@ -35,7 +35,7 @@ public class ErrorMessages { // General Errors ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "internal error: %s", 1); ADD_MESSAGE(ResultCode.NOT_IMPLEMENTED, "not implemented feature: %s", 1); - ADD_MESSAGE(ResultCode.UNSUPPORTED, "unsupported feature: %s", 1); + ADD_MESSAGE(ResultCode.FEATURE_NOT_SUPPORTED, "unsupported feature: %s", 1); ADD_MESSAGE(ResultCode.INVALID_RPC_CALL, "invalid RPC Call: %s", 1); // Query Management and Scheduler diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java b/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java index a4d9977119..9ca55394b2 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java @@ -24,10 +24,10 @@ public class UnsupportedException extends TajoRuntimeException { private static final long serialVersionUID = 6702291354858193578L; public UnsupportedException(String featureName) { - super(Errors.ResultCode.UNSUPPORTED, featureName); + super(Errors.ResultCode.FEATURE_NOT_SUPPORTED, featureName); } public UnsupportedException() { - super(Errors.ResultCode.UNSUPPORTED, Thread.currentThread().getStackTrace()[1].getClassName()); + super(Errors.ResultCode.FEATURE_NOT_SUPPORTED, Thread.currentThread().getStackTrace()[1].getClassName()); } } diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index 895d1dcd3c..b4d618e6a6 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -31,7 +31,7 @@ enum ResultCode { // General Errors INTERNAL_ERROR = 201; // Error caused by internal bugs (See also TajoInternalException.java) NOT_IMPLEMENTED = 202; // Planned, but not implemented yet. - UNSUPPORTED = 203; // Unsupported feature (usually for unreasonable feature) + 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) // Query Management and Scheduler @@ -116,6 +116,7 @@ enum ResultCode { CLIENT_CONNECTION_EXCEPTION = 1101; // SQLState: 08000 - Client connection error CLIENT_UNABLE_TO_ESTABLISH_CONNECTION = 1102; // SQLState: 08001 - + CLIENT_PROTOCOL_PROTOCOL_VIOLATION = 1103; // SQLState: ? // Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H // are called "standard-defined classes". diff --git a/tajo-core/src/main/java/org/apache/tajo/benchmark/BenchmarkSet.java b/tajo-core/src/main/java/org/apache/tajo/benchmark/BenchmarkSet.java index 6c02dc5f2a..b4a28dbf28 100644 --- a/tajo-core/src/main/java/org/apache/tajo/benchmark/BenchmarkSet.java +++ b/tajo-core/src/main/java/org/apache/tajo/benchmark/BenchmarkSet.java @@ -35,6 +35,7 @@ import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @@ -45,7 +46,7 @@ public abstract class BenchmarkSet { protected Map queries = new HashMap(); protected String dataDir; - public void init(TajoConf conf, String dataDir) throws IOException { + public void init(TajoConf conf, String dataDir) throws SQLException { this.dataDir = dataDir; if (System.getProperty(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS.varname) != null) { @@ -90,7 +91,7 @@ protected void loadQueries(String dir) throws IOException { public abstract void loadQueries() throws IOException; - public abstract void loadTables() throws ServiceException; + public abstract void loadTables() throws SQLException; public String [] getTableNames() { return schemas.keySet().toArray(new String[schemas.size()]); @@ -112,7 +113,7 @@ public Schema getOutSchema(String name) { return outSchemas.get(name); } - public void perform(String queryName) throws IOException, ServiceException { + public void perform(String queryName) throws SQLException { String query = getQuery(queryName); if (query == null) { throw new IllegalArgumentException("#{queryName} does not exists"); diff --git a/tajo-core/src/main/java/org/apache/tajo/benchmark/TPCH.java b/tajo-core/src/main/java/org/apache/tajo/benchmark/TPCH.java index 9994634c30..dd3a43b813 100644 --- a/tajo-core/src/main/java/org/apache/tajo/benchmark/TPCH.java +++ b/tajo-core/src/main/java/org/apache/tajo/benchmark/TPCH.java @@ -192,7 +192,7 @@ public void loadQueries() throws IOException { loadQueries(BENCHMARK_DIR); } - public void loadTables() throws ServiceException { + public void loadTables() throws SQLException { loadTable(LINEITEM); loadTable(CUSTOMER); loadTable(CUSTOMER_PARTS); @@ -206,7 +206,7 @@ public void loadTables() throws ServiceException { } - public void loadTable(String tableName) throws ServiceException { + public void loadTable(String tableName) throws SQLException { TableMeta meta = CatalogUtil.newTableMeta("CSV"); meta.putOption(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER); @@ -221,12 +221,9 @@ public void loadTable(String tableName) throws ServiceException { "c_nationkey", expressionSchema); } - try { - tajo.createExternalTable(tableName, getSchema(tableName), - new Path(dataDir, tableName).toUri(), meta, partitionMethodDesc); - } catch (SQLException s) { - throw new ServiceException(s); - } + + tajo.createExternalTable(tableName, getSchema(tableName), + new Path(dataDir, tableName).toUri(), meta, partitionMethodDesc); } public static List getDataFilePaths(String... tables) { diff --git a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java index 463c85d504..461b8ec741 100644 --- a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java +++ b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java @@ -97,7 +97,7 @@ public void init(ServletConfig config) throws ServletException { tajoClient = new TajoClientImpl(ServiceTrackerFactory.get(tajoConf)); new QueryRunnerCleaner().start(); - } catch (IOException e) { + } catch (Throwable e) { LOG.error(e.getMessage(), e); } } @@ -359,7 +359,11 @@ public void run() { finishTime = System.currentTimeMillis(); if (queryId != null) { - tajoClient.closeQuery(queryId); + try { + tajoClient.closeQuery(queryId); + } catch (SQLException e) { + LOG.warn(e); + } } } } @@ -391,7 +395,7 @@ private void getSimpleQueryResult(ClientProtos.SubmitQueryResponse response) { } } - private QueryStatus waitForComplete(QueryId queryid) throws ServiceException { + private QueryStatus waitForComplete(QueryId queryid) throws SQLException { QueryStatus status = null; while (!stop.get()) { diff --git a/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java b/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java index 6691df15a3..eae9e8c10d 100644 --- a/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java +++ b/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java @@ -47,6 +47,7 @@ import java.io.IOException; import java.net.URL; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.UUID; public class LocalTajoTestingUtility { @@ -139,7 +140,7 @@ public TajoTestingCluster getTestingCluster() { return util; } - public ResultSet execute(String query) throws IOException, ServiceException { + public ResultSet execute(String query) throws IOException, SQLException { return client.executeQueryAndGetResult(query); } diff --git a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java index 9cc1407156..13c67e7d99 100644 --- a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java +++ b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java @@ -208,7 +208,7 @@ public static void setUpClass() throws Exception { } @AfterClass - public static void tearDownClass() throws ServiceException { + public static void tearDownClass() throws SQLException { for (String tableName : createdTableGlobalSet) { client.updateQuery("DROP TABLE IF EXISTS " + CatalogUtil.denormalizeIdentifier(tableName)); } @@ -539,7 +539,7 @@ protected void runSimpleTests() throws Exception { for (String cleanup : annotation.cleanup()) { try { client.executeQueryAndGetResult(cleanup).close(); - } catch (ServiceException e) { + } catch (SQLException e) { // ignore } } @@ -668,7 +668,7 @@ public final void cleanupQuery(ResultSet resultSet) throws IOException { * Assert that the database exists. * @param databaseName The database name to be checked. This name is case sensitive. */ - public void assertDatabaseExists(String databaseName) throws ServiceException { + public void assertDatabaseExists(String databaseName) throws SQLException { assertTrue(client.existDatabase(databaseName)); } @@ -676,7 +676,7 @@ public void assertDatabaseExists(String databaseName) throws ServiceException { * Assert that the database does not exists. * @param databaseName The database name to be checked. This name is case sensitive. */ - public void assertDatabaseNotExists(String databaseName) throws ServiceException { + public void assertDatabaseNotExists(String databaseName) throws SQLException { assertTrue(!client.existDatabase(databaseName)); } @@ -686,7 +686,7 @@ public void assertDatabaseNotExists(String databaseName) throws ServiceException * @param tableName The table name to be checked. This name is case sensitive. * @throws ServiceException */ - public void assertTableExists(String tableName) throws ServiceException { + public void assertTableExists(String tableName) throws SQLException { assertTrue(client.existTable(tableName)); } @@ -695,7 +695,7 @@ public void assertTableExists(String tableName) throws ServiceException { * * @param tableName The table name to be checked. This name is case sensitive. */ - public void assertTableNotExists(String tableName) throws ServiceException { + public void assertTableNotExists(String tableName) throws SQLException { assertTrue(!client.existTable(tableName)); } diff --git a/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java b/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java index 973f1e8f5e..015ec76047 100644 --- a/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java +++ b/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java @@ -61,6 +61,7 @@ import java.net.InetSocketAddress; import java.net.URI; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.TimeZone; @@ -628,7 +629,7 @@ public static ResultSet run(String[] names, } } - public static TajoClient newTajoClient(TajoTestingCluster util) throws InterruptedException, IOException { + public static TajoClient newTajoClient(TajoTestingCluster util) throws SQLException, InterruptedException { while(true) { if(util.getMaster().isMasterRunning()) { break; diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java index 73b97fa37f..9bf9c9823c 100644 --- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java +++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java @@ -21,7 +21,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.google.protobuf.ServiceException; import net.jcip.annotations.NotThreadSafe; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,6 +34,7 @@ import org.apache.tajo.catalog.TableDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.error.Errors; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.QueryHistoryProto; import org.apache.tajo.ipc.ClientProtos.QueryInfoProto; @@ -83,7 +83,7 @@ private static Path writeTmpTable(String tableName) throws IOException { } @Test - public final void testCreateAndDropDatabases() throws ServiceException { + public final void testCreateAndDropDatabases() throws SQLException { int currentNum = client.getAllDatabaseNames().size(); String prefix = CatalogUtil.normalizeIdentifier("testCreateDatabase_"); @@ -114,7 +114,7 @@ public final void testCreateAndDropDatabases() throws ServiceException { } @Test - public final void testCurrentDatabase() throws IOException, ServiceException, InterruptedException { + public final void testCurrentDatabase() throws IOException, SQLException, InterruptedException { int currentNum = client.getAllDatabaseNames().size(); assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase()); @@ -131,7 +131,7 @@ public final void testCurrentDatabase() throws IOException, ServiceException, In } @Test - public final void testSelectDatabaseToInvalidOne() throws IOException, ServiceException, InterruptedException { + public final void testSelectDatabaseToInvalidOne() throws IOException, SQLException, InterruptedException { int currentNum = client.getAllDatabaseNames().size(); assertFalse(client.existDatabase("invaliddatabase")); @@ -146,7 +146,7 @@ public final void testSelectDatabaseToInvalidOne() throws IOException, ServiceEx } @Test - public final void testDropCurrentDatabase() throws IOException, ServiceException, InterruptedException { + public final void testDropCurrentDatabase() throws IOException, SQLException, InterruptedException { int currentNum = client.getAllDatabaseNames().size(); String databaseName = CatalogUtil.normalizeIdentifier("testdropcurrentdatabase"); assertTrue(client.createDatabase(databaseName)); @@ -166,7 +166,7 @@ public final void testDropCurrentDatabase() throws IOException, ServiceException } @Test - public final void testSessionVariables() throws IOException, ServiceException, InterruptedException { + public final void testSessionVariables() throws IOException, SQLException, InterruptedException { String prefixName = "key_"; String prefixValue = "val_"; @@ -212,7 +212,7 @@ public final void testSessionVariables() throws IOException, ServiceException, I } @Test - public final void testKillQuery() throws IOException, ServiceException, InterruptedException { + public final void testKillQuery() throws IOException, SQLException, InterruptedException { ClientProtos.SubmitQueryResponse res = client.executeQuery("select sleep(1) from lineitem"); Thread.sleep(1000); QueryId queryId = new QueryId(res.getQueryId()); @@ -221,7 +221,7 @@ public final void testKillQuery() throws IOException, ServiceException, Interrup } @Test - public final void testUpdateQuery() throws IOException, ServiceException { + public final void testUpdateQuery() throws IOException, SQLException { final String tableName = CatalogUtil.normalizeIdentifier("testUpdateQuery"); Path tablePath = writeTmpTable(tableName); @@ -236,8 +236,7 @@ public final void testUpdateQuery() throws IOException, ServiceException { } @Test - public final void testCreateAndDropExternalTable() - throws IOException, ServiceException, SQLException { + public final void testCreateAndDropExternalTable() throws IOException, SQLException { final String tableName = "testCreateAndDropExternalTable"; Path tablePath = writeTmpTable(tableName); LOG.error("Full path:" + tablePath.toUri().getRawPath()); @@ -255,7 +254,7 @@ public final void testCreateAndDropExternalTable() } @Test - public final void testCreateAndPurgeExternalTable() throws IOException, ServiceException, SQLException { + public final void testCreateAndPurgeExternalTable() throws IOException, SQLException { final String tableName = "testCreateAndPurgeExternalTable"; Path tablePath = writeTmpTable(tableName); LOG.error("Full path:" + tablePath.toUri().getRawPath()); @@ -273,7 +272,7 @@ public final void testCreateAndPurgeExternalTable() throws IOException, ServiceE } @Test - public final void testCreateAndDropExternalTableByExecuteQuery() throws IOException, ServiceException { + public final void testCreateAndDropExternalTableByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropExternalTableByExecuteQuery"); @@ -293,7 +292,7 @@ public final void testCreateAndDropExternalTableByExecuteQuery() throws IOExcept } @Test - public final void testCreateAndPurgeExternalTableByExecuteQuery() throws IOException, ServiceException { + public final void testCreateAndPurgeExternalTableByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndPurgeExternalTableByExecuteQuery"); @@ -313,7 +312,7 @@ public final void testCreateAndPurgeExternalTableByExecuteQuery() throws IOExcep } @Test - public final void testCreateAndDropTableByExecuteQuery() throws IOException, ServiceException, SQLException { + public final void testCreateAndDropTableByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropTableByExecuteQuery"); @@ -334,7 +333,7 @@ public final void testCreateAndDropTableByExecuteQuery() throws IOException, Ser } @Test - public final void testCreateAndPurgeTableByExecuteQuery() throws IOException, ServiceException, SQLException { + public final void testCreateAndPurgeTableByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndPurgeTableByExecuteQuery"); @@ -355,7 +354,7 @@ public final void testCreateAndPurgeTableByExecuteQuery() throws IOException, Se } @Test - public final void testDDLByExecuteQuery() throws IOException, ServiceException { + public final void testDDLByExecuteQuery() throws IOException, SQLException { final String tableName = CatalogUtil.normalizeIdentifier("testDDLByExecuteQuery"); Path tablePath = writeTmpTable(tableName); @@ -368,7 +367,7 @@ public final void testDDLByExecuteQuery() throws IOException, ServiceException { } @Test - public final void testGetTableList() throws IOException, ServiceException { + public final void testGetTableList() throws IOException, SQLException { String tableName1 = "GetTableList1".toLowerCase(); String tableName2 = "GetTableList2".toLowerCase(); @@ -388,7 +387,7 @@ public final void testGetTableList() throws IOException, ServiceException { Log LOG = LogFactory.getLog(TestTajoClient.class); @Test - public final void testGetTableDesc() throws IOException, ServiceException, SQLException { + public final void testGetTableDesc() throws IOException, SQLException { final String tableName1 = CatalogUtil.normalizeIdentifier("table3"); Path tablePath = writeTmpTable(tableName1); LOG.error("Full path:" + tablePath.toUri().getRawPath()); @@ -408,8 +407,7 @@ public final void testGetTableDesc() throws IOException, ServiceException, SQLEx } //@Test - public final void testCreateAndDropTablePartitionedHash1ByExecuteQuery() throws IOException, - ServiceException, SQLException { + public final void testCreateAndDropTablePartitionedHash1ByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = "testCreateAndDropTablePartitionedHash1ByExecuteQuery"; @@ -432,8 +430,7 @@ public final void testCreateAndDropTablePartitionedHash1ByExecuteQuery() throws } //@Test - public final void testCreateAndPurgeTablePartitionedHash1ByExecuteQuery() throws IOException, - ServiceException, SQLException { + public final void testCreateAndPurgeTablePartitionedHash1ByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = "testCreateAndPurgeTablePartitionedHash1ByExecuteQuery"; @@ -456,8 +453,7 @@ public final void testCreateAndPurgeTablePartitionedHash1ByExecuteQuery() throws } //@Test - public final void testCreateAndDropTablePartitionedHash2ByExecuteQuery() throws IOException, - ServiceException, SQLException { + public final void testCreateAndDropTablePartitionedHash2ByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = "testCreateAndDropTablePartitionedHash2ByExecuteQuery"; @@ -480,8 +476,7 @@ public final void testCreateAndDropTablePartitionedHash2ByExecuteQuery() throws } //@Test - public final void testCreateAndDropTablePartitionedListByExecuteQuery() throws IOException, - ServiceException, SQLException { + public final void testCreateAndDropTablePartitionedListByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = "testCreateAndDropTablePartitionedListByExecuteQuery"; @@ -505,8 +500,7 @@ public final void testCreateAndDropTablePartitionedListByExecuteQuery() throws I } //@Test - public final void testCreateAndDropTablePartitionedRangeByExecuteQuery() throws IOException, - ServiceException, SQLException { + public final void testCreateAndDropTablePartitionedRangeByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = "testCreateAndDropTablePartitionedRangeByExecuteQuery"; @@ -525,14 +519,13 @@ public final void testCreateAndDropTablePartitionedRangeByExecuteQuery() throws FileSystem hdfs = tablePath.getFileSystem(conf); assertTrue(hdfs.exists(tablePath)); - client.updateQuery("drop table " + tableName +" purge"); + client.updateQuery("drop table " + tableName + " purge"); assertFalse(client.existTable(tableName)); assertFalse(hdfs.exists(tablePath)); } @Test - public final void testFailCreateTablePartitionedOtherExceptColumn() throws IOException, - ServiceException, SQLException { + public final void testFailCreateTablePartitionedOtherExceptColumn() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = "testFailCreateTablePartitionedOtherExceptColumn"; @@ -544,25 +537,39 @@ public final void testFailCreateTablePartitionedOtherExceptColumn() throws IOExc rangeSql += "PARTITION sub_part2 VALUES LESS THAN (5),"; rangeSql += "PARTITION sub_part2 VALUES LESS THAN (MAXVALUE) )"; - assertFalse(client.updateQuery(rangeSql)); + try { + client.updateQuery(rangeSql); + fail(); + } catch (SQLException se) { + assertEquals(Errors.ResultCode.FEATURE_NOT_SUPPORTED.getNumber(), se.getErrorCode()); + } String listSql = "create table " + tableName + " (deptname text, score int4)"; listSql += "PARTITION BY LIST (deptname)"; listSql += "( PARTITION sub_part1 VALUES('r&d', 'design'),"; listSql += "PARTITION sub_part2 VALUES('sales', 'hr') )"; - assertFalse(client.updateQuery(listSql)); + try { + assertFalse(client.updateQuery(listSql)); + fail(); + } catch (SQLException se) { + assertEquals(Errors.ResultCode.FEATURE_NOT_SUPPORTED.getNumber(), se.getErrorCode()); + } String hashSql = "create table " + tableName + " (deptname text, score int4)"; hashSql += "PARTITION BY HASH (deptname)"; hashSql += "PARTITIONS 2"; - assertFalse(client.updateQuery(hashSql)); + try { + assertFalse(client.updateQuery(hashSql)); + fail(); + } catch (SQLException se) { + assertEquals(Errors.ResultCode.FEATURE_NOT_SUPPORTED.getNumber(), se.getErrorCode()); + } } @Test - public final void testCreateAndDropTablePartitionedColumnByExecuteQuery() throws IOException, - ServiceException, SQLException { + public final void testCreateAndDropTablePartitionedColumnByExecuteQuery() throws IOException, SQLException { TajoConf conf = cluster.getConfiguration(); final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropTablePartitionedColumnByExecuteQuery"); @@ -584,8 +591,7 @@ public final void testCreateAndDropTablePartitionedColumnByExecuteQuery() throws } @Test - public final void testGetFunctions() throws IOException, - ServiceException, SQLException { + public final void testGetFunctions() throws IOException, SQLException { Collection catalogFunctions = cluster.getMaster().getCatalog().getFunctions(); String functionName = "sum"; int numFunctions = 0; @@ -606,8 +612,7 @@ public final void testGetFunctions() throws IOException, } @Test - public final void testGetFinishedQueryList() throws IOException, - ServiceException, SQLException { + public final void testGetFinishedQueryList() throws IOException, SQLException { final String tableName = CatalogUtil.normalizeIdentifier("testGetFinishedQueryList"); String sql = "create table " + tableName + " (deptname text, score int4)"; diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java index 6eedb4223a..f14544c435 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java @@ -29,6 +29,7 @@ import org.junit.runners.Parameterized; import java.sql.ResultSet; +import java.sql.SQLException; @Category(IntegrationTest.class) @RunWith(Parameterized.class) @@ -45,7 +46,7 @@ public static void setup() throws Exception { } @AfterClass - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { TestJoinQuery.classTearDown(); } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java index 2bcb5d9262..18699461c8 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java @@ -29,6 +29,7 @@ import org.junit.runners.Parameterized; import java.sql.ResultSet; +import java.sql.SQLException; @Category(IntegrationTest.class) @RunWith(Parameterized.class) @@ -45,7 +46,7 @@ public static void setup() throws Exception { } @AfterClass - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { TestJoinQuery.classTearDown(); } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java index da0f59d29d..8fe7b8568e 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java @@ -32,6 +32,7 @@ import org.junit.runners.Parameterized; import java.sql.ResultSet; +import java.sql.SQLException; import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; import static org.junit.Assert.assertEquals; @@ -66,7 +67,7 @@ public static void setup() throws Exception { } @AfterClass - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { TestJoinQuery.classTearDown(); client.executeQuery("DROP TABLE IF EXISTS customer_parts PURGE"); client.executeQuery("DROP TABLE IF EXISTS nation_partitioned PURGE"); diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java index ccbefc64f4..4ef5e9b7ea 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java @@ -110,7 +110,7 @@ public static void setup() throws Exception { } } - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname, ConfVars.$TEST_BROADCAST_JOIN_ENABLED.defaultVal); testingCluster.setAllTajoDaemonConfValue(ConfVars.$DIST_QUERY_BROADCAST_JOIN_THRESHOLD.varname, @@ -194,7 +194,7 @@ public Tuple createTuple(String[] columnDatas) { addEmptyDataFile("nation_multifile", false); } - protected static void dropCommonTables() throws ServiceException { + protected static void dropCommonTables() throws SQLException { LOG.info("Clear common tables for join tests"); client.executeQuery("DROP TABLE IF EXISTS jointable11 PURGE;"); diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java index b772d904b2..b4ab1d7987 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java @@ -29,6 +29,8 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.sql.SQLException; + @Category(IntegrationTest.class) @RunWith(Parameterized.class) @NamedTest("TestJoinQuery") @@ -44,7 +46,7 @@ public static void setup() throws Exception { } @AfterClass - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { TestJoinQuery.classTearDown(); } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java index 9d0e0bc27e..6e9454f0ad 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java @@ -29,6 +29,7 @@ import org.junit.runners.Parameterized; import java.sql.ResultSet; +import java.sql.SQLException; @Category(IntegrationTest.class) @RunWith(Parameterized.class) @@ -45,7 +46,7 @@ public static void setup() throws Exception { } @AfterClass - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { TestJoinQuery.classTearDown(); } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java index 71db0274a7..8e7094dacd 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java @@ -27,6 +27,8 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.sql.SQLException; + import static org.junit.Assert.assertEquals; @Category(IntegrationTest.class) @@ -44,7 +46,7 @@ public static void setup() throws Exception { } @AfterClass - public static void classTearDown() throws ServiceException { + public static void classTearDown() throws SQLException { TestJoinQuery.classTearDown(); } diff --git a/tajo-core/src/test/java/org/apache/tajo/worker/TestHistory.java b/tajo-core/src/test/java/org/apache/tajo/worker/TestHistory.java index df6d714732..3da3ed8edf 100644 --- a/tajo-core/src/test/java/org/apache/tajo/worker/TestHistory.java +++ b/tajo-core/src/test/java/org/apache/tajo/worker/TestHistory.java @@ -34,6 +34,7 @@ import java.io.File; import java.io.IOException; +import java.sql.SQLException; import java.util.Collection; import java.util.Map; @@ -65,7 +66,7 @@ public static void tearDown() throws IOException { } @Test - public final void testTaskRunnerHistory() throws IOException, ServiceException, InterruptedException { + public final void testTaskRunnerHistory() throws IOException, SQLException, InterruptedException { int beforeFinishedQueriesCount = master.getContext().getQueryJobManager().getFinishedQueries().size(); client.executeQueryAndGetResult("select count(*) from lineitem"); @@ -92,7 +93,7 @@ public final void testTaskRunnerHistory() throws IOException, ServiceException, } @Test - public final void testTaskHistory() throws IOException, ServiceException, InterruptedException { + public final void testTaskHistory() throws IOException, SQLException, InterruptedException { int beforeFinishedQueriesCount = master.getContext().getQueryJobManager().getFinishedQueries().size(); client.executeQueryAndGetResult("select count(*) from lineitem"); 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 d57596816a..6db14474b1 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 @@ -217,11 +217,7 @@ public boolean getAutoCommit() throws SQLException { @Override public String getCatalog() throws SQLException { - try { - return tajoClient.getCurrentDatabase(); - } catch (ServiceException e) { - throw new SQLException(e); - } + return tajoClient.getCurrentDatabase(); } @Override @@ -271,21 +267,13 @@ public boolean isReadOnly() throws SQLException { @Override public boolean isValid(int timeout) throws SQLException { - try { - if (tajoClient.isConnected()) { - ResultSet resultSet = tajoClient.executeQueryAndGetResult("SELECT 1;"); - boolean next = resultSet.next(); - boolean valid = next && resultSet.getLong(1) == 1; - resultSet.close(); - return valid; - } else { - return false; - } - } catch (ServiceException e) { - LOG.error("TajoMaster is not available.", e); - return false; - } catch (IOException e) { - LOG.error("JDBC connection is not valid.", e); + if (tajoClient.isConnected()) { + ResultSet resultSet = tajoClient.executeQueryAndGetResult("SELECT 1;"); + boolean next = resultSet.next(); + boolean valid = next && resultSet.getLong(1) == 1; + resultSet.close(); + return valid; + } else { return false; } } @@ -369,22 +357,16 @@ public void setAutoCommit(boolean autoCommit) throws SQLException { @Override public void setCatalog(String catalog) throws SQLException { - try { - tajoClient.selectDatabase(catalog); - } catch (ServiceException e) { - throw new SQLException(e); - } + tajoClient.selectDatabase(catalog); } @Override - public void setClientInfo(Properties properties) - throws SQLClientInfoException { + public void setClientInfo(Properties properties) throws SQLClientInfoException { throw new UnsupportedOperationException("setClientInfo"); } @Override - public void setClientInfo(String name, String value) - throws SQLClientInfoException { + public void setClientInfo(String name, String value) throws SQLClientInfoException { throw new UnsupportedOperationException("setClientInfo"); } diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java index d4ef55e02a..04742583c9 100644 --- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java +++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java @@ -422,11 +422,8 @@ public int compare(MetaDataTuple table1, MetaDataTuple table2) { @Override public ResultSet getSchemas() throws SQLException { String databaseName; - try { - databaseName = conn.getQueryClient().getCurrentDatabase(); - } catch (ServiceException e) { - throw new SQLException(e); - } + + databaseName = conn.getQueryClient().getCurrentDatabase(); MetaDataTuple tuple = new MetaDataTuple(2); tuple.put(0, new TextDatum(DEFAULT_SCHEMA_NAME)); @@ -441,11 +438,8 @@ public ResultSet getSchemas() throws SQLException { @Override public ResultSet getCatalogs() throws SQLException { Collection databaseNames; - try { - databaseNames = conn.getCatalogAdminClient().getAllDatabaseNames(); - } catch (ServiceException e) { - throw new SQLException(e); - } + + databaseNames = conn.getCatalogAdminClient().getAllDatabaseNames(); List tuples = new ArrayList(); for (String databaseName : databaseNames) { @@ -765,11 +759,8 @@ public RowIdLifetime getRowIdLifetime() @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { String databaseName; - try { - databaseName = conn.getQueryClient().getCurrentDatabase(); - } catch (ServiceException e) { - throw new SQLException(e); - } + + databaseName = conn.getQueryClient().getCurrentDatabase(); MetaDataTuple tuple = new MetaDataTuple(2); tuple.put(0, new TextDatum(DEFAULT_SCHEMA_NAME)); 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 13c74f03fa..aa7ea4ad3b 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 @@ -159,29 +159,22 @@ protected ResultSet executeSQL(String sql) throws SQLException { return unSetSessionVariable(tajoClient, sql); } - - try { - ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql); - SQLExceptionUtil.throwIfError(response.getState()); - - QueryId queryId = new QueryId(response.getQueryId()); - if (response.getIsForwarded() && !queryId.isNull()) { - WaitingResultSet result = new WaitingResultSet(tajoClient, queryId, fetchSize); - if (blockWait) { - result.getSchema(); - } - return result; + ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql); + SQLExceptionUtil.throwIfError(response.getState()); + + QueryId queryId = new QueryId(response.getQueryId()); + if (response.getIsForwarded() && !queryId.isNull()) { + WaitingResultSet result = new WaitingResultSet(tajoClient, queryId, fetchSize); + if (blockWait) { + result.getSchema(); } + return result; + } - if (response.hasResultSet() || response.hasTableDesc()) { - return TajoClientUtil.createResultSet(tajoClient, response, fetchSize); - } - return TajoClientUtil.createNullResultSet(queryId); - } catch (SQLException s) { - throw s; - } catch (Throwable t) { - throw new SQLException(t.getMessage(), t); + if (response.hasResultSet() || response.hasTableDesc()) { + return TajoClientUtil.createResultSet(tajoClient, response, fetchSize); } + return TajoClientUtil.createNullResultSet(queryId); } protected void checkConnection(String errorMsg) throws SQLException { @@ -218,12 +211,7 @@ private ResultSet setSessionVariable(TajoClient client, String sql) throws SQLEx } Map variable = new HashMap(); variable.put(tokens[0].trim(), tokens[1].trim()); - try { - client.updateSessionVariables(variable); - } catch (ServiceException e) { - throw new SQLException(e.getMessage(), e); - } - + client.updateSessionVariables(variable); return TajoClientUtil.createNullResultSet(); } @@ -237,11 +225,7 @@ private ResultSet unSetSessionVariable(TajoClient client, String sql) throws SQL if (key.isEmpty()) { throw new SQLException("UNSET statement should be : " + sql); } - try { - client.unsetSessionVariables(Lists.newArrayList(key)); - } catch (ServiceException e) { - throw new SQLException(e.getMessage(), e); - } + client.unsetSessionVariables(Lists.newArrayList(key)); return TajoClientUtil.createNullResultSet(); } @@ -249,13 +233,8 @@ private ResultSet unSetSessionVariable(TajoClient client, String sql) throws SQL @Override public int executeUpdate(String sql) throws SQLException { checkConnection("Can't execute update"); - try { - tajoClient.executeQuery(sql); - - return 1; - } catch (Exception ex) { - throw new SQLException(ex.toString()); - } + tajoClient.executeQuery(sql); + return 1; } @Override From aa4404fd0fceabf8495dbc591a31fce0e78ed17d Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 02:15:07 -0700 Subject: [PATCH 11/30] Removed duplicate exception. --- .../src/main/java/org/apache/tajo/client/TajoClientImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 e005974c3c..c81fafcafd 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 @@ -198,13 +198,13 @@ public boolean existTable(final String tableName) throws SQLException { } public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, - final TableMeta meta) throws SQLException, SQLException { + final TableMeta meta) throws SQLException { return catalogClient.createExternalTable(tableName, schema, path, meta); } public TableDesc createExternalTable(final String tableName, final Schema schema, final URI path, final TableMeta meta, final PartitionMethodDesc partitionMethodDesc) - throws SQLException, SQLException { + throws SQLException { return catalogClient.createExternalTable(tableName, schema, path, meta, partitionMethodDesc); } From 2376e3002f3a329302a3fd9fe7ae509582b75c5e Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 02:51:05 -0700 Subject: [PATCH 12/30] Applied ResponseState to all client APIs. --- .../tajo/client/CatalogAdminClientImpl.java | 8 ++- .../apache/tajo/client/SessionConnection.java | 15 ++++- tajo-client/src/main/proto/ClientProtos.proto | 23 ++++++-- .../main/proto/TajoMasterClientProtocol.proto | 10 ++-- .../tajo/master/TajoMasterClientService.java | 56 +++++++++++++------ .../org/apache/tajo/QueryTestCaseBase.java | 13 +---- 6 files changed, 82 insertions(+), 43 deletions(-) diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index 5b77f16309..d8fdfba759 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -30,6 +30,7 @@ import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.DropTableRequest; import org.apache.tajo.ipc.ClientProtos.SessionedStringProto; +import org.apache.tajo.ipc.ClientProtos.StringListResponse; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; @@ -174,14 +175,15 @@ public List getTableList(@Nullable final String databaseName) throws SQL final BlockingInterface stub = conn.getTMStub(); - PrimitiveProtos.StringListProto res; + StringListResponse response; try { - res = stub.getTableList(null, conn.getSessionedString(databaseName)); + response = stub.getTableList(null, conn.getSessionedString(databaseName)); } catch (ServiceException e) { throw new RuntimeException(e); } - return res.getValuesList(); + throwIfError(response.getState()); + return response.getValuesList(); } @Override 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 db1742bd2a..8beaaa7c87 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 @@ -27,7 +27,9 @@ import org.apache.tajo.annotation.Nullable; import org.apache.tajo.auth.UserRoleInfo; import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.KeyValueSetResponse; import org.apache.tajo.ipc.ClientProtos.SessionUpdateResponse; +import org.apache.tajo.ipc.ClientProtos.StringResponse; import org.apache.tajo.ipc.TajoMasterClientProtocol; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.RpcChannelFactory; @@ -51,6 +53,7 @@ import static org.apache.tajo.client.ClientErrorUtil.*; import static org.apache.tajo.client.SQLExceptionUtil.convert; +import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; import static org.apache.tajo.ipc.ClientProtos.CreateSessionResponse; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -180,11 +183,15 @@ public String getCurrentDatabase() throws SQLException { TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + StringResponse response; try { - return tajoMasterService.getCurrentDatabase(null, sessionId).getValue(); + response = tajoMasterService.getCurrentDatabase(null, sessionId); } catch (ServiceException e) { throw new RuntimeException(e); } + + throwIfError(response.getState()); + return response.getValue(); } public Map updateSessionVariables(final Map variables) throws SQLException { @@ -284,11 +291,15 @@ public Map getAllSessionVariables() throws SQLException { checkSessionAndGet(client); TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + KeyValueSetResponse response; try { - return ProtoUtil.convertToMap(stub.getAllSessionVariables(null, sessionId)); + response = stub.getAllSessionVariables(null, sessionId); } catch (ServiceException e) { throw new RuntimeException(e); } + + throwIfError(response.getState()); + return ProtoUtil.convertToMap(response.getValue()); } public Boolean selectDatabase(final String databaseName) throws SQLException { diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index 73f9882cc3..6d5afa6ded 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -37,6 +37,21 @@ message ResponseState { optional tajo.error.StackTrace stack_trace = 3; } +message StringListResponse { + required ResponseState state = 1; + repeated string values = 2; +} + +message KeyValueSetResponse { + required ResponseState state = 1; + optional KeyValueSetProto value = 2; +} + +message StringResponse { + required ResponseState state = 1; + optional string value = 2; +} + message CreateSessionRequest { required string username = 1; optional string baseDatabaseName = 2; @@ -130,8 +145,8 @@ message SerializedResultSet { message SubmitQueryResponse { required ResponseState state = 1; - required QueryIdProto queryId = 2; - required string userName = 3; + optional QueryIdProto queryId = 2; + optional string userName = 3; optional bool isForwarded = 4 [default = false]; optional string queryMasterHost = 5; @@ -146,7 +161,7 @@ message SubmitQueryResponse { message GetQueryStatusResponse { required ResponseState state = 1; - required QueryIdProto queryId = 2; + optional QueryIdProto queryId = 2; optional QueryState query_state = 3; optional float progress = 4; optional int64 submitTime = 5; @@ -166,7 +181,7 @@ message GetQueryResultDataRequest { message GetQueryResultDataResponse { required ResponseState state = 1; - required SerializedResultSet resultSet = 2; + optional SerializedResultSet resultSet = 2; } message GetClusterInfoRequest { diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto index b48e01eb1a..4db4a8182d 100644 --- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto +++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto @@ -34,11 +34,11 @@ service TajoMasterClientProtocolService { // Session APIs rpc createSession(CreateSessionRequest) returns (CreateSessionResponse); - rpc removeSession(SessionIdProto) returns (BoolProto); + rpc removeSession(SessionIdProto) returns (ResponseState); rpc updateSessionVariables(UpdateSessionVariableRequest) returns (SessionUpdateResponse); rpc existSessionVariable(SessionedStringProto) returns (ResponseState); rpc getSessionVariable(SessionedStringProto) returns (StringProto); - rpc getAllSessionVariables(SessionIdProto) returns (KeyValueSetProto); + rpc getAllSessionVariables(SessionIdProto) returns (KeyValueSetResponse); // Query Submission and Result APIs rpc submitQuery(QueryRequest) returns (SubmitQueryResponse); @@ -59,15 +59,15 @@ service TajoMasterClientProtocolService { rpc createDatabase(SessionedStringProto) returns (ResponseState); rpc existDatabase(SessionedStringProto) returns (ResponseState); rpc dropDatabase(SessionedStringProto) returns (ResponseState); - rpc getAllDatabases(SessionIdProto) returns (StringListProto); - rpc getCurrentDatabase(SessionIdProto) returns (StringProto); + rpc getAllDatabases(SessionIdProto) returns (StringListResponse); + rpc getCurrentDatabase(SessionIdProto) returns (StringResponse); rpc selectDatabase(SessionedStringProto) returns (ResponseState); // Table Management APIs rpc createExternalTable(CreateTableRequest) returns (TableResponse); rpc existTable(SessionedStringProto) returns (ResponseState); rpc dropTable(DropTableRequest) returns (ResponseState); - rpc getTableList(SessionedStringProto) returns (StringListProto); + rpc getTableList(SessionedStringProto) returns (StringListResponse); rpc getTableDesc(SessionedStringProto) returns (TableResponse); rpc getFunctionList(SessionedStringProto) returns (FunctionResponse); } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index bf224f360c..63fac14690 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -155,14 +155,14 @@ public CreateSessionResponse createSession(RpcController controller, CreateSessi } @Override - public BoolProto removeSession(RpcController controller, TajoIdProtos.SessionIdProto request) + public ResponseState removeSession(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { if (request != null) { context.getSessionManager().removeSession(request.getId()); } - return BOOL_TRUE; + return OK; } @Override @@ -220,29 +220,40 @@ public ResponseState existSessionVariable(RpcController controller, SessionedStr } @Override - public KeyValueSetProto getAllSessionVariables(RpcController controller, + public KeyValueSetResponse getAllSessionVariables(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { + try { String sessionId = request.getId(); KeyValueSet keyValueSet = new KeyValueSet(); keyValueSet.putAll(context.getSessionManager().getAllVariables(sessionId)); - return keyValueSet.getProto(); + + return KeyValueSetResponse.newBuilder() + .setState(OK) + .setValue(keyValueSet.getProto()) + .build(); } catch (Throwable t) { - throw new ServiceException(t); + return KeyValueSetResponse.newBuilder() + .setState(returnError(t)) + .build(); } } @Override - public StringProto getCurrentDatabase(RpcController controller, TajoIdProtos.SessionIdProto request) + public StringResponse getCurrentDatabase(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { try { - String sessionId = request.getId(); - return ProtoUtil.convertString(context.getSessionManager().getSession(sessionId).getCurrentDatabase()); + return StringResponse.newBuilder() + .setState(OK) + .setValue(context.getSessionManager().getSession(request.getId()).getCurrentDatabase()) + .build(); } catch (Throwable t) { - throw new ServiceException(t); + return StringResponse.newBuilder() + .setState(returnError(t)) + .build(); } } @@ -714,15 +725,21 @@ public ResponseState dropDatabase(RpcController controller, SessionedStringProto } @Override - public StringListProto getAllDatabases(RpcController controller, TajoIdProtos.SessionIdProto + public StringListResponse getAllDatabases(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { try { context.getSessionManager().touch(request.getId()); - return ProtoUtil.convertStrings(catalog.getAllDatabaseNames()); - } catch (Throwable e) { - throw new ServiceException(e); + return StringListResponse.newBuilder() + .setState(OK) + .addAllValues(catalog.getAllDatabaseNames()) + .build(); + + } catch (Throwable t) { + return StringListResponse.newBuilder() + .setState(returnError(t)) + .build(); } } @@ -755,7 +772,7 @@ public ResponseState existTable(RpcController controller, SessionedStringProto r } @Override - public StringListProto getTableList(RpcController controller, + public StringListResponse getTableList(RpcController controller, SessionedStringProto request) throws ServiceException { try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); @@ -766,13 +783,16 @@ public StringListProto getTableList(RpcController controller, databaseName = session.getCurrentDatabase(); } Collection tableNames = catalog.getAllTableNames(databaseName); - StringListProto.Builder builder = StringListProto.newBuilder(); - builder.addAllValues(tableNames); - return builder.build(); + return StringListResponse.newBuilder() + .setState(OK) + .addAllValues(tableNames) + .build(); } catch (Throwable t) { - throw new ServiceException(t); + return StringListResponse.newBuilder() + .setState(returnError(t)) + .build(); } } diff --git a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java index 13c67e7d99..11b497dcc1 100644 --- a/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java +++ b/tajo-core/src/test/java/org/apache/tajo/QueryTestCaseBase.java @@ -57,22 +57,13 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; import java.lang.reflect.Method; import java.net.URL; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import static org.junit.Assert.*; From 254c044f190a7a37130716969c487cbb1a250f96 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 04:54:09 -0700 Subject: [PATCH 13/30] Fixed method names. --- .../UndefinedTablespaceException.java | 2 +- .../apache/tajo/client/ClientErrorUtil.java | 29 +++++++------------ .../apache/tajo/exception/ExceptionUtil.java | 28 ++++++++++++++---- .../tajo/master/TajoMasterClientService.java | 26 ++++++++--------- .../tajo/master/exec/QueryExecutor.java | 6 ++-- 5 files changed, 48 insertions(+), 43 deletions(-) diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java index ab6282c1da..ffe57897fd 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTablespaceException.java @@ -24,6 +24,6 @@ public class UndefinedTablespaceException extends CatalogException { private static final long serialVersionUID = 277182608283894937L; public UndefinedTablespaceException(String spaceName) { - super(Errors.ResultCode.UNDEFINED_PARTITION, spaceName); + super(Errors.ResultCode.UNDEFINED_TABLESPACE, spaceName); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java index 8934a9076d..f10acd31b9 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java @@ -23,6 +23,7 @@ import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.ErrorMessages; import org.apache.tajo.exception.ErrorUtil; +import org.apache.tajo.exception.ExceptionUtil; import org.apache.tajo.exception.TajoExceptionInterface; import org.apache.tajo.ipc.ClientProtos.ResponseState; @@ -38,10 +39,6 @@ public class ClientErrorUtil { OK = builder.build(); } - public static ResponseState returnOk() { - return OK; - } - public static ResponseState returnError(ResultCode code) { ResponseState.Builder builder = ResponseState.newBuilder(); builder.setReturnCode(code); @@ -61,7 +58,7 @@ public static ResponseState returnError(ResultCode code, String...args) { public static ResponseState returnError(Throwable t) { ResponseState.Builder builder = ResponseState.newBuilder(); - if (t instanceof TajoExceptionInterface) { + if (ExceptionUtil.isExceptionWithResultCode(t)) { TajoExceptionInterface tajoException = (TajoExceptionInterface) t; builder.setReturnCode(tajoException.getErrorCode()); builder.setMessage(tajoException.getMessage()); @@ -94,43 +91,39 @@ public static boolean isError(ResponseState state) { return ErrorUtil.isFailed(state.getReturnCode()); } - public static boolean isThisError(ResponseState state, ResultCode expected) { - return state.getReturnCode() == expected; - } - - public static ResponseState ERR_INVALID_RPC_CALL(String message) { + public static ResponseState errInvalidRpcCall(String message) { return returnError(ResultCode.INVALID_RPC_CALL, message); } - public static ResponseState ERR_NO_SUCH_QUERY_ID(QueryId queryId) { + public static ResponseState errNoSuchQueryId(QueryId queryId) { return returnError(ResultCode.NO_SUCH_QUERYID, queryId.toString()); } - public static ResponseState ERR_NO_DATA(QueryId queryId) { + public static ResponseState errNoData(QueryId queryId) { return returnError(ResultCode.NO_DATA, queryId.toString()); } - public static ResponseState ERR_INCOMPLETE_QUERY(QueryId queryId) { + public static ResponseState errIncompleteQuery(QueryId queryId) { return returnError(ResultCode.INCOMPLETE_QUERY, queryId.toString()); } - public static ResponseState ERR_INVALID_SESSION(String sessionId) { + public static ResponseState errInvalidSession(String sessionId) { return returnError(ResultCode.INVALID_SESSION, sessionId); } - public static ResponseState ERR_NO_SESSION_VARIABLE(String varName) { + public static ResponseState errNoSessionVar(String varName) { return returnError(ResultCode.NO_SUCH_QUERYID, varName); } - public static ResponseState ERR_UNDEFIED_DATABASE(String dbName) { + public static ResponseState errUndefinedDatabase(String dbName) { return returnError(ResultCode.UNDEFINED_DATABASE, dbName); } - public static ResponseState ERR_UNDEFIED_TABLE(String tableName) { + public static ResponseState errUndefinedTable(String tableName) { return returnError(ResultCode.UNDEFINED_TABLE, tableName); } - public static ResponseState ERR_DUPLICATE_DATABASE(String dbName) { + public static ResponseState errDuplicateDatabase(String dbName) { return returnError(ResultCode.DUPLICATE_DATABASE, dbName); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java index 9da78c38a7..bc01cb9f9d 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java @@ -24,18 +24,26 @@ public class ExceptionUtil { - public static TajoRuntimeException makeNotSupported(String feature) { - return new UnsupportedException(feature); + /** + * Determine if a Throwable has Tajo's ReturnCode and error message. + * + * @param t Throwable + * @return true if a Throwable has Tajo's ReturnCode and error message. + */ + public static boolean isExceptionWithResultCode(Throwable t) { + return t instanceof TajoExceptionInterface; } + /** + * Determine if a Throwable is caused by user's wrong input and invalid data instead of a bug. + * + * @param t Throwable + * @return true if a Throwable has Tajo's ReturnCode and error message. + */ public static boolean isManagedException(Throwable t) { return t instanceof TajoException || t instanceof TajoRuntimeException; } - public static InvalidDataTypeException makeInvalidDataType(DataType dataType) { - return new InvalidDataTypeException(dataType); - } - private static void printStackTrace(Log log, Throwable t) { log.error("\nStack Trace:\n" + StringUtils.stringifyException(t)); } @@ -45,4 +53,12 @@ public static void printStackTraceIfError(Log log, Throwable t) { ExceptionUtil.printStackTrace(log, t); } } + + public static UnsupportedException makeNotSupported(String feature) { + return new UnsupportedException(feature); + } + + public static InvalidDataTypeException makeInvalidDataType(DataType dataType) { + return new InvalidDataTypeException(dataType); + } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 63fac14690..b993078f5a 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -54,7 +54,6 @@ import org.apache.tajo.querymaster.QueryJobEvent; import org.apache.tajo.rpc.BlockingRpcServer; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto; import org.apache.tajo.session.Session; import org.apache.tajo.util.KeyValueSet; @@ -68,7 +67,6 @@ import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; import static org.apache.tajo.client.ClientErrorUtil.*; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueProto; -import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueSetProto; public class TajoMasterClientService extends AbstractService { private final static Log LOG = LogFactory.getLog(TajoMasterClientService.class); @@ -212,7 +210,7 @@ public ResponseState existSessionVariable(RpcController controller, SessionedStr if (value != null) { return OK; } else { - return ERR_NO_SESSION_VARIABLE(request.getValue()); + return errNoSessionVar(request.getValue()); } } catch (Throwable t) { return returnError(t); @@ -267,7 +265,7 @@ public ResponseState selectDatabase(RpcController controller, SessionedStringPro context.getSessionManager().getSession(sessionId).selectDatabase(databaseName); return OK; } else { - return ERR_UNDEFIED_DATABASE(databaseName); + return errUndefinedDatabase(databaseName); } } catch (Throwable t) { return returnError(t); @@ -339,7 +337,7 @@ public GetQueryResultResponse getQueryResult(RpcController controller, // the query result was expired due to timeout. // In this case, we will result in error. if (queryInfo == null) { - builder.setState(ERR_NO_SUCH_QUERY_ID(queryId)); + builder.setState(errNoSuchQueryId(queryId)); return builder.build(); } @@ -352,11 +350,11 @@ public GetQueryResultResponse getQueryResult(RpcController controller, break; case QUERY_FAILED: case QUERY_ERROR: - builder.setState(ERR_NO_DATA(queryId)); + builder.setState(errNoData(queryId)); break; default: - builder.setState(ERR_INCOMPLETE_QUERY(queryId)); + builder.setState(errIncompleteQuery(queryId)); } return builder.build(); @@ -490,7 +488,7 @@ public GetQueryStatusResponse getQueryStatus(RpcController controller, builder.setState(OK); builder.setQueryState(QueryState.QUERY_SUCCEEDED); } else { - builder.setState(ERR_NO_SUCH_QUERY_ID(queryId)); + builder.setState(errNoSuchQueryId(queryId)); } } } @@ -684,7 +682,7 @@ public ResponseState createDatabase(RpcController controller, SessionedStringPro if (context.getGlobalEngine().getDDLExecutor().createDatabase(queryContext, request.getValue(), null, false)) { return OK; } else { - return ERR_DUPLICATE_DATABASE(request.getValue()); + return errDuplicateDatabase(request.getValue()); } } catch (Throwable t) { @@ -699,7 +697,7 @@ public ResponseState existDatabase(RpcController controller, SessionedStringProt if (catalog.existDatabase(request.getValue())) { return OK; } else { - return ERR_UNDEFIED_DATABASE(request.getValue()); + return errUndefinedDatabase(request.getValue()); } } catch (Throwable t) { @@ -716,7 +714,7 @@ public ResponseState dropDatabase(RpcController controller, SessionedStringProto if (context.getGlobalEngine().getDDLExecutor().dropDatabase(queryContext, request.getValue(), false)) { return OK; } else { - return ERR_UNDEFIED_DATABASE(request.getValue()); + return errUndefinedDatabase(request.getValue()); } } catch (Throwable t) { @@ -763,7 +761,7 @@ public ResponseState existTable(RpcController controller, SessionedStringProto r if (catalog.existsTable(databaseName, tableName)) { return OK; } else { - return ERR_UNDEFIED_TABLE(tableName); + return errUndefinedTable(tableName); } } catch (Throwable t) { @@ -802,7 +800,7 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto if (!request.hasValue()) { return TableResponse.newBuilder() - .setState(ERR_INVALID_RPC_CALL("Table name is required")) + .setState(errInvalidRpcCall("Table name is required")) .build(); } @@ -826,7 +824,7 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto .build(); } else { return TableResponse.newBuilder() - .setState(ERR_UNDEFIED_TABLE(request.getValue())) + .setState(errUndefinedTable(request.getValue())) .build(); } } catch (Throwable t) { 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 7563d995a0..55f05b2af2 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 @@ -34,7 +34,6 @@ import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.statistics.TableStats; -import org.apache.tajo.client.ClientErrorUtil; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.datum.DatumFactory; @@ -43,7 +42,6 @@ import org.apache.tajo.engine.planner.physical.EvalExprExec; import org.apache.tajo.engine.planner.physical.InsertRowsExec; import org.apache.tajo.engine.query.QueryContext; -import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; import org.apache.tajo.master.QueryInfo; @@ -73,7 +71,7 @@ import java.util.ArrayList; import java.util.List; -import static org.apache.tajo.client.ClientErrorUtil.ERR_UNDEFIED_DATABASE; +import static org.apache.tajo.client.ClientErrorUtil.errUndefinedDatabase; import static org.apache.tajo.client.ClientErrorUtil.OK; public class QueryExecutor { @@ -151,7 +149,7 @@ public void execSetSession(Session session, LogicalPlan plan, session.selectDatabase(setSessionNode.getValue()); } else { response.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); - response.setState(ERR_UNDEFIED_DATABASE(databaseName)); + response.setState(errUndefinedDatabase(databaseName)); } // others From 1c3c8196fc73deddc8b821625bf0eba00ae7f7b5 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 11:26:24 -0700 Subject: [PATCH 14/30] Changed the package. --- .../apache/tajo/client/ClientErrorUtil.java | 43 +++++++++---------- .../tajo/client/ExceptionConvertor.java | 6 +-- .../apache/tajo/client/SQLExceptionUtil.java | 6 +-- .../apache/tajo/client/TajoClientUtil.java | 3 -- tajo-client/src/main/proto/ClientProtos.proto | 36 ++++++++-------- .../main/proto/TajoMasterClientProtocol.proto | 20 ++++----- .../src/main/proto/PrimitiveProtos.proto | 5 +++ .../tajo/master/TajoMasterClientService.java | 20 ++++----- 8 files changed, 70 insertions(+), 69 deletions(-) diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java index f10acd31b9..3012b8208a 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java @@ -25,38 +25,37 @@ import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.exception.ExceptionUtil; import org.apache.tajo.exception.TajoExceptionInterface; -import org.apache.tajo.ipc.ClientProtos.ResponseState; - -import java.sql.SQLException; +import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.ReturnState; public class ClientErrorUtil { - public static final ResponseState OK; + public static final ClientProtos.ReturnState OK; static { - ResponseState.Builder builder = ResponseState.newBuilder(); + ClientProtos.ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(ResultCode.OK); OK = builder.build(); } - public static ResponseState returnError(ResultCode code) { - ResponseState.Builder builder = ResponseState.newBuilder(); + public static ClientProtos.ReturnState returnError(ResultCode code) { + ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(code); builder.setMessage(ErrorMessages.getMessage(code)); return builder.build(); } - public static ResponseState returnError(ResultCode code, String...args) { + public static ReturnState returnError(ResultCode code, String...args) { Preconditions.checkNotNull(args); - ResponseState.Builder builder = ResponseState.newBuilder(); + ClientProtos.ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(code); builder.setMessage(ErrorMessages.getMessage(code, args)); return builder.build(); } - public static ResponseState returnError(Throwable t) { - ResponseState.Builder builder = ResponseState.newBuilder(); + public static ClientProtos.ReturnState returnError(Throwable t) { + ReturnState.Builder builder = ClientProtos.ReturnState.newBuilder(); if (ExceptionUtil.isExceptionWithResultCode(t)) { TajoExceptionInterface tajoException = (TajoExceptionInterface) t; @@ -77,7 +76,7 @@ public static ResponseState returnError(Throwable t) { * @param state ResponseState to be checked * @return True if ResponseState is success. */ - public static boolean isSuccess(ResponseState state) { + public static boolean isSuccess(ClientProtos.ReturnState state) { return ErrorUtil.isOk(state.getReturnCode()); } @@ -87,43 +86,43 @@ public static boolean isSuccess(ResponseState state) { * @param state ResponseState to be checked * @return True if ResponseState is failed. */ - public static boolean isError(ResponseState state) { + public static boolean isError(ClientProtos.ReturnState state) { return ErrorUtil.isFailed(state.getReturnCode()); } - public static ResponseState errInvalidRpcCall(String message) { + public static ReturnState errInvalidRpcCall(String message) { return returnError(ResultCode.INVALID_RPC_CALL, message); } - public static ResponseState errNoSuchQueryId(QueryId queryId) { + public static ClientProtos.ReturnState errNoSuchQueryId(QueryId queryId) { return returnError(ResultCode.NO_SUCH_QUERYID, queryId.toString()); } - public static ResponseState errNoData(QueryId queryId) { + public static ClientProtos.ReturnState errNoData(QueryId queryId) { return returnError(ResultCode.NO_DATA, queryId.toString()); } - public static ResponseState errIncompleteQuery(QueryId queryId) { + public static ReturnState errIncompleteQuery(QueryId queryId) { return returnError(ResultCode.INCOMPLETE_QUERY, queryId.toString()); } - public static ResponseState errInvalidSession(String sessionId) { + public static ClientProtos.ReturnState errInvalidSession(String sessionId) { return returnError(ResultCode.INVALID_SESSION, sessionId); } - public static ResponseState errNoSessionVar(String varName) { + public static ClientProtos.ReturnState errNoSessionVar(String varName) { return returnError(ResultCode.NO_SUCH_QUERYID, varName); } - public static ResponseState errUndefinedDatabase(String dbName) { + public static ReturnState errUndefinedDatabase(String dbName) { return returnError(ResultCode.UNDEFINED_DATABASE, dbName); } - public static ResponseState errUndefinedTable(String tableName) { + public static ClientProtos.ReturnState errUndefinedTable(String tableName) { return returnError(ResultCode.UNDEFINED_TABLE, tableName); } - public static ResponseState errDuplicateDatabase(String dbName) { + public static ClientProtos.ReturnState errDuplicateDatabase(String dbName) { return returnError(ResultCode.DUPLICATE_DATABASE, dbName); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java b/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java index aa49d5eac0..3fe207eea8 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java @@ -22,7 +22,7 @@ import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.exception.TajoException; import org.apache.tajo.exception.TajoRuntimeException; -import org.apache.tajo.ipc.ClientProtos.ResponseState; +import org.apache.tajo.ipc.ClientProtos; /** * @@ -33,9 +33,9 @@ private static boolean isManagedException(Throwable t) { return t instanceof TajoException || t instanceof TajoRuntimeException; } - public ResponseState convert(Throwable t) { + public ClientProtos.ReturnState convert(Throwable t) { - ResponseState.Builder builder = ResponseState.newBuilder(); + ClientProtos.ReturnState.Builder builder = ClientProtos.ReturnState.newBuilder(); if (isManagedException(t)) { diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java index 5880375d61..a3f620e163 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -21,7 +21,7 @@ import com.google.common.collect.Maps; import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.ErrorMessages; -import org.apache.tajo.ipc.ClientProtos.ResponseState; +import org.apache.tajo.ipc.ClientProtos; import java.sql.SQLException; import java.util.Map; @@ -38,13 +38,13 @@ public class SQLExceptionUtil { SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601"); } - public static void throwIfError(ResponseState state) throws SQLException { + public static void throwIfError(ClientProtos.ReturnState state) throws SQLException { if (ClientErrorUtil.isError(state)) { throw convert(state); } } - public static SQLException convert(ResponseState state) throws SQLException { + public static SQLException convert(ClientProtos.ReturnState state) throws SQLException { if (SQLSTATES.containsKey(state.getReturnCode())) { return new SQLException( state.getMessage(), diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java index a4f7c7ebc6..90894feb35 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java @@ -18,7 +18,6 @@ package org.apache.tajo.client; -import com.google.protobuf.ServiceException; import org.apache.tajo.QueryId; import org.apache.tajo.QueryIdFactory; import org.apache.tajo.SessionVars; @@ -26,9 +25,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.ipc.ClientProtos; -import org.apache.tajo.ipc.ClientProtos.ResponseState; import org.apache.tajo.jdbc.FetchResultSet; import org.apache.tajo.jdbc.TajoMemoryResultSet; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index 6d5afa6ded..bf9b35af69 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -31,24 +31,24 @@ import "PrimitiveProtos.proto"; import "errors.proto"; // tajo-common import "stacktrace.proto"; // tajo-common -message ResponseState { +message ReturnState { required tajo.error.ResultCode return_code = 1; optional string message = 2; optional tajo.error.StackTrace stack_trace = 3; } message StringListResponse { - required ResponseState state = 1; + required ReturnState state = 1; repeated string values = 2; } message KeyValueSetResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional KeyValueSetProto value = 2; } message StringResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional string value = 2; } @@ -58,7 +58,7 @@ message CreateSessionRequest { } message CreateSessionResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional SessionIdProto sessionId = 2; optional KeyValueSetProto sessionVars = 3; } @@ -70,7 +70,7 @@ message UpdateSessionVariableRequest { } message SessionUpdateResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional KeyValueSetProto sessionVars = 2; } @@ -80,7 +80,7 @@ message SessionedStringProto { } message ExplainQueryResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional string explain = 2; } @@ -92,7 +92,7 @@ message QueryRequest { } message UpdateQueryResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional KeyValueSetProto sessionVars = 2; } @@ -102,7 +102,7 @@ message GetQueryResultRequest { } message GetQueryResultResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional TableDescProto tableDesc = 2; optional string tajoUserName = 3; } @@ -128,7 +128,7 @@ message BriefQueryInfo { } message GetQueryListResponse { - required ResponseState state = 1; + required ReturnState state = 1; repeated BriefQueryInfo queryList = 2; } @@ -144,7 +144,7 @@ message SerializedResultSet { } message SubmitQueryResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional QueryIdProto queryId = 2; optional string userName = 3; optional bool isForwarded = 4 [default = false]; @@ -160,7 +160,7 @@ message SubmitQueryResponse { } message GetQueryStatusResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional QueryIdProto queryId = 2; optional QueryState query_state = 3; optional float progress = 4; @@ -180,7 +180,7 @@ message GetQueryResultDataRequest { } message GetQueryResultDataResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional SerializedResultSet resultSet = 2; } @@ -206,7 +206,7 @@ message WorkerResourceInfo { } message GetClusterInfoResponse { - required ResponseState state = 1; + required ReturnState state = 1; repeated WorkerResourceInfo workerList = 2; } @@ -226,12 +226,12 @@ message DropTableRequest { } message TableResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional TableDescProto tableDesc = 2; } message FunctionResponse { - required ResponseState state = 1; + required ReturnState state = 1; repeated FunctionDescProto functions = 2; optional string errorMessage = 3; } @@ -286,12 +286,12 @@ message QueryHistoryProto { } message GetQueryHistoryResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional QueryHistoryProto queryHistory = 2; } message GetQueryInfoResponse { - required ResponseState state = 1; + required ReturnState state = 1; optional QueryInfoProto queryInfo = 2; } diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto index 4db4a8182d..ff75ceeb84 100644 --- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto +++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto @@ -34,9 +34,9 @@ service TajoMasterClientProtocolService { // Session APIs rpc createSession(CreateSessionRequest) returns (CreateSessionResponse); - rpc removeSession(SessionIdProto) returns (ResponseState); + rpc removeSession(SessionIdProto) returns (ReturnState); rpc updateSessionVariables(UpdateSessionVariableRequest) returns (SessionUpdateResponse); - rpc existSessionVariable(SessionedStringProto) returns (ResponseState); + rpc existSessionVariable(SessionedStringProto) returns (ReturnState); rpc getSessionVariable(SessionedStringProto) returns (StringProto); rpc getAllSessionVariables(SessionIdProto) returns (KeyValueSetResponse); @@ -50,23 +50,23 @@ service TajoMasterClientProtocolService { rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse); rpc getRunningQueryList(SessionIdProto) returns (GetQueryListResponse); rpc getFinishedQueryList(SessionIdProto) returns (GetQueryListResponse); - rpc killQuery(QueryIdRequest) returns (ResponseState); + rpc killQuery(QueryIdRequest) returns (ReturnState); rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse); - rpc closeNonForwardQuery(QueryIdRequest) returns (ResponseState); + rpc closeNonForwardQuery(QueryIdRequest) returns (ReturnState); rpc getQueryInfo(QueryIdRequest) returns (GetQueryInfoResponse); // Database Management APIs - rpc createDatabase(SessionedStringProto) returns (ResponseState); - rpc existDatabase(SessionedStringProto) returns (ResponseState); - rpc dropDatabase(SessionedStringProto) returns (ResponseState); + rpc createDatabase(SessionedStringProto) returns (ReturnState); + rpc existDatabase(SessionedStringProto) returns (ReturnState); + rpc dropDatabase(SessionedStringProto) returns (ReturnState); rpc getAllDatabases(SessionIdProto) returns (StringListResponse); rpc getCurrentDatabase(SessionIdProto) returns (StringResponse); - rpc selectDatabase(SessionedStringProto) returns (ResponseState); + rpc selectDatabase(SessionedStringProto) returns (ReturnState); // Table Management APIs rpc createExternalTable(CreateTableRequest) returns (TableResponse); - rpc existTable(SessionedStringProto) returns (ResponseState); - rpc dropTable(DropTableRequest) returns (ResponseState); + rpc existTable(SessionedStringProto) returns (ReturnState); + rpc dropTable(DropTableRequest) returns (ReturnState); rpc getTableList(SessionedStringProto) returns (StringListResponse); rpc getTableDesc(SessionedStringProto) returns (TableResponse); rpc getFunctionList(SessionedStringProto) returns (FunctionResponse); diff --git a/tajo-common/src/main/proto/PrimitiveProtos.proto b/tajo-common/src/main/proto/PrimitiveProtos.proto index 631916aeba..697026e420 100644 --- a/tajo-common/src/main/proto/PrimitiveProtos.proto +++ b/tajo-common/src/main/proto/PrimitiveProtos.proto @@ -16,11 +16,16 @@ * limitations under the License. */ +package tajo.proto; + option java_package = "org.apache.tajo.rpc.protocolrecords"; option java_outer_classname = "PrimitiveProtos"; option java_generic_services = true; option java_generate_equals_and_hash = true; +import "errors.proto"; +import "stacktrace.proto"; + message StringProto { required string value = 1; } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index b993078f5a..a6b37f3055 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -153,7 +153,7 @@ public CreateSessionResponse createSession(RpcController controller, CreateSessi } @Override - public ResponseState removeSession(RpcController controller, TajoIdProtos.SessionIdProto request) + public ReturnState removeSession(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { if (request != null) { @@ -203,7 +203,7 @@ public StringProto getSessionVariable(RpcController controller, SessionedStringP } @Override - public ResponseState existSessionVariable(RpcController controller, SessionedStringProto request) + public ReturnState existSessionVariable(RpcController controller, SessionedStringProto request) throws ServiceException { try { String value = context.getSessionManager().getVariable(request.getSessionId().getId(), request.getValue()); @@ -256,7 +256,7 @@ public StringResponse getCurrentDatabase(RpcController controller, TajoIdProtos. } @Override - public ResponseState selectDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ReturnState selectDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { String sessionId = request.getSessionId().getId(); String databaseName = request.getValue(); @@ -554,7 +554,7 @@ public GetQueryResultDataResponse getQueryResultData(RpcController controller, G } @Override - public ResponseState closeNonForwardQuery(RpcController controller, QueryIdRequest request) + public ReturnState closeNonForwardQuery(RpcController controller, QueryIdRequest request) throws ServiceException { try { @@ -604,7 +604,7 @@ public GetQueryInfoResponse getQueryInfo(RpcController controller, QueryIdReques * It is invoked by TajoContainerProxy. */ @Override - public ResponseState killQuery(RpcController controller, QueryIdRequest request) throws ServiceException { + public ReturnState killQuery(RpcController controller, QueryIdRequest request) throws ServiceException { try { context.getSessionManager().touch(request.getSessionId().getId()); QueryId queryId = new QueryId(request.getQueryId()); @@ -674,7 +674,7 @@ public GetClusterInfoResponse getClusterInfo(RpcController controller, } @Override - public ResponseState createDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ReturnState createDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); @@ -691,7 +691,7 @@ public ResponseState createDatabase(RpcController controller, SessionedStringPro } @Override - public ResponseState existDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ReturnState existDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { context.getSessionManager().touch(request.getSessionId().getId()); if (catalog.existDatabase(request.getValue())) { @@ -706,7 +706,7 @@ public ResponseState existDatabase(RpcController controller, SessionedStringProt } @Override - public ResponseState dropDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { + public ReturnState dropDatabase(RpcController controller, SessionedStringProto request) throws ServiceException { try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); @@ -742,7 +742,7 @@ public StringListResponse getAllDatabases(RpcController controller, TajoIdProtos } @Override - public ResponseState existTable(RpcController controller, SessionedStringProto request) throws ServiceException { + public ReturnState existTable(RpcController controller, SessionedStringProto request) throws ServiceException { try { Session session = context.getSessionManager().getSession(request.getSessionId().getId()); @@ -878,7 +878,7 @@ public TableResponse createExternalTable(RpcController controller, CreateTableRe } @Override - public ResponseState dropTable(RpcController controller, DropTableRequest dropTable) throws ServiceException { + public ReturnState dropTable(RpcController controller, DropTableRequest dropTable) throws ServiceException { try { Session session = context.getSessionManager().getSession(dropTable.getSessionId().getId()); QueryContext queryContext = new QueryContext(conf, session); From 43a2d2a3b158a6a9785bf6d0f7e18b2653068c56 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 13:20:06 -0700 Subject: [PATCH 15/30] Moved ReturnState to PrimitiveProtos. --- .../tajo/client/CatalogAdminClientImpl.java | 7 +-- .../apache/tajo/client/ClientErrorUtil.java | 31 +++++---- .../tajo/client/ExceptionConvertor.java | 59 ----------------- .../apache/tajo/client/SQLExceptionUtil.java | 18 +++--- .../apache/tajo/client/SessionConnection.java | 15 ++--- tajo-client/src/main/proto/ClientProtos.proto | 24 ------- .../src/main/proto/PrimitiveProtos.proto | 23 ++++++- .../tajo/master/TajoMasterClientService.java | 4 +- .../rs/resources/TestQueryResultResource.java | 63 ------------------- 9 files changed, 59 insertions(+), 185 deletions(-) delete mode 100644 tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index d8fdfba759..b0c798a0e4 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -25,14 +25,11 @@ import org.apache.tajo.catalog.TableDesc; import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.partition.PartitionMethodDesc; -import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionDescProto; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.DropTableRequest; -import org.apache.tajo.ipc.ClientProtos.SessionedStringProto; -import org.apache.tajo.ipc.ClientProtos.StringListResponse; import org.apache.tajo.rpc.NettyClientBase; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; import java.io.IOException; import java.net.URI; @@ -144,7 +141,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema if (isSuccess(res.getState())) { return CatalogUtil.newTableDesc(res.getTableDesc()); } else { - throw SQLExceptionUtil.convert(res.getState()); + throw SQLExceptionUtil.toSQLException(res.getState()); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java index 3012b8208a..0eb3bec1e0 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java @@ -25,20 +25,19 @@ import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.exception.ExceptionUtil; import org.apache.tajo.exception.TajoExceptionInterface; -import org.apache.tajo.ipc.ClientProtos; -import org.apache.tajo.ipc.ClientProtos.ReturnState; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; public class ClientErrorUtil { - public static final ClientProtos.ReturnState OK; + public static final ReturnState OK; static { - ClientProtos.ReturnState.Builder builder = ReturnState.newBuilder(); + ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(ResultCode.OK); OK = builder.build(); } - public static ClientProtos.ReturnState returnError(ResultCode code) { + public static ReturnState returnError(ResultCode code) { ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(code); builder.setMessage(ErrorMessages.getMessage(code)); @@ -48,14 +47,14 @@ public static ClientProtos.ReturnState returnError(ResultCode code) { public static ReturnState returnError(ResultCode code, String...args) { Preconditions.checkNotNull(args); - ClientProtos.ReturnState.Builder builder = ReturnState.newBuilder(); + ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(code); builder.setMessage(ErrorMessages.getMessage(code, args)); return builder.build(); } - public static ClientProtos.ReturnState returnError(Throwable t) { - ReturnState.Builder builder = ClientProtos.ReturnState.newBuilder(); + public static ReturnState returnError(Throwable t) { + ReturnState.Builder builder = ReturnState.newBuilder(); if (ExceptionUtil.isExceptionWithResultCode(t)) { TajoExceptionInterface tajoException = (TajoExceptionInterface) t; @@ -76,7 +75,7 @@ public static ClientProtos.ReturnState returnError(Throwable t) { * @param state ResponseState to be checked * @return True if ResponseState is success. */ - public static boolean isSuccess(ClientProtos.ReturnState state) { + public static boolean isSuccess(ReturnState state) { return ErrorUtil.isOk(state.getReturnCode()); } @@ -86,7 +85,7 @@ public static boolean isSuccess(ClientProtos.ReturnState state) { * @param state ResponseState to be checked * @return True if ResponseState is failed. */ - public static boolean isError(ClientProtos.ReturnState state) { + public static boolean isError(ReturnState state) { return ErrorUtil.isFailed(state.getReturnCode()); } @@ -94,11 +93,11 @@ public static ReturnState errInvalidRpcCall(String message) { return returnError(ResultCode.INVALID_RPC_CALL, message); } - public static ClientProtos.ReturnState errNoSuchQueryId(QueryId queryId) { + public static ReturnState errNoSuchQueryId(QueryId queryId) { return returnError(ResultCode.NO_SUCH_QUERYID, queryId.toString()); } - public static ClientProtos.ReturnState errNoData(QueryId queryId) { + public static ReturnState errNoData(QueryId queryId) { return returnError(ResultCode.NO_DATA, queryId.toString()); } @@ -106,11 +105,11 @@ public static ReturnState errIncompleteQuery(QueryId queryId) { return returnError(ResultCode.INCOMPLETE_QUERY, queryId.toString()); } - public static ClientProtos.ReturnState errInvalidSession(String sessionId) { + public static ReturnState errInvalidSession(String sessionId) { return returnError(ResultCode.INVALID_SESSION, sessionId); } - public static ClientProtos.ReturnState errNoSessionVar(String varName) { + public static ReturnState errNoSessionVar(String varName) { return returnError(ResultCode.NO_SUCH_QUERYID, varName); } @@ -118,11 +117,11 @@ public static ReturnState errUndefinedDatabase(String dbName) { return returnError(ResultCode.UNDEFINED_DATABASE, dbName); } - public static ClientProtos.ReturnState errUndefinedTable(String tableName) { + public static ReturnState errUndefinedTable(String tableName) { return returnError(ResultCode.UNDEFINED_TABLE, tableName); } - public static ClientProtos.ReturnState errDuplicateDatabase(String dbName) { + public static ReturnState errDuplicateDatabase(String dbName) { return returnError(ResultCode.DUPLICATE_DATABASE, dbName); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java b/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java deleted file mode 100644 index 3fe207eea8..0000000000 --- a/tajo-client/src/main/java/org/apache/tajo/client/ExceptionConvertor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.client; - -import org.apache.tajo.error.Errors; -import org.apache.tajo.exception.ErrorUtil; -import org.apache.tajo.exception.TajoException; -import org.apache.tajo.exception.TajoRuntimeException; -import org.apache.tajo.ipc.ClientProtos; - -/** - * - */ -public class ExceptionConvertor { - - private static boolean isManagedException(Throwable t) { - return t instanceof TajoException || t instanceof TajoRuntimeException; - } - - public ClientProtos.ReturnState convert(Throwable t) { - - ClientProtos.ReturnState.Builder builder = ClientProtos.ReturnState.newBuilder(); - - if (isManagedException(t)) { - - - } else { - // uncaught Exception, RuntimeException, and Error are mostly bugs, - // and they should be handled as internal error. - - builder.setReturnCode(Errors.ResultCode.INTERNAL_ERROR); - - if (t.getMessage() != null) { - builder.setMessage(t.getMessage()); - } - - builder.setStackTrace(ErrorUtil.convertStacktrace(t)); - } - - return builder.build(); - } - -} diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java index a3f620e163..0089939bc4 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -21,11 +21,13 @@ import com.google.common.collect.Maps; import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.ErrorMessages; -import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; import java.sql.SQLException; import java.util.Map; +import static org.apache.tajo.client.ClientErrorUtil.isError; + public class SQLExceptionUtil { private static final Map SQLSTATES = Maps.newHashMap(); @@ -38,25 +40,27 @@ public class SQLExceptionUtil { SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601"); } - public static void throwIfError(ClientProtos.ReturnState state) throws SQLException { - if (ClientErrorUtil.isError(state)) { - throw convert(state); + public static void throwIfError(ReturnState state) throws SQLException { + if (isError(state)) { + throw toSQLException(state); } } - public static SQLException convert(ClientProtos.ReturnState state) throws SQLException { + public static SQLException toSQLException(ReturnState state) throws SQLException { if (SQLSTATES.containsKey(state.getReturnCode())) { return new SQLException( state.getMessage(), SQLSTATES.get(state.getReturnCode()), - state.getReturnCode().getNumber()); + state.getReturnCode().getNumber() + ); } else { // If there is no SQLState corresponding to error code, // It will make SQLState '42000' (Syntax Error Or Access Rule Violation). return new SQLException( state.getMessage(), "42000", - ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_VALUE); + ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_VALUE + ); } } 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 8beaaa7c87..fd336bba1f 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 @@ -27,14 +27,14 @@ import org.apache.tajo.annotation.Nullable; import org.apache.tajo.auth.UserRoleInfo; import org.apache.tajo.ipc.ClientProtos; -import org.apache.tajo.ipc.ClientProtos.KeyValueSetResponse; import org.apache.tajo.ipc.ClientProtos.SessionUpdateResponse; -import org.apache.tajo.ipc.ClientProtos.StringResponse; import org.apache.tajo.ipc.TajoMasterClientProtocol; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.RpcChannelFactory; import org.apache.tajo.rpc.RpcClientManager; import org.apache.tajo.rpc.RpcConstants; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueSetResponse; +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; @@ -51,8 +51,9 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import static org.apache.tajo.client.ClientErrorUtil.*; -import static org.apache.tajo.client.SQLExceptionUtil.convert; +import static org.apache.tajo.client.ClientErrorUtil.isError; +import static org.apache.tajo.client.ClientErrorUtil.isSuccess; +import static org.apache.tajo.client.SQLExceptionUtil.toSQLException; import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; import static org.apache.tajo.ipc.ClientProtos.CreateSessionResponse; @@ -217,7 +218,7 @@ public Map updateSessionVariables(final Map vari updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { - throw convert(response.getState()); + throw toSQLException(response.getState()); } } @@ -242,7 +243,7 @@ public Map unsetSessionVariables(final List variables) t updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars())); return Collections.unmodifiableMap(sessionVarsCache); } else { - throw convert(response.getState()); + throw toSQLException(response.getState()); } } @@ -380,7 +381,7 @@ protected void checkSessionAndGet(NettyClientBase client) throws SQLException { LOG.debug(String.format("Got session %s as a user '%s'.", sessionId.getId(), userInfo.getUserName())); } } else { - throw SQLExceptionUtil.convert(response.getState()); + throw SQLExceptionUtil.toSQLException(response.getState()); } } } diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index bf9b35af69..e48e2ae63e 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -28,30 +28,6 @@ import "TajoIdProtos.proto"; import "CatalogProtos.proto"; import "PrimitiveProtos.proto"; -import "errors.proto"; // tajo-common -import "stacktrace.proto"; // tajo-common - -message ReturnState { - required tajo.error.ResultCode return_code = 1; - optional string message = 2; - optional tajo.error.StackTrace stack_trace = 3; -} - -message StringListResponse { - required ReturnState state = 1; - repeated string values = 2; -} - -message KeyValueSetResponse { - required ReturnState state = 1; - optional KeyValueSetProto value = 2; -} - -message StringResponse { - required ReturnState state = 1; - optional string value = 2; -} - message CreateSessionRequest { required string username = 1; optional string baseDatabaseName = 2; diff --git a/tajo-common/src/main/proto/PrimitiveProtos.proto b/tajo-common/src/main/proto/PrimitiveProtos.proto index 697026e420..0fdd1bb223 100644 --- a/tajo-common/src/main/proto/PrimitiveProtos.proto +++ b/tajo-common/src/main/proto/PrimitiveProtos.proto @@ -16,8 +16,6 @@ * limitations under the License. */ -package tajo.proto; - option java_package = "org.apache.tajo.rpc.protocolrecords"; option java_outer_classname = "PrimitiveProtos"; option java_generic_services = true; @@ -57,3 +55,24 @@ message KeyValueProto { message KeyValueSetProto { repeated KeyValueProto keyval = 1; } + +message ReturnState { + required tajo.error.ResultCode return_code = 1; + optional string message = 2; + optional tajo.error.StackTrace stack_trace = 3; +} + +message StringListResponse { + required ReturnState state = 1; + repeated string values = 2; +} + +message KeyValueSetResponse { + required ReturnState state = 1; + optional KeyValueSetProto value = 2; +} + +message StringResponse { + required ReturnState state = 1; + optional string value = 2; +} \ No newline at end of file diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index a6b37f3055..7f77cd6fc6 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -53,8 +53,8 @@ import org.apache.tajo.plan.logical.ScanNode; import org.apache.tajo.querymaster.QueryJobEvent; import org.apache.tajo.rpc.BlockingRpcServer; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.*; import org.apache.tajo.session.Session; import org.apache.tajo.util.KeyValueSet; import org.apache.tajo.util.NetUtils; diff --git a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java index 68d999cd78..fec5dbaa09 100644 --- a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java +++ b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java @@ -223,69 +223,6 @@ public void testGetQueryResultSet() throws Exception { } } - @Test - public void testGetQueryResultSetWithOffset() throws Exception { - String sessionId = generateNewSessionAndGetId(); - URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem"); - URI queryResultURI = new URI(queryIdURI + "/result"); - - GetQueryResultDataResponse response = restClient.target(queryResultURI) - .request().header(tajoSessionIdHeaderName, sessionId) - .get(new GenericType(GetQueryResultDataResponse.class)); - - assertNotNull(response); - assertNotNull(response.getResultCode()); - assertTrue(isOk(response.getResultCode())); - assertNotNull(response.getSchema()); - assertEquals(16, response.getSchema().getRootColumns().size()); - assertNotNull(response.getResultset()); - assertTrue(response.getResultset().getId() != 0); - assertNotNull(response.getResultset().getLink()); - - URI queryResultSetURI = response.getResultset().getLink(); - - Response queryResultSetResponse = restClient.target(queryResultSetURI) - .queryParam("count", 100) - .queryParam("offset", 3) - .request().header(tajoSessionIdHeaderName, sessionId) - .get(); - - assertNotNull(queryResultSetResponse); - String tajoDigest = queryResultSetResponse.getHeaderString(tajoDigestHeaderName); - assertTrue(tajoDigest != null && !tajoDigest.isEmpty()); - - DataInputStream queryResultSetInputStream = - new DataInputStream(new BufferedInputStream(queryResultSetResponse.readEntity(InputStream.class))); - - assertNotNull(queryResultSetInputStream); - - boolean isFinished = false; - List tupleList = TUtil.newList(); - RowStoreUtil.RowStoreDecoder decoder = RowStoreUtil.createDecoder(response.getSchema()); - MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); - while (!isFinished) { - try { - int length = queryResultSetInputStream.readInt(); - byte[] dataByteArray = new byte[length]; - int readBytes = queryResultSetInputStream.read(dataByteArray); - - assertEquals(length, readBytes); - - tupleList.add(decoder.toTuple(dataByteArray)); - messageDigest.update(dataByteArray); - } catch (EOFException eof) { - isFinished = true; - } - } - - assertEquals(3, tupleList.size()); - assertEquals(tajoDigest, Base64.encodeBase64String(messageDigest.digest())); - - for (Tuple aTuple: tupleList) { - assertTrue(aTuple.getInt4(response.getSchema().getColumnId("l_orderkey")) > 0); - } - } - @Test public void testGetQueryResultSetWithDefaultCount() throws Exception { String sessionId = generateNewSessionAndGetId(); From 904dd38c51e60962387c38da99defa45724e5076 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 15:30:28 -0700 Subject: [PATCH 16/30] Fixed many catalog client APIs. --- .../tajo/catalog/AbstractCatalogClient.java | 434 +++++++++------- .../src/main/proto/CatalogProtocol.proto | 42 +- .../org/apache/tajo/catalog/CatalogUtil.java | 11 +- ...tion.java => UndefinedTableException.java} | 6 +- .../tajo/catalog/store/HiveCatalogStore.java | 2 +- .../apache/tajo/catalog/CatalogServer.java | 475 ++++++++++-------- .../InfoSchemaMetadataDictionary.java | 6 +- .../tajo/catalog/store/AbstractDBStore.java | 2 +- .../apache/tajo/catalog/store/MemStore.java | 8 +- .../org/apache/tajo/cli/tsql/TajoCli.java | 9 +- .../tajo/client/CatalogAdminClientImpl.java | 2 +- .../apache/tajo/client/QueryClientImpl.java | 5 +- .../apache/tajo/client/SQLExceptionUtil.java | 2 +- .../apache/tajo/client/SessionConnection.java | 4 +- .../org/apache/tajo/common/type/IPv4.java | 2 +- .../apache/tajo/exception/ErrorMessages.java | 4 +- .../exception/InvalidAddressException.java | 2 +- .../tajo/exception/ReturnStateUtil.java | 54 +- tajo-common/src/main/proto/errors.proto | 4 +- .../org/apache/tajo/common/type/TestIPv4.java | 2 +- .../org/apache/tajo/master/GlobalEngine.java | 10 +- .../tajo/master/TajoMasterClientService.java | 7 +- .../apache/tajo/master/exec/DDLExecutor.java | 8 +- .../tajo/master/exec/QueryExecutor.java | 4 +- .../tajo/webapp/QueryExecutorServlet.java | 8 +- .../tajo/worker/TajoWorkerClientService.java | 6 +- .../tajo/ws/rs/resources/QueryResource.java | 4 +- .../engine/query/TestTablePartitions.java | 6 +- .../plan/verifier/PreLogicalPlanVerifier.java | 2 +- 29 files changed, 626 insertions(+), 505 deletions(-) rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{UndefinedTbleException.java => UndefinedTableException.java} (86%) rename tajo-common/src/main/java/org/apache/tajo/{common => }/exception/InvalidAddressException.java (95%) rename tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java => tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java (69%) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index a628199a2f..6085519c93 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -22,14 +22,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tajo.annotation.Nullable; -import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService; +import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService.BlockingInterface; import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.*; import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.conf.TajoConf; -import org.apache.tajo.exception.InvalidOperationException; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; import org.apache.tajo.util.ProtoUtil; @@ -39,6 +38,9 @@ import java.util.Collection; import java.util.List; +import static org.apache.tajo.catalog.CatalogUtil.buildTableIdentifier; +import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; + /** * CatalogClient provides a client API to access the catalog server. */ @@ -51,74 +53,87 @@ public AbstractCatalogClient(TajoConf conf) { this.conf = conf; } - abstract CatalogProtocolService.BlockingInterface getStub() throws ServiceException; + abstract BlockingInterface getStub() throws ServiceException; @Override public final Boolean createTablespace(final String tablespaceName, final String tablespaceUri) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); + final BlockingInterface stub = getStub(); + final CreateTablespaceRequest request = CreateTablespaceRequest.newBuilder() + .setTablespaceName(tablespaceName) + .setTablespaceUri(tablespaceUri) + .build(); - CreateTablespaceRequest.Builder builder = CreateTablespaceRequest.newBuilder(); - builder.setTablespaceName(tablespaceName); - builder.setTablespaceUri(tablespaceUri); - return stub.createTablespace(null, builder.build()).getValue(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - return Boolean.FALSE; + return isSuccess(stub.createTablespace(null, request)); + + } catch (ServiceException e) { + throw new RuntimeException(e); } } @Override public final Boolean dropTablespace(final String tablespaceName) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.dropTablespace(null, ProtoUtil.convertString(tablespaceName)).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.dropTablespace(null, ProtoUtil.convertString(tablespaceName))); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return Boolean.FALSE; + throw new RuntimeException(e); } } @Override public final Boolean existTablespace(final String tablespaceName) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.existTablespace(null, ProtoUtil.convertString(tablespaceName)).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.existTablespace(null, ProtoUtil.convertString(tablespaceName))); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return Boolean.FALSE; + throw new RuntimeException(e); } } @Override public final Collection getAllTablespaceNames() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); + final BlockingInterface stub = getStub(); PrimitiveProtos.StringListProto response = stub.getAllTablespaceNames(null, ProtoUtil.NULL_PROTO); + return ProtoUtil.convertStrings(response); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public List getAllTablespaces() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); + final BlockingInterface stub = getStub(); CatalogProtos.GetTablespacesProto response = stub.getAllTablespaces(null, ProtoUtil.NULL_PROTO); + return response.getTablespaceList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public TablespaceProto getTablespace(final String tablespaceName) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); + return stub.getTablespace(null, ProtoUtil.convertString(tablespaceName)); + } catch (ServiceException e) { LOG.error(e.getMessage(), e); return null; @@ -127,37 +142,44 @@ public TablespaceProto getTablespace(final String tablespaceName) { @Override public Boolean alterTablespace(final AlterTablespaceProto alterTablespace) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.alterTablespace(null, alterTablespace).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.alterTablespace(null, alterTablespace)); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override public final Boolean createDatabase(final String databaseName, @Nullable final String tablespaceName) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); + final BlockingInterface stub = getStub(); CreateDatabaseRequest.Builder builder = CreateDatabaseRequest.newBuilder(); builder.setDatabaseName(databaseName); if (tablespaceName != null) { builder.setTablespaceName(tablespaceName); } - return stub.createDatabase(null, builder.build()).getValue(); + + return isSuccess(stub.createDatabase(null, builder.build())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return Boolean.FALSE; + throw new RuntimeException(e); } } @Override public final Boolean dropDatabase(final String databaseName) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.dropDatabase(null, ProtoUtil.convertString(databaseName)).getValue(); + BlockingInterface stub = getStub(); + + return isSuccess(stub.dropDatabase(null, ProtoUtil.convertString(databaseName))); + } catch (ServiceException e) { LOG.error(e.getMessage(), e); return Boolean.FALSE; @@ -166,51 +188,55 @@ public final Boolean dropDatabase(final String databaseName) { @Override public final Boolean existDatabase(final String databaseName) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.existDatabase(null, ProtoUtil.convertString(databaseName)).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.existDatabase(null, ProtoUtil.convertString(databaseName))); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return Boolean.FALSE; + throw new RuntimeException(e); } } @Override public final Collection getAllDatabaseNames() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); + final BlockingInterface stub = getStub(); PrimitiveProtos.StringListProto response = stub.getAllDatabaseNames(null, ProtoUtil.NULL_PROTO); + return ProtoUtil.convertStrings(response); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public List getAllDatabases() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - GetDatabasesProto response = stub.getAllDatabases(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetDatabasesProto response = stub.getAllDatabases(null, ProtoUtil.NULL_PROTO); + return response.getDatabaseList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public final TableDesc getTableDesc(final String databaseName, final String tableName) { + try { - TableIdentifierProto.Builder builder = TableIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); + final BlockingInterface stub = getStub(); + final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); + + return CatalogUtil.newTableDesc(stub.getTableDesc(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return CatalogUtil.newTableDesc(stub.getTableDesc(null, builder.build())); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return null; + throw new RuntimeException(e); } } @@ -222,79 +248,83 @@ public TableDesc getTableDesc(String qualifiedName) { @Override public List getAllTables() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - GetTablesProto response = stub.getAllTables(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetTablesProto response = stub.getAllTables(null, ProtoUtil.NULL_PROTO); + return response.getTableList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public List getAllTableOptions() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - GetTableOptionsProto response = stub.getAllTableOptions(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetTableOptionsProto response = stub.getAllTableOptions(null, ProtoUtil.NULL_PROTO); + return response.getTableOptionList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public List getAllTableStats() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - GetTableStatsProto response = stub.getAllTableStats(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetTableStatsProto response = stub.getAllTableStats(null, ProtoUtil.NULL_PROTO); + return response.getStatList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public List getAllColumns() { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - GetColumnsProto response = stub.getAllColumns(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetColumnsProto response = stub.getAllColumns(null, ProtoUtil.NULL_PROTO); + return response.getColumnList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public final PartitionMethodDesc getPartitionMethod(final String databaseName, final String tableName) { + try { - TableIdentifierProto.Builder builder = TableIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); + final BlockingInterface stub = getStub(); + final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); + + return CatalogUtil.newPartitionMethodDesc(stub.getPartitionMethodByTableName(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return CatalogUtil.newPartitionMethodDesc(stub.getPartitionMethodByTableName(null, builder.build())); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return null; + throw new RuntimeException(e); } } @Override public final boolean existPartitionMethod(final String databaseName, final String tableName) { try { - TableIdentifierProto.Builder builder = TableIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); + final BlockingInterface stub = getStub(); + final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); + return isSuccess(stub.existPartitionMethod(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.existPartitionMethod(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @@ -302,55 +332,56 @@ public final boolean existPartitionMethod(final String databaseName, final Strin public final PartitionDescProto getPartition(final String databaseName, final String tableName, final String partitionName) { try { - PartitionIdentifierProto.Builder builder = PartitionIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); - builder.setPartitionName(partitionName); + final BlockingInterface stub = getStub(); + final PartitionIdentifierProto request = PartitionIdentifierProto.newBuilder() + .setDatabaseName(databaseName) + .setTableName(tableName) + .setPartitionName(partitionName) + .build(); + + return stub.getPartitionByPartitionName(null, request); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.getPartitionByPartitionName(null, builder.build()); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return null; + throw new RuntimeException(e); } } @Override public final List getPartitions(final String databaseName, final String tableName) { try { - PartitionIdentifierProto.Builder builder = PartitionIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); + final BlockingInterface stub = getStub(); + final PartitionIdentifierProto request = PartitionIdentifierProto.newBuilder() + .setDatabaseName(databaseName) + .setTableName(tableName) + .build(); - CatalogProtocolService.BlockingInterface stub = getStub(); - PartitionsProto response = stub.getPartitionsByTableName(null, builder.build()); + final PartitionsProto response = stub.getPartitionsByTableName(null, request); return response.getPartitionList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public List getAllPartitions() { try { - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); GetTablePartitionsProto response = stub.getAllPartitions(null, ProtoUtil.NULL_PROTO); return response.getPartList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public final Collection getAllTableNames(final String databaseName) { try { - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); PrimitiveProtos.StringListProto response = stub.getAllTableNames(null, ProtoUtil.convertString(databaseName)); return ProtoUtil.convertStrings(response); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @@ -359,7 +390,7 @@ public final Collection getFunctions() { List list = new ArrayList(); try { GetFunctionsResponse response; - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); response = stub.getFunctions(null, NullProto.newBuilder().build()); int size = response.getFunctionDescCount(); for (int i = 0; i < size; i++) { @@ -372,19 +403,19 @@ public final Collection getFunctions() { } return list; } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return list; + throw new RuntimeException(e); } } @Override public final boolean createTable(final TableDesc desc) { try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.createTable(null, desc.getProto()).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.createTable(null, desc.getProto())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @@ -395,15 +426,13 @@ public boolean dropTable(String tableName) { final String simpleName = splitted[1]; try { - TableIdentifierProto.Builder builder = TableIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(simpleName); + final BlockingInterface stub = getStub(); + final TableIdentifierProto request = buildTableIdentifier(databaseName, simpleName); + + return isSuccess(stub.dropTable(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.dropTable(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @@ -413,16 +442,15 @@ public final boolean existsTable(final String databaseName, final String tableNa throw new IllegalArgumentException( "tableName cannot be composed of multiple parts, but it is \"" + tableName + "\""); } + try { - TableIdentifierProto.Builder builder = TableIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); + final BlockingInterface stub = getStub(); + final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); + + return isSuccess(stub.existsTable(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.existsTable(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override @@ -433,27 +461,31 @@ public final boolean existsTable(final String tableName) { @Override public final boolean createIndex(final IndexDesc index) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.createIndex(null, index.getProto()).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.createIndex(null, index.getProto())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override public final boolean existIndexByName(final String databaseName, final String indexName) { try { - IndexNameProto.Builder builder = IndexNameProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setIndexName(indexName); + final IndexNameProto request = IndexNameProto.newBuilder() + .setDatabaseName(databaseName) + .setIndexName(indexName) + .build(); + + final BlockingInterface stub = getStub(); + + return isSuccess(stub.existIndexByName(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.existIndexByName(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @@ -461,30 +493,34 @@ public final boolean existIndexByName(final String databaseName, final String in public boolean existIndexByColumn(final String databaseName, final String tableName, final String columnName) { try { - GetIndexByColumnRequest.Builder builder = GetIndexByColumnRequest.newBuilder(); - builder.setTableIdentifier(CatalogUtil.buildTableIdentifier(databaseName, tableName)); - builder.setColumnName(columnName); + final GetIndexByColumnRequest request = GetIndexByColumnRequest.newBuilder() + .setTableIdentifier(buildTableIdentifier(databaseName, tableName)) + .setColumnName(columnName) + .build(); + + final BlockingInterface stub = getStub(); + + return isSuccess(stub.existIndexByColumn(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.existIndexByColumn(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override public final IndexDesc getIndexByName(final String databaseName, final String indexName) { + try { - IndexNameProto.Builder builder = IndexNameProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setIndexName(indexName); + final IndexNameProto request = IndexNameProto.newBuilder() + .setDatabaseName(databaseName) + .setIndexName(indexName) + .build(); + + final BlockingInterface stub = getStub(); + return new IndexDesc(stub.getIndexByName(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return new IndexDesc(stub.getIndexByName(null, builder.build())); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return null; + throw new RuntimeException(e); } } @@ -494,14 +530,14 @@ public final IndexDesc getIndexByColumn(final String databaseName, final String columnName) { try { GetIndexByColumnRequest.Builder builder = GetIndexByColumnRequest.newBuilder(); - builder.setTableIdentifier(CatalogUtil.buildTableIdentifier(databaseName, tableName)); + builder.setTableIdentifier(buildTableIdentifier(databaseName, tableName)); builder.setColumnName(columnName); - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); return new IndexDesc(stub.getIndexByColumn(null, builder.build())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return null; + throw new RuntimeException(e); } } @@ -509,52 +545,58 @@ public final IndexDesc getIndexByColumn(final String databaseName, public boolean dropIndex(final String databaseName, final String indexName) { try { - IndexNameProto.Builder builder = IndexNameProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setIndexName(indexName); + final IndexNameProto request = IndexNameProto.newBuilder() + .setDatabaseName(databaseName) + .setIndexName(indexName) + .build(); + + final BlockingInterface stub = getStub(); + + return isSuccess(stub.dropIndex(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.dropIndex(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override public List getAllIndexes() { try { - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); GetIndexesProto response = stub.getAllIndexes(null, ProtoUtil.NULL_PROTO); return response.getIndexList(); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return new ArrayList(); + throw new RuntimeException(e); } } @Override public final boolean createFunction(final FunctionDesc funcDesc) { try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.createFunction(null, funcDesc.getProto()).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.createFunction(null, funcDesc.getProto())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override public final boolean dropFunction(final String signature) { + try { - UnregisterFunctionRequest.Builder builder = UnregisterFunctionRequest.newBuilder(); - builder.setSignature(signature); + final UnregisterFunctionRequest request = UnregisterFunctionRequest.newBuilder() + .setSignature(signature) + .build(); + + final BlockingInterface stub = getStub(); + + return isSuccess(stub.dropFunction(null, request)); - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.dropFunction(null, builder.build()).getValue(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @@ -576,12 +618,12 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT FunctionDescProto descProto = null; try { - CatalogProtocolService.BlockingInterface stub = getStub(); + BlockingInterface stub = getStub(); descProto = stub.getFunctionMeta(null, builder.build()); } catch (UndefinedFunctionException e) { LOG.debug(e.getMessage()); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); + throw new RuntimeException(e); } if (descProto == null) { @@ -591,8 +633,7 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT try { return new FunctionDesc(descProto); } catch (ClassNotFoundException e) { - LOG.error(e, e); - throw new UndefinedFunctionException(signature, paramTypes); + throw new RuntimeException(e); } } @@ -603,8 +644,9 @@ public final boolean containFunction(final String signature, DataType... paramTy @Override public final boolean containFunction(final String signature, FunctionType funcType, DataType... paramTypes) { - final ContainFunctionRequest.Builder builder = - ContainFunctionRequest.newBuilder(); + + final ContainFunctionRequest.Builder builder = ContainFunctionRequest.newBuilder(); + if (funcType != null) { builder.setFunctionType(funcType); } @@ -614,35 +656,37 @@ public final boolean containFunction(final String signature, FunctionType funcTy } try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.containFunction(null, builder.build()).getValue(); - } catch (InvalidOperationException e) { - LOG.error(e.getMessage()); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.containFunction(null, builder.build())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); + throw new RuntimeException(e); } - return false; } @Override public final boolean alterTable(final AlterTableDesc desc) { + try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.alterTable(null, desc.getProto()).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.alterTable(null, desc.getProto())); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } @Override public boolean updateTableStats(final UpdateTableStatsProto updateTableStatsProto) { try { - CatalogProtocolService.BlockingInterface stub = getStub(); - return stub.updateTableStats(null, updateTableStatsProto).getValue(); + final BlockingInterface stub = getStub(); + + return isSuccess(stub.updateTableStats(null, updateTableStatsProto)); + } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return false; + throw new RuntimeException(e); } } } diff --git a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto index 5ace32e7a4..822f6ba541 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto +++ b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto @@ -26,25 +26,25 @@ import "PrimitiveProtos.proto"; service CatalogProtocolService { - rpc createTablespace(CreateTablespaceRequest) returns (BoolProto); - rpc dropTablespace(StringProto) returns (BoolProto); - rpc existTablespace(StringProto) returns (BoolProto); + rpc createTablespace(CreateTablespaceRequest) returns (ReturnState); + rpc dropTablespace(StringProto) returns (ReturnState); + rpc existTablespace(StringProto) returns (ReturnState); rpc getAllTablespaces(NullProto) returns (GetTablespacesProto); rpc getAllTablespaceNames(NullProto) returns (StringListProto); rpc getTablespace(StringProto) returns (TablespaceProto); - rpc alterTablespace(AlterTablespaceProto) returns (BoolProto); - rpc alterTable(AlterTableDescProto) returns (BoolProto); - rpc updateTableStats(UpdateTableStatsProto) returns (BoolProto); + rpc alterTablespace(AlterTablespaceProto) returns (ReturnState); + rpc alterTable(AlterTableDescProto) returns (ReturnState); + rpc updateTableStats(UpdateTableStatsProto) returns (ReturnState); - rpc createDatabase(CreateDatabaseRequest) returns (BoolProto); - rpc dropDatabase(StringProto) returns (BoolProto); - rpc existDatabase(StringProto) returns (BoolProto); + rpc createDatabase(CreateDatabaseRequest) returns (ReturnState); + rpc dropDatabase(StringProto) returns (ReturnState); + rpc existDatabase(StringProto) returns (ReturnState); rpc getAllDatabaseNames(NullProto) returns (StringListProto); rpc getAllDatabases(NullProto) returns (GetDatabasesProto); - rpc createTable(TableDescProto) returns (BoolProto); - rpc dropTable(TableIdentifierProto) returns (BoolProto); - rpc existsTable(TableIdentifierProto) returns (BoolProto); + rpc createTable(TableDescProto) returns (ReturnState); + rpc dropTable(TableIdentifierProto) returns (ReturnState); + rpc existsTable(TableIdentifierProto) returns (ReturnState); rpc getTableDesc(TableIdentifierProto) returns (TableDescProto); rpc getAllTableNames(StringProto) returns (StringListProto); rpc getAllTables(NullProto) returns (GetTablesProto); @@ -53,24 +53,24 @@ service CatalogProtocolService { rpc getAllColumns(NullProto) returns (GetColumnsProto); rpc getPartitionMethodByTableName(TableIdentifierProto) returns (PartitionMethodProto); - rpc existPartitionMethod(TableIdentifierProto) returns (BoolProto); - rpc dropPartitionMethod(TableIdentifierProto) returns (BoolProto); + rpc existPartitionMethod(TableIdentifierProto) returns (ReturnState); + rpc dropPartitionMethod(TableIdentifierProto) returns (ReturnState); rpc getPartitionByPartitionName(PartitionIdentifierProto) returns (PartitionDescProto); rpc getPartitionsByTableName(PartitionIdentifierProto) returns (PartitionsProto); rpc getAllPartitions(NullProto) returns (GetTablePartitionsProto); - rpc createIndex(IndexDescProto) returns (BoolProto); - rpc dropIndex(IndexNameProto) returns (BoolProto); - rpc existIndexByName(IndexNameProto) returns (BoolProto); - rpc existIndexByColumn(GetIndexByColumnRequest) returns (BoolProto); + rpc createIndex(IndexDescProto) returns (ReturnState); + rpc dropIndex(IndexNameProto) returns (ReturnState); + rpc existIndexByName(IndexNameProto) returns (ReturnState); + rpc existIndexByColumn(GetIndexByColumnRequest) returns (ReturnState); rpc getIndexByName(IndexNameProto) returns (IndexDescProto); rpc getIndexByColumn(GetIndexByColumnRequest) returns (IndexDescProto); rpc getAllIndexes(NullProto) returns (GetIndexesProto); - rpc createFunction(FunctionDescProto) returns (BoolProto); - rpc dropFunction(UnregisterFunctionRequest) returns (BoolProto); + rpc createFunction(FunctionDescProto) returns (ReturnState); + rpc dropFunction(UnregisterFunctionRequest) returns (ReturnState); rpc getFunctions(NullProto) returns (GetFunctionsResponse); rpc getFunctionMeta(GetFunctionMetaRequest) returns (FunctionDescProto); - rpc containFunction(ContainFunctionRequest) returns (BoolProto); + rpc containFunction(ContainFunctionRequest) returns (ReturnState); } \ No newline at end of file diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java index 638ebca6a0..0f11785c04 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java @@ -27,6 +27,7 @@ import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.SchemaProto; import org.apache.tajo.catalog.proto.CatalogProtos.TableDescProto; +import org.apache.tajo.catalog.proto.CatalogProtos.TableIdentifierProto; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.exception.InvalidOperationException; @@ -689,11 +690,11 @@ public static DataType getWidestType(DataType...types) { return widest; } - public static CatalogProtos.TableIdentifierProto buildTableIdentifier(String databaseName, String tableName) { - CatalogProtos.TableIdentifierProto.Builder builder = CatalogProtos.TableIdentifierProto.newBuilder(); - builder.setDatabaseName(databaseName); - builder.setTableName(tableName); - return builder.build(); + public static TableIdentifierProto buildTableIdentifier(String databaseName, String tableName) { + return TableIdentifierProto.newBuilder() + .setDatabaseName(databaseName) + .setTableName(tableName) + .build(); } public static void closeQuietly(Connection conn) { diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTbleException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTableException.java similarity index 86% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTbleException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTableException.java index 1d3f2bac76..2513783e92 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTbleException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedTableException.java @@ -22,14 +22,14 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.error.Errors.ResultCode; -public class UndefinedTbleException extends CatalogException { +public class UndefinedTableException extends CatalogException { private static final long serialVersionUID = 277182608283894937L; - public UndefinedTbleException(String dbName, String tbName) { + public UndefinedTableException(String dbName, String tbName) { super(ResultCode.UNDEFINED_TABLE, CatalogUtil.buildFQName(dbName, tbName)); } - public UndefinedTbleException(String relName) { + public UndefinedTableException(String relName) { super(ResultCode.UNDEFINED_TABLE, relName); } } diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java index dcbc9dcee1..afc627222b 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java @@ -128,7 +128,7 @@ public final CatalogProtos.TableDescProto getTable(String databaseName, final St table = HiveCatalogUtil.getTable(client.getHiveClient(), databaseName, tableName); path = table.getPath(); } catch (NoSuchObjectException nsoe) { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } catch (Exception e) { throw new TajoInternalError(e); } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java index 18eec78f8a..6f99e7e05b 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java @@ -40,12 +40,14 @@ import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; -import org.apache.tajo.error.Errors; import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.exception.TajoInternalError; +import org.apache.tajo.function.FunctionUtil; import org.apache.tajo.rpc.BlockingRpcServer; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto; import org.apache.tajo.util.NetUtils; import org.apache.tajo.util.ProtoUtil; @@ -62,6 +64,9 @@ import static org.apache.tajo.catalog.proto.CatalogProtos.AlterTablespaceProto.AlterTablespaceCommand; import static org.apache.tajo.catalog.proto.CatalogProtos.FunctionType.*; +import static org.apache.tajo.exception.ExceptionUtil.printStackTraceIfError; +import static org.apache.tajo.exception.ReturnStateUtil.*; +import static org.apache.tajo.function.FunctionUtil.buildSimpleFunctionSignature; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListProto; /** @@ -224,7 +229,8 @@ public InetSocketAddress getBindAddress() { public class CatalogProtocolHandler implements CatalogProtocolService.BlockingInterface { @Override - public BoolProto createTablespace(RpcController controller, CreateTablespaceRequest request) throws ServiceException { + public ReturnState createTablespace(RpcController controller, CreateTablespaceRequest request) { + final String tablespaceName = request.getTablespaceName(); final String uri = request.getTablespaceUri(); @@ -236,18 +242,18 @@ public BoolProto createTablespace(RpcController controller, CreateTablespaceRequ store.createTablespace(tablespaceName, uri); LOG.info(String.format("tablespace \"%s\" (%s) is created", tablespaceName, uri)); - return ProtoUtil.TRUE; - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + return OK; + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); } finally { wlock.unlock(); } } @Override - public BoolProto dropTablespace(RpcController controller, StringProto request) throws ServiceException { + public ReturnState dropTablespace(RpcController controller, StringProto request) { String tablespaceName = request.getValue(); wlock.lock(); @@ -261,30 +267,31 @@ public BoolProto dropTablespace(RpcController controller, StringProto request) t } store.dropTablespace(tablespaceName); - return ProtoUtil.TRUE; - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); } finally { wlock.unlock(); } } @Override - public BoolProto existTablespace(RpcController controller, StringProto request) throws ServiceException { - String tablespaceName = request.getValue(); + public ReturnState existTablespace(RpcController controller, StringProto request) { + String spaceName = request.getValue(); rlock.lock(); try { - if (store.existTablespace(tablespaceName)) { - return ProtoUtil.TRUE; + if (store.existTablespace(spaceName)) { + return OK; } else { - return ProtoUtil.FALSE; + return errUndefinedTablespace(spaceName); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); } finally { rlock.unlock(); } @@ -295,9 +302,9 @@ public StringListProto getAllTablespaceNames(RpcController controller, NullProto rlock.lock(); try { return ProtoUtil.convertStrings(store.getAllDatabaseNames()); - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + throw new ServiceException(t); } finally { rlock.unlock(); } @@ -308,8 +315,9 @@ public GetTablespacesProto getAllTablespaces(RpcController controller, NullProto rlock.lock(); try { return GetTablespacesProto.newBuilder().addAllTablespace(store.getTablespaces()).build(); - } catch (Exception e) { - throw new ServiceException(e); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + throw new ServiceException(t); } finally { rlock.unlock(); } @@ -318,18 +326,21 @@ public GetTablespacesProto getAllTablespaces(RpcController controller, NullProto @Override public TablespaceProto getTablespace(RpcController controller, StringProto request) throws ServiceException { rlock.lock(); + try { return store.getTablespace(request.getValue()); - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + throw new ServiceException(t); + } finally { rlock.unlock(); } } @Override - public BoolProto alterTablespace(RpcController controller, AlterTablespaceProto request) throws ServiceException { + public ReturnState alterTablespace(RpcController controller, AlterTablespaceProto request) { wlock.lock(); try { if (!store.existTablespace(request.getSpaceName())) { @@ -351,132 +362,145 @@ public BoolProto alterTablespace(RpcController controller, AlterTablespaceProto } store.alterTablespace(request); - return ProtoUtil.TRUE; - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); } } @Override - public BoolProto createDatabase(RpcController controller, CreateDatabaseRequest request) throws ServiceException { + public ReturnState createDatabase(RpcController controller, CreateDatabaseRequest request) { String databaseName = request.getDatabaseName(); String tablespaceName = request.getTablespaceName(); + // check virtual database manually because catalog actually does not contain them. if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system database name."); + return errDuplicateDatabase(databaseName); } wlock.lock(); try { if (store.existDatabase(databaseName)) { - throw new DuplicateDatabaseException(databaseName); + return errDuplicateDatabase(databaseName); } store.createDatabase(databaseName, tablespaceName); LOG.info(String.format("database \"%s\" is created", databaseName)); - return ProtoUtil.TRUE; - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); } } @Override - public BoolProto updateTableStats(RpcController controller, UpdateTableStatsProto proto) throws - ServiceException { + public ReturnState updateTableStats(RpcController controller, UpdateTableStatsProto proto) { + wlock.lock(); + try { String [] split = CatalogUtil.splitTableName(proto.getTableName()); if (!store.existTable(split[0], split[1])) { - throw new UndefinedTbleException(proto.getTableName()); + return errDuplicateTable(proto.getTableName()); } store.updateTableStats(proto); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - return BOOL_FALSE; + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); - LOG.info("Table " + proto.getTableName() + " is updated in the catalog (" - + bindAddressStr + ")"); } - return BOOL_TRUE; } @Override - public BoolProto alterTable(RpcController controller, AlterTableDescProto proto) throws ServiceException { + public ReturnState alterTable(RpcController controller, AlterTableDescProto proto) { String [] split = CatalogUtil.splitTableName(proto.getTableName()); if (metaDictionary.isSystemDatabase(split[0])) { - throw new ServiceException(split[0] + " is a system database."); + return errInsufficientPrivilege("alter a table in database '" + split[0] + "'"); } wlock.lock(); + try { if (!store.existTable(split[0], split[1])) { - throw new UndefinedTbleException(proto.getTableName()); + return errUndefinedTable(proto.getTableName()); } store.alterTable(proto); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - return BOOL_FALSE; + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); - LOG.info("Table " + proto.getTableName() + " is altered in the catalog (" - + bindAddressStr + ")"); } - return BOOL_TRUE; } @Override - public BoolProto dropDatabase(RpcController controller, StringProto request) throws ServiceException { + public ReturnState dropDatabase(RpcController controller, StringProto request) { String databaseName = request.getValue(); if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system database."); + return errInsufficientPrivilege("drop a table in database '" + databaseName + "'"); } wlock.lock(); try { if (!store.existDatabase(databaseName)) { - throw new UndefinedDatabaseException(databaseName); + return errUndefinedDatabase(databaseName); } store.dropDatabase(databaseName); - return ProtoUtil.TRUE; - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); } finally { wlock.unlock(); } } @Override - public BoolProto existDatabase(RpcController controller, StringProto request) throws ServiceException { - String databaseName = request.getValue(); + public ReturnState existDatabase(RpcController controller, StringProto request) { + String dbName = request.getValue(); - if (!metaDictionary.isSystemDatabase(databaseName)) { - rlock.lock(); - try { - if (store.existDatabase(databaseName)) { - return ProtoUtil.TRUE; - } else { - return ProtoUtil.FALSE; - } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); - } finally { - rlock.unlock(); + if (metaDictionary.isSystemDatabase(dbName)) { + return OK; + } + + rlock.lock(); + try { + if (store.existDatabase(dbName)) { + return OK; + } else { + return errUndefinedDatabase(dbName); } - } else { - return ProtoUtil.TRUE; + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + + } finally { + rlock.unlock(); } } @@ -528,7 +552,7 @@ public TableDescProto getTableDesc(RpcController controller, if (contain) { return store.getTable(databaseName, tableName); } else { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } } else { throw new UndefinedDatabaseException(databaseName); @@ -580,114 +604,114 @@ public GetFunctionsResponse getFunctions(RpcController controller, } @Override - public BoolProto createTable(RpcController controller, TableDescProto request)throws ServiceException { + public ReturnState createTable(RpcController controller, TableDescProto request) { - String [] splitted = - CatalogUtil.splitFQTableName(request.getTableName()); + String [] splitted = CatalogUtil.splitFQTableName(request.getTableName()); - String databaseName = splitted[0]; - String tableName = splitted[1]; + String dbName = splitted[0]; + String tbName = splitted[1]; - if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system database."); + if (metaDictionary.isSystemDatabase(dbName)) { + return errInsufficientPrivilege("create a table in database '" + dbName + "'"); } wlock.lock(); try { - boolean contain = store.existDatabase(databaseName); + boolean contain = store.existDatabase(dbName); if (contain) { - if (store.existTable(databaseName, tableName)) { - throw new DuplicateTableException(tableName); + if (store.existTable(dbName, tbName)) { + return errDuplicateTable(tbName); } store.createTable(request); LOG.info(String.format("relation \"%s\" is added to the catalog (%s)", - CatalogUtil.getCanonicalTableName(databaseName, tableName), bindAddressStr)); + CatalogUtil.getCanonicalTableName(dbName, tbName), bindAddressStr)); } else { - throw new UndefinedDatabaseException(databaseName); + return errUndefinedDatabase(dbName); } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - return ProtoUtil.FALSE; + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); } - - return ProtoUtil.TRUE; } @Override - public BoolProto dropTable(RpcController controller, TableIdentifierProto request) throws ServiceException { + public ReturnState dropTable(RpcController controller, TableIdentifierProto request) throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + String dbName = request.getDatabaseName(); + String tbName = request.getTableName(); - if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system database."); + if (metaDictionary.isSystemDatabase(dbName)) { + return errInsufficientPrivilege("drop a table in database '" + dbName + "'"); } wlock.lock(); try { - boolean contain = store.existDatabase(databaseName); + boolean contain = store.existDatabase(dbName); if (contain) { - if (!store.existTable(databaseName, tableName)) { - throw new UndefinedTbleException(databaseName, tableName); + if (!store.existTable(dbName, tbName)) { + return errUndefinedTable(tbName); } - store.dropTable(databaseName, tableName); + store.dropTable(dbName, tbName); LOG.info(String.format("relation \"%s\" is deleted from the catalog (%s)", - CatalogUtil.getCanonicalTableName(databaseName, tableName), bindAddressStr)); + CatalogUtil.getCanonicalTableName(dbName, tbName), bindAddressStr)); } else { - throw new UndefinedDatabaseException(databaseName); + return errUndefinedDatabase(dbName); } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - return BOOL_FALSE; + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); } - - return BOOL_TRUE; } @Override - public BoolProto existsTable(RpcController controller, TableIdentifierProto request) - throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + public ReturnState existsTable(RpcController controller, TableIdentifierProto request) { + String dbName = request.getDatabaseName(); + String tbName = request.getTableName(); + + if (metaDictionary.isSystemDatabase(dbName)) { + return metaDictionary.existTable(tbName) ? OK : errUndefinedTable(tbName); - if (!metaDictionary.isSystemDatabase(databaseName)) { + } else { rlock.lock(); try { - boolean contain = store.existDatabase(databaseName); + boolean contain = store.existDatabase(dbName); if (contain) { - if (store.existTable(databaseName, tableName)) { - return BOOL_TRUE; + if (store.existTable(dbName, tbName)) { + return OK; } else { - return BOOL_FALSE; + return errUndefinedTable(tbName); } } else { - throw new UndefinedDatabaseException(databaseName); + return errUndefinedDatabase(dbName); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { rlock.unlock(); } - } else { - if (metaDictionary.existTable(tableName)) { - return BOOL_TRUE; - } else { - return BOOL_FALSE; - } } - } @Override @@ -764,7 +788,7 @@ public PartitionMethodProto getPartitionMethodByTableName(RpcController controll throw new NoPartitionedTableException(databaseName, tableName); } } else { - throw new UndefinedTbleException(databaseName); + throw new UndefinedTableException(databaseName); } } else { throw new UndefinedDatabaseException(databaseName); @@ -778,13 +802,12 @@ public PartitionMethodProto getPartitionMethodByTableName(RpcController controll } @Override - public BoolProto existPartitionMethod(RpcController controller, TableIdentifierProto request) - throws ServiceException { + public ReturnState existPartitionMethod(RpcController controller, TableIdentifierProto request) { String databaseName = request.getDatabaseName(); String tableName = request.getTableName(); if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system database. Partition Method does not support yet."); + ReturnStateUtil.errFeatureNotSupported("partition feature in virtual tables"); } rlock.lock(); @@ -797,28 +820,28 @@ public BoolProto existPartitionMethod(RpcController controller, TableIdentifierP contain = store.existTable(databaseName, tableName); if (contain) { if (store.existPartitionMethod(databaseName, tableName)) { - return ProtoUtil.TRUE; + return OK; } else { - return ProtoUtil.FALSE; + return ReturnStateUtil.errUndefinedPartitionMethod(tableName); } } else { - throw new UndefinedTbleException(databaseName); + return errUndefinedTable(tableName); } } else { - throw new UndefinedDatabaseException(databaseName); + return errUndefinedDatabase(databaseName); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { rlock.unlock(); } } @Override - public BoolProto dropPartitionMethod(RpcController controller, TableIdentifierProto request) - throws ServiceException { - return ProtoUtil.TRUE; + public ReturnState dropPartitionMethod(RpcController controller, TableIdentifierProto request) { + return errFeatureNotSupported("dropPartitionMethod"); } @Override @@ -851,7 +874,7 @@ public PartitionDescProto getPartitionByPartitionName(RpcController controller, throw new NoPartitionedTableException(databaseName, tableName); } } else { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } } else { throw new UndefinedDatabaseException(databaseName); @@ -893,7 +916,7 @@ public PartitionsProto getPartitionsByTableName(RpcController controller, Partit throw new NoPartitionedTableException(databaseName, tableName); } } else { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } } else { throw new UndefinedDatabaseException(databaseName); @@ -919,49 +942,50 @@ public GetTablePartitionsProto getAllPartitions(RpcController controller, NullPr } @Override - public BoolProto createIndex(RpcController controller, IndexDescProto indexDesc) - throws ServiceException { - String databaseName = indexDesc.getTableIdentifier().getDatabaseName(); + public ReturnState createIndex(RpcController controller, IndexDescProto indexDesc) { + String dbName = indexDesc.getTableIdentifier().getDatabaseName(); rlock.lock(); try { if (store.existIndexByName( - databaseName, + dbName, indexDesc.getIndexName())) { - throw new DuplicateIndexException(indexDesc.getIndexName()); + return errDuplicateTable(indexDesc.getIndexName()); } store.createIndex(indexDesc); - } catch (Exception e) { - LOG.error("ERROR : cannot add index " + indexDesc.getIndexName(), e); - LOG.error(indexDesc); - throw new ServiceException(e); + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { rlock.unlock(); } - - return BOOL_TRUE; } @Override - public BoolProto existIndexByName(RpcController controller, IndexNameProto request) throws ServiceException { + public ReturnState existIndexByName(RpcController controller, IndexNameProto request) { - String databaseName = request.getDatabaseName(); + String dbName = request.getDatabaseName(); String indexName = request.getIndexName(); rlock.lock(); try { - return store.existIndexByName(databaseName, indexName) ? ProtoUtil.TRUE : ProtoUtil.FALSE; - } catch (Exception e) { - LOG.error(e, e); - return BoolProto.newBuilder().setValue(false).build(); + return store.existIndexByName(dbName, indexName) ? OK : errUndefinedIndexName(indexName); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { rlock.unlock(); } } @Override - public BoolProto existIndexByColumn(RpcController controller, GetIndexByColumnRequest request) - throws ServiceException { + public ReturnState existIndexByColumn(RpcController controller, GetIndexByColumnRequest request) { TableIdentifierProto identifier = request.getTableIdentifier(); String databaseName = identifier.getDatabaseName(); @@ -971,10 +995,12 @@ public BoolProto existIndexByColumn(RpcController controller, GetIndexByColumnRe rlock.lock(); try { return store.existIndexByColumn(databaseName, tableName, columnName) ? - ProtoUtil.TRUE : ProtoUtil.FALSE; - } catch (Exception e) { - LOG.error(e, e); - return BoolProto.newBuilder().setValue(false).build(); + OK : errUndefinedIndex(tableName, columnName); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { rlock.unlock(); } @@ -1025,25 +1051,27 @@ public IndexDescProto getIndexByColumn(RpcController controller, GetIndexByColum } @Override - public BoolProto dropIndex(RpcController controller, IndexNameProto request) - throws ServiceException { + public ReturnState dropIndex(RpcController controller, IndexNameProto request) { - String databaseName = request.getDatabaseName(); + String dbName = request.getDatabaseName(); String indexName = request.getIndexName(); wlock.lock(); try { - if (!store.existIndexByName(databaseName, indexName)) { - throw new UndefinedIndexException(indexName); + if (!store.existIndexByName(dbName, indexName)) { + return errUndefinedIndexName(indexName); } - store.dropIndex(databaseName, indexName); - } catch (Exception e) { - LOG.error(e, e); + store.dropIndex(dbName, indexName); + + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { wlock.unlock(); } - - return BOOL_TRUE; } @Override @@ -1058,10 +1086,6 @@ public GetIndexesProto getAllIndexes(RpcController controller, NullProto request } } - public boolean checkIfBuiltin(FunctionType type) { - return type == GENERAL || type == AGGREGATION || type == DISTINCT_AGGREGATION; - } - private boolean containFunction(String signature) { List found = findFunction(signature); return found != null && found.size() > 0; @@ -1186,37 +1210,43 @@ private FunctionDescProto findFunctionStrictType(FunctionDescProto target, boole } @Override - public BoolProto createFunction(RpcController controller, FunctionDescProto funcDesc) - throws ServiceException { - FunctionSignature signature = FunctionSignature.create(funcDesc); + public ReturnState createFunction(RpcController controller, FunctionDescProto funcDesc) { + + try { + FunctionSignature signature = FunctionSignature.create(funcDesc); - if (functions.containsKey(funcDesc.getSignature())) { - FunctionDescProto found = findFunctionStrictType(funcDesc, true); - if (found != null) { - throw new ServiceException(new DuplicateFunctionException(signature.toString())); + if (functions.containsKey(funcDesc.getSignature())) { + FunctionDescProto found = findFunctionStrictType(funcDesc, true); + if (found != null) { + return errDuplicateFunction(signature.toString()); + } } - } - TUtil.putToNestedList(functions, funcDesc.getSignature().getName(), funcDesc); - if (LOG.isDebugEnabled()) { - LOG.info("Function " + signature + " is registered."); - } + TUtil.putToNestedList(functions, funcDesc.getSignature().getName(), funcDesc); - return BOOL_TRUE; + return OK; + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } } @Override - public BoolProto dropFunction(RpcController controller, UnregisterFunctionRequest request) - throws ServiceException { + public ReturnState dropFunction(RpcController controller, UnregisterFunctionRequest request) { + try { + if (!containFunction(request.getSignature())) { + return errUndefinedFunction(request.toString()); + } - if (!containFunction(request.getSignature())) { - throw new ServiceException(new UndefinedFunctionException(request.getSignature(), new DataType[]{})); - } + functions.remove(request.getSignature()); - functions.remove(request.getSignature()); - LOG.info(request.getSignature() + " is dropped."); + return OK; - return BOOL_TRUE; + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } } @Override @@ -1239,16 +1269,25 @@ public FunctionDescProto getFunctionMeta(RpcController controller, GetFunctionMe } @Override - public BoolProto containFunction(RpcController controller, ContainFunctionRequest request) - throws ServiceException { - boolean returnValue; - if (request.hasFunctionType()) { - returnValue = containFunction(request.getSignature(), request.getFunctionType(), - request.getParameterTypesList()); - } else { - returnValue = containFunction(request.getSignature(), request.getParameterTypesList()); + public ReturnState containFunction(RpcController controller, ContainFunctionRequest request) { + + try { + boolean returnValue; + if (request.hasFunctionType()) { + returnValue = containFunction(request.getSignature(), request.getFunctionType(), + request.getParameterTypesList()); + } else { + returnValue = containFunction(request.getSignature(), request.getParameterTypesList()); + } + + return returnValue ? + OK : + errUndefinedFunction(buildSimpleFunctionSignature(request.getSignature(), request.getParameterTypesList())); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); } - return BoolProto.newBuilder().setValue(returnValue).build(); } } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java index bf3d1036a0..f798c1dfc6 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java @@ -22,7 +22,7 @@ import java.util.Collections; import java.util.List; -import org.apache.tajo.catalog.exception.UndefinedTbleException; +import org.apache.tajo.catalog.exception.UndefinedTableException; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.StoreType; import org.apache.tajo.util.TUtil; @@ -95,7 +95,7 @@ private TableDescriptor getTableDescriptor(String tableName) { TableDescriptor tableDescriptor = null; if (tableName == null || tableName.isEmpty()) { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } tableName = tableName.toUpperCase(); @@ -115,7 +115,7 @@ public CatalogProtos.TableDescProto getTableDesc(String tableName) { tableDescriptor = getTableDescriptor(tableName); if (tableDescriptor == null) { - throw new UndefinedTbleException(DATABASE_NAME, tableName); + throw new UndefinedTableException(DATABASE_NAME, tableName); } return tableDescriptor.getTableDescription(); diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java index fc884d7d99..4d43691706 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java @@ -730,7 +730,7 @@ private int getTableId(int databaseId, String databaseName, String tableName) { } return res.getInt(1); } catch (SQLException se) { - throw new UndefinedTbleException(databaseName, tableName); + throw new UndefinedTableException(databaseName, tableName); } finally { CatalogUtil.closeQuietly(pstmt, res); } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java index 2697ab2839..1a3a1360ff 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java @@ -251,7 +251,7 @@ public void dropTable(String dbName, String tbName) throws CatalogException { if (database.containsKey(tbName)) { database.remove(tbName); } else { - throw new UndefinedTbleException(tbName); + throw new UndefinedTableException(tbName); } } @@ -397,7 +397,7 @@ public CatalogProtos.TableDescProto getTable(String databaseName, String tableNa builder.setSchema(schemaProto); return builder.build(); } else { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } } @@ -536,7 +536,7 @@ public CatalogProtos.PartitionMethodProto getPartitionMethod(String databaseName CatalogProtos.TableDescProto table = database.get(tableName); return table.hasPartition() ? table.getPartition() : null; } else { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } } @@ -549,7 +549,7 @@ public boolean existPartitionMethod(String databaseName, String tableName) CatalogProtos.TableDescProto table = database.get(tableName); return table.hasPartition(); } else { - throw new UndefinedTbleException(tableName); + throw new UndefinedTableException(tableName); } } diff --git a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java index abc56d9fc1..bc5fa7af74 100644 --- a/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java +++ b/tajo-cli/src/main/java/org/apache/tajo/cli/tsql/TajoCli.java @@ -31,6 +31,7 @@ import org.apache.tajo.cli.tsql.SimpleParser.ParsingState; import org.apache.tajo.cli.tsql.commands.*; import org.apache.tajo.client.*; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; import org.apache.tajo.ipc.ClientProtos; @@ -490,7 +491,7 @@ private void executeJsonQuery(String json) throws SQLException { ClientProtos.SubmitQueryResponse response = client.executeQueryWithJson(json); if (response == null) { onError("response is null", null); - } else if (ClientErrorUtil.isSuccess(response.getState())) { + } else if (ReturnStateUtil.isSuccess(response.getState())) { if (response.getIsForwarded()) { QueryId queryId = new QueryId(response.getQueryId()); waitForQueryCompleted(queryId); @@ -503,7 +504,7 @@ private void executeJsonQuery(String json) throws SQLException { } } } else { - if (ClientErrorUtil.isError(response.getState())) { + if (ReturnStateUtil.isError(response.getState())) { onError(response.getState().getMessage(), null); } } @@ -520,7 +521,7 @@ private int executeQuery(String statement) throws SQLException { } if (response != null) { - if (ClientErrorUtil.isSuccess(response.getState())) { + if (ReturnStateUtil.isSuccess(response.getState())) { if (response.getIsForwarded()) { QueryId queryId = new QueryId(response.getQueryId()); waitForQueryCompleted(queryId); @@ -532,7 +533,7 @@ private int executeQuery(String statement) throws SQLException { } } } else { - if (ClientErrorUtil.isError(response.getState())) { + if (ReturnStateUtil.isError(response.getState())) { onError(response.getState().getMessage(), null); } } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index b0c798a0e4..337279c147 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -36,7 +36,7 @@ import java.sql.SQLException; import java.util.List; -import static org.apache.tajo.client.ClientErrorUtil.isSuccess; +import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; 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 3c720c0453..9c1c897112 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 @@ -44,9 +44,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import static org.apache.tajo.client.ClientErrorUtil.isError; -import static org.apache.tajo.client.ClientErrorUtil.isSuccess; -import static org.apache.tajo.client.ClientErrorUtil.returnError; +import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; +import static org.apache.tajo.exception.ReturnStateUtil.returnError; import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.*; import static org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService; diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java index 0089939bc4..fe4a5a59c4 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java @@ -26,7 +26,7 @@ import java.sql.SQLException; import java.util.Map; -import static org.apache.tajo.client.ClientErrorUtil.isError; +import static org.apache.tajo.exception.ReturnStateUtil.isError; public class SQLExceptionUtil { 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 fd336bba1f..69c0651bad 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 @@ -51,8 +51,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import static org.apache.tajo.client.ClientErrorUtil.isError; -import static org.apache.tajo.client.ClientErrorUtil.isSuccess; +import static org.apache.tajo.exception.ReturnStateUtil.isError; +import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; import static org.apache.tajo.client.SQLExceptionUtil.toSQLException; import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; diff --git a/tajo-common/src/main/java/org/apache/tajo/common/type/IPv4.java b/tajo-common/src/main/java/org/apache/tajo/common/type/IPv4.java index ba1575f060..b5a0da2165 100644 --- a/tajo-common/src/main/java/org/apache/tajo/common/type/IPv4.java +++ b/tajo-common/src/main/java/org/apache/tajo/common/type/IPv4.java @@ -19,7 +19,7 @@ package org.apache.tajo.common.type; import org.apache.hadoop.io.Writable; -import org.apache.tajo.common.exception.InvalidAddressException; +import org.apache.tajo.exception.InvalidAddressException; import java.io.DataInput; import java.io.DataOutput; 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 df4f3d118b..00840bcd8a 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 @@ -49,10 +49,11 @@ public class ErrorMessages { ADD_MESSAGE(ResultCode.INVALID_SESSION_VARIABLE, "invalid session variable '%s': %s", 2); - ADD_MESSAGE(ResultCode.INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s"); ADD_MESSAGE(ResultCode.SYNTAX_ERROR, "%s", 1); + ADD_MESSAGE(ResultCode.INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s"); + ADD_MESSAGE(ResultCode.UNDEFINED_TABLESPACE, "tablespace '%s' does not exist", 1); ADD_MESSAGE(ResultCode.UNDEFINED_DATABASE, "database '%s' does not exist", 1); ADD_MESSAGE(ResultCode.UNDEFINED_SCHEMA, "schema '%s' does not exist", 1); ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "relation '%s' does not exist", 1); @@ -60,6 +61,7 @@ public class ErrorMessages { ADD_MESSAGE(ResultCode.UNDEFINED_FUNCTION, "function does not exist: %s", 1); ADD_MESSAGE(ResultCode.UNDEFINED_OPERATOR, "operator does not exist: '%s'", 1); + ADD_MESSAGE(ResultCode.DUPLICATE_TABLESPACE, "tablespace '%s' already exists", 1); ADD_MESSAGE(ResultCode.DUPLICATE_DATABASE, "database '%s' already exists", 1); ADD_MESSAGE(ResultCode.DUPLICATE_SCHEMA, "schema '%s' already exists", 1); ADD_MESSAGE(ResultCode.DUPLICATE_TABLE, "table '%s' already exists", 1); diff --git a/tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java similarity index 95% rename from tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java rename to tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java index a4805cc0ed..1300a6ebb8 100644 --- a/tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.tajo.common.exception; +package org.apache.tajo.exception; public class InvalidAddressException extends Exception { diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java similarity index 69% rename from tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java rename to tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java index 0eb3bec1e0..32ceaf9d25 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ClientErrorUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java @@ -16,10 +16,12 @@ * limitations under the License. */ -package org.apache.tajo.client; +package org.apache.tajo.exception; import com.google.common.base.Preconditions; import org.apache.tajo.QueryId; +import org.apache.tajo.common.TajoDataTypes; +import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.ErrorMessages; import org.apache.tajo.exception.ErrorUtil; @@ -27,7 +29,7 @@ import org.apache.tajo.exception.TajoExceptionInterface; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; -public class ClientErrorUtil { +public class ReturnStateUtil { public static final ReturnState OK; @@ -89,6 +91,10 @@ public static boolean isError(ReturnState state) { return ErrorUtil.isFailed(state.getReturnCode()); } + public static ReturnState errFeatureNotSupported(String feature) { + return returnError(ResultCode.FEATURE_NOT_SUPPORTED, feature); + } + public static ReturnState errInvalidRpcCall(String message) { return returnError(ResultCode.INVALID_RPC_CALL, message); } @@ -113,15 +119,55 @@ public static ReturnState errNoSessionVar(String varName) { return returnError(ResultCode.NO_SUCH_QUERYID, varName); } + public static ReturnState errInsufficientPrivilege(String message) { + return returnError(ResultCode.INSUFFICIENT_PRIVILEGE, message); + } + + public static ReturnState errUndefinedTablespace(String spaceName) { + return returnError(ResultCode.UNDEFINED_TABLESPACE, spaceName); + } + public static ReturnState errUndefinedDatabase(String dbName) { return returnError(ResultCode.UNDEFINED_DATABASE, dbName); } - public static ReturnState errUndefinedTable(String tableName) { - return returnError(ResultCode.UNDEFINED_TABLE, tableName); + public static ReturnState errUndefinedTable(String tbName) { + return returnError(ResultCode.UNDEFINED_TABLE, tbName); + } + + public static ReturnState errUndefinedPartition(String partitionName) { + return returnError(ResultCode.UNDEFINED_PARTITION, partitionName); + } + + public static ReturnState errUndefinedPartitionMethod(String tbName) { + return returnError(ResultCode.UNDEFINED_PARTITION_METHOD, tbName); + } + + public static ReturnState errUndefinedIndex(String tbName, String columnName) { + return returnError(ResultCode.UNDEFINED_INDEX, tbName, columnName); + } + + public static ReturnState errUndefinedIndexName(String indexName) { + return returnError(ResultCode.UNDEFINED_INDEX_NAME, indexName); + } + + public static ReturnState errUndefinedFunction(String funcName) { + return returnError(ResultCode.UNDEFINED_FUNCTION, funcName); } public static ReturnState errDuplicateDatabase(String dbName) { return returnError(ResultCode.DUPLICATE_DATABASE, dbName); } + + public static ReturnState errDuplicateTable(String tbName) { + return returnError(ResultCode.DUPLICATE_TABLE, tbName); + } + + public static ReturnState errDuplicateIndex(String indexName) { + return returnError(ResultCode.DUPLICATE_INDEX, indexName); + } + + public static ReturnState errDuplicateFunction(String signature) { + return returnError(ResultCode.DUPLICATE_FUNCTION, signature); + } } diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index b4d618e6a6..06c688cc2b 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -58,7 +58,8 @@ enum ResultCode { UNDEFINED_INDEX = 506; // ? UNDEFINED_INDEX_NAME = 507; // ? UNDEFINED_PARTITION = 508; // ? - UNDEFINED_OPERATOR = 509; // SQLState: 42883 (=UNDEFINED_FUNCTION) + UNDEFINED_PARTITION_METHOD = 509; // ? + UNDEFINED_OPERATOR = 510; // SQLState: 42883 (=UNDEFINED_FUNCTION) DUPLICATE_TABLESPACE = 510; DUPLICATE_DATABASE = 511; // SQLState: 42P04 @@ -74,7 +75,6 @@ enum ResultCode { AMBIGUOUS_COLUMN = 522; // SQLState: 42702; AMBIGUOUS_FUNCTION = 523; // SQLState: 42725; - // Section: Syntax Error or Access Rule Violation SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 601; // SQLState: 42000 SYNTAX_ERROR = 602; // SQLState: 42601 diff --git a/tajo-common/src/test/java/org/apache/tajo/common/type/TestIPv4.java b/tajo-common/src/test/java/org/apache/tajo/common/type/TestIPv4.java index 884ad8f848..baac91cefb 100644 --- a/tajo-common/src/test/java/org/apache/tajo/common/type/TestIPv4.java +++ b/tajo-common/src/test/java/org/apache/tajo/common/type/TestIPv4.java @@ -19,7 +19,7 @@ package org.apache.tajo.common.type; import org.junit.Test; -import org.apache.tajo.common.exception.InvalidAddressException; +import org.apache.tajo.exception.InvalidAddressException; import static org.junit.Assert.*; diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java index c3788072ce..00d346a4ff 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java @@ -26,7 +26,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.service.AbstractService; -import org.apache.hadoop.util.StringUtils; import org.apache.tajo.QueryId; import org.apache.tajo.QueryIdFactory; import org.apache.tajo.SessionVars; @@ -35,15 +34,12 @@ import org.apache.tajo.catalog.CatalogService; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.client.ClientErrorUtil; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.engine.parser.SQLAnalyzer; import org.apache.tajo.engine.parser.SQLSyntaxError; import org.apache.tajo.engine.query.QueryContext; import org.apache.tajo.exception.ExceptionUtil; -import org.apache.tajo.exception.TajoException; -import org.apache.tajo.exception.TajoInternalError; -import org.apache.tajo.exception.TajoRuntimeException; import org.apache.tajo.master.TajoMaster.MasterContext; import org.apache.tajo.master.exec.DDLExecutor; import org.apache.tajo.master.exec.QueryExecutor; @@ -61,7 +57,7 @@ import java.sql.SQLException; import java.util.concurrent.TimeUnit; -import static org.apache.tajo.client.ClientErrorUtil.returnError; +import static org.apache.tajo.exception.ReturnStateUtil.returnError; import static org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; public class GlobalEngine extends AbstractService { @@ -199,7 +195,7 @@ public SubmitQueryResponse executeQuery(Session session, String query, boolean i responseBuilder.setUserName(queryContext.get(SessionVars.USERNAME)); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); responseBuilder.setIsForwarded(true); - responseBuilder.setState(ClientErrorUtil.returnError(t)); + responseBuilder.setState(ReturnStateUtil.returnError(t)); return responseBuilder.build(); } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 7f77cd6fc6..60279c1dfd 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -53,7 +53,6 @@ import org.apache.tajo.plan.logical.ScanNode; import org.apache.tajo.querymaster.QueryJobEvent; import org.apache.tajo.rpc.BlockingRpcServer; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.*; import org.apache.tajo.session.Session; import org.apache.tajo.util.KeyValueSet; @@ -65,8 +64,7 @@ import java.util.*; import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; -import static org.apache.tajo.client.ClientErrorUtil.*; -import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueProto; +import static org.apache.tajo.exception.ReturnStateUtil.*; public class TajoMasterClientService extends AbstractService { private final static Log LOG = LogFactory.getLog(TajoMasterClientService.class); @@ -438,8 +436,7 @@ public GetQueryListResponse getFinishedQueryList(RpcController controller, TajoI } @Override - public GetQueryStatusResponse getQueryStatus(RpcController controller, - GetQueryStatusRequest request) + public GetQueryStatusResponse getQueryStatus(RpcController controller, GetQueryStatusRequest request) throws ServiceException { try { 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 0f78597dfa..71b600da00 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 @@ -305,7 +305,7 @@ public boolean dropTable(QueryContext queryContext, String tableName, boolean if LOG.info("relation \"" + qualifiedName + "\" is already exists." ); return true; } else { // Otherwise, it causes an exception. - throw new UndefinedTbleException(qualifiedName); + throw new UndefinedTableException(qualifiedName); } } @@ -348,7 +348,7 @@ public void truncateTable(final QueryContext queryContext, final TruncateTableNo final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName); if (!catalog.existsTable(databaseName, simpleTableName)) { - throw new UndefinedTbleException(qualifiedName); + throw new UndefinedTableException(qualifiedName); } Path warehousePath = new Path(TajoConf.getWarehouseDir(context.getConf()), databaseName); @@ -398,13 +398,13 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName); if (!catalog.existsTable(databaseName, simpleTableName)) { - throw new UndefinedTbleException(qualifiedName); + throw new UndefinedTableException(qualifiedName); } switch (alterTable.getAlterTableOpType()) { case RENAME_TABLE: if (!catalog.existsTable(databaseName, simpleTableName)) { - throw new UndefinedTbleException(alterTable.getTableName()); + throw new UndefinedTableException(alterTable.getTableName()); } if (catalog.existsTable(databaseName, alterTable.getNewTableName())) { throw new DuplicateTableException(alterTable.getNewTableName()); 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 55f05b2af2..d3530a0d42 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 @@ -71,8 +71,8 @@ import java.util.ArrayList; import java.util.List; -import static org.apache.tajo.client.ClientErrorUtil.errUndefinedDatabase; -import static org.apache.tajo.client.ClientErrorUtil.OK; +import static org.apache.tajo.exception.ReturnStateUtil.errUndefinedDatabase; +import static org.apache.tajo.exception.ReturnStateUtil.OK; public class QueryExecutor { private static final Log LOG = LogFactory.getLog(QueryExecutor.class); diff --git a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java index 461b8ec741..1df8e7a41d 100644 --- a/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java +++ b/tajo-core/src/main/java/org/apache/tajo/webapp/QueryExecutorServlet.java @@ -1,6 +1,5 @@ package org.apache.tajo.webapp; -import com.google.protobuf.ServiceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.util.StringUtils; @@ -11,7 +10,6 @@ import org.apache.tajo.catalog.TableDesc; import org.apache.tajo.client.*; import org.apache.tajo.conf.TajoConf; -import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.jdbc.FetchResultSet; import org.apache.tajo.service.ServiceTrackerFactory; @@ -41,10 +39,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import static org.apache.tajo.client.ClientErrorUtil.isError; -import static org.apache.tajo.client.ClientErrorUtil.isSuccess; -import static org.apache.tajo.exception.ErrorUtil.isFailed; -import static org.apache.tajo.exception.ErrorUtil.isOk; +import static org.apache.tajo.exception.ReturnStateUtil.isError; +import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; /** * Licensed to the Apache Software Foundation (ASF) under one diff --git a/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java b/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java index 09d5d00966..edb5703624 100644 --- a/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java @@ -26,7 +26,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.service.AbstractService; import org.apache.tajo.QueryId; -import org.apache.tajo.client.ClientErrorUtil; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.ipc.ClientProtos.GetQueryHistoryResponse; import org.apache.tajo.ipc.ClientProtos.QueryIdRequest; @@ -129,10 +129,10 @@ public GetQueryHistoryResponse getQueryHistory(RpcController controller, QueryId if (queryHistory != null) { builder.setQueryHistory(queryHistory.getProto()); } - builder.setState(ClientErrorUtil.OK); + builder.setState(ReturnStateUtil.OK); } catch (Throwable t) { LOG.error(t.getMessage(), t); - builder.setState(ClientErrorUtil.returnError(t)); + builder.setState(ReturnStateUtil.returnError(t)); } return builder.build(); diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java index ae42bef263..86b1fe8916 100644 --- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java +++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java @@ -22,7 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.tajo.QueryId; import org.apache.tajo.TajoProtos; -import org.apache.tajo.client.ClientErrorUtil; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.ipc.ClientProtos.SubmitQueryResponse; import org.apache.tajo.master.QueryInProgress; import org.apache.tajo.master.QueryInfo; @@ -262,7 +262,7 @@ public Response run(JerseyResourceDelegateContext context) { SubmitQueryResponse response = masterContext.getGlobalEngine().executeQuery(session, request.getQuery(), false); - if (ClientErrorUtil.isError(response.getState())) { + if (ReturnStateUtil.isError(response.getState())) { return ResourcesUtil.createExceptionResponse(LOG, response.getState().getMessage()); } else { JerseyResourceDelegateContextKey uriInfoKey = diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java index b5d52fbfe5..77bfca6213 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java @@ -31,7 +31,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.client.ClientErrorUtil; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.engine.planner.global.DataChannel; @@ -865,7 +865,7 @@ public final void testColumnPartitionedTableWithSmallerExpressions1() throws Exc ClientProtos.SubmitQueryResponse response = client.executeQuery("insert overwrite into " + tableName + " select l_orderkey, l_partkey from lineitem"); - assertTrue(ClientErrorUtil.isError(response.getState())); + assertTrue(ReturnStateUtil.isError(response.getState())); assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns"); res = executeFile("case14.sql"); @@ -891,7 +891,7 @@ public final void testColumnPartitionedTableWithSmallerExpressions2() throws Exc response = client.executeQuery("insert overwrite into " + tableName + " select l_returnflag , l_orderkey, l_partkey from lineitem"); - assertTrue(ClientErrorUtil.isError(response.getState())); + assertTrue(ReturnStateUtil.isError(response.getState())); assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns"); res = executeFile("case15.sql"); 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 87122e8d68..84e7634560 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 @@ -301,7 +301,7 @@ public Expr visitInsert(Context context, Stack stack, Insert expr) throws TableDesc table = catalog.getTableDesc(qualifiedName); if (table == null) { - context.state.addVerification(new UndefinedTbleException(qualifiedName)); + context.state.addVerification(new UndefinedTableException(qualifiedName)); return null; } if (table.hasPartition()) { From 4c69367b7d45b36d6174856f31d4b15558c8f410 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Thu, 2 Jul 2015 16:22:05 -0700 Subject: [PATCH 17/30] removed unused variables. --- .../main/java/org/apache/tajo/catalog/CatalogServer.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java index 6f99e7e05b..275cc903b9 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java @@ -100,11 +100,6 @@ public class CatalogServer extends AbstractService { @SuppressWarnings("unused") private volatile boolean isOnline = false; - private static BoolProto BOOL_TRUE = BoolProto.newBuilder(). - setValue(true).build(); - private static BoolProto BOOL_FALSE = BoolProto.newBuilder(). - setValue(false).build(); - private Collection builtingFuncs; public CatalogServer() throws IOException { @@ -1262,7 +1257,7 @@ public FunctionDescProto getFunctionMeta(RpcController controller, GetFunctionMe } if (function == null) { - throw new ServiceException(new UndefinedFunctionException(request.getSignature(), request.getParameterTypesList())); + throw new UndefinedFunctionException(request.getSignature(), request.getParameterTypesList()); } else { return function; } From d4bc2db572e65bd8ea84439c60ff4fb04acb6f51 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Fri, 3 Jul 2015 03:33:52 -0700 Subject: [PATCH 18/30] Refactored all catalog APIs. --- .../tajo/catalog/AbstractCatalogClient.java | 192 ++++--- .../src/main/proto/CatalogProtocol.proto | 115 ++++- .../apache/tajo/catalog/CatalogService.java | 6 +- .../src/main/proto/CatalogProtos.proto | 44 +- .../tajo/catalog/store/HiveCatalogStore.java | 2 +- .../apache/tajo/catalog/CatalogServer.java | 471 ++++++++++++------ .../tajo/catalog/store/AbstractDBStore.java | 3 +- .../tajo/catalog/store/CatalogStore.java | 6 +- .../apache/tajo/catalog/store/MemStore.java | 2 +- .../tajo/client/CatalogAdminClientImpl.java | 3 +- .../apache/tajo/client/QueryClientImpl.java | 7 +- .../apache/tajo/client/SessionConnection.java | 53 +- .../tajo/exception/ReturnStateUtil.java | 27 + .../tajo/exception}/SQLExceptionUtil.java | 13 +- .../tajo/exception/TajoRuntimeException.java | 6 + .../tajo/engine/parser/SQLSyntaxError.java | 2 + .../org/apache/tajo/jdbc/TajoStatement.java | 4 +- .../org/apache/tajo/plan/ExprAnnotator.java | 5 + 18 files changed, 627 insertions(+), 334 deletions(-) rename {tajo-client/src/main/java/org/apache/tajo/client => tajo-common/src/main/java/org/apache/tajo/exception}/SQLExceptionUtil.java (90%) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index 6085519c93..a5adfa0ceb 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -6,9 +6,9 @@ * 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 - * + *

+ * 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. @@ -23,14 +23,15 @@ import org.apache.commons.logging.LogFactory; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService.BlockingInterface; +import org.apache.tajo.catalog.CatalogProtocol.*; import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; -import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.*; import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.conf.TajoConf; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; import org.apache.tajo.util.ProtoUtil; import java.io.Closeable; @@ -39,7 +40,8 @@ import java.util.List; import static org.apache.tajo.catalog.CatalogUtil.buildTableIdentifier; -import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; +import static org.apache.tajo.exception.ExceptionUtil.printStackTraceIfError; +import static org.apache.tajo.exception.ReturnStateUtil.*; /** * CatalogClient provides a client API to access the catalog server. @@ -77,7 +79,6 @@ public final Boolean dropTablespace(final String tablespaceName) { try { final BlockingInterface stub = getStub(); - return isSuccess(stub.dropTablespace(null, ProtoUtil.convertString(tablespaceName))); } catch (ServiceException e) { @@ -90,7 +91,6 @@ public final Boolean existTablespace(final String tablespaceName) { try { final BlockingInterface stub = getStub(); - return isSuccess(stub.existTablespace(null, ProtoUtil.convertString(tablespaceName))); } catch (ServiceException e) { @@ -103,21 +103,23 @@ public final Collection getAllTablespaceNames() { try { final BlockingInterface stub = getStub(); - PrimitiveProtos.StringListProto response = stub.getAllTablespaceNames(null, ProtoUtil.NULL_PROTO); + final StringListResponse response = stub.getAllTablespaceNames(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); - return ProtoUtil.convertStrings(response); + return response.getValuesList(); } catch (ServiceException e) { throw new RuntimeException(e); } } - + @Override public List getAllTablespaces() { try { final BlockingInterface stub = getStub(); - CatalogProtos.GetTablespacesProto response = stub.getAllTablespaces(null, ProtoUtil.NULL_PROTO); + final GetTablespacesResponse response = stub.getAllTablespaces(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); return response.getTablespaceList(); @@ -130,13 +132,14 @@ public List getAllTablespaces() { public TablespaceProto getTablespace(final String tablespaceName) { try { - BlockingInterface stub = getStub(); + final BlockingInterface stub = getStub(); + final GetTablespaceResponse response = stub.getTablespace(null, ProtoUtil.convertString(tablespaceName)); + ensureOk(response.getState()); - return stub.getTablespace(null, ProtoUtil.convertString(tablespaceName)); + return response.getTablespace(); } catch (ServiceException e) { - LOG.error(e.getMessage(), e); - return null; + throw new RuntimeException(e); } } @@ -145,7 +148,6 @@ public Boolean alterTablespace(final AlterTablespaceProto alterTablespace) { try { final BlockingInterface stub = getStub(); - return isSuccess(stub.alterTablespace(null, alterTablespace)); } catch (ServiceException e) { @@ -159,7 +161,7 @@ public final Boolean createDatabase(final String databaseName, @Nullable final S try { final BlockingInterface stub = getStub(); - CreateDatabaseRequest.Builder builder = CreateDatabaseRequest.newBuilder(); + final CreateDatabaseRequest.Builder builder = CreateDatabaseRequest.newBuilder(); builder.setDatabaseName(databaseName); if (tablespaceName != null) { builder.setTablespaceName(tablespaceName); @@ -176,8 +178,7 @@ public final Boolean createDatabase(final String databaseName, @Nullable final S public final Boolean dropDatabase(final String databaseName) { try { - BlockingInterface stub = getStub(); - + final BlockingInterface stub = getStub(); return isSuccess(stub.dropDatabase(null, ProtoUtil.convertString(databaseName))); } catch (ServiceException e) { @@ -191,7 +192,6 @@ public final Boolean existDatabase(final String databaseName) { try { final BlockingInterface stub = getStub(); - return isSuccess(stub.existDatabase(null, ProtoUtil.convertString(databaseName))); } catch (ServiceException e) { @@ -204,20 +204,23 @@ public final Collection getAllDatabaseNames() { try { final BlockingInterface stub = getStub(); - PrimitiveProtos.StringListProto response = stub.getAllDatabaseNames(null, ProtoUtil.NULL_PROTO); + final StringListResponse response = stub.getAllDatabaseNames(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); + + return response.getValuesList(); - return ProtoUtil.convertStrings(response); } catch (ServiceException e) { throw new RuntimeException(e); } } - + @Override public List getAllDatabases() { try { final BlockingInterface stub = getStub(); - final GetDatabasesProto response = stub.getAllDatabases(null, ProtoUtil.NULL_PROTO); + final GetDatabasesResponse response = stub.getAllDatabases(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); return response.getDatabaseList(); @@ -233,7 +236,10 @@ public final TableDesc getTableDesc(final String databaseName, final String tabl final BlockingInterface stub = getStub(); final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); - return CatalogUtil.newTableDesc(stub.getTableDesc(null, request)); + TableDescResponse response = stub.getTableDesc(null, request); + ensureOk(response.getState()); + + return CatalogUtil.newTableDesc(response.getTable()); } catch (ServiceException e) { throw new RuntimeException(e); @@ -242,16 +248,17 @@ public final TableDesc getTableDesc(final String databaseName, final String tabl @Override public TableDesc getTableDesc(String qualifiedName) { - String [] splitted = CatalogUtil.splitFQTableName(qualifiedName); + String[] splitted = CatalogUtil.splitFQTableName(qualifiedName); return getTableDesc(splitted[0], splitted[1]); } - + @Override public List getAllTables() { try { final BlockingInterface stub = getStub(); - final GetTablesProto response = stub.getAllTables(null, ProtoUtil.NULL_PROTO); + final GetTablesResponse response = stub.getAllTables(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); return response.getTableList(); @@ -259,41 +266,44 @@ public List getAllTables() { throw new RuntimeException(e); } } - + @Override public List getAllTableOptions() { try { final BlockingInterface stub = getStub(); - final GetTableOptionsProto response = stub.getAllTableOptions(null, ProtoUtil.NULL_PROTO); + final GetTablePropertiesResponse response = stub.getAllTableProperties(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); - return response.getTableOptionList(); + return response.getPropertiesList(); } catch (ServiceException e) { throw new RuntimeException(e); } } - + @Override public List getAllTableStats() { try { final BlockingInterface stub = getStub(); - final GetTableStatsProto response = stub.getAllTableStats(null, ProtoUtil.NULL_PROTO); + final GetTableStatsResponse response = stub.getAllTableStats(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); - return response.getStatList(); + return response.getStatsList(); } catch (ServiceException e) { throw new RuntimeException(e); } } - + @Override public List getAllColumns() { try { final BlockingInterface stub = getStub(); - final GetColumnsProto response = stub.getAllColumns(null, ProtoUtil.NULL_PROTO); + final GetColumnsResponse response = stub.getAllColumns(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); return response.getColumnList(); @@ -308,8 +318,10 @@ public final PartitionMethodDesc getPartitionMethod(final String databaseName, f try { final BlockingInterface stub = getStub(); final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); + final GetPartitionMethodResponse response = stub.getPartitionMethodByTableName(null, request); + ensureOk(response.getState()); - return CatalogUtil.newPartitionMethodDesc(stub.getPartitionMethodByTableName(null, request)); + return CatalogUtil.newPartitionMethodDesc(response.getPartition()); } catch (ServiceException e) { throw new RuntimeException(e); @@ -339,7 +351,10 @@ public final PartitionDescProto getPartition(final String databaseName, final St .setPartitionName(partitionName) .build(); - return stub.getPartitionByPartitionName(null, request); + final GetPartitionDescResponse response = stub.getPartitionByPartitionName(null, request); + ensureOk(response.getState()); + + return response.getPartition(); } catch (ServiceException e) { throw new RuntimeException(e); @@ -355,18 +370,23 @@ public final List getPartitions(final String databaseName, f .setTableName(tableName) .build(); - final PartitionsProto response = stub.getPartitionsByTableName(null, request); + final GetPartitionsResponse response = stub.getPartitionsByTableName(null, request); + ensureOk(response.getState()); + return response.getPartitionList(); } catch (ServiceException e) { throw new RuntimeException(e); } } + @Override public List getAllPartitions() { try { - BlockingInterface stub = getStub(); - GetTablePartitionsProto response = stub.getAllPartitions(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetTablePartitionsResponse response = stub.getAllPartitions(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); + return response.getPartList(); } catch (ServiceException e) { @@ -377,9 +397,12 @@ public List getAllPartitions() { @Override public final Collection getAllTableNames(final String databaseName) { try { - BlockingInterface stub = getStub(); - PrimitiveProtos.StringListProto response = stub.getAllTableNames(null, ProtoUtil.convertString(databaseName)); - return ProtoUtil.convertStrings(response); + final BlockingInterface stub = getStub(); + final StringListResponse response = stub.getAllTableNames(null, ProtoUtil.convertString(databaseName)); + ensureOk(response.getState()); + + return response.getValuesList(); + } catch (ServiceException e) { throw new RuntimeException(e); } @@ -421,7 +444,7 @@ public final boolean createTable(final TableDesc desc) { @Override public boolean dropTable(String tableName) { - String [] splitted = CatalogUtil.splitFQTableName(tableName); + String[] splitted = CatalogUtil.splitFQTableName(tableName); final String databaseName = splitted[0]; final String simpleName = splitted[1]; @@ -453,9 +476,10 @@ public final boolean existsTable(final String databaseName, final String tableNa throw new RuntimeException(e); } } + @Override public final boolean existsTable(final String tableName) { - String [] splitted = CatalogUtil.splitFQTableName(tableName); + String[] splitted = CatalogUtil.splitFQTableName(tableName); return existsTable(splitted[0], splitted[1]); } @@ -517,7 +541,10 @@ public final IndexDesc getIndexByName(final String databaseName, final String in .build(); final BlockingInterface stub = getStub(); - return new IndexDesc(stub.getIndexByName(null, request)); + final GetIndexResponse response = stub.getIndexByName(null, request); + ensureOk(response.getState()); + + return new IndexDesc(response.getIndex()); } catch (ServiceException e) { throw new RuntimeException(e); @@ -529,12 +556,17 @@ public final IndexDesc getIndexByColumn(final String databaseName, final String tableName, final String columnName) { try { - GetIndexByColumnRequest.Builder builder = GetIndexByColumnRequest.newBuilder(); - builder.setTableIdentifier(buildTableIdentifier(databaseName, tableName)); - builder.setColumnName(columnName); - BlockingInterface stub = getStub(); - return new IndexDesc(stub.getIndexByColumn(null, builder.build())); + final GetIndexByColumnRequest request = GetIndexByColumnRequest.newBuilder() + .setTableIdentifier(buildTableIdentifier(databaseName, tableName)) + .setColumnName(columnName) + .build(); + + final BlockingInterface stub = getStub(); + final GetIndexResponse response = stub.getIndexByColumn(null, request); + ensureOk(response.getState());; + + return new IndexDesc(response.getIndex()); } catch (ServiceException e) { throw new RuntimeException(e); @@ -542,11 +574,10 @@ public final IndexDesc getIndexByColumn(final String databaseName, } @Override - public boolean dropIndex(final String databaseName, - final String indexName) { + public boolean dropIndex(final String dbName, final String indexName) { try { final IndexNameProto request = IndexNameProto.newBuilder() - .setDatabaseName(databaseName) + .setDatabaseName(dbName) .setIndexName(indexName) .build(); @@ -558,12 +589,15 @@ public boolean dropIndex(final String databaseName, throw new RuntimeException(e); } } - + @Override public List getAllIndexes() { + try { - BlockingInterface stub = getStub(); - GetIndexesProto response = stub.getAllIndexes(null, ProtoUtil.NULL_PROTO); + final BlockingInterface stub = getStub(); + final GetIndexesResponse response = stub.getAllIndexes(null, ProtoUtil.NULL_PROTO); + ensureOk(response.getState()); + return response.getIndexList(); } catch (ServiceException e) { @@ -573,9 +607,9 @@ public List getAllIndexes() { @Override public final boolean createFunction(final FunctionDesc funcDesc) { + try { final BlockingInterface stub = getStub(); - return isSuccess(stub.createFunction(null, funcDesc.getProto())); } catch (ServiceException e) { @@ -592,7 +626,6 @@ public final boolean dropFunction(final String signature) { .build(); final BlockingInterface stub = getStub(); - return isSuccess(stub.dropFunction(null, request)); } catch (ServiceException e) { @@ -601,12 +634,15 @@ public final boolean dropFunction(final String signature) { } @Override - public final FunctionDesc getFunction(final String signature, DataType... paramTypes) { + public final FunctionDesc getFunction(final String signature, DataType... paramTypes) + throws UndefinedFunctionException { return getFunction(signature, null, paramTypes); } @Override - public final FunctionDesc getFunction(final String signature, FunctionType funcType, DataType... paramTypes) { + public final FunctionDesc getFunction(final String signature, FunctionType funcType, DataType... paramTypes) + throws UndefinedFunctionException { + final GetFunctionMetaRequest.Builder builder = GetFunctionMetaRequest.newBuilder(); builder.setSignature(signature); if (funcType != null) { @@ -616,24 +652,20 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT builder.addParameterTypes(type); } - FunctionDescProto descProto = null; try { - BlockingInterface stub = getStub(); - descProto = stub.getFunctionMeta(null, builder.build()); - } catch (UndefinedFunctionException e) { - LOG.debug(e.getMessage()); - } catch (ServiceException e) { - throw new RuntimeException(e); - } + final BlockingInterface stub = getStub(); + final FunctionDescResponse response = stub.getFunctionMeta(null, builder.build()); - if (descProto == null) { - throw new UndefinedFunctionException(signature, paramTypes); - } + if (isThisError(response.getState(), ResultCode.UNDEFINED_FUNCTION)) { + throw new UndefinedFunctionException(signature, paramTypes); + } + ensureOk(response.getState()); - try { - return new FunctionDesc(descProto); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); + return new FunctionDesc(response.getFunction()); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + throw new RuntimeException(t); } } @@ -657,7 +689,6 @@ public final boolean containFunction(final String signature, FunctionType funcTy try { final BlockingInterface stub = getStub(); - return isSuccess(stub.containFunction(null, builder.build())); } catch (ServiceException e) { @@ -670,7 +701,6 @@ public final boolean alterTable(final AlterTableDesc desc) { try { final BlockingInterface stub = getStub(); - return isSuccess(stub.alterTable(null, desc.getProto())); } catch (ServiceException e) { @@ -680,9 +710,9 @@ public final boolean alterTable(final AlterTableDesc desc) { @Override public boolean updateTableStats(final UpdateTableStatsProto updateTableStatsProto) { + try { final BlockingInterface stub = getStub(); - return isSuccess(stub.updateTableStats(null, updateTableStatsProto)); } catch (ServiceException e) { diff --git a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto index 822f6ba541..6bca573faa 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto +++ b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto @@ -24,14 +24,89 @@ option java_generate_equals_and_hash = true; import "CatalogProtos.proto"; import "PrimitiveProtos.proto"; +message GetTablespacesResponse { + required ReturnState state = 1; + repeated TablespaceProto tablespace = 2; +} + +message GetTablespaceResponse { + required ReturnState state = 1; + optional TablespaceProto tablespace = 2; +} + +message GetDatabasesResponse { + required ReturnState state = 1; + repeated DatabaseProto database = 2; +} + +message TableDescResponse { + required ReturnState state = 1; + optional TableDescProto table = 2; +} + +message GetTablesResponse { + required ReturnState state = 1; + repeated TableDescriptorProto table = 2; +} + +message FunctionDescResponse { + required ReturnState state = 1; + optional FunctionDescProto function = 2; +} + +message GetTablePropertiesResponse { + required ReturnState state = 1; + repeated TableOptionProto properties = 2; +} + +message GetTableStatsResponse { + required ReturnState state = 1; + repeated TableStatsProto stats = 2; +} + +message GetColumnsResponse { + required ReturnState state = 1; + repeated ColumnProto column = 2; +} + +message GetPartitionMethodResponse { + required ReturnState state = 1; + optional PartitionMethodProto partition = 2; +} + +message GetPartitionDescResponse { + required ReturnState state = 1; + optional PartitionDescProto partition = 2; +} + +message GetIndexResponse { + required ReturnState state = 1; + optional IndexDescProto index = 2; +} + +message GetIndexesResponse { + required ReturnState state = 1; + repeated IndexProto index = 2; +} + +message GetPartitionsResponse { + required ReturnState state = 1; + repeated PartitionDescProto partition = 2; +} + +message GetTablePartitionsResponse { + required ReturnState state = 1; + repeated TablePartitionProto part = 2; +} + service CatalogProtocolService { rpc createTablespace(CreateTablespaceRequest) returns (ReturnState); rpc dropTablespace(StringProto) returns (ReturnState); rpc existTablespace(StringProto) returns (ReturnState); - rpc getAllTablespaces(NullProto) returns (GetTablespacesProto); - rpc getAllTablespaceNames(NullProto) returns (StringListProto); - rpc getTablespace(StringProto) returns (TablespaceProto); + rpc getAllTablespaces(NullProto) returns (GetTablespacesResponse); + rpc getAllTablespaceNames(NullProto) returns (StringListResponse); + rpc getTablespace(StringProto) returns (GetTablespaceResponse); rpc alterTablespace(AlterTablespaceProto) returns (ReturnState); rpc alterTable(AlterTableDescProto) returns (ReturnState); rpc updateTableStats(UpdateTableStatsProto) returns (ReturnState); @@ -39,38 +114,38 @@ service CatalogProtocolService { rpc createDatabase(CreateDatabaseRequest) returns (ReturnState); rpc dropDatabase(StringProto) returns (ReturnState); rpc existDatabase(StringProto) returns (ReturnState); - rpc getAllDatabaseNames(NullProto) returns (StringListProto); - rpc getAllDatabases(NullProto) returns (GetDatabasesProto); + rpc getAllDatabaseNames(NullProto) returns (StringListResponse); + rpc getAllDatabases(NullProto) returns (GetDatabasesResponse); rpc createTable(TableDescProto) returns (ReturnState); rpc dropTable(TableIdentifierProto) returns (ReturnState); rpc existsTable(TableIdentifierProto) returns (ReturnState); - rpc getTableDesc(TableIdentifierProto) returns (TableDescProto); - rpc getAllTableNames(StringProto) returns (StringListProto); - rpc getAllTables(NullProto) returns (GetTablesProto); - rpc getAllTableOptions(NullProto) returns (GetTableOptionsProto); - rpc getAllTableStats(NullProto) returns (GetTableStatsProto); - rpc getAllColumns(NullProto) returns (GetColumnsProto); - - rpc getPartitionMethodByTableName(TableIdentifierProto) returns (PartitionMethodProto); + rpc getTableDesc(TableIdentifierProto) returns (TableDescResponse); + rpc getAllTableNames(StringProto) returns (StringListResponse); + rpc getAllTables(NullProto) returns (GetTablesResponse); + rpc getAllTableProperties(NullProto) returns (GetTablePropertiesResponse); + rpc getAllTableStats(NullProto) returns (GetTableStatsResponse); + rpc getAllColumns(NullProto) returns (GetColumnsResponse); + + rpc getPartitionMethodByTableName(TableIdentifierProto) returns (GetPartitionMethodResponse); rpc existPartitionMethod(TableIdentifierProto) returns (ReturnState); rpc dropPartitionMethod(TableIdentifierProto) returns (ReturnState); - rpc getPartitionByPartitionName(PartitionIdentifierProto) returns (PartitionDescProto); - rpc getPartitionsByTableName(PartitionIdentifierProto) returns (PartitionsProto); - rpc getAllPartitions(NullProto) returns (GetTablePartitionsProto); + rpc getPartitionByPartitionName(PartitionIdentifierProto) returns (GetPartitionDescResponse); + rpc getPartitionsByTableName(PartitionIdentifierProto) returns (GetPartitionsResponse); + rpc getAllPartitions(NullProto) returns (GetTablePartitionsResponse); rpc createIndex(IndexDescProto) returns (ReturnState); rpc dropIndex(IndexNameProto) returns (ReturnState); rpc existIndexByName(IndexNameProto) returns (ReturnState); rpc existIndexByColumn(GetIndexByColumnRequest) returns (ReturnState); - rpc getIndexByName(IndexNameProto) returns (IndexDescProto); - rpc getIndexByColumn(GetIndexByColumnRequest) returns (IndexDescProto); - rpc getAllIndexes(NullProto) returns (GetIndexesProto); + rpc getIndexByName(IndexNameProto) returns (GetIndexResponse); + rpc getIndexByColumn(GetIndexByColumnRequest) returns (GetIndexResponse); + rpc getAllIndexes(NullProto) returns (GetIndexesResponse); rpc createFunction(FunctionDescProto) returns (ReturnState); rpc dropFunction(UnregisterFunctionRequest) returns (ReturnState); rpc getFunctions(NullProto) returns (GetFunctionsResponse); - rpc getFunctionMeta(GetFunctionMetaRequest) returns (FunctionDescProto); + rpc getFunctionMeta(GetFunctionMetaRequest) returns (FunctionDescResponse); rpc containFunction(ContainFunctionRequest) returns (ReturnState); } \ No newline at end of file diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java index 86b773b704..1d3001f076 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java @@ -18,6 +18,7 @@ package org.apache.tajo.catalog; +import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto; @@ -29,6 +30,7 @@ import org.apache.tajo.catalog.proto.CatalogProtos.TableStatsProto; import org.apache.tajo.common.TajoDataTypes.DataType; +import java.sql.SQLException; import java.util.Collection; import java.util.List; @@ -209,9 +211,9 @@ public interface CatalogService { boolean dropFunction(String signature); - FunctionDesc getFunction(String signature, DataType... paramTypes); + FunctionDesc getFunction(String signature, DataType... paramTypes) throws UndefinedFunctionException; - FunctionDesc getFunction(String signature, FunctionType funcType, DataType... paramTypes); + FunctionDesc getFunction(String signature, FunctionType funcType, DataType... paramTypes) throws UndefinedFunctionException; boolean containFunction(String signature, DataType... paramTypes); diff --git a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto index b213916f30..bd3459824c 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto +++ b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto @@ -133,42 +133,10 @@ enum IndexMethod { BITMAP_IDX = 3; } -message GetAllTableNamesResponse { - repeated string tableName = 1; -} - -message GetTablespacesProto { - repeated TablespaceProto tablespace = 1; -} - -message GetDatabasesProto { - repeated DatabaseProto database = 1; -} - -message GetTablesProto { - repeated TableDescriptorProto table = 1; -} - -message GetColumnsProto { - repeated ColumnProto column = 1; -} - message GetIndexesProto { repeated IndexProto index = 1; } -message GetTableOptionsProto { - repeated TableOptionProto tableOption = 1; -} - -message GetTableStatsProto { - repeated TableStatsProto stat = 1; -} - -message GetTablePartitionsProto { - repeated TablePartitionProto part = 1; -} - message IndexProto { required int32 dbId = 1; required int32 tId = 2; @@ -281,11 +249,6 @@ message SortSpecProto { optional bool nullFirst = 3 [default = false]; } - -message PartitionsProto { - repeated PartitionDescProto partition = 1; -} - message PartitionMethodProto { required TableIdentifierProto tableIdentifier = 1; required PartitionType partitionType = 2; @@ -304,7 +267,6 @@ message PartitionKeyProto { required string partitionValue = 2; } - message PartitionIdentifierProto { required string databaseName = 1; required string tableName = 2; @@ -319,9 +281,9 @@ message TablespaceProto { } message DatabaseProto { - required int32 spaceId = 1; - required int32 id = 2; - required string name = 3; + required int32 spaceId = 1; + required int32 id = 2; + required string name = 3; } message TableDescriptorProto { diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java index afc627222b..daba8bacbf 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java @@ -942,7 +942,7 @@ public List getAllPartitions() throws CatalogException { } @Override - public List getAllTableOptions() throws CatalogException { + public List getAllTableProperties() throws CatalogException { throw new UnsupportedOperationException(); } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java index 275cc903b9..cbc24234e2 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java @@ -23,14 +23,13 @@ import com.google.common.collect.Lists; import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.service.AbstractService; import org.apache.tajo.TajoConstants; import org.apache.tajo.annotation.ThreadSafe; -import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService; +import org.apache.tajo.catalog.CatalogProtocol.*; import org.apache.tajo.catalog.dictionary.InfoSchemaMetadataDictionary; import org.apache.tajo.catalog.exception.*; import org.apache.tajo.catalog.proto.CatalogProtos.*; @@ -43,14 +42,12 @@ import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.exception.TajoInternalError; -import org.apache.tajo.function.FunctionUtil; import org.apache.tajo.rpc.BlockingRpcServer; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto; import org.apache.tajo.util.NetUtils; -import org.apache.tajo.util.ProtoUtil; import org.apache.tajo.util.TUtil; import java.io.IOException; @@ -63,11 +60,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import static org.apache.tajo.catalog.proto.CatalogProtos.AlterTablespaceProto.AlterTablespaceCommand; -import static org.apache.tajo.catalog.proto.CatalogProtos.FunctionType.*; import static org.apache.tajo.exception.ExceptionUtil.printStackTraceIfError; import static org.apache.tajo.exception.ReturnStateUtil.*; import static org.apache.tajo.function.FunctionUtil.buildSimpleFunctionSignature; -import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListProto; /** * This class provides the catalog service. The catalog service enables clients @@ -95,11 +90,6 @@ public class CatalogServer extends AbstractService { private String bindAddressStr; final CatalogProtocolHandler handler; - // Server status variables - private volatile boolean stopped = false; - @SuppressWarnings("unused") - private volatile boolean isOnline = false; - private Collection builtingFuncs; public CatalogServer() throws IOException { @@ -293,23 +283,31 @@ public ReturnState existTablespace(RpcController controller, StringProto request } @Override - public StringListProto getAllTablespaceNames(RpcController controller, NullProto request) throws ServiceException { + public StringListResponse getAllTablespaceNames(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); try { - return ProtoUtil.convertStrings(store.getAllDatabaseNames()); + return StringListResponse.newBuilder() + .setState(OK) + .addAllValues(store.getAllDatabaseNames()) + .build(); + } catch (Throwable t) { printStackTraceIfError(LOG, t); - throw new ServiceException(t); + return returnFailedStringList(t); } finally { rlock.unlock(); } } @Override - public GetTablespacesProto getAllTablespaces(RpcController controller, NullProto request) throws ServiceException { + public GetTablespacesResponse getAllTablespaces(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); try { - return GetTablespacesProto.newBuilder().addAllTablespace(store.getTablespaces()).build(); + return GetTablespacesResponse.newBuilder() + .setState(OK) + .addAllTablespace(store.getTablespaces()) + .build(); + } catch (Throwable t) { printStackTraceIfError(LOG, t); throw new ServiceException(t); @@ -319,15 +317,22 @@ public GetTablespacesProto getAllTablespaces(RpcController controller, NullProto } @Override - public TablespaceProto getTablespace(RpcController controller, StringProto request) throws ServiceException { + public GetTablespaceResponse getTablespace(RpcController controller, StringProto request) { rlock.lock(); try { - return store.getTablespace(request.getValue()); + + return GetTablespaceResponse.newBuilder() + .setState(OK) + .setTablespace(store.getTablespace(request.getValue())) + .build(); } catch (Throwable t) { + printStackTraceIfError(LOG, t); - throw new ServiceException(t); + return GetTablespaceResponse.newBuilder() + .setState(returnError(t)) + .build(); } finally { rlock.unlock(); @@ -500,61 +505,88 @@ public ReturnState existDatabase(RpcController controller, StringProto request) } @Override - public StringListProto getAllDatabaseNames(RpcController controller, NullProto request) throws ServiceException { + public StringListResponse getAllDatabaseNames(RpcController controller, NullProto request) { rlock.lock(); try { - StringListProto.Builder builder = StringListProto.newBuilder(); - builder.addAllValues(store.getAllDatabaseNames()); - builder.addValues(metaDictionary.getSystemDatabaseName()); - return builder.build(); - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + return StringListResponse.newBuilder() + .setState(OK) + .addAllValues(store.getAllDatabaseNames()) + .addValues(metaDictionary.getSystemDatabaseName()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnFailedStringList(t); + } finally { rlock.unlock(); } } @Override - public GetDatabasesProto getAllDatabases(RpcController controller, NullProto request) throws ServiceException { + public GetDatabasesResponse getAllDatabases(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); try { - return GetDatabasesProto.newBuilder().addAllDatabase(store.getAllDatabases()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetDatabasesResponse.newBuilder() + .setState(OK) + .addAllDatabase(store.getAllDatabases()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetDatabasesResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public TableDescProto getTableDesc(RpcController controller, + public TableDescResponse getTableDesc(RpcController controller, TableIdentifierProto request) throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + String dbName = request.getDatabaseName(); + String tbName = request.getTableName(); - if (metaDictionary.isSystemDatabase(databaseName)){ - return metaDictionary.getTableDesc(tableName); + if (metaDictionary.isSystemDatabase(dbName)) { + return TableDescResponse.newBuilder() + .setState(OK) + .setTable(metaDictionary.getTableDesc(tbName)) + .build(); } else { rlock.lock(); try { boolean contain; - contain = store.existDatabase(databaseName); + contain = store.existDatabase(dbName); if (contain) { - contain = store.existTable(databaseName, tableName); + contain = store.existTable(dbName, tbName); if (contain) { - return store.getTable(databaseName, tableName); + return TableDescResponse.newBuilder() + .setState(OK) + .setTable(store.getTable(dbName, tbName)) + .build(); } else { - throw new UndefinedTableException(tableName); + return TableDescResponse.newBuilder() + .setState(errUndefinedTable(tbName)) + .build(); } } else { - throw new UndefinedDatabaseException(databaseName); + return TableDescResponse.newBuilder() + .setState(errUndefinedDatabase(dbName)) + .build(); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return TableDescResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } @@ -562,24 +594,29 @@ public TableDescProto getTableDesc(RpcController controller, } @Override - public StringListProto getAllTableNames(RpcController controller, StringProto request) - throws ServiceException { + public StringListResponse getAllTableNames(RpcController controller, StringProto request) { - String databaseName = request.getValue(); + String dbName = request.getValue(); + + if (metaDictionary.isSystemDatabase(dbName)) { + + return returnStringList(metaDictionary.getAllSystemTables()); - if (metaDictionary.isSystemDatabase(databaseName)) { - return ProtoUtil.convertStrings(metaDictionary.getAllSystemTables()); } else { rlock.lock(); try { - if (store.existDatabase(databaseName)) { - return ProtoUtil.convertStrings(store.getAllTableNames(databaseName)); + if (store.existDatabase(dbName)) { + return returnStringList(store.getAllTableNames(dbName)); } else { - throw new UndefinedDatabaseException(databaseName); + return StringListResponse.newBuilder() + .setState(errUndefinedDatabase(dbName)) + .build(); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnFailedStringList(t); + } finally { rlock.unlock(); } @@ -710,55 +747,90 @@ public ReturnState existsTable(RpcController controller, TableIdentifierProto re } @Override - public GetTablesProto getAllTables(RpcController controller, NullProto request) throws ServiceException { + public GetTablesResponse getAllTables(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); try { - return GetTablesProto.newBuilder().addAllTable(store.getAllTables()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetTablesResponse.newBuilder() + .setState(OK) + .addAllTable(store.getAllTables()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetTablesResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public GetTableOptionsProto getAllTableOptions(RpcController controller, NullProto request) throws ServiceException { + public GetTablePropertiesResponse getAllTableProperties(RpcController controller, NullProto request) { rlock.lock(); try { - return GetTableOptionsProto.newBuilder().addAllTableOption(store.getAllTableOptions()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetTablePropertiesResponse.newBuilder() + .setState(OK) + .addAllProperties(store.getAllTableProperties()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetTablePropertiesResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public GetTableStatsProto getAllTableStats(RpcController controller, NullProto request) throws ServiceException { + public GetTableStatsResponse getAllTableStats(RpcController controller, NullProto request) { rlock.lock(); try { - return GetTableStatsProto.newBuilder().addAllStat(store.getAllTableStats()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetTableStatsResponse.newBuilder() + .addAllStats(store.getAllTableStats()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetTableStatsResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public GetColumnsProto getAllColumns(RpcController controller, NullProto request) throws ServiceException { + public GetColumnsResponse getAllColumns(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); try { - return GetColumnsProto.newBuilder().addAllColumn(store.getAllColumns()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetColumnsResponse + .newBuilder() + .addAllColumn(store.getAllColumns()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetColumnsResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public PartitionMethodProto getPartitionMethodByTableName(RpcController controller, + public GetPartitionMethodResponse getPartitionMethodByTableName(RpcController controller, TableIdentifierProto request) throws ServiceException { String databaseName = request.getDatabaseName(); @@ -777,20 +849,36 @@ public PartitionMethodProto getPartitionMethodByTableName(RpcController controll if (contain) { contain = store.existTable(databaseName, tableName); if (contain) { + if (store.existPartitionMethod(databaseName, tableName)) { - return store.getPartitionMethod(databaseName, tableName); + + return GetPartitionMethodResponse.newBuilder() + .setState(OK) + .setPartition(store.getPartitionMethod(databaseName, tableName)) + .build(); + } else { - throw new NoPartitionedTableException(databaseName, tableName); + return GetPartitionMethodResponse.newBuilder() + .setState(errUndefinedPartitionMethod(tableName)) + .build(); } } else { - throw new UndefinedTableException(databaseName); + return GetPartitionMethodResponse.newBuilder() + .setState(errUndefinedTable(tableName)) + .build(); } } else { - throw new UndefinedDatabaseException(databaseName); + return GetPartitionMethodResponse.newBuilder() + .setState(errUndefinedDatabase(tableName)) + .build(); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return GetPartitionMethodResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } @@ -817,7 +905,7 @@ public ReturnState existPartitionMethod(RpcController controller, TableIdentifie if (store.existPartitionMethod(databaseName, tableName)) { return OK; } else { - return ReturnStateUtil.errUndefinedPartitionMethod(tableName); + return errUndefinedPartitionMethod(tableName); } } else { return errUndefinedTable(tableName); @@ -840,97 +928,136 @@ public ReturnState dropPartitionMethod(RpcController controller, TableIdentifier } @Override - public PartitionDescProto getPartitionByPartitionName(RpcController controller, PartitionIdentifierProto request) + public GetPartitionDescResponse getPartitionByPartitionName(RpcController controller, PartitionIdentifierProto request) throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + String dbName = request.getDatabaseName(); + String tbName = request.getTableName(); String partitionName = request.getPartitionName(); - if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system databsae. It does not contain any partitioned tables."); + if (metaDictionary.isSystemDatabase(dbName)) { + throw new ServiceException(dbName + " is a system databsae. It does not contain any partitioned tables."); } rlock.lock(); try { boolean contain; - contain = store.existDatabase(databaseName); + contain = store.existDatabase(dbName); if (contain) { - contain = store.existTable(databaseName, tableName); + contain = store.existTable(dbName, tbName); if (contain) { - if (store.existPartitionMethod(databaseName, tableName)) { - PartitionDescProto partitionDesc = store.getPartition(databaseName, tableName, partitionName); - if (partitionDesc != null) { - return partitionDesc; - } else { - throw new UndefinedPartitionException(partitionName); - } + + if (store.existPartitionMethod(dbName, tbName)) { + PartitionDescProto partitionDesc = store.getPartition(dbName, tbName, partitionName); + + + return GetPartitionDescResponse.newBuilder() + .setState(OK) + .setPartition(partitionDesc) + .build(); + } else { - throw new NoPartitionedTableException(databaseName, tableName); + return GetPartitionDescResponse.newBuilder() + .setState(errUndefinedPartitionMethod(tbName)) + .build(); } } else { - throw new UndefinedTableException(tableName); + return GetPartitionDescResponse.newBuilder() + .setState(errUndefinedTable(tbName)) + .build(); } } else { - throw new UndefinedDatabaseException(databaseName); + return GetPartitionDescResponse.newBuilder() + .setState(errUndefinedDatabase(dbName)) + .build(); } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetPartitionDescResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public PartitionsProto getPartitionsByTableName(RpcController controller, PartitionIdentifierProto request) + public GetPartitionsResponse getPartitionsByTableName(RpcController controller, PartitionIdentifierProto request) throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + String dbName = request.getDatabaseName(); + String tbName = request.getTableName(); - if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system databsae. It does not contain any partitioned tables."); + if (metaDictionary.isSystemDatabase(dbName)) { + throw new ServiceException(dbName + " is a system databsae. It does not contain any partitioned tables."); } rlock.lock(); try { boolean contain; - contain = store.existDatabase(databaseName); + contain = store.existDatabase(dbName); if (contain) { - contain = store.existTable(databaseName, tableName); + contain = store.existTable(dbName, tbName); if (contain) { - if (store.existPartitionMethod(databaseName, tableName)) { - List partitions = store.getPartitions(databaseName, tableName); - PartitionsProto.Builder builder = PartitionsProto.newBuilder(); + if (store.existPartitionMethod(dbName, tbName)) { + List partitions = store.getPartitions(dbName, tbName); + + GetPartitionsResponse.Builder builder = GetPartitionsResponse.newBuilder(); for(PartitionDescProto partition : partitions) { builder.addPartition(partition); } + + builder.setState(OK); return builder.build(); + } else { - throw new NoPartitionedTableException(databaseName, tableName); + return GetPartitionsResponse.newBuilder() + .setState(errUndefinedPartitionMethod(tbName)) + .build(); } + } else { - throw new UndefinedTableException(tableName); + return GetPartitionsResponse.newBuilder() + .setState(errUndefinedTable(tbName)) + .build(); } } else { - throw new UndefinedDatabaseException(databaseName); + return GetPartitionsResponse.newBuilder() + .setState(errUndefinedDatabase(dbName)) + .build(); + } - } catch (Exception e) { - LOG.error(e); - throw new ServiceException(e); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetPartitionsResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public GetTablePartitionsProto getAllPartitions(RpcController controller, NullProto request) throws ServiceException { + public GetTablePartitionsResponse getAllPartitions(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); + try { - return GetTablePartitionsProto.newBuilder().addAllPart(store.getAllPartitions()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetTablePartitionsResponse.newBuilder() + .setState(OK) + .addAllPart(store.getAllPartitions()) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetTablePartitionsResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } @@ -1002,7 +1129,7 @@ public ReturnState existIndexByColumn(RpcController controller, GetIndexByColumn } @Override - public IndexDescProto getIndexByName(RpcController controller, IndexNameProto request) + public GetIndexResponse getIndexByName(RpcController controller, IndexNameProto request) throws ServiceException { String databaseName = request.getDatabaseName(); @@ -1010,20 +1137,32 @@ public IndexDescProto getIndexByName(RpcController controller, IndexNameProto re rlock.lock(); try { + if (!store.existIndexByName(databaseName, indexName)) { - throw new UndefinedIndexException(indexName); + return GetIndexResponse.newBuilder() + .setState(errUndefinedIndexName(indexName)) + .build(); } - return store.getIndexByName(databaseName, indexName); - } catch (Exception e) { - LOG.error("ERROR : cannot get index " + indexName, e); - return null; + + return GetIndexResponse.newBuilder() + .setState(OK) + .setIndex(store.getIndexByName(databaseName, indexName)) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetIndexResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } } @Override - public IndexDescProto getIndexByColumn(RpcController controller, GetIndexByColumnRequest request) + public GetIndexResponse getIndexByColumn(RpcController controller, GetIndexByColumnRequest request) throws ServiceException { TableIdentifierProto identifier = request.getTableIdentifier(); @@ -1034,12 +1173,23 @@ public IndexDescProto getIndexByColumn(RpcController controller, GetIndexByColum rlock.lock(); try { if (!store.existIndexByColumn(databaseName, tableName, columnName)) { - throw new UndefinedIndexException(columnName); + return GetIndexResponse.newBuilder() + .setState(errUndefinedIndex(tableName, columnName)) + .build(); } - return store.getIndexByColumn(databaseName, tableName, columnName); - } catch (Exception e) { - LOG.error("ERROR : cannot get index for " + tableName + "." + columnName, e); - return null; + + return GetIndexResponse.newBuilder() + .setState(OK) + .setIndex(store.getIndexByColumn(databaseName, tableName, columnName)) + .build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetIndexResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } @@ -1070,12 +1220,18 @@ public ReturnState dropIndex(RpcController controller, IndexNameProto request) { } @Override - public GetIndexesProto getAllIndexes(RpcController controller, NullProto request) throws ServiceException { + public GetIndexesResponse getAllIndexes(RpcController controller, NullProto request) throws ServiceException { rlock.lock(); try { - return GetIndexesProto.newBuilder().addAllIndex(store.getAllIndexes()).build(); - } catch (Exception e) { - throw new ServiceException(e); + return GetIndexesResponse.newBuilder().addAllIndex(store.getAllIndexes()).build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return GetIndexesResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { rlock.unlock(); } @@ -1245,21 +1401,38 @@ public ReturnState dropFunction(RpcController controller, UnregisterFunctionRequ } @Override - public FunctionDescProto getFunctionMeta(RpcController controller, GetFunctionMetaRequest request) - throws ServiceException { + public FunctionDescResponse getFunctionMeta(RpcController controller, GetFunctionMetaRequest request) { + FunctionDescProto function = null; - if (request.hasFunctionType()) { - if (containFunction(request.getSignature(), request.getFunctionType(), request.getParameterTypesList())) { - function = findFunction(request.getSignature(), request.getFunctionType(), request.getParameterTypesList(),true); + + try { + if (request.hasFunctionType()) { + if (containFunction(request.getSignature(), request.getFunctionType(), request.getParameterTypesList())) { + function = findFunction(request.getSignature(), request.getFunctionType(), request.getParameterTypesList(), true); + } + } else { + function = findFunction(request.getSignature(), request.getParameterTypesList()); } - } else { - function = findFunction(request.getSignature(), request.getParameterTypesList()); - } - if (function == null) { - throw new UndefinedFunctionException(request.getSignature(), request.getParameterTypesList()); - } else { - return function; + if (function != null) { + return FunctionDescResponse.newBuilder() + .setState(OK) + .setFunction(function) + .build(); + } else { + + return FunctionDescResponse.newBuilder() + .setState(errUndefinedFunction( + buildSimpleFunctionSignature(request.getSignature(), request.getParameterTypesList()))) + .build(); + } + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return FunctionDescResponse.newBuilder() + .setState(returnError(t)) + .build(); } } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java index 4d43691706..4b1c2c4b2c 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java @@ -38,6 +38,7 @@ import org.apache.tajo.exception.InternalException; import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.util.FileUtil; +import org.apache.tajo.util.KeyValueSet; import org.apache.tajo.util.Pair; import org.apache.tajo.util.TUtil; @@ -1792,7 +1793,7 @@ public List getAllTables() throws CatalogException { } @Override - public List getAllTableOptions() throws CatalogException { + public List getAllTableProperties() throws CatalogException { Connection conn = null; Statement stmt = null; ResultSet resultSet = null; diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java index 57ee74f88a..4ffedcfc62 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java @@ -32,6 +32,8 @@ import java.io.Closeable; import org.apache.tajo.catalog.exception.CatalogException; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.KeyValueProto; import java.util.Collection; import java.util.List; @@ -81,8 +83,8 @@ public interface CatalogStore extends Closeable { void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException; List getAllTables() throws CatalogException; - - List getAllTableOptions() throws CatalogException; + + List getAllTableProperties() throws CatalogException; List getAllTableStats() throws CatalogException; diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java index 1a3a1360ff..67c88c5198 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java @@ -441,7 +441,7 @@ public List getAllTables() throws CatalogException { } @Override - public List getAllTableOptions() throws CatalogException { + public List getAllTableProperties() throws CatalogException { List optionList = new ArrayList(); int tid = 0; diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index 337279c147..e6ba680a29 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -26,6 +26,7 @@ import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionDescProto; +import org.apache.tajo.exception.SQLExceptionUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.DropTableRequest; import org.apache.tajo.rpc.NettyClientBase; @@ -37,7 +38,7 @@ import java.util.List; import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; -import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; +import static org.apache.tajo.exception.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; public class CatalogAdminClientImpl implements CatalogAdminClient { 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 9c1c897112..80a49c2bae 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 @@ -27,6 +27,7 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Schema; import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.exception.SQLExceptionUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.QueryMasterClientProtocol; import org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; @@ -46,7 +47,7 @@ import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; import static org.apache.tajo.exception.ReturnStateUtil.returnError; -import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; +import static org.apache.tajo.exception.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.*; import static org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService; @@ -164,11 +165,11 @@ public ClientProtos.SubmitQueryResponse executeQuery(final String sql) throws SQ @Override public ClientProtos.SubmitQueryResponse executeQueryWithJson(final String json) throws SQLException { - final BlockingInterface tajoMasterService = conn.getTMStub(); + final BlockingInterface stub = conn.getTMStub(); final QueryRequest request = buildQueryRequest(json, true); try { - return tajoMasterService.submitQuery(null, request); + return stub.submitQuery(null, request); } catch (ServiceException e) { throw new RuntimeException(e); } 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 69c0651bad..788d193ab4 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 @@ -26,9 +26,12 @@ import org.apache.tajo.annotation.NotNull; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.auth.UserRoleInfo; +import org.apache.tajo.exception.SQLExceptionUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.SessionUpdateResponse; +import org.apache.tajo.ipc.ClientProtos.UpdateSessionVariableRequest; import org.apache.tajo.ipc.TajoMasterClientProtocol; +import org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService.BlockingInterface; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.RpcChannelFactory; import org.apache.tajo.rpc.RpcClientManager; @@ -53,8 +56,8 @@ import static org.apache.tajo.exception.ReturnStateUtil.isError; import static org.apache.tajo.exception.ReturnStateUtil.isSuccess; -import static org.apache.tajo.client.SQLExceptionUtil.toSQLException; -import static org.apache.tajo.client.SQLExceptionUtil.throwIfError; +import static org.apache.tajo.exception.SQLExceptionUtil.toSQLException; +import static org.apache.tajo.exception.SQLExceptionUtil.throwIfError; import static org.apache.tajo.ipc.ClientProtos.CreateSessionRequest; import static org.apache.tajo.ipc.ClientProtos.CreateSessionResponse; import static org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService; @@ -91,7 +94,7 @@ public class SessionConnection implements Closeable { * @param baseDatabase The base database name. It is case sensitive. If it is null, * the 'default' database will be used. * @param properties configurations - * @throws java.io.IOException + * @throws SQLException */ public SessionConnection(@NotNull ServiceTracker tracker, @Nullable String baseDatabase, @NotNull KeyValueSet properties) throws SQLException { @@ -138,10 +141,10 @@ public synchronized NettyClientBase getTajoMasterConnection() throws SQLExceptio } } - protected TajoMasterClientProtocolService.BlockingInterface getTMStub() throws SQLException { + protected BlockingInterface getTMStub() throws SQLException { NettyClientBase tmClient; tmClient = getTajoMasterConnection(); - TajoMasterClientProtocolService.BlockingInterface stub = tmClient.getStub(); + BlockingInterface stub = tmClient.getStub(); checkSessionAndGet(tmClient); return stub; } @@ -182,7 +185,7 @@ public String getCurrentDatabase() throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + BlockingInterface tajoMasterService = client.getStub(); StringResponse response; try { @@ -199,10 +202,10 @@ public Map updateSessionVariables(final Map vari NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + BlockingInterface tajoMasterService = client.getStub(); KeyValueSet keyValueSet = new KeyValueSet(); keyValueSet.putAll(variables); - ClientProtos.UpdateSessionVariableRequest request = ClientProtos.UpdateSessionVariableRequest.newBuilder() + UpdateSessionVariableRequest request = UpdateSessionVariableRequest.newBuilder() .setSessionId(sessionId) .setSessionVars(keyValueSet.getProto()).build(); @@ -223,18 +226,16 @@ public Map updateSessionVariables(final Map vari } public Map unsetSessionVariables(final List variables) throws SQLException { - NettyClientBase client = getTajoMasterConnection(); - checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - ClientProtos.UpdateSessionVariableRequest request = ClientProtos.UpdateSessionVariableRequest.newBuilder() + final BlockingInterface stub = getTMStub(); + final UpdateSessionVariableRequest request = UpdateSessionVariableRequest.newBuilder() .setSessionId(sessionId) - .addAllUnsetVariables(variables).build(); + .addAllUnsetVariables(variables) + .build(); SessionUpdateResponse response; - try { - response = tajoMasterService.updateSessionVariables(null, request); + response = stub.updateSessionVariables(null, request); } catch (ServiceException e) { throw new RuntimeException(e); } @@ -265,7 +266,7 @@ public String getSessionVariable(final String varname) throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + BlockingInterface stub = client.getStub(); try { return stub.getSessionVariable(null, getSessionedString(varname)).getValue(); @@ -276,10 +277,8 @@ public String getSessionVariable(final String varname) throws SQLException { } public Boolean existSessionVariable(final String varname) throws SQLException { - NettyClientBase client = getTajoMasterConnection(); - checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + BlockingInterface stub = getTMStub(); try { return isSuccess(stub.existSessionVariable(null, getSessionedString(varname))); } catch (ServiceException e) { @@ -291,7 +290,7 @@ public Map getAllSessionVariables() throws SQLException { NettyClientBase client = getTajoMasterConnection(); checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); + BlockingInterface stub = client.getStub(); KeyValueSetResponse response; try { response = stub.getAllSessionVariables(null, sessionId); @@ -304,11 +303,9 @@ public Map getAllSessionVariables() throws SQLException { } public Boolean selectDatabase(final String databaseName) throws SQLException { - NettyClientBase client = getTajoMasterConnection(); - checkSessionAndGet(client); - TajoMasterClientProtocolService.BlockingInterface stub = client.getStub(); - boolean selected = false; + BlockingInterface stub = getTMStub(); + boolean selected; try { selected = isSuccess(stub.selectDatabase(null, getSessionedString(databaseName))); } catch (ServiceException e) { @@ -331,7 +328,7 @@ public void close() { NettyClientBase client = null; try { client = getTajoMasterConnection(); - TajoMasterClientProtocolService.BlockingInterface tajoMaster = client.getStub(); + BlockingInterface tajoMaster = client.getStub(); tajoMaster.removeSession(null, sessionId); } catch (Throwable e) { // ignore @@ -356,7 +353,7 @@ protected void checkSessionAndGet(NettyClientBase client) throws SQLException { if (sessionId == null) { - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + BlockingInterface tajoMasterService = client.getStub(); CreateSessionRequest.Builder builder = CreateSessionRequest.newBuilder(); builder.setUsername(userInfo.getUserName()).build(); @@ -396,7 +393,7 @@ public boolean reconnect() throws Exception { NettyClientBase client = getTajoMasterConnection(); // create new session - TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); + BlockingInterface tajoMasterService = client.getStub(); CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); if (isError(response.getState())) { return false; @@ -418,7 +415,7 @@ public boolean reconnect() throws Exception { try { KeyValueSet keyValueSet = new KeyValueSet(); keyValueSet.putAll(sessionVarsCache); - ClientProtos.UpdateSessionVariableRequest request = ClientProtos.UpdateSessionVariableRequest.newBuilder() + UpdateSessionVariableRequest request = UpdateSessionVariableRequest.newBuilder() .setSessionId(sessionId) .setSessionVars(keyValueSet.getProto()).build(); diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java index 32ceaf9d25..862889eb04 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java @@ -27,7 +27,11 @@ import org.apache.tajo.exception.ErrorUtil; import org.apache.tajo.exception.ExceptionUtil; import org.apache.tajo.exception.TajoExceptionInterface; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; + +import java.util.Collection; public class ReturnStateUtil { @@ -39,6 +43,25 @@ public class ReturnStateUtil { OK = builder.build(); } + public static void ensureOk(ReturnState state) { + if (isError(state)) { + throw new TajoRuntimeException(state); + } + } + + public static StringListResponse returnStringList(Collection values) { + return StringListResponse.newBuilder() + .setState(OK) + .addAllValues(values) + .build(); + } + + public static StringListResponse returnFailedStringList(Throwable t) { + return StringListResponse.newBuilder() + .setState(returnError(t)) + .build(); + } + public static ReturnState returnError(ResultCode code) { ReturnState.Builder builder = ReturnState.newBuilder(); builder.setReturnCode(code); @@ -91,6 +114,10 @@ public static boolean isError(ReturnState state) { return ErrorUtil.isFailed(state.getReturnCode()); } + public static boolean isThisError(ReturnState state, ResultCode code) { + return state.getReturnCode() == code; + } + public static ReturnState errFeatureNotSupported(String feature) { return returnError(ResultCode.FEATURE_NOT_SUPPORTED, feature); } diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java similarity index 90% rename from tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java rename to tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java index fe4a5a59c4..10b5aff985 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SQLExceptionUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.tajo.client; +package org.apache.tajo.exception; import com.google.common.collect.Maps; import org.apache.tajo.error.Errors.ResultCode; @@ -40,6 +40,14 @@ public class SQLExceptionUtil { SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601"); } + public static boolean isThisError(SQLException e, ResultCode code) { + if (SQLSTATES.containsKey(code)) { + return e.getSQLState().equals(SQLSTATES.get(code)); + } else { + throw new TajoInternalError("Unknown error code: " + code.name()); + } + } + public static void throwIfError(ReturnState state) throws SQLException { if (isError(state)) { throw toSQLException(state); @@ -47,12 +55,15 @@ public static void throwIfError(ReturnState state) throws SQLException { } public static SQLException toSQLException(ReturnState state) throws SQLException { + if (SQLSTATES.containsKey(state.getReturnCode())) { + return new SQLException( state.getMessage(), SQLSTATES.get(state.getReturnCode()), state.getReturnCode().getNumber() ); + } else { // If there is no SQLState corresponding to error code, // It will make SQLState '42000' (Syntax Error Or Access Rule Violation). diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java index e29ce888d6..37ab2dec58 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java @@ -19,10 +19,16 @@ package org.apache.tajo.exception; import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; public class TajoRuntimeException extends RuntimeException implements TajoExceptionInterface { private ResultCode code; + public TajoRuntimeException(ReturnState state) { + super(state.getMessage()); + this.code = state.getReturnCode(); + } + public TajoRuntimeException(ResultCode code) { super(ErrorMessages.getMessage(code)); this.code = code; diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java index 0249daf2c4..0b50d4b4b1 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLSyntaxError.java @@ -21,6 +21,8 @@ import org.apache.tajo.error.Errors; import org.apache.tajo.exception.TajoRuntimeException; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; public class SQLSyntaxError extends TajoRuntimeException { private static final long serialVersionUID = 5388279335175632067L; 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 aa7ea4ad3b..60f7ca39a9 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 @@ -18,15 +18,13 @@ package org.apache.tajo.jdbc; import com.google.common.collect.Lists; -import com.google.protobuf.ServiceException; import org.apache.tajo.QueryId; import org.apache.tajo.SessionVars; -import org.apache.tajo.client.SQLExceptionUtil; +import org.apache.tajo.exception.SQLExceptionUtil; import org.apache.tajo.client.TajoClient; import org.apache.tajo.client.TajoClientUtil; import org.apache.tajo.ipc.ClientProtos; -import java.io.IOException; import java.sql.*; import java.util.HashMap; import java.util.Map; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java index 0ec485085c..453edd5263 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java @@ -30,7 +30,11 @@ import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.datum.*; +import org.apache.tajo.error.Errors; +import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.InvalidOperationException; +import org.apache.tajo.exception.SQLExceptionUtil; +import org.apache.tajo.function.FunctionUtil; import org.apache.tajo.plan.algebra.BaseAlgebraVisitor; import org.apache.tajo.plan.expr.*; import org.apache.tajo.plan.logical.NodeType; @@ -41,6 +45,7 @@ import org.apache.tajo.util.datetime.DateTimeUtil; import org.apache.tajo.util.datetime.TimeMeta; +import java.sql.SQLException; import java.util.Set; import java.util.Stack; import java.util.TimeZone; From 3a737dd446b3975f0eca6afabf8358686a3548fc Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 11:42:10 +0900 Subject: [PATCH 19/30] TAJO-1679: Client APIs should validate identifiers for database object names. --- .../org/apache/tajo/catalog/CatalogUtil.java | 31 +++++++++++++++++++ .../exception/InvalidNameException.java | 28 +++++++++++++++++ .../org/apache/tajo/util/StringUtils.java | 4 +++ .../apache/tajo/master/exec/DDLExecutor.java | 17 +++++++++- 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java index 638ebca6a0..e1e146feeb 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java @@ -51,6 +51,37 @@ public class CatalogUtil { public static final String TEXTFILE_NAME = "TEXT"; + + public static boolean isValidQualifiedIdentifier(String identifier) { + return isValidIdentifier(identifier, true); + } + + public static boolean isValidSimplIdentifier(String identifier) { + return isValidIdentifier(identifier, false); + } + + private static boolean isValidIdentifier(String identifier, boolean inclusiveDot) { + Preconditions.checkNotNull("isValidIdentifier cannot null value"); + + boolean valid = identifier.length() > 0; + valid &= StringUtils.isValidFirstIdentifierChar(identifier.charAt(0)); + + for (int i = 0; i < identifier.length(); i++) { + if (inclusiveDot) { + valid &= StringUtils.isPartOfAnsiSQLIdentifier(identifier.charAt(i)) || + identifier.charAt(i) == CatalogConstants.IDENTIFIER_DELIMITER_REGEXP.charAt(0); + } else { + valid &= StringUtils.isPartOfAnsiSQLIdentifier(identifier.charAt(i)); + } + + if (!valid) { + return false; + } + } + + return true; + } + /** * Normalize an identifier. Normalization means a translation from a identifier to be a refined identifier name. * diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java new file mode 100644 index 0000000000..6eb8eede2a --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java @@ -0,0 +1,28 @@ +/* + * Lisensed 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.catalog.exception; + + +public class InvalidNameException extends CatalogException { + public InvalidNameException() {} + + public InvalidNameException(String databaseName) { + super("ERROR: invalid name \"" + databaseName + "\""); + } +} diff --git a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java index 0a160725f7..50d720518e 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java @@ -92,6 +92,10 @@ public static String doubleQuote(String str) { return "\"" + str + "\""; } + public static boolean isValidFirstIdentifierChar(char character) { + return isLowerCaseAlphabet(character) || isUpperCaseAlphabet(character) || isUndersscore(character); + } + public static boolean isPartOfAnsiSQLIdentifier(char character) { return isLowerCaseAlphabet(character) || 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 7104412db2..af795081bd 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 @@ -145,6 +145,10 @@ public boolean createDatabase(@Nullable QueryContext queryContext, String databa tablespaceName = tablespace; } + if (!CatalogUtil.isValidSimplIdentifier(databaseName)) { + throw new InvalidNameException(databaseName); + } + // CREATE DATABASE IF NOT EXISTS boolean exists = catalog.existDatabase(databaseName); if (exists) { @@ -192,8 +196,8 @@ public boolean dropDatabase(QueryContext queryContext, String databaseName, bool //-------------------------------------------------------------------------- private TableDesc createTable(QueryContext queryContext, CreateTableNode createTable, boolean ifNotExists) throws IOException { - TableMeta meta; + TableMeta meta; if (createTable.hasOptions()) { meta = CatalogUtil.newTableMeta(createTable.getStorageType(), createTable.getOptions()); } else { @@ -226,6 +230,17 @@ public TableDesc createTable(QueryContext queryContext, boolean isExternal, @Nullable PartitionMethodDesc partitionDesc, boolean ifNotExists) throws IOException { + + // Validate identifiers + if (!CatalogUtil.isValidQualifiedIdentifier(tableName)) { + throw new InvalidNameException(tableName); + } + for (Column c :schema.getAllColumns()) { + if (!CatalogUtil.isValidQualifiedIdentifier(c.getQualifiedName())) { + throw new InvalidNameException(tableName); + } + } + String databaseName; String simpleTableName; if (CatalogUtil.isFQTableName(tableName)) { From 76c5d146fb8a2dd20f90a0207369c5f025eff629 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 14:29:52 +0900 Subject: [PATCH 20/30] Add some unit tests. --- .../exception/InvalidNameException.java | 5 +- .../apache/tajo/exception/ErrorMessages.java | 77 ++++++------- tajo-common/src/main/proto/errors.proto | 20 ++-- .../tajo/client/TestTajoClientFailures.java | 104 ++++++++++++++++++ 4 files changed, 158 insertions(+), 48 deletions(-) create mode 100644 tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java index 6eb8eede2a..16927778f4 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidNameException.java @@ -19,10 +19,11 @@ package org.apache.tajo.catalog.exception; +import org.apache.tajo.error.Errors; + public class InvalidNameException extends CatalogException { - public InvalidNameException() {} public InvalidNameException(String databaseName) { - super("ERROR: invalid name \"" + databaseName + "\""); + super(Errors.ResultCode.INVALID_NAME, databaseName); } } 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 00840bcd8a..3f672500e6 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 @@ -24,6 +24,8 @@ import java.util.Map; +import static org.apache.tajo.error.Errors.ResultCode.*; + public class ErrorMessages { public static final Map> MESSAGES; @@ -33,57 +35,58 @@ public class ErrorMessages { // Warnings // General Errors - ADD_MESSAGE(ResultCode.INTERNAL_ERROR, "internal error: %s", 1); - ADD_MESSAGE(ResultCode.NOT_IMPLEMENTED, "not implemented feature: %s", 1); - ADD_MESSAGE(ResultCode.FEATURE_NOT_SUPPORTED, "unsupported feature: %s", 1); - ADD_MESSAGE(ResultCode.INVALID_RPC_CALL, "invalid RPC Call: %s", 1); + ADD_MESSAGE(INTERNAL_ERROR, "internal error: %s", 1); + ADD_MESSAGE(NOT_IMPLEMENTED, "not implemented feature: %s", 1); + ADD_MESSAGE(FEATURE_NOT_SUPPORTED, "unsupported feature: %s", 1); + ADD_MESSAGE(INVALID_RPC_CALL, "invalid RPC Call: %s", 1); // Query Management and Scheduler - ADD_MESSAGE(ResultCode.NO_SUCH_QUERYID, "query %s does not exist", 1); - ADD_MESSAGE(ResultCode.NO_DATA, "no data for %s due to query failure or error", 1); - ADD_MESSAGE(ResultCode.INCOMPLETE_QUERY, "query %s is stilling running", 1); + ADD_MESSAGE(NO_SUCH_QUERYID, "query %s does not exist", 1); + ADD_MESSAGE(NO_DATA, "no data for %s due to query failure or error", 1); + ADD_MESSAGE(INCOMPLETE_QUERY, "query %s is stilling running", 1); // Session - ADD_MESSAGE(ResultCode.INVALID_SESSION, "invalid Session '%s'", 1); - ADD_MESSAGE(ResultCode.NO_SUCH_SESSION_VARIABLE, "no such session variable '%s", 1); - ADD_MESSAGE(ResultCode.INVALID_SESSION_VARIABLE, "invalid session variable '%s': %s", 2); + ADD_MESSAGE(INVALID_SESSION, "invalid Session '%s'", 1); + ADD_MESSAGE(NO_SUCH_SESSION_VARIABLE, "no such session variable '%s", 1); + ADD_MESSAGE(INVALID_SESSION_VARIABLE, "invalid session variable '%s': %s", 2); - ADD_MESSAGE(ResultCode.SYNTAX_ERROR, "%s", 1); - ADD_MESSAGE(ResultCode.INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s"); + ADD_MESSAGE(SYNTAX_ERROR, "%s", 1); + ADD_MESSAGE(INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s"); + ADD_MESSAGE(INVALID_NAME, "Invalid name '%s'"); - ADD_MESSAGE(ResultCode.UNDEFINED_TABLESPACE, "tablespace '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_DATABASE, "database '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_SCHEMA, "schema '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_TABLE, "relation '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_COLUMN, "column '%s' does not exist", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_FUNCTION, "function does not exist: %s", 1); - ADD_MESSAGE(ResultCode.UNDEFINED_OPERATOR, "operator does not exist: '%s'", 1); + ADD_MESSAGE(UNDEFINED_TABLESPACE, "tablespace '%s' does not exist", 1); + ADD_MESSAGE(UNDEFINED_DATABASE, "database '%s' does not exist", 1); + ADD_MESSAGE(UNDEFINED_SCHEMA, "schema '%s' does not exist", 1); + ADD_MESSAGE(UNDEFINED_TABLE, "relation '%s' does not exist", 1); + ADD_MESSAGE(UNDEFINED_COLUMN, "column '%s' does not exist", 1); + ADD_MESSAGE(UNDEFINED_FUNCTION, "function does not exist: %s", 1); + ADD_MESSAGE(UNDEFINED_OPERATOR, "operator does not exist: '%s'", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_TABLESPACE, "tablespace '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_DATABASE, "database '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_SCHEMA, "schema '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_TABLE, "table '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_COLUMN, "column '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_ALIAS, "table name '%s' specified more than once", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_INDEX, "index '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DUPLICATE_PARTITION, "partition '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_TABLESPACE, "tablespace '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_DATABASE, "database '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_SCHEMA, "schema '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_TABLE, "table '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_COLUMN, "column '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_ALIAS, "table name '%s' specified more than once", 1); + ADD_MESSAGE(DUPLICATE_INDEX, "index '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_PARTITION, "partition '%s' already exists", 1); - ADD_MESSAGE(ResultCode.DIVISION_BY_ZERO, "Division by zero: %s", 1); + ADD_MESSAGE(DIVISION_BY_ZERO, "Division by zero: %s", 1); - ADD_MESSAGE(ResultCode.DATATYPE_MISMATCH, + ADD_MESSAGE(DATATYPE_MISMATCH, "column \"%s\" is of type %s but expression %s is of type %s", 4); - ADD_MESSAGE(ResultCode.SET_OPERATION_SCHEMA_MISMATCH, "each %s query must have the same number of columns", 1); - ADD_MESSAGE(ResultCode.SET_OPERATION_DATATYPE_MISMATCH, "%s types %s and %s cannot be matched"); + ADD_MESSAGE(SET_OPERATION_SCHEMA_MISMATCH, "each %s query must have the same number of columns", 1); + ADD_MESSAGE(SET_OPERATION_DATATYPE_MISMATCH, "%s types %s and %s cannot be matched"); - ADD_MESSAGE(ResultCode.CAT_UPGRADE_REQUIRED, "catalog must be upgraded"); - ADD_MESSAGE(ResultCode.CAT_CANNOT_CONNECT, "cannot connect metadata store '%s': %s", 2); + ADD_MESSAGE(CAT_UPGRADE_REQUIRED, "catalog must be upgraded"); + ADD_MESSAGE(CAT_CANNOT_CONNECT, "cannot connect metadata store '%s': %s", 2); - ADD_MESSAGE(ResultCode.TMC_NO_MATCHED_DATATYPE, "no matched type for %s", 1); + ADD_MESSAGE(TMC_NO_MATCHED_DATATYPE, "no matched type for %s", 1); - ADD_MESSAGE(ResultCode.UNKNOWN_DATAFORMAT, "Unknown data format: '%s'", 1); + ADD_MESSAGE(UNKNOWN_DATAFORMAT, "Unknown data format: '%s'", 1); } private static void ADD_MESSAGE(ResultCode code, String msgFormat) { @@ -95,12 +98,12 @@ private static void ADD_MESSAGE(ResultCode code, String msgFormat, int argNum) { } public static String getInternalErrorMessage() { - return MESSAGES.get(ResultCode.INTERNAL_ERROR).getFirst(); + return MESSAGES.get(INTERNAL_ERROR).getFirst(); } public static String getInternalErrorMessage(Throwable t) { if (t.getMessage() != null) { - return MESSAGES.get(ResultCode.INTERNAL_ERROR).getFirst() + ": " + t.getMessage(); + return MESSAGES.get(INTERNAL_ERROR).getFirst() + ": " + t.getMessage(); } else { return getInternalErrorMessage(); } diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index 06c688cc2b..87e2f311e3 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -21,6 +21,8 @@ option java_package = "org.apache.tajo.error"; import "stacktrace.proto"; +// Unstable - this is still evolving. + enum ResultCode { // Class // 00 - Successful Completion @@ -47,8 +49,12 @@ enum ResultCode { // Data Exception (SQLState Class - 22) DIVISION_BY_ZERO = 451; // SQLState: 22012 - Division by zero - // Query and Catalog Errors + // Section: Class 42 - Syntax Error or Access Rule Violation + SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 601; // SQLState: 42000 + SYNTAX_ERROR = 602; // SQLState: 42601 + INSUFFICIENT_PRIVILEGE = 603; // SQLState: 42501 + UNDEFINED_TABLESPACE = 500; // ? UNDEFINED_DATABASE = 501; // ? UNDEFINED_SCHEMA = 502; // ? @@ -75,25 +81,21 @@ enum ResultCode { AMBIGUOUS_COLUMN = 522; // SQLState: 42702; AMBIGUOUS_FUNCTION = 523; // SQLState: 42725; - // Section: Syntax Error or Access Rule Violation - SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 601; // SQLState: 42000 - SYNTAX_ERROR = 602; // SQLState: 42601 - INSUFFICIENT_PRIVILEGE = 603; // SQLState: 42501 CANNOT_CAST = 604; // SQLState: 42846 - Cast from source type to target type is not supported. GROUPING_ERROR = 605; // SQLState: 42803 WINDOWING_ERROR = 606; // SQLState: 42P20 - PgSQL implementation-defined INVALID_RECURSION = 607; // SQLState: 42P19 - PgSQL implementation-defined SET_OPERATION_SCHEMA_MISMATCH = 608; // SQLState: 42601 (=SYNTAX_ERROR) SET_OPERATION_DATATYPE_MISMATCH = 609; // SQLState: 42601 (=SYNTAX_ERROR) - INVALID_FOREIGN_KEY = 621; // SQLState: 42830 INVALID_NAME = 622; // SQLState: 42602 + INVALID_COLUMN_DEFINITION = 631; // SQLState: 42611 NAME_TOO_LONG = 623; // SQLState: 42622 RESERVED_NAME = 624; // SQLState: 42939 - DATATYPE_MISMATCH = 625; // SQLState: 42804; - INDETERMINATE_DATATYPE = 626; // SQLState: 42P18; - PgSQL implementation -defined + DATATYPE_MISMATCH = 625; // SQLState: 42804 + INDETERMINATE_DATATYPE = 626; // SQLState: 42P18 - PgSQL implementation -defined + - INVALID_COLUMN_DEFINITION = 631; // SQLState: 42611; // Expressions INVALID_EXPRESSION = 701; diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java new file mode 100644 index 0000000000..1b37a4f467 --- /dev/null +++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java @@ -0,0 +1,104 @@ +/** + * 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.client; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.jcip.annotations.NotThreadSafe; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.tajo.*; +import org.apache.tajo.TajoProtos.QueryState; +import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.catalog.FunctionDesc; +import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.ErrorUtil; +import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.QueryHistoryProto; +import org.apache.tajo.ipc.ClientProtos.QueryInfoProto; +import org.apache.tajo.ipc.ClientProtos.StageHistoryProto; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; +import org.apache.tajo.storage.StorageConstants; +import org.apache.tajo.storage.StorageUtil; +import org.apache.tajo.util.CommonTestingUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +import static org.junit.Assert.*; + +@Category(IntegrationTest.class) +@NotThreadSafe +public class TestTajoClientFailures { + private static TajoTestingCluster cluster; + private static TajoConf conf; + private static TajoClient client; + private static Path testDir; + + @BeforeClass + public static void setUp() throws Exception { + cluster = TpchTestBase.getInstance().getTestingCluster(); + conf = cluster.getConfiguration(); + client = cluster.newTajoClient(); + testDir = CommonTestingUtil.getTestDir(); + } + + @AfterClass + public static void tearDown() throws Exception { + client.close(); + } + + @Test + public final void testCreateDatabase() throws SQLException { + assertFalse(client.createDatabase("12345")); // invalid name + assertFalse(client.createDatabase("default")); // duplicate database + + assertFalse(client.dropDatabase("default")); // duplicate database + } + + @Test + public final void testDropDatabase() throws SQLException { + assertFalse(client.dropDatabase("unknown-database")); // duplicate database + } + + @Test + public void testExecuteSQL() throws SQLException { + // This is just an error propagation unit test. Specified SQL errors will be addressed in other unit tests. + ReturnState state = client.executeQuery("select * from unknown_table").getState(); + assertEquals(Errors.ResultCode.UNDEFINED_TABLE, state.getReturnCode()); + + state = client.executeQuery("create table default.lineitem (name int);").getState(); + assertEquals(Errors.ResultCode.DUPLICATE_TABLE, state.getReturnCode()); + } +} From d16ce4613702201b019bcad96a834c12580ecd71 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 14:37:33 +0900 Subject: [PATCH 21/30] Removed TAJO-1679. --- .../org/apache/tajo/catalog/CatalogUtil.java | 30 ------------------- .../org/apache/tajo/util/StringUtils.java | 4 --- .../apache/tajo/master/exec/DDLExecutor.java | 14 --------- 3 files changed, 48 deletions(-) diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java index 43819a7f4e..809547992e 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java @@ -53,36 +53,6 @@ public class CatalogUtil { public static final String TEXTFILE_NAME = "TEXT"; - public static boolean isValidQualifiedIdentifier(String identifier) { - return isValidIdentifier(identifier, true); - } - - public static boolean isValidSimplIdentifier(String identifier) { - return isValidIdentifier(identifier, false); - } - - private static boolean isValidIdentifier(String identifier, boolean inclusiveDot) { - Preconditions.checkNotNull("isValidIdentifier cannot null value"); - - boolean valid = identifier.length() > 0; - valid &= StringUtils.isValidFirstIdentifierChar(identifier.charAt(0)); - - for (int i = 0; i < identifier.length(); i++) { - if (inclusiveDot) { - valid &= StringUtils.isPartOfAnsiSQLIdentifier(identifier.charAt(i)) || - identifier.charAt(i) == CatalogConstants.IDENTIFIER_DELIMITER_REGEXP.charAt(0); - } else { - valid &= StringUtils.isPartOfAnsiSQLIdentifier(identifier.charAt(i)); - } - - if (!valid) { - return false; - } - } - - return true; - } - /** * Normalize an identifier. Normalization means a translation from a identifier to be a refined identifier name. * diff --git a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java index 50d720518e..0a160725f7 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java @@ -92,10 +92,6 @@ public static String doubleQuote(String str) { return "\"" + str + "\""; } - public static boolean isValidFirstIdentifierChar(char character) { - return isLowerCaseAlphabet(character) || isUpperCaseAlphabet(character) || isUndersscore(character); - } - public static boolean isPartOfAnsiSQLIdentifier(char character) { return isLowerCaseAlphabet(character) || 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 e950537e72..80ac544d5d 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 @@ -146,10 +146,6 @@ public boolean createDatabase(@Nullable QueryContext queryContext, String databa tablespaceName = tablespace; } - if (!CatalogUtil.isValidSimplIdentifier(databaseName)) { - throw new InvalidNameException(databaseName); - } - // CREATE DATABASE IF NOT EXISTS boolean exists = catalog.existDatabase(databaseName); if (exists) { @@ -232,16 +228,6 @@ public TableDesc createTable(QueryContext queryContext, @Nullable PartitionMethodDesc partitionDesc, boolean ifNotExists) throws IOException { - // Validate identifiers - if (!CatalogUtil.isValidQualifiedIdentifier(tableName)) { - throw new InvalidNameException(tableName); - } - for (Column c :schema.getAllColumns()) { - if (!CatalogUtil.isValidQualifiedIdentifier(c.getQualifiedName())) { - throw new InvalidNameException(tableName); - } - } - String databaseName; String simpleTableName; if (CatalogUtil.isFQTableName(tableName)) { From deb8a2b7459becbffc4797fc0795bce5e09b6da8 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 15:31:36 +0900 Subject: [PATCH 22/30] Fixed undefined function exception test. --- .../tajo/catalog/AbstractCatalogClient.java | 25 ++++++++++++------- .../exception/DuplicateFunctionException.java | 7 ++++-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index a5adfa0ceb..72eeb0966f 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -24,6 +24,7 @@ import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService.BlockingInterface; import org.apache.tajo.catalog.CatalogProtocol.*; +import org.apache.tajo.catalog.exception.DuplicateFunctionException; import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos.*; @@ -652,20 +653,26 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT builder.addParameterTypes(type); } + FunctionDescResponse response = null; try { final BlockingInterface stub = getStub(); - final FunctionDescResponse response = stub.getFunctionMeta(null, builder.build()); + response = stub.getFunctionMeta(null, builder.build()); + } catch (ServiceException se) { + throw new RuntimeException(se); + } - if (isThisError(response.getState(), ResultCode.UNDEFINED_FUNCTION)) { - throw new UndefinedFunctionException(signature, paramTypes); - } - ensureOk(response.getState()); + if (isThisError(response.getState(), ResultCode.UNDEFINED_FUNCTION)) { + throw new UndefinedFunctionException(signature, paramTypes); + } else if (isThisError(response.getState(), ResultCode.AMBIGUOUS_FUNCTION)) { + throw new DuplicateFunctionException(signature, paramTypes); + } - return new FunctionDesc(response.getFunction()); + ensureOk(response.getState()); - } catch (Throwable t) { - printStackTraceIfError(LOG, t); - throw new RuntimeException(t); + try { + return new FunctionDesc(response.getFunction()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java index 4daa7c711b..b5cde13164 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/DuplicateFunctionException.java @@ -18,12 +18,15 @@ package org.apache.tajo.catalog.exception; +import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.error.Errors; +import static org.apache.tajo.function.FunctionUtil.buildSimpleFunctionSignature; + public class DuplicateFunctionException extends CatalogException { private static final long serialVersionUID = 3224521585413794703L; - public DuplicateFunctionException(String funcName) { - super(Errors.ResultCode.DUPLICATE_FUNCTION, funcName); + public DuplicateFunctionException(String funcName, DataType[] parameters) { + super(Errors.ResultCode.DUPLICATE_FUNCTION, buildSimpleFunctionSignature(funcName, parameters)); } } From 5d2a9980cadd04964197281b5448367cea7305a0 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 15:39:45 +0900 Subject: [PATCH 23/30] Removed unnecessary html tag. --- .../java/org/apache/tajo/catalog/AbstractCatalogClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index 72eeb0966f..f4274e07d9 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -6,9 +6,9 @@ * 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. From 215b22847aebe59e99e9c0a576dd3b2187305826 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 16:27:56 +0900 Subject: [PATCH 24/30] Fixed wrong unit tests. --- .../java/org/apache/tajo/catalog/AbstractCatalogClient.java | 3 +-- .../java/org/apache/tajo/client/TestTajoClientFailures.java | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index f4274e07d9..9034b0c370 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -7,7 +7,7 @@ * "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 + * 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, @@ -41,7 +41,6 @@ import java.util.List; import static org.apache.tajo.catalog.CatalogUtil.buildTableIdentifier; -import static org.apache.tajo.exception.ExceptionUtil.printStackTraceIfError; import static org.apache.tajo.exception.ReturnStateUtil.*; /** diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java index 1b37a4f467..314893ad98 100644 --- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java +++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java @@ -83,8 +83,6 @@ public static void tearDown() throws Exception { public final void testCreateDatabase() throws SQLException { assertFalse(client.createDatabase("12345")); // invalid name assertFalse(client.createDatabase("default")); // duplicate database - - assertFalse(client.dropDatabase("default")); // duplicate database } @Test From 85c00b08f2bb5f4687239e717d827543d14518c8 Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 20:31:39 +0900 Subject: [PATCH 25/30] Fixed wrong unit tests. --- .../test/java/org/apache/tajo/client/TestTajoClientFailures.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java index 314893ad98..6f7b9cf306 100644 --- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java +++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java @@ -81,7 +81,6 @@ public static void tearDown() throws Exception { @Test public final void testCreateDatabase() throws SQLException { - assertFalse(client.createDatabase("12345")); // invalid name assertFalse(client.createDatabase("default")); // duplicate database } From ccc44cd286accc65f5247f4e7edec5a56dcc3cdb Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 13 Jul 2015 20:38:37 +0900 Subject: [PATCH 26/30] Add more unit tests. --- .../tajo/client/TestTajoClientFailures.java | 45 +++++-------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java index 6f7b9cf306..d482ccf0c4 100644 --- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java +++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java @@ -18,60 +18,32 @@ package org.apache.tajo.client; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import net.jcip.annotations.NotThreadSafe; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.fs.FileStatus; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.Path; -import org.apache.tajo.*; -import org.apache.tajo.TajoProtos.QueryState; -import org.apache.tajo.catalog.CatalogUtil; -import org.apache.tajo.catalog.FunctionDesc; -import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.catalog.proto.CatalogProtos; -import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.IntegrationTest; +import org.apache.tajo.TajoTestingCluster; +import org.apache.tajo.TpchTestBase; import org.apache.tajo.error.Errors; -import org.apache.tajo.exception.ErrorUtil; -import org.apache.tajo.ipc.ClientProtos; -import org.apache.tajo.ipc.ClientProtos.QueryHistoryProto; -import org.apache.tajo.ipc.ClientProtos.QueryInfoProto; -import org.apache.tajo.ipc.ClientProtos.StageHistoryProto; -import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; -import org.apache.tajo.storage.StorageConstants; -import org.apache.tajo.storage.StorageUtil; -import org.apache.tajo.util.CommonTestingUtil; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.io.IOException; -import java.io.InputStream; -import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; @Category(IntegrationTest.class) @NotThreadSafe public class TestTajoClientFailures { private static TajoTestingCluster cluster; - private static TajoConf conf; private static TajoClient client; - private static Path testDir; @BeforeClass public static void setUp() throws Exception { cluster = TpchTestBase.getInstance().getTestingCluster(); - conf = cluster.getConfiguration(); client = cluster.newTajoClient(); - testDir = CommonTestingUtil.getTestDir(); } @AfterClass @@ -86,7 +58,12 @@ public final void testCreateDatabase() throws SQLException { @Test public final void testDropDatabase() throws SQLException { - assertFalse(client.dropDatabase("unknown-database")); // duplicate database + assertFalse(client.dropDatabase("unknown-database")); // unknown database + } + + @Test + public final void testDropTable() throws SQLException { + assertFalse(client.dropTable("unknown-table")); // unknown table } @Test From db6370ee23bd95b916eeebb1bfe3440bde1ad5df Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Tue, 14 Jul 2015 15:51:07 +0900 Subject: [PATCH 27/30] Removed unused imports. --- .../java/org/apache/tajo/client/TestTajoClientFailures.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java index d482ccf0c4..d43f61c4f6 100644 --- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java +++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClientFailures.java @@ -19,7 +19,6 @@ package org.apache.tajo.client; import net.jcip.annotations.NotThreadSafe; -import org.apache.tajo.IntegrationTest; import org.apache.tajo.TajoTestingCluster; import org.apache.tajo.TpchTestBase; import org.apache.tajo.error.Errors; @@ -27,14 +26,12 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.experimental.categories.Category; import java.sql.SQLException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -@Category(IntegrationTest.class) @NotThreadSafe public class TestTajoClientFailures { private static TajoTestingCluster cluster; From 9be741b5a1229c81a1f0117a45b38c0e49eb425f Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 20 Jul 2015 12:45:45 +0900 Subject: [PATCH 28/30] Reflected comments. --- .../tajo/catalog/AbstractCatalogClient.java | 9 +- .../src/main/proto/CatalogProtocol.proto | 18 +- .../exception/AmbiguousFunctionException.java | 31 +++ .../exception/CatalogExceptionUtil.java | 22 +-- ....java => MetadataConnectionException.java} | 4 +- .../src/main/proto/CatalogProtos.proto | 15 ++ .../tajo/catalog/store/HiveCatalogUtil.java | 4 +- .../apache/tajo/catalog/CatalogServer.java | 25 +-- .../tajo/catalog/store/AbstractDBStore.java | 3 +- .../tajo/client/CatalogAdminClientImpl.java | 14 +- tajo-client/src/main/proto/ClientProtos.proto | 11 -- .../main/proto/TajoMasterClientProtocol.proto | 2 +- .../apache/tajo/exception/ErrorMessages.java | 2 +- .../apache/tajo/exception/TajoException.java | 4 + .../exception/TajoExceptionInterface.java | 6 + .../tajo/exception/TajoInternalError.java | 4 - .../tajo/exception/TajoRuntimeException.java | 5 + tajo-common/src/main/proto/errors.proto | 177 +++++++++--------- .../tajo/master/TajoMasterClientService.java | 14 +- .../plan/verifier/PreLogicalPlanVerifier.java | 12 -- 20 files changed, 198 insertions(+), 184 deletions(-) create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java rename tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/{TMCConnectionException.java => MetadataConnectionException.java} (89%) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index 9034b0c370..62485ba7fa 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -24,6 +24,7 @@ import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService.BlockingInterface; import org.apache.tajo.catalog.CatalogProtocol.*; +import org.apache.tajo.catalog.exception.AmbiguousFunctionException; import org.apache.tajo.catalog.exception.DuplicateFunctionException; import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; @@ -118,7 +119,7 @@ public List getAllTablespaces() { try { final BlockingInterface stub = getStub(); - final GetTablespacesResponse response = stub.getAllTablespaces(null, ProtoUtil.NULL_PROTO); + final GetTablespaceListResponse response = stub.getAllTablespaces(null, ProtoUtil.NULL_PROTO); ensureOk(response.getState()); return response.getTablespaceList(); @@ -236,7 +237,7 @@ public final TableDesc getTableDesc(final String databaseName, final String tabl final BlockingInterface stub = getStub(); final TableIdentifierProto request = buildTableIdentifier(databaseName, tableName); - TableDescResponse response = stub.getTableDesc(null, request); + TableResponse response = stub.getTableDesc(null, request); ensureOk(response.getState()); return CatalogUtil.newTableDesc(response.getTable()); @@ -652,7 +653,7 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT builder.addParameterTypes(type); } - FunctionDescResponse response = null; + FunctionResponse response = null; try { final BlockingInterface stub = getStub(); response = stub.getFunctionMeta(null, builder.build()); @@ -663,7 +664,7 @@ public final FunctionDesc getFunction(final String signature, FunctionType funcT if (isThisError(response.getState(), ResultCode.UNDEFINED_FUNCTION)) { throw new UndefinedFunctionException(signature, paramTypes); } else if (isThisError(response.getState(), ResultCode.AMBIGUOUS_FUNCTION)) { - throw new DuplicateFunctionException(signature, paramTypes); + throw new AmbiguousFunctionException(signature, paramTypes); } ensureOk(response.getState()); diff --git a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto index 6bca573faa..8d0eef659b 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto +++ b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto @@ -24,7 +24,7 @@ option java_generate_equals_and_hash = true; import "CatalogProtos.proto"; import "PrimitiveProtos.proto"; -message GetTablespacesResponse { +message GetTablespaceListResponse { required ReturnState state = 1; repeated TablespaceProto tablespace = 2; } @@ -39,21 +39,11 @@ message GetDatabasesResponse { repeated DatabaseProto database = 2; } -message TableDescResponse { - required ReturnState state = 1; - optional TableDescProto table = 2; -} - message GetTablesResponse { required ReturnState state = 1; repeated TableDescriptorProto table = 2; } -message FunctionDescResponse { - required ReturnState state = 1; - optional FunctionDescProto function = 2; -} - message GetTablePropertiesResponse { required ReturnState state = 1; repeated TableOptionProto properties = 2; @@ -104,7 +94,7 @@ service CatalogProtocolService { rpc createTablespace(CreateTablespaceRequest) returns (ReturnState); rpc dropTablespace(StringProto) returns (ReturnState); rpc existTablespace(StringProto) returns (ReturnState); - rpc getAllTablespaces(NullProto) returns (GetTablespacesResponse); + rpc getAllTablespaces(NullProto) returns (GetTablespaceListResponse); rpc getAllTablespaceNames(NullProto) returns (StringListResponse); rpc getTablespace(StringProto) returns (GetTablespaceResponse); rpc alterTablespace(AlterTablespaceProto) returns (ReturnState); @@ -120,7 +110,7 @@ service CatalogProtocolService { rpc createTable(TableDescProto) returns (ReturnState); rpc dropTable(TableIdentifierProto) returns (ReturnState); rpc existsTable(TableIdentifierProto) returns (ReturnState); - rpc getTableDesc(TableIdentifierProto) returns (TableDescResponse); + rpc getTableDesc(TableIdentifierProto) returns (TableResponse); rpc getAllTableNames(StringProto) returns (StringListResponse); rpc getAllTables(NullProto) returns (GetTablesResponse); rpc getAllTableProperties(NullProto) returns (GetTablePropertiesResponse); @@ -146,6 +136,6 @@ service CatalogProtocolService { rpc createFunction(FunctionDescProto) returns (ReturnState); rpc dropFunction(UnregisterFunctionRequest) returns (ReturnState); rpc getFunctions(NullProto) returns (GetFunctionsResponse); - rpc getFunctionMeta(GetFunctionMetaRequest) returns (FunctionDescResponse); + rpc getFunctionMeta(GetFunctionMetaRequest) returns (FunctionResponse); rpc containFunction(ContainFunctionRequest) returns (ReturnState); } \ No newline at end of file diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java new file mode 100644 index 0000000000..2f7de9b4ca --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java @@ -0,0 +1,31 @@ +/** + * 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.catalog.exception; + +import org.apache.tajo.common.TajoDataTypes.DataType; +import org.apache.tajo.error.Errors; + +import static org.apache.tajo.function.FunctionUtil.buildSimpleFunctionSignature; + +public class AmbiguousFunctionException extends CatalogException { + + public AmbiguousFunctionException(String funcName, DataType[] parameters) { + super(Errors.ResultCode.AMBIGUOUS_FUNCTION, buildSimpleFunctionSignature(funcName, parameters)); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java index 5a3c73c1ec..182a3f519c 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogExceptionUtil.java @@ -27,24 +27,6 @@ public class CatalogExceptionUtil { - public static CatalogException makeUndefinedDatabase(String dbName) { - return new CatalogException(ResultCode.UNDEFINED_DATABASE, dbName); - } - - public static CatalogException makeUndefinedFunction(String signature) { - return new CatalogException(ResultCode.UNDEFINED_FUNCTION, signature); - } - - public static CatalogException makeUndefinedFunction(String funcName, TajoDataTypes.DataType[] parameters) { - return new CatalogException(ResultCode.UNDEFINED_FUNCTION, - FunctionUtil.buildSimpleFunctionSignature(funcName, parameters)); - } - - public static CatalogException makeUndefinedFunction(String funcName, Collection parameters) { - return new CatalogException( - ResultCode.UNDEFINED_FUNCTION, FunctionUtil.buildSimpleFunctionSignature(funcName, parameters)); - } - public static CatalogException makeUndefinedTable(String tbName) { return new CatalogException(ResultCode.UNDEFINED_TABLE, tbName); } @@ -57,7 +39,7 @@ public static CatalogException makeCatalogUpgrade() { return new CatalogException(ResultCode.CAT_UPGRADE_REQUIRED); } - public static CatalogException makeTMCNoMatchedDataType(String dataType) { - return new CatalogException(ResultCode.TMC_NO_MATCHED_DATATYPE, dataType); + public static CatalogException makeMDCNoMatchedDataType(String dataType) { + return new CatalogException(ResultCode.MDC_NO_MATCHED_DATATYPE, dataType); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/MetadataConnectionException.java similarity index 89% rename from tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java rename to tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/MetadataConnectionException.java index b3a536e5fb..e155bf1fad 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/TMCConnectionException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/MetadataConnectionException.java @@ -24,9 +24,9 @@ /** * Tajo Metadata Connector's connection error */ -public class TMCConnectionException extends TajoError { +public class MetadataConnectionException extends TajoError { - public TMCConnectionException(String uri, Throwable t) { + public MetadataConnectionException(String uri, Throwable t) { super(ResultCode.CAT_CANNOT_CONNECT, t, uri, t.getMessage()); } } diff --git a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto index bd3459824c..d0cf238487 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto +++ b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto @@ -392,3 +392,18 @@ message PythonInvocationDescProto { required string filePath = 2; required bool isScalarFunction = 3; } + +message TableResponse { + required ReturnState state = 1; + optional TableDescProto table = 2; +} + +message FunctionResponse { + required ReturnState state = 1; + optional FunctionDescProto function = 2; +} + +message FunctionListResponse { + required ReturnState state = 1; + repeated FunctionDescProto function = 2; +} diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java index 06ff6b8f30..ef7d4bd1de 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogUtil.java @@ -26,7 +26,6 @@ import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.tajo.catalog.exception.CatalogException; -import org.apache.tajo.catalog.exception.CatalogExceptionUtil; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.common.TajoDataTypes; @@ -34,6 +33,7 @@ import org.apache.thrift.TException; import parquet.hadoop.mapred.DeprecatedParquetOutputFormat; +import static org.apache.tajo.catalog.exception.CatalogExceptionUtil.makeMDCNoMatchedDataType; import static org.apache.tajo.exception.ExceptionUtil.makeNotSupported; public class HiveCatalogUtil { @@ -73,7 +73,7 @@ public static TajoDataTypes.Type getTajoFieldType(String dataType) { } else if(dataType.equalsIgnoreCase(serdeConstants.DATE_TYPE_NAME)) { return TajoDataTypes.Type.DATE; } else { - throw CatalogExceptionUtil.makeTMCNoMatchedDataType(dataType); + throw makeMDCNoMatchedDataType(dataType); } } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java index cbc24234e2..f85070ea20 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java @@ -300,10 +300,11 @@ public StringListResponse getAllTablespaceNames(RpcController controller, NullPr } @Override - public GetTablespacesResponse getAllTablespaces(RpcController controller, NullProto request) throws ServiceException { + public GetTablespaceListResponse getAllTablespaces(RpcController controller, NullProto request) + throws ServiceException { rlock.lock(); try { - return GetTablespacesResponse.newBuilder() + return GetTablespaceListResponse.newBuilder() .setState(OK) .addAllTablespace(store.getTablespaces()) .build(); @@ -545,13 +546,13 @@ public GetDatabasesResponse getAllDatabases(RpcController controller, NullProto } @Override - public TableDescResponse getTableDesc(RpcController controller, + public TableResponse getTableDesc(RpcController controller, TableIdentifierProto request) throws ServiceException { String dbName = request.getDatabaseName(); String tbName = request.getTableName(); if (metaDictionary.isSystemDatabase(dbName)) { - return TableDescResponse.newBuilder() + return TableResponse.newBuilder() .setState(OK) .setTable(metaDictionary.getTableDesc(tbName)) .build(); @@ -565,17 +566,17 @@ public TableDescResponse getTableDesc(RpcController controller, if (contain) { contain = store.existTable(dbName, tbName); if (contain) { - return TableDescResponse.newBuilder() + return TableResponse.newBuilder() .setState(OK) .setTable(store.getTable(dbName, tbName)) .build(); } else { - return TableDescResponse.newBuilder() + return TableResponse.newBuilder() .setState(errUndefinedTable(tbName)) .build(); } } else { - return TableDescResponse.newBuilder() + return TableResponse.newBuilder() .setState(errUndefinedDatabase(dbName)) .build(); } @@ -583,7 +584,7 @@ public TableDescResponse getTableDesc(RpcController controller, } catch (Throwable t) { printStackTraceIfError(LOG, t); - return TableDescResponse.newBuilder() + return TableResponse.newBuilder() .setState(returnError(t)) .build(); @@ -1401,7 +1402,7 @@ public ReturnState dropFunction(RpcController controller, UnregisterFunctionRequ } @Override - public FunctionDescResponse getFunctionMeta(RpcController controller, GetFunctionMetaRequest request) { + public FunctionResponse getFunctionMeta(RpcController controller, GetFunctionMetaRequest request) { FunctionDescProto function = null; @@ -1415,13 +1416,13 @@ public FunctionDescResponse getFunctionMeta(RpcController controller, GetFunctio } if (function != null) { - return FunctionDescResponse.newBuilder() + return FunctionResponse.newBuilder() .setState(OK) .setFunction(function) .build(); } else { - return FunctionDescResponse.newBuilder() + return FunctionResponse.newBuilder() .setState(errUndefinedFunction( buildSimpleFunctionSignature(request.getSignature(), request.getParameterTypesList()))) .build(); @@ -1430,7 +1431,7 @@ public FunctionDescResponse getFunctionMeta(RpcController controller, GetFunctio } catch (Throwable t) { printStackTraceIfError(LOG, t); - return FunctionDescResponse.newBuilder() + return FunctionResponse.newBuilder() .setState(returnError(t)) .build(); } diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java index 4b1c2c4b2c..c6b7d36315 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java @@ -38,7 +38,6 @@ import org.apache.tajo.exception.InternalException; import org.apache.tajo.exception.TajoInternalError; import org.apache.tajo.util.FileUtil; -import org.apache.tajo.util.KeyValueSet; import org.apache.tajo.util.Pair; import org.apache.tajo.util.TUtil; @@ -138,7 +137,7 @@ public AbstractDBStore(Configuration conf) throws InternalException { conn = createConnection(conf); LOG.info("Connected to database (" + catalogUri + ")"); } catch (SQLException e) { - throw new TMCConnectionException(catalogUri , e); + throw new MetadataConnectionException(catalogUri , e); } String schemaPath = getCatalogSchemaPath(); diff --git a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java index e6ba680a29..e73a032188 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java @@ -25,7 +25,9 @@ import org.apache.tajo.catalog.TableDesc; import org.apache.tajo.catalog.TableMeta; import org.apache.tajo.catalog.partition.PartitionMethodDesc; +import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionDescProto; +import org.apache.tajo.catalog.proto.CatalogProtos.TableResponse; import org.apache.tajo.exception.SQLExceptionUtil; import org.apache.tajo.ipc.ClientProtos; import org.apache.tajo.ipc.ClientProtos.DropTableRequest; @@ -132,7 +134,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema builder.setPartition(partitionMethodDesc.getProto()); } - ClientProtos.TableResponse res; + TableResponse res; try { res = tajoMasterService.createExternalTable(null, builder.build()); } catch (ServiceException e) { @@ -140,7 +142,7 @@ public TableDesc createExternalTable(final String tableName, final Schema schema } if (isSuccess(res.getState())) { - return CatalogUtil.newTableDesc(res.getTableDesc()); + return CatalogUtil.newTableDesc(res.getTable()); } else { throw SQLExceptionUtil.toSQLException(res.getState()); } @@ -189,7 +191,7 @@ public TableDesc getTableDesc(final String tableName) throws SQLException { final BlockingInterface stub = conn.getTMStub(); - ClientProtos.TableResponse res; + TableResponse res; try { res = stub.getTableDesc(null, conn.getSessionedString(tableName)); } catch (ServiceException e) { @@ -197,7 +199,7 @@ public TableDesc getTableDesc(final String tableName) throws SQLException { } throwIfError(res.getState()); - return CatalogUtil.newTableDesc(res.getTableDesc()); + return CatalogUtil.newTableDesc(res.getTable()); } @Override @@ -206,7 +208,7 @@ public List getFunctions(final String functionName) throws SQ final BlockingInterface stub = conn.getTMStub(); String paramFunctionName = functionName == null ? "" : functionName; - ClientProtos.FunctionResponse res; + CatalogProtos.FunctionListResponse res; try { res = stub.getFunctionList(null, conn.getSessionedString(paramFunctionName)); } catch (ServiceException e) { @@ -214,7 +216,7 @@ public List getFunctions(final String functionName) throws SQ } throwIfError(res.getState()); - return res.getFunctionsList(); + return res.getFunctionList(); } @Override diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index e48e2ae63e..957e8e2dfa 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -201,17 +201,6 @@ message DropTableRequest { optional bool purge = 3 [default = false]; } -message TableResponse { - required ReturnState state = 1; - optional TableDescProto tableDesc = 2; -} - -message FunctionResponse { - required ReturnState state = 1; - repeated FunctionDescProto functions = 2; - optional string errorMessage = 3; -} - message QueryInfoProto { required string queryId = 1; optional string sql = 2; diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto index ff75ceeb84..1dcf1ac08d 100644 --- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto +++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto @@ -69,5 +69,5 @@ service TajoMasterClientProtocolService { rpc dropTable(DropTableRequest) returns (ReturnState); rpc getTableList(SessionedStringProto) returns (StringListResponse); rpc getTableDesc(SessionedStringProto) returns (TableResponse); - rpc getFunctionList(SessionedStringProto) returns (FunctionResponse); + rpc getFunctionList(SessionedStringProto) returns (FunctionListResponse); } 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 3f672500e6..42ae436d61 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 @@ -84,7 +84,7 @@ public class ErrorMessages { ADD_MESSAGE(CAT_UPGRADE_REQUIRED, "catalog must be upgraded"); ADD_MESSAGE(CAT_CANNOT_CONNECT, "cannot connect metadata store '%s': %s", 2); - ADD_MESSAGE(TMC_NO_MATCHED_DATATYPE, "no matched type for %s", 1); + ADD_MESSAGE(MDC_NO_MATCHED_DATATYPE, "no matched type for %s", 1); ADD_MESSAGE(UNKNOWN_DATAFORMAT, "Unknown data format: '%s'", 1); } 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 8bd8c0910a..781d1a06e6 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 @@ -20,6 +20,10 @@ import org.apache.tajo.error.Errors.ResultCode; +/** + * TajoException contains all exceptions with any exact reason. + * It always have an exact error code and an error message. + */ public class TajoException extends Exception implements TajoExceptionInterface { private ResultCode code; diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java index d92c094711..e0444a00f4 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java @@ -20,6 +20,12 @@ import org.apache.tajo.error.Errors.ResultCode; +/** + * Abstracted exception or error interface. TajoException and + * TajoRuntimeException always have a ResultCode and a message. + * This interface helps routines access both TajoException and + * TajoRuntimeException in a common way. + */ public interface TajoExceptionInterface { ResultCode getErrorCode(); diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java index 34ead32974..5ffa26d90b 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java @@ -22,10 +22,6 @@ /** * Exception for Internal Bugs and Unexpected exception - * - * When should we use TajoInternalError? - * * Cases that must not be happened - * * Developer bugs */ public class TajoInternalError extends TajoError { diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java index 37ab2dec58..dfde5342e2 100644 --- a/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java +++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java @@ -21,6 +21,11 @@ import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; +/** + * It is used in unexpected cases or error that we know the cause. + * + * @see @{link TajoException} + */ public class TajoRuntimeException extends RuntimeException implements TajoExceptionInterface { private ResultCode code; diff --git a/tajo-common/src/main/proto/errors.proto b/tajo-common/src/main/proto/errors.proto index 87e2f311e3..1ad9c856c6 100644 --- a/tajo-common/src/main/proto/errors.proto +++ b/tajo-common/src/main/proto/errors.proto @@ -23,6 +23,48 @@ import "stacktrace.proto"; // Unstable - this is still evolving. + +// SQLState Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H +// are called "standard-defined classes". This is borrowed from PostgreSQL and IBM DB2. + +// 00 - Successful Completion +// 01 - Warning +// 02 - No Data +// 07 - Dynamic SQL Error +// 08 - Connection Exception +// 09 - Triggered Action Exception +// 0A - Feature Not Supported +// 0D - Invalid Target Type Specification +// 0F - Invalid Token +// 0K - Invalid RESIGNAL Statement +// 0N - SQL/XML mapping error +// 20 - Case Not Found for CASE Statement +// 21 - Cardinality Violation +// 22 - Data Exception +// 23 - Constraint Violation +// 24 - Invalid Cursor State +// 25 - Invalid Transaction State +// 26 - Invalid SQL Statement Identifier +// 28 - Invalid Authorization Specification +// 2D - Invalid Transaction Termination +// 2E - Invalid Connection Name +// 34 - Invalid Cursor Name +// 36 - Cursor Sensitivity Exception +// 38 - External Function Exception +// 39 - External Function Call Exception +// 3B - Invalid SAVEPOINT +// 40 - Transaction Rollback +// 42 - Syntax Error or Access Rule Violation +// 44 - WITH CHECK OPTION Violation +// 46 - Java DDL +// 51 - Invalid Application State +// 53 - Invalid Operand or Inconsistent Specification +// 54 - SQL or Product Limit Exceeded +// 55 - Object Not in Prerequisite State +// 56 - Miscellaneous SQL or Product Error +// 57 - Resource Not Available or Operator Intervention +// 58 - System Error + enum ResultCode { // Class // 00 - Successful Completion @@ -37,9 +79,9 @@ enum ResultCode { INVALID_RPC_CALL = 204; // When invalid RPC call is invoked (e.g., wrong message and absent fields) // Query Management and Scheduler - NO_SUCH_QUERYID = 300; // No query id in TajoMaster - NO_DATA = 301; // No data due to query fail or error - INCOMPLETE_QUERY = 302; // It occurs when a client requests something of a completed query. + NO_SUCH_QUERYID = 301; // No query id in TajoMaster + NO_DATA = 302; // No data due to query fail or error + INCOMPLETE_QUERY = 303; // It occurs when a client requests something of a completed query. // Session INVALID_SESSION = 401; // Session already was invalid @@ -51,49 +93,49 @@ enum ResultCode { // Section: Class 42 - Syntax Error or Access Rule Violation - SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 601; // SQLState: 42000 - SYNTAX_ERROR = 602; // SQLState: 42601 - INSUFFICIENT_PRIVILEGE = 603; // SQLState: 42501 - - UNDEFINED_TABLESPACE = 500; // ? - UNDEFINED_DATABASE = 501; // ? - UNDEFINED_SCHEMA = 502; // ? - UNDEFINED_TABLE = 503; // ? - UNDEFINED_COLUMN = 504; // SQLState: 42703 - UNDEFINED_FUNCTION = 505; // SQLState: 42883 - UNDEFINED_INDEX = 506; // ? - UNDEFINED_INDEX_NAME = 507; // ? - UNDEFINED_PARTITION = 508; // ? - UNDEFINED_PARTITION_METHOD = 509; // ? - UNDEFINED_OPERATOR = 510; // SQLState: 42883 (=UNDEFINED_FUNCTION) - - DUPLICATE_TABLESPACE = 510; - DUPLICATE_DATABASE = 511; // SQLState: 42P04 - DUPLICATE_SCHEMA = 512; // SQLState: 42P06 - DUPLICATE_TABLE = 513; // SQLState: 42P07 - DUPLICATE_COLUMN = 514; // SQLState: 42701 - DUPLICATE_ALIAS = 515; // SQLState: 42712 - DUPLICATE_FUNCTION = 516; // SQLState: 42723 - DUPLICATE_INDEX = 517; // SQLState: ? - DUPLICATE_PARTITION = 518; // SQLState: ? - - AMBIGUOUS_TABLE = 521; // ? - AMBIGUOUS_COLUMN = 522; // SQLState: 42702; - AMBIGUOUS_FUNCTION = 523; // SQLState: 42725; - - CANNOT_CAST = 604; // SQLState: 42846 - Cast from source type to target type is not supported. - GROUPING_ERROR = 605; // SQLState: 42803 - WINDOWING_ERROR = 606; // SQLState: 42P20 - PgSQL implementation-defined - INVALID_RECURSION = 607; // SQLState: 42P19 - PgSQL implementation-defined - SET_OPERATION_SCHEMA_MISMATCH = 608; // SQLState: 42601 (=SYNTAX_ERROR) - SET_OPERATION_DATATYPE_MISMATCH = 609; // SQLState: 42601 (=SYNTAX_ERROR) + SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION = 501; // SQLState: 42000 + SYNTAX_ERROR = 502; // SQLState: 42601 + INSUFFICIENT_PRIVILEGE = 503; // SQLState: 42501 + + UNDEFINED_TABLESPACE = 511; // ? + UNDEFINED_DATABASE = 512; // ? + UNDEFINED_SCHEMA = 513; // ? + UNDEFINED_TABLE = 514; // ? + UNDEFINED_COLUMN = 515; // SQLState: 42703 + UNDEFINED_FUNCTION = 516; // SQLState: 42883 + UNDEFINED_INDEX = 517; // ? + UNDEFINED_INDEX_NAME = 518; // ? + UNDEFINED_PARTITION = 519; // ? + UNDEFINED_PARTITION_METHOD = 520; // ? + UNDEFINED_OPERATOR = 521; // SQLState: 42883 (=UNDEFINED_FUNCTION) + + DUPLICATE_TABLESPACE = 531; + DUPLICATE_DATABASE = 532; // SQLState: 42P04 + DUPLICATE_SCHEMA = 533; // SQLState: 42P06 + DUPLICATE_TABLE = 534; // SQLState: 42P07 + DUPLICATE_COLUMN = 535; // SQLState: 42701 + DUPLICATE_ALIAS = 536; // SQLState: 42712 + DUPLICATE_FUNCTION = 537; // SQLState: 42723 + DUPLICATE_INDEX = 538; // SQLState: ? + DUPLICATE_PARTITION = 539; // SQLState: ? + + AMBIGUOUS_TABLE = 541; // ? + AMBIGUOUS_COLUMN = 542; // SQLState: 42702; + AMBIGUOUS_FUNCTION = 543; // SQLState: 42725; + + CANNOT_CAST = 601; // SQLState: 42846 - Cast from source type to target type is not supported. + GROUPING_ERROR = 602; // SQLState: 42803 + WINDOWING_ERROR = 603; // SQLState: 42P20 - PgSQL implementation-defined + INVALID_RECURSION = 604; // SQLState: 42P19 - PgSQL implementation-defined + SET_OPERATION_SCHEMA_MISMATCH = 605; // SQLState: 42601 (=SYNTAX_ERROR) + SET_OPERATION_DATATYPE_MISMATCH = 606; // SQLState: 42601 (=SYNTAX_ERROR) INVALID_FOREIGN_KEY = 621; // SQLState: 42830 INVALID_NAME = 622; // SQLState: 42602 - INVALID_COLUMN_DEFINITION = 631; // SQLState: 42611 - NAME_TOO_LONG = 623; // SQLState: 42622 - RESERVED_NAME = 624; // SQLState: 42939 - DATATYPE_MISMATCH = 625; // SQLState: 42804 - INDETERMINATE_DATATYPE = 626; // SQLState: 42P18 - PgSQL implementation -defined + INVALID_COLUMN_DEFINITION = 623; // SQLState: 42611 + NAME_TOO_LONG = 624; // SQLState: 42622 + RESERVED_NAME = 625; // SQLState: 42939 + DATATYPE_MISMATCH = 626; // SQLState: 42804 + INDETERMINATE_DATATYPE = 627; // SQLState: 42P18 - PgSQL implementation -defined @@ -102,15 +144,15 @@ enum ResultCode { INVALID_CAST = 702; INVALID_DATATYPE = 703; - //NUMERIC_OVERFLOW = 803; // Numeric value overflow - //VALUE_LARGER_THAN_PRECISION = 804; // Value larger than column precision + NUMERIC_OVERFLOW = 803; // Numeric value overflow + VALUE_LARGER_THAN_PRECISION = 804; // Value larger than column precision // Meta Catalog CAT_UPGRADE_REQUIRED = 901; // Migration CAT_CANNOT_CONNECT = 902; // Cannot connect metadata server - // Metadata Connector - TMC_NO_MATCHED_DATATYPE = 910; // No matched data type between Tajo and connector + // MetaData Connector (MDC) + MDC_NO_MATCHED_DATATYPE = 910; // No matched data type between Tajo and connector // Storage and Data Format UNKNOWN_DATAFORMAT = 1001; // Unknown Data Format @@ -120,43 +162,6 @@ enum ResultCode { CLIENT_UNABLE_TO_ESTABLISH_CONNECTION = 1102; // SQLState: 08001 - CLIENT_PROTOCOL_PROTOCOL_VIOLATION = 1103; // SQLState: ? - // Class values that begin with 0, 1, 2, 3, 4, A, B, C, D, E, F, G or H - // are called "standard-defined classes". - - - - // 01 - Warning - // 02 - No Data - // 07 - Dynamic SQL Error - // 08 - Connection Exception - // 09 - Triggered Action Exception - // 0A - Feature Not Supported - // 0D - Invalid Target Type Specification - // 0F - Invalid Token - // 0K - Invalid RESIGNAL Statement - // 0N - SQL/XML mapping error - // 20 - Case Not Found for CASE Statement - // 21 - Cardinality Violation - // 22 - Data Exception - // 23 - Constraint Violation - // 24 - Invalid Cursor State - // 25 - Invalid Transaction State - // 26 - Invalid SQL Statement Identifier - // 28 - Invalid Authorization Specification - // 2D - Invalid Transaction Termination - // 2E - Invalid Connection Name - // 34 - Invalid Cursor Name - // 36 - Cursor Sensitivity Exception - // 38 - External Function Exception - // 39 - External Function Call Exception - // 3B - Invalid SAVEPOINT - // 40 - Transaction Rollback - - - // 44 - WITH CHECK OPTION Violation - // 46 - Java DDL - // 51 - Invalid Application State - // 53 - Invalid Operand or Inconsistent Specification INSUFFICIENT_RESOURCE = 53000; DISK_FULL = 53100; @@ -178,8 +183,6 @@ enum ResultCode { // 58 - System Error IO_ERROR = 58030; - // 5U - Utilities Table - // underlying system errors based on errno.h. EPERM = 10001; // Operation not permitted diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 60279c1dfd..6e3bd84c56 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -36,6 +36,8 @@ import org.apache.tajo.catalog.exception.UndefinedDatabaseException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.catalog.proto.CatalogProtos.FunctionListResponse; +import org.apache.tajo.catalog.proto.CatalogProtos.TableResponse; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.conf.TajoConf.ConfVars; import org.apache.tajo.engine.query.QueryContext; @@ -817,7 +819,7 @@ public TableResponse getTableDesc(RpcController controller, SessionedStringProto if (catalog.existsTable(databaseName, tableName)) { return TableResponse.newBuilder() .setState(OK) - .setTableDesc(catalog.getTableDesc(databaseName, tableName).getProto()) + .setTable(catalog.getTableDesc(databaseName, tableName).getProto()) .build(); } else { return TableResponse.newBuilder() @@ -865,7 +867,7 @@ public TableResponse createExternalTable(RpcController controller, CreateTableRe return TableResponse.newBuilder() .setState(OK) - .setTableDesc(desc.getProto()).build(); + .setTable(desc.getProto()).build(); } catch (Throwable t) { return TableResponse.newBuilder() @@ -890,7 +892,7 @@ public ReturnState dropTable(RpcController controller, DropTableRequest dropTabl } @Override - public FunctionResponse getFunctionList(RpcController controller, SessionedStringProto request) + public FunctionListResponse getFunctionList(RpcController controller, SessionedStringProto request) throws ServiceException { try { @@ -910,13 +912,13 @@ public FunctionResponse getFunctionList(RpcController controller, SessionedStrin } } } - return FunctionResponse.newBuilder() + return FunctionListResponse.newBuilder() .setState(OK) - .addAllFunctions(functionProtos) + .addAllFunction(functionProtos) .build(); } catch (Throwable t) { - return FunctionResponse.newBuilder().setState(returnError(t)).build(); + return FunctionListResponse.newBuilder().setState(returnError(t)).build(); } } } 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 84e7634560..6330268eb6 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 @@ -321,16 +321,4 @@ public Expr visitInsert(Context context, Stack stack, Insert expr) throws return expr; } - - @Override - public Expr visitAlterTable(Context context, Stack stack, AlterTable expr) throws PlanningException { - super.visitAlterTable(context, stack, expr); - - if (expr.getAlterTableOpType() == AlterTableOpType.ADD_PARTITION - || expr.getAlterTableOpType() == AlterTableOpType.DROP_PARTITION) { - context.state.addVerification(new UnimplementedException(expr.getAlterTableOpType().name())); - } - - return expr; - } } From e4bd9bc5e35a501fe2ca94e46b27f6593e1de23d Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 20 Jul 2015 14:16:01 +0900 Subject: [PATCH 29/30] Fixed exception handling in DDLExecutor. --- .../tajo/catalog/AbstractCatalogClient.java | 10 ++++- .../apache/tajo/catalog/CatalogService.java | 4 +- .../apache/tajo/exception/ErrorMessages.java | 3 +- .../apache/tajo/master/exec/DDLExecutor.java | 41 +++++++++++-------- .../testAlterTableAddDropPartition.result | 2 +- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index 62485ba7fa..f7f77851dc 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -25,13 +25,14 @@ import org.apache.tajo.catalog.CatalogProtocol.CatalogProtocolService.BlockingInterface; import org.apache.tajo.catalog.CatalogProtocol.*; import org.apache.tajo.catalog.exception.AmbiguousFunctionException; -import org.apache.tajo.catalog.exception.DuplicateFunctionException; import org.apache.tajo.catalog.exception.UndefinedFunctionException; +import org.apache.tajo.catalog.exception.UndefinedPartitionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos.*; import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; import org.apache.tajo.util.ProtoUtil; @@ -343,7 +344,7 @@ public final boolean existPartitionMethod(final String databaseName, final Strin @Override public final PartitionDescProto getPartition(final String databaseName, final String tableName, - final String partitionName) { + final String partitionName) throws UndefinedPartitionException { try { final BlockingInterface stub = getStub(); final PartitionIdentifierProto request = PartitionIdentifierProto.newBuilder() @@ -353,6 +354,11 @@ public final PartitionDescProto getPartition(final String databaseName, final St .build(); final GetPartitionDescResponse response = stub.getPartitionByPartitionName(null, request); + + if (ReturnStateUtil.isThisError(response.getState(), ResultCode.UNDEFINED_PARTITION)) { + throw new UndefinedPartitionException(partitionName); + } + ensureOk(response.getState()); return response.getPartition(); diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java index 1d3001f076..5dc54126e1 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java @@ -19,6 +19,7 @@ package org.apache.tajo.catalog; import org.apache.tajo.catalog.exception.UndefinedFunctionException; +import org.apache.tajo.catalog.exception.UndefinedPartitionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto; @@ -187,7 +188,8 @@ public interface CatalogService { boolean existPartitionMethod(String databaseName, String tableName); - CatalogProtos.PartitionDescProto getPartition(String databaseName, String tableName, String partitionName); + CatalogProtos.PartitionDescProto getPartition(String databaseName, String tableName, String partitionName) + throws UndefinedPartitionException; List getPartitions(String databaseName, String tableName); 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 42ae436d61..b051eb57fb 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 @@ -62,6 +62,7 @@ public class ErrorMessages { ADD_MESSAGE(UNDEFINED_TABLE, "relation '%s' does not exist", 1); ADD_MESSAGE(UNDEFINED_COLUMN, "column '%s' does not exist", 1); ADD_MESSAGE(UNDEFINED_FUNCTION, "function does not exist: %s", 1); + ADD_MESSAGE(UNDEFINED_PARTITION, "partition '%s' does not exist", 1); ADD_MESSAGE(UNDEFINED_OPERATOR, "operator does not exist: '%s'", 1); ADD_MESSAGE(DUPLICATE_TABLESPACE, "tablespace '%s' already exists", 1); @@ -71,7 +72,7 @@ public class ErrorMessages { ADD_MESSAGE(DUPLICATE_COLUMN, "column '%s' already exists", 1); ADD_MESSAGE(DUPLICATE_ALIAS, "table name '%s' specified more than once", 1); ADD_MESSAGE(DUPLICATE_INDEX, "index '%s' already exists", 1); - ADD_MESSAGE(DUPLICATE_PARTITION, "partition '%s' already exists", 1); + ADD_MESSAGE(DUPLICATE_PARTITION, "partition for '%s' already exists", 1); ADD_MESSAGE(DIVISION_BY_ZERO, "Division by zero: %s", 1); 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 3a0fca1c97..b0024dc08f 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 @@ -421,14 +421,6 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer desc = catalog.getTableDesc(databaseName, simpleTableName); } - // When adding a partition or dropping a partition, check existing partition column information. - if (alterTable.getAlterTableOpType() == AlterTableOpType.ADD_PARTITION - || alterTable.getAlterTableOpType() == AlterTableOpType.DROP_PARTITION) { - pair = CatalogUtil.getPartitionKeyNamePair(alterTable.getPartitionColumns(), alterTable.getPartitionValues()); - partitionDescProto = catalog.getPartition(databaseName, simpleTableName, pair.getSecond()); - existPartitionColumnNames(qualifiedName, alterTable.getPartitionColumns()); - } - switch (alterTable.getAlterTableOpType()) { case RENAME_TABLE: if (!catalog.existsTable(databaseName, simpleTableName)) { @@ -458,14 +450,14 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer AlterTableType.RENAME_TABLE)); break; case RENAME_COLUMN: - if (existColumnName(qualifiedName, alterTable.getNewColumnName())) { + if (ensureColumnExistance(qualifiedName, alterTable.getNewColumnName())) { throw new DuplicateColumnException(alterTable.getNewColumnName()); } catalog.alterTable(CatalogUtil.renameColumn(qualifiedName, alterTable.getColumnName(), alterTable.getNewColumnName(), AlterTableType.RENAME_COLUMN)); break; case ADD_COLUMN: - if (existColumnName(qualifiedName, alterTable.getAddNewColumn().getSimpleName())) { + if (ensureColumnExistance(qualifiedName, alterTable.getAddNewColumn().getSimpleName())) { throw new DuplicateColumnException(alterTable.getAddNewColumn().getSimpleName()); } catalog.alterTable(CatalogUtil.addNewColumn(qualifiedName, alterTable.getAddNewColumn(), AlterTableType.ADD_COLUMN)); @@ -474,7 +466,17 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer catalog.alterTable(CatalogUtil.setProperty(qualifiedName, alterTable.getProperties(), AlterTableType.SET_PROPERTY)); break; case ADD_PARTITION: - if (partitionDescProto != null) { + pair = CatalogUtil.getPartitionKeyNamePair(alterTable.getPartitionColumns(), alterTable.getPartitionValues()); + ensureColumnPartitionKeys(qualifiedName, alterTable.getPartitionColumns()); + + // checking a duplicated partition + boolean duplicatedPartition = true; + try { + catalog.getPartition(databaseName, simpleTableName, pair.getSecond()); + } catch (UndefinedPartitionException npe) { + duplicatedPartition = false; + } + if (duplicatedPartition) { throw new DuplicatePartitionException(pair.getSecond()); } @@ -491,8 +493,7 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer // If there is a directory which was assumed to be a partitioned directory and users don't input another // location, this will throw exception. Path assumedDirectory = new Path(desc.getUri().toString(), pair.getSecond()); - boolean result1 = fs.exists(assumedDirectory); - boolean result2 = fs.exists(partitionPath); + if (fs.exists(assumedDirectory) && !assumedDirectory.equals(partitionPath)) { throw new AlreadyExistsAssumedPartitionDirectoryException(assumedDirectory.toString()); } @@ -506,6 +507,10 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer } break; case DROP_PARTITION: + ensureColumnPartitionKeys(qualifiedName, alterTable.getPartitionColumns()); + pair = CatalogUtil.getPartitionKeyNamePair(alterTable.getPartitionColumns(), alterTable.getPartitionValues()); + partitionDescProto = catalog.getPartition(databaseName, simpleTableName, pair.getSecond()); + if (partitionDescProto == null) { throw new NoSuchPartitionException(tableName, pair.getSecond()); } @@ -537,16 +542,16 @@ private void deletePartitionPath(CatalogProtos.PartitionDescProto partitionDescP } } - private boolean existPartitionColumnNames(String tableName, String[] columnNames) { + private boolean ensureColumnPartitionKeys(String tableName, String[] columnNames) { for(String columnName : columnNames) { - if (!existPartitionColumnName(tableName, columnName)) { + if (!ensureColumnPartitionKeys(tableName, columnName)) { throw new NoSuchPartitionKeyException(tableName, columnName); } } return true; } - private boolean existPartitionColumnName(String tableName, String columnName) { + private boolean ensureColumnPartitionKeys(String tableName, String columnName) { final TableDesc tableDesc = catalog.getTableDesc(tableName); if (tableDesc.getPartitionMethod().getExpressionSchema().contains(columnName)) { return true; @@ -555,8 +560,8 @@ private boolean existPartitionColumnName(String tableName, String columnName) { } } - private boolean existColumnName(String tableName, String columnName) { + private boolean ensureColumnExistance(String tableName, String columnName) { final TableDesc tableDesc = catalog.getTableDesc(tableName); - return tableDesc.getSchema().containsByName(columnName) ? true : false; + return tableDesc.getSchema().containsByName(columnName); } } diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddDropPartition.result b/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddDropPartition.result index c16c311dd6..d01038a32b 100644 --- a/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddDropPartition.result +++ b/tajo-core/src/test/resources/results/TestTajoCli/testAlterTableAddDropPartition.result @@ -2,7 +2,7 @@ OK ERROR: "key2" column is not the partition key of "default.testaltertableaddpartition". OK OK -ERROR: "key=0.1" is not the partition of "testaltertableaddpartition". +ERROR: partition 'key=0.1' does not exist OK OK OK From f86f22793c4a8553bafa5b2c2472531e217a435e Mon Sep 17 00:00:00 2001 From: Hyunsik Choi Date: Mon, 20 Jul 2015 16:45:09 +0900 Subject: [PATCH 30/30] Fixed indent. --- .../tajo/catalog/exception/AmbiguousFunctionException.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java index 2f7de9b4ca..d1f17fd2b8 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AmbiguousFunctionException.java @@ -24,8 +24,7 @@ import static org.apache.tajo.function.FunctionUtil.buildSimpleFunctionSignature; public class AmbiguousFunctionException extends CatalogException { - - public AmbiguousFunctionException(String funcName, DataType[] parameters) { - super(Errors.ResultCode.AMBIGUOUS_FUNCTION, buildSimpleFunctionSignature(funcName, parameters)); - } + public AmbiguousFunctionException(String funcName, DataType[] parameters) { + super(Errors.ResultCode.AMBIGUOUS_FUNCTION, buildSimpleFunctionSignature(funcName, parameters)); + } }