tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hyun...@apache.org
Subject [4/8] tajo git commit: TAJO-1670: Refactor client errors and exceptions.
Date Mon, 20 Jul 2015 11:43:53 GMT
http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java b/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
index e1a3791..788d193 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,22 +26,26 @@ import org.apache.tajo.TajoIdProtos;
 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.ResultCode;
 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;
 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;
 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;
 import java.util.HashMap;
 import java.util.List;
@@ -50,6 +54,10 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import static org.apache.tajo.exception.ReturnStateUtil.isError;
+import static org.apache.tajo.exception.ReturnStateUtil.isSuccess;
+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;
@@ -86,10 +94,10 @@ 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 IOException {
+                           @NotNull KeyValueSet properties) throws SQLException {
     this.serviceTracker = tracker;
     this.baseDatabase = baseDatabase;
     this.properties = properties;
@@ -98,33 +106,49 @@ public class SessionConnection implements Closeable {
     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<String, String> getClientSideSessionVars() {
     return Collections.unmodifiableMap(sessionVarsCache);
   }
 
-  public synchronized NettyClientBase getTajoMasterConnection() throws ServiceException {
-    if (client != null && client.isConnected()) return client;
-    else {
+  public synchronized NettyClientBase getTajoMasterConnection() throws SQLException {
+
+    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 BlockingInterface getTMStub() throws SQLException {
+    NettyClientBase tmClient;
+    tmClient = getTajoMasterConnection();
+    BlockingInterface stub = tmClient.getStub();
+    checkSessionAndGet(tmClient);
+    return stub;
+  }
+
   public KeyValueSet getProperties() {
     return properties;
   }
@@ -134,8 +158,8 @@ public class SessionConnection implements Closeable {
     this.sessionId = sessionId;
   }
 
-  public TajoIdProtos.SessionIdProto getSessionId() {
-    return sessionId;
+  public String getSessionId() {
+    return sessionId.getId();
   }
 
   public String getBaseDatabase() {
@@ -157,51 +181,70 @@ public class SessionConnection implements Closeable {
     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();
+    BlockingInterface tajoMasterService = client.getStub();
+
+    StringResponse response;
+    try {
+      response = tajoMasterService.getCurrentDatabase(null, sessionId);
+    } catch (ServiceException e) {
+      throw new RuntimeException(e);
+    }
+
+    throwIfError(response.getState());
+    return response.getValue();
   }
 
-  public Map<String, String> updateSessionVariables(final Map<String, String> variables) throws ServiceException {
+  public Map<String, String> updateSessionVariables(final Map<String, String> variables) throws SQLException {
     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();
 
-    SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request);
+    SessionUpdateResponse response;
 
-    if (response.getResultCode() == ResultCode.OK) {
+    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.getMessage());
+      throw toSQLException(response.getState());
     }
   }
 
-  public Map<String, String> unsetSessionVariables(final List<String> variables) throws ServiceException {
-    NettyClientBase client = getTajoMasterConnection();
-    checkSessionAndGet(client);
+  public Map<String, String> unsetSessionVariables(final List<String> variables) throws SQLException {
 
-    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 = tajoMasterService.updateSessionVariables(null, request);
+    SessionUpdateResponse response;
+    try {
+      response = stub.updateSessionVariables(null, request);
+    } catch (ServiceException e) {
+      throw new RuntimeException(e);
+    }
 
-    if (response.getResultCode() == ResultCode.OK) {
+    if (isSuccess(response.getState())) {
       updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars()));
       return Collections.unmodifiableMap(sessionVarsCache);
     } else {
-      throw new ServiceException(response.getMessage());
+      throw toSQLException(response.getState());
     }
   }
 
@@ -212,7 +255,7 @@ public class SessionConnection implements Closeable {
     }
   }
 
-  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)) {
@@ -223,38 +266,51 @@ public class SessionConnection implements Closeable {
     NettyClientBase client = getTajoMasterConnection();
     checkSessionAndGet(client);
 
-    TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-    return tajoMasterService.getSessionVariable(null, convertSessionedString(varname)).getValue();
-  }
+    BlockingInterface stub = client.getStub();
 
-  public Boolean existSessionVariable(final String varname) throws ServiceException {
-    NettyClientBase client = getTajoMasterConnection();
-    checkSessionAndGet(client);
+    try {
+      return stub.getSessionVariable(null, getSessionedString(varname)).getValue();
 
-    TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-    return tajoMasterService.existSessionVariable(null, convertSessionedString(varname)).getValue();
+    } catch (ServiceException e) {
+      throw new RuntimeException(e);
+    }
   }
 
-  public Map<String, String> getCachedAllSessionVariables() {
-    synchronized (sessionVarsCache) {
-      return Collections.unmodifiableMap(sessionVarsCache);
+  public Boolean existSessionVariable(final String varname) throws SQLException {
+
+    BlockingInterface stub = getTMStub();
+    try {
+      return isSuccess(stub.existSessionVariable(null, getSessionedString(varname)));
+    } catch (ServiceException e) {
+      throw new RuntimeException(e);
     }
   }
 
-  public Map<String, String> getAllSessionVariables() throws ServiceException {
+  public Map<String, String> getAllSessionVariables() throws SQLException {
     NettyClientBase client = getTajoMasterConnection();
     checkSessionAndGet(client);
 
-    TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-    return ProtoUtil.convertToMap(tajoMasterService.getAllSessionVariables(null, sessionId));
+    BlockingInterface stub = client.getStub();
+    KeyValueSetResponse response;
+    try {
+      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 ServiceException {
-    NettyClientBase client = getTajoMasterConnection();
-    checkSessionAndGet(client);
+  public Boolean selectDatabase(final String databaseName) throws SQLException {
 
-    TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-    boolean selected = tajoMasterService.selectDatabase(null, convertSessionedString(databaseName)).getValue();
+    BlockingInterface stub = getTMStub();
+    boolean selected;
+    try {
+      selected = isSuccess(stub.selectDatabase(null, getSessionedString(databaseName)));
+    } catch (ServiceException e) {
+      throw new RuntimeException(e);
+    }
 
     if (selected) {
       this.baseDatabase = databaseName;
@@ -272,7 +328,7 @@ public class SessionConnection implements Closeable {
     NettyClientBase client = null;
     try {
       client = getTajoMasterConnection();
-      TajoMasterClientProtocolService.BlockingInterface tajoMaster = client.getStub();
+      BlockingInterface tajoMaster = client.getStub();
       tajoMaster.removeSession(null, sessionId);
     } catch (Throwable e) {
       // ignore
@@ -293,11 +349,11 @@ public class SessionConnection implements Closeable {
     return serviceTracker.getClientServiceAddress();
   }
 
-  protected void checkSessionAndGet(NettyClientBase client) throws ServiceException {
+  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();
 
@@ -305,18 +361,24 @@ public class SessionConnection implements Closeable {
         builder.setBaseDatabaseName(baseDatabase);
       }
 
-      CreateSessionResponse response = tajoMasterService.createSession(null, builder.build());
 
-      if (response.getResultCode() == ResultCode.OK) {
+      CreateSessionResponse response = null;
+
+      try {
+        response = tajoMasterService.createSession(null, builder.build());
+      } catch (ServiceException se) {
+        throw new RuntimeException(se);
+      }
+
+      if (isSuccess(response.getState())) {
 
         sessionId = response.getSessionId();
         updateSessionVarsCache(ProtoUtil.convertToMap(response.getSessionVars()));
         if (LOG.isDebugEnabled()) {
           LOG.debug(String.format("Got session %s as a user '%s'.", sessionId.getId(), userInfo.getUserName()));
         }
-
       } else {
-        throw new InvalidClientSessionException(response.getMessage());
+        throw SQLExceptionUtil.toSQLException(response.getState());
       }
     }
   }
@@ -331,9 +393,9 @@ public class SessionConnection implements Closeable {
     NettyClientBase client = getTajoMasterConnection();
 
     // create new session
-    TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+    BlockingInterface tajoMasterService = client.getStub();
     CreateSessionResponse response = tajoMasterService.createSession(null, builder.build());
-    if (response.getResultCode() != ResultCode.OK) {
+    if (isError(response.getState())) {
       return false;
     }
 
@@ -353,11 +415,11 @@ public class SessionConnection implements Closeable {
     try {
       KeyValueSet keyValueSet = new KeyValueSet();
       keyValueSet.putAll(sessionVarsCache);
-      ClientProtos.UpdateSessionVariableRequest request = ClientProtos.UpdateSessionVariableRequest.newBuilder()
+      UpdateSessionVariableRequest request = UpdateSessionVariableRequest.newBuilder()
           .setSessionId(sessionId)
           .setSessionVars(keyValueSet.getProto()).build();
 
-      if (tajoMasterService.updateSessionVariables(null, request).getResultCode() != ResultCode.OK) {
+      if (isError(tajoMasterService.updateSessionVariables(null, request).getState())) {
         tajoMasterService.removeSession(null, sessionId);
         return false;
       }
@@ -376,10 +438,12 @@ public class SessionConnection implements Closeable {
     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();
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
index 85929e8..d2b688a 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 org.apache.tajo.util.KeyValueSet;
 import java.io.Closeable;
 
 @ThreadSafe
-public interface TajoClient extends QueryClient, CatalogAdminClient, Closeable {
 
+public interface TajoClient extends QueryClient, CatalogAdminClient, Closeable {
   KeyValueSet getProperties();
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClientImpl.java
index 612b56e..c81fafc 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.jdbc.TajoMemoryResultSet;
 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 class TajoClientImpl extends SessionConnection implements TajoClient, Que
    * @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<BriefQueryInfo> getRunningQueryList() throws ServiceException {
+  public List<BriefQueryInfo> getRunningQueryList() throws SQLException {
     return queryClient.getRunningQueryList();
   }
 
-  public List<BriefQueryInfo> getFinishedQueryList() throws ServiceException {
+  public List<BriefQueryInfo> getFinishedQueryList() throws SQLException {
     return queryClient.getFinishedQueryList();
   }
 
-  public List<WorkerResourceInfo> getClusterInfo() throws ServiceException {
+  public List<WorkerResourceInfo> 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,54 +177,54 @@ public class TajoClientImpl extends SessionConnection implements TajoClient, Que
   // 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<String> getAllDatabaseNames() throws ServiceException {
+  public List<String> 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 {
     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 {
     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<String> getTableList(@Nullable final String databaseName) throws ServiceException {
+  public List<String> getTableList(@Nullable final String databaseName) throws SQLException {
     return catalogClient.getTableList(databaseName);
   }
 
-  public TableDesc getTableDesc(final String tableName) throws ServiceException {
+  public TableDesc getTableDesc(final String tableName) throws SQLException {
     return catalogClient.getTableDesc(tableName);
   }
 
-  public List<CatalogProtos.FunctionDescProto> getFunctions(final String functionName) throws ServiceException {
+  public List<CatalogProtos.FunctionDescProto> getFunctions(final String functionName) throws SQLException {
     return catalogClient.getFunctions(functionName);
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/java/org/apache/tajo/client/TajoClientUtil.java
----------------------------------------------------------------------
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 bab699e..90894fe 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;
@@ -29,12 +28,11 @@ import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.ipc.ClientProtos;
 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;
 import java.sql.ResultSet;
+import java.sql.SQLException;
 
 public class TajoClientUtil {
 
@@ -60,7 +58,7 @@ public class TajoClientUtil {
     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 +80,7 @@ public class TajoClientUtil {
     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]

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java
----------------------------------------------------------------------
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 32ab19c..0000000
--- 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;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/proto/ClientProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto
index 9c20fd8..021cfe7 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;
@@ -26,21 +28,15 @@ import "TajoIdProtos.proto";
 import "CatalogProtos.proto";
 import "PrimitiveProtos.proto";
 
-enum ResultCode {
-  OK = 0;
-  ERROR = 1;
-}
-
 message CreateSessionRequest {
   required string username = 1;
   optional string baseDatabaseName = 2;
 }
 
 message CreateSessionResponse {
-  required ResultCode resultCode = 1;
+  required ReturnState state = 1;
   optional SessionIdProto sessionId = 2;
   optional KeyValueSetProto sessionVars = 3;
-  optional string message = 4;
 }
 
 message UpdateSessionVariableRequest {
@@ -50,9 +46,8 @@ message UpdateSessionVariableRequest {
 }
 
 message SessionUpdateResponse {
-  required ResultCode resultCode = 1;
+  required ReturnState state = 1;
   optional KeyValueSetProto sessionVars = 2;
-  optional string message = 3;
 }
 
 message SessionedStringProto {
@@ -61,9 +56,8 @@ message SessionedStringProto {
 }
 
 message ExplainQueryResponse {
-  required ResultCode resultCode = 1;
+  required ReturnState state = 1;
   optional string explain = 2;
-  optional string errorMessage = 3;
 }
 
 message QueryRequest {
@@ -74,9 +68,8 @@ message QueryRequest {
 }
 
 message UpdateQueryResponse {
-  required ResultCode resultCode = 1;
-  optional string errorMessage = 2;
-  optional KeyValueSetProto sessionVars = 3;
+  required ReturnState state = 1;
+  optional KeyValueSetProto sessionVars = 2;
 }
 
 message GetQueryResultRequest {
@@ -85,8 +78,8 @@ message GetQueryResultRequest {
 }
 
 message GetQueryResultResponse {
-  optional TableDescProto tableDesc = 1;
-  optional string errorMessage = 2;
+  required ReturnState state = 1;
+  optional TableDescProto tableDesc = 2;
   optional string tajoUserName = 3;
 }
 
@@ -111,7 +104,8 @@ message BriefQueryInfo {
 }
 
 message GetQueryListResponse {
-  repeated BriefQueryInfo queryList = 1;
+  required ReturnState state = 1;
+  repeated BriefQueryInfo queryList = 2;
 }
 
 message GetQueryStatusRequest {
@@ -126,9 +120,9 @@ message SerializedResultSet {
 }
 
 message SubmitQueryResponse {
-  required ResultCode resultCode = 1;
-  required QueryIdProto queryId = 2;
-  required string userName = 3;
+  required ReturnState state = 1;
+  optional QueryIdProto queryId = 2;
+  optional string userName = 3;
   optional bool isForwarded = 4 [default = false];
 
   optional string queryMasterHost = 5;
@@ -138,16 +132,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 ResultCode resultCode = 1;
-  required QueryIdProto queryId = 2;
-  optional QueryState state = 3;
+  required ReturnState state = 1;
+  optional QueryIdProto queryId = 2;
+  optional QueryState query_state = 3;
   optional float progress = 4;
   optional int64 submitTime = 5;
   optional int64 finishTime = 7;
@@ -165,10 +156,8 @@ message GetQueryResultDataRequest {
 }
 
 message GetQueryResultDataResponse {
-  required ResultCode resultCode = 1;
-  required SerializedResultSet resultSet = 2;
-  optional string errorMessage = 3;
-  optional string errorTrace = 4;
+  required ReturnState state = 1;
+  optional SerializedResultSet resultSet = 2;
 }
 
 message GetClusterInfoRequest {
@@ -186,7 +175,8 @@ message WorkerResourceInfo {
 }
 
 message GetClusterInfoResponse {
-  repeated WorkerResourceInfo workerList = 1;
+  required ReturnState state = 1;
+  repeated WorkerResourceInfo workerList = 2;
 }
 
 message CreateTableRequest {
@@ -204,18 +194,6 @@ message DropTableRequest {
   optional bool purge = 3 [default = false];
 }
 
-message TableResponse {
-  required ResultCode resultCode = 1;
-  optional TableDescProto tableDesc = 2;
-  optional string errorMessage = 3;
-}
-
-message FunctionResponse {
-  required ResultCode resultCode = 1;
-  repeated FunctionDescProto functions = 2;
-  optional string errorMessage = 3;
-}
-
 message QueryInfoProto {
   required string queryId = 1;
   optional string sql = 2;
@@ -266,14 +244,12 @@ message QueryHistoryProto {
 }
 
 message GetQueryHistoryResponse {
-  required ResultCode resultCode = 1;
+  required ReturnState state = 1;
   optional QueryHistoryProto queryHistory = 2;
-  optional string errorMessage = 3;
 }
 
 message GetQueryInfoResponse {
-  required ResultCode resultCode = 1;
+  required ReturnState state = 1;
   optional QueryInfoProto queryInfo = 2;
-  optional string errorMessage = 3;
 }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/proto/QueryMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/QueryMasterClientProtocol.proto b/tajo-client/src/main/proto/QueryMasterClientProtocol.proto
index 0b11566..eb0443d 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 {

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
index 468a998..1dcf1ac 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;
@@ -32,11 +34,11 @@ service TajoMasterClientProtocolService {
 
   // Session APIs
   rpc createSession(CreateSessionRequest) returns (CreateSessionResponse);
-  rpc removeSession(SessionIdProto) returns (BoolProto);
+  rpc removeSession(SessionIdProto) returns (ReturnState);
   rpc updateSessionVariables(UpdateSessionVariableRequest) returns (SessionUpdateResponse);
-  rpc existSessionVariable(SessionedStringProto) returns (BoolProto);
+  rpc existSessionVariable(SessionedStringProto) returns (ReturnState);
   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);
@@ -48,24 +50,24 @@ 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 (ReturnState);
   rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse);
-  rpc closeNonForwardQuery(QueryIdRequest) returns (BoolProto);
+  rpc closeNonForwardQuery(QueryIdRequest) returns (ReturnState);
   rpc getQueryInfo(QueryIdRequest) returns (GetQueryInfoResponse);
 
   // Database Management APIs
-  rpc createDatabase(SessionedStringProto) returns (BoolProto);
-  rpc existDatabase(SessionedStringProto) returns (BoolProto);
-  rpc dropDatabase(SessionedStringProto) returns (BoolProto);
-  rpc getAllDatabases(SessionIdProto) returns (StringListProto);
-  rpc getCurrentDatabase(SessionIdProto) returns (StringProto);
-  rpc selectDatabase(SessionedStringProto) returns (BoolProto);
+  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 (ReturnState);
 
   // Table Management APIs
   rpc createExternalTable(CreateTableRequest) returns (TableResponse);
-  rpc existTable(SessionedStringProto) returns (BoolProto);
-  rpc dropTable(DropTableRequest) returns (BoolProto);
-  rpc getTableList(SessionedStringProto) returns (StringListProto);
+  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);
+  rpc getFunctionList(SessionedStringProto) returns (FunctionListResponse);
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-common/pom.xml b/tajo-common/pom.xml
index 2f96a2c..6806265 100644
--- a/tajo-common/pom.xml
+++ b/tajo-common/pom.xml
@@ -151,6 +151,8 @@
                 <argument>src/main/proto/DataTypes.proto</argument>
                 <argument>src/main/proto/PrimitiveProtos.proto</argument>
                 <argument>src/main/proto/tajo_protos.proto</argument>
+                <argument>src/main/proto/stacktrace.proto</argument>
+                <argument>src/main/proto/errors.proto</argument>
               </arguments>
             </configuration>
             <goals>

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java b/tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java
deleted file mode 100644
index a4805cc..0000000
--- a/tajo-common/src/main/java/org/apache/tajo/common/exception/InvalidAddressException.java
+++ /dev/null
@@ -1,25 +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 InvalidAddressException extends Exception {
-
-	private static final long serialVersionUID = -7266998886109689882L;
-
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/common/exception/NotImplementedException.java
----------------------------------------------------------------------
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 2690b47..0000000
--- 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);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/common/type/IPv4.java
----------------------------------------------------------------------
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 ba1575f..b5a0da2 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;

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
new file mode 100644
index 0000000..b051eb5
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorMessages.java
@@ -0,0 +1,134 @@
+/*
+ * 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.Map;
+
+import static org.apache.tajo.error.Errors.ResultCode.*;
+
+public class ErrorMessages {
+  public static final Map<ResultCode, Pair<String, Integer>> MESSAGES;
+
+  static {
+    MESSAGES = Maps.newHashMap();
+
+    // Warnings
+
+    // General Errors
+    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(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(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(SYNTAX_ERROR, "%s", 1);
+    ADD_MESSAGE(INSUFFICIENT_PRIVILEGE, "Insufficient privilege to %s");
+    ADD_MESSAGE(INVALID_NAME, "Invalid name '%s'");
+
+    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_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);
+    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 for '%s' already exists", 1);
+
+    ADD_MESSAGE(DIVISION_BY_ZERO, "Division by zero: %s", 1);
+
+    ADD_MESSAGE(DATATYPE_MISMATCH,
+        "column \"%s\" is of type %s but expression %s is of type %s", 4);
+
+    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(CAT_UPGRADE_REQUIRED, "catalog must be upgraded");
+    ADD_MESSAGE(CAT_CANNOT_CONNECT, "cannot connect metadata store '%s': %s", 2);
+
+    ADD_MESSAGE(MDC_NO_MATCHED_DATATYPE, "no matched type for %s", 1);
+
+    ADD_MESSAGE(UNKNOWN_DATAFORMAT, "Unknown data format: '%s'", 1);
+  }
+
+  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<String, Integer>(msgFormat, argNum));
+  }
+
+  public static String getInternalErrorMessage() {
+    return MESSAGES.get(INTERNAL_ERROR).getFirst();
+  }
+
+  public static String getInternalErrorMessage(Throwable t) {
+    if (t.getMessage() != null) {
+      return MESSAGES.get(INTERNAL_ERROR).getFirst() + ": " + t.getMessage();
+    } else {
+      return getInternalErrorMessage();
+    }
+
+  }
+
+  public static String getMessage(ResultCode code, String...args) {
+    if (!MESSAGES.containsKey(code)) {
+      throw new TajoInternalError("no error message for " + code);
+    } else {
+
+      Pair<String, Integer> 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);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/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 0000000..025a20c
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/ErrorUtil.java
@@ -0,0 +1,44 @@
+/**
+ * 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;
+import org.apache.tajo.error.Stacktrace;
+
+public class ErrorUtil {
+  public static boolean isOk(ResultCode code) {
+    return code == ResultCode.OK;
+  }
+
+  public static boolean isFailed(ResultCode code) {
+    return code != ResultCode.OK;
+  }
+
+  public static Stacktrace.StackTrace convertStacktrace(Throwable t) {
+    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();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java
----------------------------------------------------------------------
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 0000000..bc01cb9
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/ExceptionUtil.java
@@ -0,0 +1,64 @@
+/*
+ * 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.commons.logging.Log;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+
+public class ExceptionUtil {
+
+  /**
+   * 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;
+  }
+
+  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);
+    }
+  }
+
+  public static UnsupportedException makeNotSupported(String feature) {
+    return new UnsupportedException(feature);
+  }
+
+  public static InvalidDataTypeException makeInvalidDataType(DataType dataType) {
+    return new InvalidDataTypeException(dataType);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java
new file mode 100644
index 0000000..1300a6e
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidAddressException.java
@@ -0,0 +1,25 @@
+/**
+ * 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;
+
+public class InvalidAddressException extends Exception {
+
+	private static final long serialVersionUID = -7266998886109689882L;
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.java
new file mode 100644
index 0000000..9f470f2
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/InvalidDataTypeException.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.exception;
+
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.error.Errors;
+
+public class InvalidDataTypeException extends TajoRuntimeException {
+
+  public InvalidDataTypeException(DataType dataType) {
+    super(Errors.ResultCode.INVALID_DATATYPE, dataType.getType().name());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..862889e
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/ReturnStateUtil.java
@@ -0,0 +1,200 @@
+/*
+ * 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.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;
+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 {
+
+  public static final ReturnState OK;
+
+  static {
+    ReturnState.Builder builder = ReturnState.newBuilder();
+    builder.setReturnCode(ResultCode.OK);
+    OK = builder.build();
+  }
+
+  public static void ensureOk(ReturnState state) {
+    if (isError(state)) {
+      throw new TajoRuntimeException(state);
+    }
+  }
+
+  public static StringListResponse returnStringList(Collection<String> 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);
+    builder.setMessage(ErrorMessages.getMessage(code));
+    return builder.build();
+  }
+
+  public static ReturnState returnError(ResultCode code, String...args) {
+    Preconditions.checkNotNull(args);
+
+    ReturnState.Builder builder = ReturnState.newBuilder();
+    builder.setReturnCode(code);
+    builder.setMessage(ErrorMessages.getMessage(code, args));
+    return builder.build();
+  }
+
+  public static ReturnState returnError(Throwable t) {
+    ReturnState.Builder builder = ReturnState.newBuilder();
+
+    if (ExceptionUtil.isExceptionWithResultCode(t)) {
+      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(ReturnState 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(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);
+  }
+
+  public static ReturnState errInvalidRpcCall(String message) {
+    return returnError(ResultCode.INVALID_RPC_CALL, message);
+  }
+
+  public static ReturnState errNoSuchQueryId(QueryId queryId) {
+    return returnError(ResultCode.NO_SUCH_QUERYID, queryId.toString());
+  }
+
+  public static ReturnState errNoData(QueryId queryId) {
+    return returnError(ResultCode.NO_DATA, queryId.toString());
+  }
+
+  public static ReturnState errIncompleteQuery(QueryId queryId) {
+    return returnError(ResultCode.INCOMPLETE_QUERY, queryId.toString());
+  }
+
+  public static ReturnState errInvalidSession(String sessionId) {
+    return returnError(ResultCode.INVALID_SESSION, sessionId);
+  }
+
+  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 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);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java b/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
new file mode 100644
index 0000000..10b5aff
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/SQLExceptionUtil.java
@@ -0,0 +1,99 @@
+/*
+ * 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.exception.ErrorMessages;
+import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState;
+
+import java.sql.SQLException;
+import java.util.Map;
+
+import static org.apache.tajo.exception.ReturnStateUtil.isError;
+
+public class SQLExceptionUtil {
+
+  private static final Map<ResultCode, String> SQLSTATES = Maps.newHashMap();
+
+  static {
+    // TODO - All SQLState should be be filled
+    SQLSTATES.put(ResultCode.FEATURE_NOT_SUPPORTED, "0A000");
+    SQLSTATES.put(ResultCode.NOT_IMPLEMENTED, "0A000");
+
+    SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601");
+  }
+
+  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);
+    }
+  }
+
+  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).
+      return new SQLException(
+          state.getMessage(),
+          "42000",
+          ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_VALUE
+      );
+    }
+  }
+
+  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());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java
----------------------------------------------------------------------
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 0000000..dbb2748
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoError.java
@@ -0,0 +1,53 @@
+/*
+ * 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, 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;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java b/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
new file mode 100644
index 0000000..781d1a0
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoException.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * 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;
+
+  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;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java
----------------------------------------------------------------------
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 0000000..e0444a0
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoExceptionInterface.java
@@ -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.
+ */
+
+package org.apache.tajo.exception;
+
+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();
+
+  String getMessage();
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java
----------------------------------------------------------------------
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 0000000..5ffa26d
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoInternalError.java
@@ -0,0 +1,35 @@
+/*
+ * 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 for Internal Bugs and Unexpected exception
+ */
+public class TajoInternalError extends TajoError {
+
+  public TajoInternalError(String message) {
+    super(ResultCode.INTERNAL_ERROR, message);
+  }
+
+  public TajoInternalError(Throwable t) {
+    super(ResultCode.INTERNAL_ERROR, t.getMessage());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java
----------------------------------------------------------------------
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 0000000..dfde534
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/exception/TajoRuntimeException.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+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;
+
+  public TajoRuntimeException(ReturnState state) {
+    super(state.getMessage());
+    this.code = state.getReturnCode();
+  }
+
+  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;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/UndefinedOperatorException.java
----------------------------------------------------------------------
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 0000000..9d91946
--- /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);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/UnimplementedException.java
----------------------------------------------------------------------
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 3e4555d..b32079f 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);
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/java/org/apache/tajo/exception/UnsupportedException.java
----------------------------------------------------------------------
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 1e19622..9ca5539 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.FEATURE_NOT_SUPPORTED, featureName);
   }
 
-  public UnsupportedException(String message, Throwable cause) {
-    super(message, cause);
+  public UnsupportedException() {
+    super(Errors.ResultCode.FEATURE_NOT_SUPPORTED, Thread.currentThread().getStackTrace()[1].getClassName());
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/5d62c409/tajo-common/src/main/proto/PrimitiveProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/proto/PrimitiveProtos.proto b/tajo-common/src/main/proto/PrimitiveProtos.proto
index 631916a..0fdd1bb 100644
--- a/tajo-common/src/main/proto/PrimitiveProtos.proto
+++ b/tajo-common/src/main/proto/PrimitiveProtos.proto
@@ -21,6 +21,9 @@ 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;
 }
@@ -52,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


Mime
View raw message