You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by ji...@apache.org on 2015/06/24 04:23:54 UTC

[1/8] tajo git commit: TAJO-1634: REST API: fix error when offset is zero.

Repository: tajo
Updated Branches:
  refs/heads/index_support f674fa8f0 -> 00a8c658e


TAJO-1634: REST API: fix error when offset is zero.

Closes #597

Signed-off-by: JaeHwa Jung <bl...@apache.org>


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

Branch: refs/heads/index_support
Commit: 011de8bab375b01d8c2d07abebb6bf7ca94ae8c0
Parents: dc49049
Author: DaeMyung Kang <ch...@naver.com>
Authored: Tue Jun 16 06:43:49 2015 +0900
Committer: JaeHwa Jung <bl...@apache.org>
Committed: Tue Jun 16 06:43:49 2015 +0900

----------------------------------------------------------------------
 CHANGES                                                           | 3 +++
 .../java/org/apache/tajo/ws/rs/resources/QueryResultResource.java | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/011de8ba/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 045f944..57b8baa 100644
--- a/CHANGES
+++ b/CHANGES
@@ -154,6 +154,9 @@ Release 0.11.0 - unreleased
 
   BUG FIXES
 
+    TAJO-1634: REST API: fix error when offset is zero.
+    (Contributed by DaeMyung Kang, Committed by jaehwa)
+
     TAJO-1630: Test failure after TAJO-1130. (jihoon)
 
     TAJO-1623: INSERT INTO with wrong target columns causes NPE. (hyunsik)

http://git-wip-us.apache.org/repos/asf/tajo/blob/011de8ba/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResultResource.java
----------------------------------------------------------------------
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 6d110e5..3384c90 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
@@ -349,7 +349,7 @@ public class QueryResultResource {
     }
 
     private void skipOffsetRow(NonForwardQueryResultScanner queryResultScanner, int offset) throws IOException {
-      if (offset < 0) {
+      if (offset <= 0) {
         return;
       }
 


[6/8] tajo git commit: TAJO-751: JDBC driver should support cancel() method.

Posted by ji...@apache.org.
TAJO-751: JDBC driver should support cancel() method.

Closes #605, Closes #459

Signed-off-by: Jihoon Son <ji...@apache.org>


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

Branch: refs/heads/index_support
Commit: 0f7ff8f01170665000ac7d2edc1d28710de69af4
Parents: fc92be7
Author: navis.ryu <na...@apache.org>
Authored: Tue Jun 23 13:48:44 2015 +0900
Committer: Jihoon Son <ji...@apache.org>
Committed: Tue Jun 23 13:48:44 2015 +0900

----------------------------------------------------------------------
 CHANGES                                         |   3 +
 .../org/apache/tajo/client/QueryClientImpl.java |  12 +-
 .../apache/tajo/client/SessionConnection.java   |  18 +-
 .../java/org/apache/tajo/client/TajoClient.java |   3 +
 .../org/apache/tajo/client/TajoClientUtil.java  |  21 +-
 .../org/apache/tajo/jdbc/FetchResultSet.java    |  15 +-
 .../apache/tajo/jdbc/TajoMemoryResultSet.java   |  10 +-
 .../org/apache/tajo/jdbc/TajoResultSetBase.java |  19 +-
 .../org/apache/tajo/jdbc/WaitingResultSet.java  |  71 +++++
 .../java/org/apache/tajo/OverridableConf.java   |   4 +
 .../src/main/java/org/apache/tajo/QueryId.java  |   4 +
 .../main/java/org/apache/tajo/SessionVars.java  |   4 +-
 .../java/org/apache/tajo/conf/TajoConf.java     |   1 +
 .../java/org/apache/tajo/util/KeyValueSet.java  |  59 +++-
 .../org/apache/tajo/master/QueryInProgress.java |  10 +-
 .../tajo/master/TajoMasterClientService.java    |   7 +-
 .../apache/tajo/querymaster/Repartitioner.java  |   4 +-
 .../java/org/apache/tajo/jdbc/TestTajoJdbc.java |  37 ++-
 .../TestTajoCli/testHelpSessionVars.result      |   1 +
 .../org/apache/tajo/jdbc/JdbcConnection.java    |   6 +-
 .../apache/tajo/jdbc/TajoMetaDataResultSet.java |   9 +-
 .../apache/tajo/jdbc/TajoPreparedStatement.java | 276 ++-----------------
 .../org/apache/tajo/jdbc/TajoStatement.java     | 199 ++++++++-----
 23 files changed, 396 insertions(+), 397 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 6c54511..d64022a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,9 @@ Release 0.11.0 - unreleased
 
   IMPROVEMENT
 
+    TAJO-751: JDBC driver should support cancel() method.
+    (Contributed by navis, Committed by jihoon)
+
     TAJO-1649: Change Rest API /databases/{database-name}/functions to 
     /functions. (Contributed by DaeMyung Kang, Committed by hyunsik)
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
index ac25933..da10f55 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
@@ -258,17 +258,7 @@ public class QueryClientImpl implements QueryClient {
       return createNullResultSet(queryId);
     }
 
-    QueryStatus status = getQueryStatus(queryId);
-
-    while(status != null && !TajoClientUtil.isQueryComplete(status.getState())) {
-      try {
-        Thread.sleep(500);
-      } catch (InterruptedException e) {
-        e.printStackTrace();
-      }
-
-      status = getQueryStatus(queryId);
-    }
+    QueryStatus status = TajoClientUtil.waitCompletion(this, queryId);
 
     if (status.getState() == TajoProtos.QueryState.QUERY_SUCCEEDED) {
       if (status.hasResult()) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/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 ee2d45a..e1a3791 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
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.tajo.SessionVars;
 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.ipc.ClientProtos;
@@ -67,16 +68,16 @@ public class SessionConnection implements Closeable {
 
   volatile TajoIdProtos.SessionIdProto sessionId;
 
-  private AtomicBoolean closed = new AtomicBoolean(false);
+  private final AtomicBoolean closed = new AtomicBoolean(false);
 
   /** session variable cache */
   private final Map<String, String> sessionVarsCache = new HashMap<String, String>();
 
-  private ServiceTracker serviceTracker;
+  private final ServiceTracker serviceTracker;
 
   private NettyClientBase client;
 
-  private KeyValueSet properties;
+  private final KeyValueSet properties;
 
   /**
    * Connect to TajoMaster
@@ -87,17 +88,16 @@ public class SessionConnection implements Closeable {
    * @param properties configurations
    * @throws java.io.IOException
    */
-  public SessionConnection(ServiceTracker tracker, @Nullable String baseDatabase,
-                           KeyValueSet properties) throws IOException {
-
+  public SessionConnection(@NotNull ServiceTracker tracker, @Nullable String baseDatabase,
+                           @NotNull KeyValueSet properties) throws IOException {
+    this.serviceTracker = tracker;
+    this.baseDatabase = baseDatabase;
     this.properties = properties;
 
     this.manager = RpcClientManager.getInstance();
     this.manager.setRetries(properties.getInt(RpcConstants.RPC_CLIENT_RETRY_MAX, RpcConstants.DEFAULT_RPC_RETRIES));
     this.userInfo = UserRoleInfo.getCurrentUser();
-    this.baseDatabase = baseDatabase != null ? baseDatabase : null;
 
-    this.serviceTracker = tracker;
     try {
       this.client = getTajoMasterConnection();
     } catch (ServiceException e) {
@@ -125,7 +125,7 @@ public class SessionConnection implements Closeable {
     }
   }
 
-  protected KeyValueSet getProperties() {
+  public KeyValueSet getProperties() {
     return properties;
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/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 376f63f..85929e8 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
@@ -19,9 +19,12 @@
 package org.apache.tajo.client;
 
 import org.apache.tajo.annotation.ThreadSafe;
+import org.apache.tajo.util.KeyValueSet;
 
 import java.io.Closeable;
 
 @ThreadSafe
 public interface TajoClient extends QueryClient, CatalogAdminClient, Closeable {
+
+  KeyValueSet getProperties();
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/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 ea15aed..bab699e 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,9 @@
 
 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;
 import org.apache.tajo.TajoProtos;
 import org.apache.tajo.catalog.CatalogUtil;
@@ -27,6 +29,8 @@ 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;
@@ -56,6 +60,21 @@ public class TajoClientUtil {
     return !isQueryWaitingForSchedule(state) && !isQueryRunning(state);
   }
 
+  public static QueryStatus waitCompletion(QueryClient client, QueryId queryId) throws ServiceException {
+    QueryStatus status = client.getQueryStatus(queryId);
+
+    while(!isQueryComplete(status.getState())) {
+      try {
+        Thread.sleep(500);
+      } catch (InterruptedException e) {
+        e.printStackTrace();
+      }
+
+      status = client.getQueryStatus(queryId);
+    }
+    return status;
+  }
+
   public static ResultSet createResultSet(TajoClient client, QueryId queryId,
                                           ClientProtos.GetQueryResultResponse response, int fetchRows)
       throws IOException {
@@ -91,7 +110,7 @@ public class TajoClientUtil {
   }
 
   public static ResultSet createNullResultSet() {
-    return new TajoMemoryResultSet(null, new Schema(), null, 0, null);
+    return new TajoMemoryResultSet(QueryIdFactory.NULL_QUERY_ID, new Schema(), null, 0, null);
   }
 
   public static ResultSet createNullResultSet(QueryId queryId) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-client/src/main/java/org/apache/tajo/jdbc/FetchResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/FetchResultSet.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/FetchResultSet.java
index efe070e..869d7c4 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/FetchResultSet.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/FetchResultSet.java
@@ -27,26 +27,19 @@ import java.io.IOException;
 import java.sql.SQLException;
 
 public class FetchResultSet extends TajoResultSetBase {
-  private QueryClient tajoClient;
-  private QueryId queryId;
+  protected QueryClient tajoClient;
   private int fetchRowNum;
   private TajoMemoryResultSet currentResultSet;
-  private boolean finished = false;
-// maxRows number is limit value of resultSet. The value must be >= 0, and 0 means there is not limit.
+  private boolean finished;
+  // maxRows number is limit value of resultSet. The value must be >= 0, and 0 means there is not limit.
   private int maxRows;
 
   public FetchResultSet(QueryClient tajoClient, Schema schema, QueryId queryId, int fetchRowNum) {
-    super(tajoClient.getClientSideSessionVars());
+    super(queryId, schema, tajoClient.getClientSideSessionVars());
     this.tajoClient = tajoClient;
     this.maxRows = tajoClient.getMaxRows();
-    this.queryId = queryId;
     this.fetchRowNum = fetchRowNum;
     this.totalRow = Integer.MAX_VALUE;
-    this.schema = schema;
-  }
-
-  public QueryId getQueryId() {
-    return queryId;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoMemoryResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoMemoryResultSet.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoMemoryResultSet.java
index 33cb838..4114d03 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoMemoryResultSet.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoMemoryResultSet.java
@@ -31,20 +31,16 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 public class TajoMemoryResultSet extends TajoResultSetBase {
-  private QueryId queryId;
   private List<ByteString> serializedTuples;
   private AtomicBoolean closed = new AtomicBoolean(false);
   private RowStoreUtil.RowStoreDecoder decoder;
 
   public TajoMemoryResultSet(QueryId queryId, Schema schema, List<ByteString> serializedTuples, int maxRowNum,
                              Map<String, String> clientSideSessionVars) {
-    super(clientSideSessionVars);
-    this.queryId = queryId;
-    this.schema = schema;
+    super(queryId, schema, clientSideSessionVars);
     this.totalRow = maxRowNum;
     this.serializedTuples = serializedTuples;
     this.decoder = RowStoreUtil.createDecoder(schema);
-    init();
   }
 
   @Override
@@ -53,10 +49,6 @@ public class TajoMemoryResultSet extends TajoResultSetBase {
     curRow = 0;
   }
 
-  public QueryId getQueryId() {
-    return queryId;
-  }
-
   @Override
   public synchronized void close() throws SQLException {
     if (closed.getAndSet(true)) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
index ed06cf3..3d8d9aa 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.jdbc;
 
+import org.apache.tajo.QueryId;
 import org.apache.tajo.SessionVars;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.common.TajoDataTypes;
@@ -47,7 +48,11 @@ public abstract class TajoResultSetBase implements ResultSet {
   protected Schema schema;
   protected Tuple cur;
 
-  public TajoResultSetBase(@Nullable Map<String, String> clientSideSessionVars) {
+  protected final QueryId queryId;
+
+  public TajoResultSetBase(QueryId queryId, Schema schema, @Nullable Map<String, String> clientSideSessionVars) {
+    this.queryId = queryId;
+    this.schema = schema;
     this.clientSideSessionVars = clientSideSessionVars;
 
     if (clientSideSessionVars != null) {
@@ -73,6 +78,14 @@ public abstract class TajoResultSetBase implements ResultSet {
     return wasNull = tuple.isBlankOrNull(index);
   }
 
+  protected Schema getSchema() throws SQLException {
+    return schema;
+  }
+
+  public QueryId getQueryId() {
+    return queryId;
+  }
+
   public Tuple getCurrentTuple() {
     return cur;
   }
@@ -395,7 +408,7 @@ public abstract class TajoResultSetBase implements ResultSet {
 
   @Override
   public int findColumn(String colName) throws SQLException {
-    return schema.getColumnIdByName(colName);
+    return getSchema().getColumnIdByName(colName);
   }
 
   @Override
@@ -511,7 +524,7 @@ public abstract class TajoResultSetBase implements ResultSet {
 
   @Override
   public ResultSetMetaData getMetaData() throws SQLException {
-    return new TajoResultSetMetaData(schema);
+    return new TajoResultSetMetaData(getSchema());
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
new file mode 100644
index 0000000..b9f8df5
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/WaitingResultSet.java
@@ -0,0 +1,71 @@
+/**
+ * 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.protobuf.ServiceException;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.TajoProtos;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.QueryClient;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.client.TajoClientUtil;
+import org.apache.tajo.ipc.ClientProtos;
+
+import java.sql.SQLException;
+
+/**
+ * Blocks on schema retrieval if it's not ready
+ */
+public class WaitingResultSet extends FetchResultSet {
+
+  public WaitingResultSet(QueryClient tajoClient, QueryId queryId, int fetchRowNum)
+      throws SQLException {
+    super(tajoClient, null, queryId, fetchRowNum);
+  }
+
+  @Override
+  public boolean next() throws SQLException {
+    getSchema();
+    return super.next();
+  }
+
+  @Override
+  protected Schema getSchema() throws SQLException {
+    return schema == null ? schema = waitOnResult() : schema;
+  }
+
+  private Schema waitOnResult() throws SQLException {
+    try {
+      QueryStatus status = TajoClientUtil.waitCompletion(tajoClient, queryId);
+
+      if (status.getState() != TajoProtos.QueryState.QUERY_SUCCEEDED) {
+        throw new ServiceException(status.getErrorMessage() != null ? status.getErrorMessage() :
+            status.getErrorTrace() != null ? status.getErrorTrace() :
+                "Failed to execute query by unknown reason");
+      }
+      ClientProtos.GetQueryResultResponse response = tajoClient.getResultResponse(queryId);
+      TableDesc tableDesc = CatalogUtil.newTableDesc(response.getTableDesc());
+      return tableDesc.getLogicalSchema();
+    } catch (ServiceException e) {
+      throw new SQLException(e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java b/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
index 61bbb5a..c22f054 100644
--- a/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
+++ b/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
@@ -98,6 +98,7 @@ public class OverridableConf extends KeyValueSet {
     }
   }
 
+  @Override
   public boolean getBool(ConfigKey key) {
     return getBool(key, null);
   }
@@ -123,6 +124,7 @@ public class OverridableConf extends KeyValueSet {
     }
   }
 
+  @Override
   public int getInt(ConfigKey key) {
     return getInt(key, null);
   }
@@ -148,6 +150,7 @@ public class OverridableConf extends KeyValueSet {
     }
   }
 
+  @Override
   public long getLong(ConfigKey key) {
     return getLong(key, null);
   }
@@ -173,6 +176,7 @@ public class OverridableConf extends KeyValueSet {
     }
   }
 
+  @Override
   public float getFloat(ConfigKey key) {
     return getLong(key, null);
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-common/src/main/java/org/apache/tajo/QueryId.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/QueryId.java b/tajo-common/src/main/java/org/apache/tajo/QueryId.java
index 85882c1..35ca75c 100644
--- a/tajo-common/src/main/java/org/apache/tajo/QueryId.java
+++ b/tajo-common/src/main/java/org/apache/tajo/QueryId.java
@@ -44,6 +44,10 @@ public class QueryId implements Comparable<QueryId> {
     return seq;
   }
 
+  public boolean isNull() {
+    return this.equals(QueryIdFactory.NULL_QUERY_ID);
+  }
+
   @Override
   public String toString() {
     return QUERY_ID_PREFIX + SEPARATOR + toStringNoPrefix();

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-common/src/main/java/org/apache/tajo/SessionVars.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/SessionVars.java b/tajo-common/src/main/java/org/apache/tajo/SessionVars.java
index 031387c..98c2f3e 100644
--- a/tajo-common/src/main/java/org/apache/tajo/SessionVars.java
+++ b/tajo-common/src/main/java/org/apache/tajo/SessionVars.java
@@ -102,7 +102,7 @@ public enum SessionVars implements ConfigKey {
   GROUPBY_PER_SHUFFLE_SIZE(ConfVars.$DIST_QUERY_GROUPBY_PARTITION_VOLUME, "shuffle output size for sort (mb)", DEFAULT,
       Integer.class, Validators.min("1")),
   TABLE_PARTITION_PER_SHUFFLE_SIZE(ConfVars.$DIST_QUERY_TABLE_PARTITION_VOLUME,
-      "shuffle output size for partition table write (mb)", DEFAULT, Long.class, Validators.min("1")),
+      "shuffle output size for partition table write (mb)", DEFAULT, Integer.class, Validators.min("1")),
 
   GROUPBY_MULTI_LEVEL_ENABLED(ConfVars.$GROUPBY_MULTI_LEVEL_ENABLED, "Multiple level groupby enabled", DEFAULT,
       Boolean.class, Validators.bool()),
@@ -133,6 +133,8 @@ public enum SessionVars implements ConfigKey {
   // ResultSet ----------------------------------------------------------------
   FETCH_ROWNUM(ConfVars.$RESULT_SET_FETCH_ROWNUM, "Sets the number of rows at a time from Master", DEFAULT,
       Integer.class, Validators.min("0")),
+  BLOCK_ON_RESULT(ConfVars.$RESULT_SET_BLOCK_WAIT, "Whether to block result set on query execution", DEFAULT,
+      Boolean.class, Validators.bool()),
 
   //-------------------------------------------------------------------------------
   // Only for Unit Testing

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java b/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
index 3f350c3..ba777c1 100644
--- a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
+++ b/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
@@ -378,6 +378,7 @@ public class TajoConf extends Configuration {
 
     // ResultSet ---------------------------------------------------------
     $RESULT_SET_FETCH_ROWNUM("tajo.resultset.fetch.rownum", 200),
+    $RESULT_SET_BLOCK_WAIT("tajo.resultset.block.wait", true),
     ;
 
     public final String varname;

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java b/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java
index 5dba9e2..0e27769 100644
--- a/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java
+++ b/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java
@@ -21,7 +21,10 @@ package org.apache.tajo.util;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.gson.annotations.Expose;
+import org.apache.tajo.ConfigKey;
+import org.apache.tajo.SessionVars;
 import org.apache.tajo.common.ProtoObject;
+import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.json.CommonGsonHelper;
 import org.apache.tajo.json.GsonObject;
 
@@ -37,7 +40,7 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
   public static final String FALSE_STR = "false";
 
   @Expose private Map<String,String> keyVals;
-	
+
 	public KeyValueSet() {
     keyVals = TUtil.newHashMap();
 	}
@@ -46,23 +49,23 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
     this();
     putAll(keyVals);
   }
-	
+
 	public KeyValueSet(KeyValueSetProto proto) {
     this.keyVals = TUtil.newHashMap();
     for(KeyValueProto keyval : proto.getKeyvalList()) {
       this.keyVals.put(keyval.getKey(), keyval.getValue());
     }
 	}
-	
+
 	public KeyValueSet(KeyValueSet keyValueSet) {
 	  this();
 	  this.keyVals.putAll(keyValueSet.keyVals);
 	}
-	
+
 	public static KeyValueSet create() {
 	  return new KeyValueSet();
 	}
-	
+
 	public static KeyValueSet create(KeyValueSet keyValueSet) {
     return new KeyValueSet(keyValueSet);
   }
@@ -119,7 +122,7 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
   public boolean getBool(String key, Boolean defaultVal) {
     if (containsKey(key)) {
       String strVal = get(key, null);
-      return strVal != null ? strVal.equalsIgnoreCase(TRUE_STR) : false;
+      return strVal != null && strVal.equalsIgnoreCase(TRUE_STR);
     } else if (defaultVal != null) {
       return defaultVal;
     } else {
@@ -131,6 +134,16 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
     return getBool(key, null);
   }
 
+  public boolean getBool(ConfigKey key) {
+    String keyName = key.keyname();
+    if (key instanceof SessionVars) {
+      return getBool(keyName, ((SessionVars)key).getConfVars().defaultBoolVal);
+    } else if (key instanceof TajoConf.ConfVars) {
+      return getBool(keyName, ((TajoConf.ConfVars)key).defaultBoolVal);
+    }
+    return getBool(keyName);
+  }
+
   public void setInt(String key, int val) {
     set(key, String.valueOf(val));
   }
@@ -150,6 +163,16 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
     return getInt(key, null);
   }
 
+  public int getInt(ConfigKey key) {
+    String keyName = key.keyname();
+    if (key instanceof SessionVars) {
+      return getInt(keyName, ((SessionVars) key).getConfVars().defaultIntVal);
+    } else if (key instanceof TajoConf.ConfVars) {
+      return getInt(keyName, ((TajoConf.ConfVars) key).defaultIntVal);
+    }
+    return getInt(keyName);
+  }
+
   public void setLong(String key, long val) {
     set(key, String.valueOf(val));
   }
@@ -169,6 +192,16 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
     return getLong(key, null);
   }
 
+  public long getLong(ConfigKey key) {
+    String keyName = key.keyname();
+    if (key instanceof SessionVars) {
+      return getLong(keyName, ((SessionVars) key).getConfVars().defaultLongVal);
+    } else if (key instanceof TajoConf.ConfVars) {
+      return getLong(keyName, ((TajoConf.ConfVars) key).defaultLongVal);
+    }
+    return getLong(keyName);
+  }
+
   public void setFloat(String key, float val) {
     set(key, String.valueOf(val));
   }
@@ -185,7 +218,7 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
         throw new IllegalArgumentException("No such a config key: "  + key);
       }
     } else if (defaultVal != null) {
-      return defaultVal.floatValue();
+      return defaultVal;
     } else {
       throw new IllegalArgumentException("No such a config key: "  + key);
     }
@@ -194,7 +227,17 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs
   public float getFloat(String key) {
     return getFloat(key, null);
   }
-	
+
+  public float getFloat(ConfigKey key) {
+    String keyName = key.keyname();
+    if (key instanceof SessionVars) {
+      return getFloat(keyName, ((SessionVars) key).getConfVars().defaultFloatVal);
+    } else if (key instanceof TajoConf.ConfVars) {
+      return getFloat(keyName, ((TajoConf.ConfVars) key).defaultFloatVal);
+    }
+    return getFloat(keyName);
+  }
+
 	public String remove(String key) {
 		return keyVals.remove(key);
 	}

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-core/src/main/java/org/apache/tajo/master/QueryInProgress.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/QueryInProgress.java b/tajo-core/src/main/java/org/apache/tajo/master/QueryInProgress.java
index 6a074a2..ece42f7 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/QueryInProgress.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/QueryInProgress.java
@@ -247,7 +247,7 @@ public class QueryInProgress {
 
       // terminal state will let client to retrieve a query result
       // So, we must set the query result before changing query state
-      if (isFinishState(this.queryInfo.getQueryState())) {
+      if (isFinishState()) {
         if (queryInfo.hasResultdesc()) {
           this.queryInfo.setResultDesc(queryInfo.getResultDesc());
         }
@@ -260,7 +260,13 @@ public class QueryInProgress {
     }
   }
 
-  private boolean isFinishState(TajoProtos.QueryState state) {
+  public boolean isKillWait() {
+    TajoProtos.QueryState state = queryInfo.getQueryState();
+    return state == TajoProtos.QueryState.QUERY_KILL_WAIT;
+  }
+
+  public boolean isFinishState() {
+    TajoProtos.QueryState state = queryInfo.getQueryState();
     return state == TajoProtos.QueryState.QUERY_FAILED ||
         state == TajoProtos.QueryState.QUERY_ERROR ||
         state == TajoProtos.QueryState.QUERY_KILLED ||

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
----------------------------------------------------------------------
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 2602d7d..31eecdc 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.plan.logical.PartitionedTableScanNode;
 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.BoolProto;
 import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListProto;
 import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto;
@@ -619,6 +618,12 @@ public class TajoMasterClientService extends AbstractService {
       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;
+        }
+
         QueryManager queryManager = context.getQueryJobManager();
         queryManager.getEventHandler().handle(new QueryJobEvent(QueryJobEvent.Type.QUERY_JOB_KILL,
             new QueryInfo(queryId)));

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-core/src/main/java/org/apache/tajo/querymaster/Repartitioner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/querymaster/Repartitioner.java b/tajo-core/src/main/java/org/apache/tajo/querymaster/Repartitioner.java
index 4fe150b..ec09145 100644
--- a/tajo-core/src/main/java/org/apache/tajo/querymaster/Repartitioner.java
+++ b/tajo-core/src/main/java/org/apache/tajo/querymaster/Repartitioner.java
@@ -962,8 +962,8 @@ public class Repartitioner {
   public static void scheduleScatteredHashShuffleFetches(TaskSchedulerContext schedulerContext,
        Stage stage, Map<ExecutionBlockId, List<IntermediateEntry>> intermediates,
        String tableName) {
-    long splitVolume = StorageUnit.MB *
-        stage.getMasterPlan().getContext().getLong(SessionVars.TABLE_PARTITION_PER_SHUFFLE_SIZE);
+    long splitVolume = (long)StorageUnit.MB *
+        stage.getMasterPlan().getContext().getInt(SessionVars.TABLE_PARTITION_PER_SHUFFLE_SIZE);
     long pageSize = ((long)StorageUnit.MB) *
         stage.getContext().getConf().getIntVar(ConfVars.SHUFFLE_HASH_APPENDER_PAGE_VOLUME); // in bytes
     if (pageSize >= splitVolume) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
----------------------------------------------------------------------
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 c8c24cd..ad74046 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
@@ -19,13 +19,12 @@
 package org.apache.tajo.jdbc;
 
 import com.google.common.collect.Maps;
-import org.apache.tajo.IntegrationTest;
-import org.apache.tajo.QueryTestCaseBase;
-import org.apache.tajo.TajoConstants;
+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;
@@ -33,10 +32,7 @@ import org.junit.experimental.categories.Category;
 
 import java.net.InetSocketAddress;
 import java.sql.*;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
 import static org.junit.Assert.*;
@@ -673,4 +669,31 @@ public class TestTajoJdbc extends QueryTestCaseBase {
       }
     }
   }
+
+  @Test
+  public final void testCancel() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        DEFAULT_DATABASE_NAME);
+    Properties props = new Properties();
+    props.setProperty(SessionVars.BLOCK_ON_RESULT.keyname(), "false");
+
+    Connection conn = new JdbcConnection(connUri, props);
+    PreparedStatement statement = conn.prepareStatement("select sleep(1) from lineitem");
+    try {
+      assertTrue("should have result set", statement.execute());
+      TajoResultSetBase result = (TajoResultSetBase) statement.getResultSet();
+      Thread.sleep(1000);   // todo query master is not killed properly if it's compiling the query (use 100, if you want see)
+      statement.cancel();
+
+      QueryStatus status = client.getQueryStatus(result.getQueryId());
+      assertEquals(TajoProtos.QueryState.QUERY_KILLED, status.getState());
+    } finally {
+      if (statement != null) {
+        statement.close();
+      }
+      if (conn != null) {
+        conn.close();
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result b/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
index 7e741a9..137b0de 100644
--- a/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
+++ b/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
@@ -37,4 +37,5 @@ Available Session Variables:
 \set CODEGEN [true or false] - Runtime code generation enabled (experiment)
 \set ARITHABORT [true or false] - If true, a running query will be terminated when an overflow or divide-by-zero occurs.
 \set FETCH_ROWNUM [int value] - Sets the number of rows at a time from Master
+\set BLOCK_ON_RESULT [true or false] - Whether to block result set on query execution
 \set DEBUG_ENABLED [true or false] - (debug only) debug mode enabled

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/JdbcConnection.java
index c5d4868..d575968 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
@@ -21,11 +21,13 @@ package org.apache.tajo.jdbc;
 import com.google.protobuf.ServiceException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.SessionVars;
 import org.apache.tajo.TajoConstants;
 import org.apache.tajo.client.CatalogAdminClient;
 import org.apache.tajo.client.QueryClient;
 import org.apache.tajo.client.TajoClient;
 import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.jdbc.util.QueryStringDecoder;
 import org.apache.tajo.rpc.RpcUtils;
 import org.apache.tajo.util.KeyValueSet;
@@ -55,6 +57,8 @@ public class JdbcConnection implements Connection {
   /** it will be used soon. */
   private final Map<String, List<String>> params;
 
+  private final KeyValueSet clientProperties;
+
   public JdbcConnection(String rawURI, Properties properties) throws SQLException {
     this.rawURI = rawURI;
     this.properties = properties;
@@ -101,7 +105,7 @@ public class JdbcConnection implements Connection {
       throw new SQLException("Invalid JDBC URI: " + rawURI, "TAJO-001");
     }
 
-    KeyValueSet clientProperties = new KeyValueSet();
+    clientProperties = new KeyValueSet();
     if(properties != null) {
       for(Map.Entry<Object, Object> entry: properties.entrySet()) {
         clientProperties.set(entry.getKey().toString(), entry.getValue().toString());

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
index eb3595f..9fba40a 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
@@ -30,17 +30,12 @@ public class TajoMetaDataResultSet extends TajoResultSetBase {
   private List<MetaDataTuple> values;
 
   public TajoMetaDataResultSet(Schema schema, List<MetaDataTuple> values) {
-    super(null);
-    init();
-    this.schema = schema;
+    super(null, schema, null);
     setDataTuples(values);
   }
 
   public TajoMetaDataResultSet(List<String> columns, List<Type> types, List<MetaDataTuple> values) {
-    super(null);
-    init();
-    schema = new Schema();
-
+    super(null, new Schema(), null);
     int index = 0;
     if(columns != null) {
       for(String columnName: columns) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
index 229587a..0574bf9 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
@@ -30,35 +30,16 @@ import java.util.HashMap;
  * TajoPreparedStatement.
  *
  */
-public class TajoPreparedStatement implements PreparedStatement {
-  private JdbcConnection conn;
+public class TajoPreparedStatement extends TajoStatement implements PreparedStatement {
+
   private final String sql;
-  private TajoClient tajoClient;
+
   /**
    * save the SQL parameters {paramLoc:paramValue}
    */
   private final HashMap<Integer, String> parameters=new HashMap<Integer, String>();
 
   /**
-   * We need to keep a reference to the result set to support the following:
-   * <code>
-   * statement.execute(String sql);
-   * statement.getResultSet();
-   * </code>.
-   */
-  private ResultSet resultSet = null;
-
-  /**
-   * Add SQLWarnings to the warningChain if needed.
-   */
-  //private  SQLWarning warningChain = null;
-
-  /**
-   * Keep state so we can fail certain calls made after close().
-   */
-  private boolean isClosed = false;
-
-  /**
    * keep the current ResultRet update count
    */
   private int updateCount = 0;
@@ -69,8 +50,7 @@ public class TajoPreparedStatement implements PreparedStatement {
   public TajoPreparedStatement(JdbcConnection conn,
                                TajoClient tajoClient,
                                String sql) {
-    this.conn = conn;
-    this.tajoClient = tajoClient;
+    super(conn, tajoClient);
     this.sql = sql;
   }
 
@@ -81,6 +61,7 @@ public class TajoPreparedStatement implements PreparedStatement {
 
   @Override
   public void clearParameters() throws SQLException {
+    checkConnection("Can't clear parameters");
     this.parameters.clear();
   }
 
@@ -101,22 +82,14 @@ public class TajoPreparedStatement implements PreparedStatement {
     return updateCount;
   }
 
-  protected ResultSet executeImmediate(String sql) throws SQLException {
-    if (isClosed) {
-      throw new SQLException("Can't execute after statement has been closed");
-    }
+  protected TajoResultSetBase executeImmediate(String sql) throws SQLException {
+    checkConnection("Can't execute");
 
     try {
       if (sql.contains("?")) {
         sql = updateSql(sql, parameters);
       }
-      if (TajoStatement.isSetVariableQuery(sql)) {
-        return TajoStatement.setSessionVariable(tajoClient, sql);
-      } else if (TajoStatement.isUnSetVariableQuery(sql)) {
-        return TajoStatement.unSetSessionVariable(tajoClient, sql);
-      } else {
-        return tajoClient.executeQueryAndGetResult(sql);
-      }
+      return (TajoResultSetBase) executeSQL(sql);
     } catch (Exception e) {
       throw new SQLException(e.getMessage(), e);
     }
@@ -131,7 +104,7 @@ public class TajoPreparedStatement implements PreparedStatement {
    */
   private String updateSql(final String sql, HashMap<Integer, String> parameters) {
 
-    StringBuffer newSql = new StringBuffer(sql);
+    StringBuilder newSql = new StringBuilder(sql);
 
     int paramLoc = 1;
     while (getCharIndexFromSqlByParamLocation(sql, '?', paramLoc) > 0) {
@@ -179,6 +152,7 @@ public class TajoPreparedStatement implements PreparedStatement {
 
   @Override
   public ResultSetMetaData getMetaData() throws SQLException {
+    checkConnection("Can't get metadata");
     if(resultSet != null) {
       return resultSet.getMetaData();
     } else {
@@ -249,6 +223,7 @@ public class TajoPreparedStatement implements PreparedStatement {
 
   @Override
   public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+    checkConnection("Can't set parameters");
     this.parameters.put(parameterIndex, "" + x);
   }
 
@@ -306,21 +281,25 @@ public class TajoPreparedStatement implements PreparedStatement {
 
   @Override
   public void setDouble(int parameterIndex, double x) throws SQLException {
+    checkConnection("Can't set parameters");
     this.parameters.put(parameterIndex,"" + x);
   }
 
   @Override
   public void setFloat(int parameterIndex, float x) throws SQLException {
+    checkConnection("Can't set parameters");
     this.parameters.put(parameterIndex,"" + x);
   }
 
   @Override
   public void setInt(int parameterIndex, int x) throws SQLException {
+    checkConnection("Can't set parameters");
     this.parameters.put(parameterIndex,"" + x);
   }
 
   @Override
   public void setLong(int parameterIndex, long x) throws SQLException {
+    checkConnection("Can't set parameters");
     this.parameters.put(parameterIndex,"" + x);
   }
 
@@ -399,11 +378,13 @@ public class TajoPreparedStatement implements PreparedStatement {
 
   @Override
   public void setShort(int parameterIndex, short x) throws SQLException {
+    checkConnection("Can't set parameters");
     this.parameters.put(parameterIndex,"" + x);
   }
 
   @Override
   public void setString(int parameterIndex, String x) throws SQLException {
+    checkConnection("Can't set parameters");
      x=x.replace("'", "\\'");
      this.parameters.put(parameterIndex,"'" + x +"'");
   }
@@ -439,227 +420,4 @@ public class TajoPreparedStatement implements PreparedStatement {
       throws SQLException {
     throw new SQLFeatureNotSupportedException("setUnicodeStream not supported");
   }
-
-  @Override
-  public void addBatch(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("addBatch not supported");
-  }
-
-  @Override
-  public void cancel() throws SQLException {
-    throw new SQLFeatureNotSupportedException("cancel not supported");
-  }
-
-  @Override
-  public void clearBatch() throws SQLException {
-    throw new SQLFeatureNotSupportedException("clearBatch not supported");
-  }
-
-  @Override
-  public void clearWarnings() throws SQLException {
-  }
-
-  public void closeOnCompletion() throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("closeOnCompletion");
-  }
-
-  @Override
-  public void close() throws SQLException {
-    if (resultSet!=null) {
-      resultSet.close();
-      resultSet = null;
-    }
-    isClosed = true;
-  }
-
-  @Override
-  public boolean execute(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute(sql) not supported");
-  }
-
-  @Override
-  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute(sql) not supported");
-  }
-
-  @Override
-  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute(sql) not supported");
-  }
-
-  @Override
-  public boolean execute(String sql, String[] columnNames) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute(sql) not supported");
-  }
-
-  @Override
-  public int[] executeBatch() throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeBatch not supported");
-  }
-
-  @Override
-  public ResultSet executeQuery(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeQuery(sql) not supported");
-  }
-
-  @Override
-  public int executeUpdate(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
-  }
-
-  @Override
-  public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
-  }
-
-  @Override
-  public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
-  }
-
-  @Override
-  public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
-  }
-
-  @Override
-  public Connection getConnection() throws SQLException {
-    return conn;
-  }
-
-  @Override
-  public int getFetchDirection() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFetchDirection not supported");
-  }
-
-  @Override
-  public int getFetchSize() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFetchSize not supported");
-  }
-
-  @Override
-  public ResultSet getGeneratedKeys() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getGeneratedKeys not supported");
-  }
-
-  @Override
-  public int getMaxFieldSize() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxFieldSize not supported");
-  }
-
-  @Override
-  public int getMaxRows() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxRows not supported");
-  }
-
-  @Override
-  public boolean getMoreResults() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMoreResults not supported");
-  }
-
-  @Override
-  public boolean getMoreResults(int current) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMoreResults not supported");
-  }
-
-  @Override
-  public int getQueryTimeout() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getQueryTimeout not supported");
-  }
-
-  @Override
-  public ResultSet getResultSet() throws SQLException {
-    return this.resultSet;
-  }
-
-  @Override
-  public int getResultSetConcurrency() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getResultSetConcurrency not supported");
-  }
-
-  @Override
-  public int getResultSetHoldability() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getResultSetHoldability not supported");
-  }
-
-  @Override
-  public int getResultSetType() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getResultSetType not supported");
-  }
-
-  @Override
-  public int getUpdateCount() throws SQLException {
-    return updateCount;
-  }
-
-  @Override
-  public SQLWarning getWarnings() throws SQLException {
-    return null;
-  }
-
-  @Override
-  public boolean isClosed() throws SQLException {
-    return isClosed;
-  }
-
-   public boolean isCloseOnCompletion() throws SQLException {
-     //JDK 1.7
-     throw new SQLFeatureNotSupportedException("isCloseOnCompletion not supported");
-   }
-
-  @Override
-  public boolean isPoolable() throws SQLException {
-    throw new SQLFeatureNotSupportedException("isPoolable not supported");
-  }
-
-  @Override
-  public void setCursorName(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setCursorName not supported");
-  }
-
-  @Override
-  public void setEscapeProcessing(boolean enable) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setEscapeProcessing not supported");
-  }
-
-  @Override
-  public void setFetchDirection(int direction) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setFetchDirection not supported");
-  }
-
-  @Override
-  public void setFetchSize(int rows) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setFetchSize not supported");
-  }
-
-  @Override
-  public void setMaxFieldSize(int max) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setMaxFieldSize not supported");
-  }
-
-  @Override
-  public void setMaxRows(int max) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setMaxRows not supported");
-  }
-
-  @Override
-  public void setPoolable(boolean poolable) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setPoolable not supported");
-  }
-
-  @Override
-  public void setQueryTimeout(int seconds) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setQueryTimeout not supported");
-  }
-
-  @Override
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isWrapperFor not supported");
-  }
-
-  @Override
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw new SQLFeatureNotSupportedException("unwrap not supported");
-  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/0f7ff8f0/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
index 820e350..0f80ddf 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
@@ -19,17 +19,21 @@ 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.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;
 
 public class TajoStatement implements Statement {
-  private JdbcConnection conn;
-  private TajoClient tajoClient;
-  private int fetchSize = 200;
+  protected JdbcConnection conn;
+  protected TajoClient tajoClient;
+  protected int fetchSize = SessionVars.FETCH_ROWNUM.getConfVars().defaultIntVal;
 
   /**
    * We need to keep a reference to the result set to support the following:
@@ -38,35 +42,65 @@ public class TajoStatement implements Statement {
    * statement.getResultSet();
    * </code>.
    */
-  private ResultSet resultSet = null;
+  protected TajoResultSetBase resultSet = null;
+
+  /**
+   * Add SQLWarnings to the warningChain if needed.
+   */
+  protected SQLWarning warningChain = null;
 
   /**
    * Keep state so we can fail certain calls made after close().
    */
-  private boolean isClosed = false;
+  private boolean isClosed;
+
+  private boolean blockWait;
 
   public TajoStatement(JdbcConnection conn, TajoClient tajoClient) {
     this.conn = conn;
     this.tajoClient = tajoClient;
+    this.blockWait = tajoClient.getProperties().getBool(SessionVars.BLOCK_ON_RESULT);
   }
 
+  /*
+   * NOTICE
+   *
+   * For unimplemented methods, this class throws an exception or prints an error message.
+   * If the unimplemented method can cause unexpected result to user application when it is called,
+   * it should throw an exception.
+   * Otherwise, it is enough that prints an error message.
+   */
+
   @Override
   public void addBatch(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("addBatch not supported");
+    throw new SQLFeatureNotSupportedException("addBatch() is not supported yet.");
   }
 
   @Override
   public void cancel() throws SQLException {
-    throw new SQLFeatureNotSupportedException("cancel not supported");
+    checkConnection("Can't cancel query");
+    if (resultSet == null || resultSet.getQueryId().isNull()) {
+      return;
+    }
+    try {
+      tajoClient.killQuery(resultSet.getQueryId());
+    } catch (Exception e) {
+      throw new SQLException(e);
+    } finally {
+      resultSet = null;
+    }
   }
 
   @Override
   public void clearBatch() throws SQLException {
-    throw new SQLFeatureNotSupportedException("clearBatch not supported");
+    throw new SQLFeatureNotSupportedException("clearBatch() is not supported yet.");
   }
 
   @Override
-  public void clearWarnings() throws SQLException {}
+  public void clearWarnings() throws SQLException {
+    checkConnection("Can't clear warnings");
+    warningChain = null;
+  }
 
   @Override
   public void close() throws SQLException {
@@ -79,55 +113,87 @@ public class TajoStatement implements Statement {
 
   public void closeOnCompletion() throws SQLException {
      // JDK 1.7
-     throw new SQLFeatureNotSupportedException("closeOnCompletion not supported");
+    throw new SQLFeatureNotSupportedException("closeOnCompletion() is not supported yet.");
   }
 
   @Override
   public boolean execute(String sql) throws SQLException {
-    resultSet = executeQuery(sql);
+    resultSet = (TajoResultSetBase) executeQuery(sql);
 
     return resultSet != null;
   }
 
   @Override
   public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute not supported");
+    throw new SQLFeatureNotSupportedException("execute() is not supported yet.");
   }
 
   @Override
   public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute not supported");
+    throw new SQLFeatureNotSupportedException("execute() is not supported yet.");
   }
 
   @Override
   public boolean execute(String sql, String[] columnNames) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute not supported");
+    throw new SQLFeatureNotSupportedException("execute() is not supported yet.");
   }
 
   @Override
   public int[] executeBatch() throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeBatch not supported");
+    throw new SQLFeatureNotSupportedException("executeBatch() is not supported yet.");
   }
 
   @Override
   public ResultSet executeQuery(String sql) throws SQLException {
-    if (isClosed) {
-      throw new SQLException("Can't execute after statement has been closed");
-    }
+    checkConnection("Can't execute");
 
     try {
-      if (isSetVariableQuery(sql)) {
-        return setSessionVariable(tajoClient, sql);
-      } else if (isUnSetVariableQuery(sql)) {
-        return unSetSessionVariable(tajoClient, sql);
-      } else {
-        return tajoClient.executeQueryAndGetResult(sql);
-      }
+      return executeSQL(sql);
     } catch (Exception e) {
       throw new SQLException(e.getMessage(), e);
     }
   }
 
+  protected ResultSet executeSQL(String sql) throws SQLException, ServiceException, IOException {
+    if (isSetVariableQuery(sql)) {
+      return setSessionVariable(tajoClient, sql);
+    }
+    if (isUnSetVariableQuery(sql)) {
+      return unSetSessionVariable(tajoClient, sql);
+    }
+
+    ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql);
+    if (response.getResultCode() == ClientProtos.ResultCode.ERROR) {
+      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");
+    }
+
+    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);
+  }
+
+  protected void checkConnection(String errorMsg) throws SQLException {
+    if (isClosed) {
+      throw new SQLException(errorMsg + " after statement has been closed");
+    }
+  }
+
   public static boolean isSetVariableQuery(String sql) {
     if (sql == null || sql.trim().isEmpty()) {
       return false;
@@ -144,7 +210,7 @@ public class TajoStatement implements Statement {
     return sql.trim().toLowerCase().startsWith("unset");
   }
 
-  public static ResultSet setSessionVariable(TajoClient client, String sql) throws SQLException {
+  private ResultSet setSessionVariable(TajoClient client, String sql) throws SQLException {
     int index = sql.toLowerCase().indexOf("set");
     if (index < 0) {
       throw new SQLException("SET statement should be started 'SET' keyword: " + sql);
@@ -165,7 +231,7 @@ public class TajoStatement implements Statement {
     return TajoClientUtil.createNullResultSet();
   }
 
-  public static ResultSet unSetSessionVariable(TajoClient client, String sql) throws SQLException {
+  private ResultSet unSetSessionVariable(TajoClient client, String sql) throws SQLException {
     int index = sql.toLowerCase().indexOf("unset");
     if (index < 0) {
       throw new SQLException("UNSET statement should be started 'UNSET' keyword: " + sql);
@@ -186,57 +252,57 @@ public class TajoStatement implements Statement {
 
   @Override
   public int executeUpdate(String sql) throws SQLException {
+    checkConnection("Can't execute update");
     try {
       tajoClient.executeQuery(sql);
 
       return 1;
     } catch (Exception ex) {
-      throw new SQLFeatureNotSupportedException(ex.toString());
+      throw new SQLException(ex.toString());
     }
   }
 
   @Override
   public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
+    throw new SQLFeatureNotSupportedException("executeUpdate() is not supported yet.");
   }
 
   @Override
   public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
+    throw new SQLFeatureNotSupportedException("executeUpdate() is not supported yet.");
   }
 
   @Override
   public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeUpdate not supported");
+    throw new SQLFeatureNotSupportedException("executeUpdate() is not supported yet.");
   }
 
   @Override
   public Connection getConnection() throws SQLException {
-    if (isClosed)
-      throw new SQLException("Can't get connection after statement has been closed");
+    checkConnection("Can't get connection");
     return conn;
   }
 
   @Override
   public int getFetchDirection() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFetchDirection not supported");
+    checkConnection("Can't get fetch direction");
+    return ResultSet.FETCH_FORWARD;
   }
 
   @Override
   public int getFetchSize() throws SQLException {
-    if (isClosed)
-      throw new SQLException("Can't get fetch size after statement has been closed");
+    checkConnection("Can't get fetch size");
     return fetchSize;
   }
 
   @Override
   public ResultSet getGeneratedKeys() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getGeneratedKeys not supported");
+    throw new SQLFeatureNotSupportedException("getGeneratedKeys() is not supported yet.");
   }
 
   @Override
   public int getMaxFieldSize() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxFieldSize not supported");
+    throw new SQLFeatureNotSupportedException("getMaxFieldSize() is not supported yet.");
   }
 
   @Override
@@ -246,53 +312,54 @@ public class TajoStatement implements Statement {
 
   @Override
   public boolean getMoreResults() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMoreResults not supported");
+    throw new SQLFeatureNotSupportedException("getMoreResults() is not supported yet.");
   }
 
   @Override
   public boolean getMoreResults(int current) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMoreResults not supported");
+    throw new SQLFeatureNotSupportedException("getMoreResults() is not supported yet.");
   }
 
   @Override
   public int getQueryTimeout() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getQueryTimeout not supported");
+    System.err.println("getResultSetConcurrency() is not supported yet.");
+    return -1;
   }
 
   @Override
   public ResultSet getResultSet() throws SQLException {
-    if (isClosed)
-      throw new SQLException("Can't get result set after statement has been closed");
+    checkConnection("Can't get result set");
     return resultSet;
   }
 
   @Override
   public int getResultSetConcurrency() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getResultSetConcurrency not supported");
+    System.err.println("getResultSetConcurrency() is not supported yet.");
+    return -1;
   }
 
   @Override
   public int getResultSetHoldability() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getResultSetHoldability not supported");
+    System.err.println("getResultSetHoldability() is not supported yet.");
+    return -1;
   }
 
   @Override
   public int getResultSetType() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getResultSetType not supported");
+    System.err.println("getResultSetType() is not supported yet.");
+    return -1;
   }
 
   @Override
   public int getUpdateCount() throws SQLException {
-    if (isClosed)
-      throw new SQLException("Can't get update count after statement has been closed");
-    return 0;
+    System.err.println("getResultSetType() is not supported yet.");
+    return -1;
   }
 
   @Override
   public SQLWarning getWarnings() throws SQLException {
-    if (isClosed)
-      throw new SQLException("Can't get warnings after statement has been closed");
-    return null;
+    checkConnection("Can't get warnings");
+    return warningChain;
   }
 
   @Override
@@ -302,40 +369,41 @@ public class TajoStatement implements Statement {
 
   public boolean isCloseOnCompletion() throws SQLException {
     // JDK 1.7
-    throw new SQLFeatureNotSupportedException("isCloseOnCompletion not supported");
+    throw new SQLFeatureNotSupportedException("isCloseOnCompletion() is not supported yet.");
   }
 
   @Override
   public boolean isPoolable() throws SQLException {
-    throw new SQLFeatureNotSupportedException("isPoolable not supported");
+    throw new SQLFeatureNotSupportedException("isPoolable() is not supported yet.");
   }
 
   @Override
   public void setCursorName(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setCursorName not supported");
+    System.err.println("setCursorName() is not supported yet.");
   }
 
   /**
    * Not necessary.
    */
   @Override
-  public void setEscapeProcessing(boolean enable) throws SQLException {}
+  public void setEscapeProcessing(boolean enable) throws SQLException {
+    System.err.println("setEscapeProcessing() is not supported yet.");
+  }
 
   @Override
   public void setFetchDirection(int direction) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setFetchDirection not supported");
+    System.err.println("setFetchDirection() is not supported yet.");
   }
 
   @Override
   public void setFetchSize(int rows) throws SQLException {
-    if (isClosed)
-      throw new SQLException("Can't set fetch size after statement has been closed");
+    checkConnection("Can't set fetch size");
     fetchSize = rows;
   }
 
   @Override
   public void setMaxFieldSize(int max) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setMaxFieldSize not supported");
+    System.err.println("setMaxFieldSize() is not supported yet.");
   }
 
   @Override
@@ -348,22 +416,23 @@ public class TajoStatement implements Statement {
 
   @Override
   public void setPoolable(boolean poolable) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setPoolable not supported");
+    System.err.println("setPoolable() is not supported yet.");
   }
 
   @Override
   public void setQueryTimeout(int seconds) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setQueryTimeout not supported");
+    System.err.println("setQueryTimeout() is not supported yet.");
   }
 
   @Override
   public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isWrapperFor not supported");
+    System.err.println("isWrapperFor() is not supported yet.");
+    return false;
   }
 
   @Override
   public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw new SQLFeatureNotSupportedException("unwrap not supported");
+    System.err.println("unwrap() is not supported yet.");
+    return null;
   }
-
 }


[2/8] tajo git commit: TAJO-1633: Cleanup TajoMasterClientService.

Posted by ji...@apache.org.
TAJO-1633: Cleanup TajoMasterClientService.

Closes #594


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

Branch: refs/heads/index_support
Commit: d926247dcaba0af8d810c54a7c668272c3c86ea5
Parents: 011de8b
Author: Hyunsik Choi <hy...@apache.org>
Authored: Mon Jun 15 19:33:33 2015 -0700
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Mon Jun 15 19:33:33 2015 -0700

----------------------------------------------------------------------
 .../tajo/client/CatalogAdminClientImpl.java     | 14 +++--
 .../org/apache/tajo/client/QueryClientImpl.java |  8 +--
 tajo-client/src/main/proto/ClientProtos.proto   | 16 +-----
 .../main/proto/TajoMasterClientProtocol.proto   |  8 +--
 .../tajo/master/TajoMasterClientService.java    | 60 ++++++++++----------
 5 files changed, 47 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/d926247d/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.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 9397fcf..1fe856a 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
@@ -27,8 +27,10 @@ import org.apache.tajo.catalog.TableMeta;
 import org.apache.tajo.catalog.partition.PartitionMethodDesc;
 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;
 
 import java.io.IOException;
 import java.net.URI;
@@ -145,13 +147,13 @@ public class CatalogAdminClientImpl implements CatalogAdminClient {
     connection.checkSessionAndGet(client);
     BlockingInterface tajoMasterService = client.getStub();
 
-    ClientProtos.GetTableListRequest.Builder builder = ClientProtos.GetTableListRequest.newBuilder();
+    SessionedStringProto.Builder builder = SessionedStringProto.newBuilder();
     builder.setSessionId(connection.sessionId);
     if (databaseName != null) {
-      builder.setDatabaseName(databaseName);
+      builder.setValue(databaseName);
     }
-    ClientProtos.GetTableListResponse res = tajoMasterService.getTableList(null, builder.build());
-    return res.getTablesList();
+    PrimitiveProtos.StringListProto res = tajoMasterService.getTableList(null, builder.build());
+    return res.getValuesList();
   }
 
   @Override
@@ -161,9 +163,9 @@ public class CatalogAdminClientImpl implements CatalogAdminClient {
     connection.checkSessionAndGet(client);
     BlockingInterface tajoMasterService = client.getStub();
 
-    ClientProtos.GetTableDescRequest.Builder builder = ClientProtos.GetTableDescRequest.newBuilder();
+    SessionedStringProto.Builder builder = SessionedStringProto.newBuilder();
     builder.setSessionId(connection.sessionId);
-    builder.setTableName(tableName);
+    builder.setValue(tableName);
     ClientProtos.TableResponse res = tajoMasterService.getTableDesc(null, builder.build());
     if (res.getResultCode() == ClientProtos.ResultCode.OK) {
       return CatalogUtil.newTableDesc(res.getTableDesc());

http://git-wip-us.apache.org/repos/asf/tajo/blob/d926247d/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
index 53889fe..ac25933 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
@@ -437,8 +437,8 @@ public class QueryClientImpl implements QueryClient {
     connection.checkSessionAndGet(client);
     TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
-    ClientProtos.GetQueryListRequest.Builder builder = ClientProtos.GetQueryListRequest.newBuilder();
-    builder.setSessionId(connection.sessionId);
+    TajoIdProtos.SessionIdProto.Builder builder = TajoIdProtos.SessionIdProto.newBuilder();
+    builder.setId(connection.sessionId.getId());
     ClientProtos.GetQueryListResponse res = tajoMasterService.getRunningQueryList(null, builder.build());
     return res.getQueryListList();
   }
@@ -450,8 +450,8 @@ public class QueryClientImpl implements QueryClient {
     connection.checkSessionAndGet(client);
     TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
-    ClientProtos.GetQueryListRequest.Builder builder = ClientProtos.GetQueryListRequest.newBuilder();
-    builder.setSessionId(connection.sessionId);
+    TajoIdProtos.SessionIdProto.Builder builder = TajoIdProtos.SessionIdProto.newBuilder();
+    builder.setId(connection.sessionId.getId());
     ClientProtos.GetQueryListResponse res = tajoMasterService.getFinishedQueryList(null, builder.build());
     return res.getQueryListList();
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/d926247d/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 ecb136e..5497faa 100644
--- a/tajo-client/src/main/proto/ClientProtos.proto
+++ b/tajo-client/src/main/proto/ClientProtos.proto
@@ -57,7 +57,7 @@ message SessionUpdateResponse {
 
 message SessionedStringProto {
   optional SessionIdProto sessionId = 1;
-  required string value = 2;
+  optional string value = 2;
 }
 
 message ExplainQueryResponse {
@@ -196,20 +196,6 @@ message GetClusterInfoResponse {
   repeated WorkerResourceInfo workerList = 1;
 }
 
-message GetTableListRequest {
-  optional SessionIdProto sessionId = 1;
-  optional string databaseName = 2;
-}
-
-message GetTableListResponse {
-  repeated string tables = 1;
-}
-
-message GetTableDescRequest {
-  optional SessionIdProto sessionId = 1;
-  required string tableName = 2;
-}
-
 message CreateTableRequest {
   optional SessionIdProto sessionId = 1;
   required string name = 2;

http://git-wip-us.apache.org/repos/asf/tajo/blob/d926247d/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 10ca268..468a998 100644
--- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
+++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
@@ -46,8 +46,8 @@ service TajoMasterClientProtocolService {
 
   // Query And Resource Management APIs
   rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
-  rpc getRunningQueryList(GetQueryListRequest) returns (GetQueryListResponse);
-  rpc getFinishedQueryList(GetQueryListRequest) returns (GetQueryListResponse);
+  rpc getRunningQueryList(SessionIdProto) returns (GetQueryListResponse);
+  rpc getFinishedQueryList(SessionIdProto) returns (GetQueryListResponse);
   rpc killQuery(QueryIdRequest) returns (BoolProto);
   rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse);
   rpc closeNonForwardQuery(QueryIdRequest) returns (BoolProto);
@@ -65,7 +65,7 @@ service TajoMasterClientProtocolService {
   rpc createExternalTable(CreateTableRequest) returns (TableResponse);
   rpc existTable(SessionedStringProto) returns (BoolProto);
   rpc dropTable(DropTableRequest) returns (BoolProto);
-  rpc getTableList(GetTableListRequest) returns (GetTableListResponse);
-  rpc getTableDesc(GetTableDescRequest) returns (TableResponse);
+  rpc getTableList(SessionedStringProto) returns (StringListProto);
+  rpc getTableDesc(SessionedStringProto) returns (TableResponse);
   rpc getFunctionList(SessionedStringProto) returns (FunctionResponse);
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/d926247d/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
----------------------------------------------------------------------
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 4fcdc88..2602d7d 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
@@ -47,19 +47,20 @@ import org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolServ
 import org.apache.tajo.master.TajoMaster.MasterContext;
 import org.apache.tajo.master.exec.NonForwardQueryResultFileScanner;
 import org.apache.tajo.master.exec.NonForwardQueryResultScanner;
+import org.apache.tajo.master.rm.Worker;
+import org.apache.tajo.master.rm.WorkerResource;
 import org.apache.tajo.plan.LogicalPlan;
 import org.apache.tajo.plan.logical.PartitionedTableScanNode;
 import org.apache.tajo.plan.logical.ScanNode;
 import org.apache.tajo.querymaster.QueryJobEvent;
-import org.apache.tajo.master.rm.Worker;
-import org.apache.tajo.master.rm.WorkerResource;
-import org.apache.tajo.session.InvalidSessionException;
-import org.apache.tajo.session.NoSuchSessionVariableException;
-import org.apache.tajo.session.Session;
 import org.apache.tajo.rpc.BlockingRpcServer;
 import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos;
 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;
 import org.apache.tajo.util.ProtoUtil;
@@ -307,11 +308,6 @@ public class TajoMasterClientService extends AbstractService {
       try {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
         QueryContext queryContext = new QueryContext(conf, session);
-        if (queryContext.getCurrentDatabase() == null) {
-          for (Map.Entry<String,String> e : queryContext.getAllKeyValus().entrySet()) {
-            System.out.println(e.getKey() + "=" + e.getValue());
-          }
-        }
 
         UpdateQueryResponse.Builder builder = UpdateQueryResponse.newBuilder();
         try {
@@ -379,12 +375,12 @@ public class TajoMasterClientService extends AbstractService {
     }
 
     @Override
-    public GetQueryListResponse getRunningQueryList(RpcController controller, GetQueryListRequest request)
+    public GetQueryListResponse getRunningQueryList(RpcController controller, TajoIdProtos.SessionIdProto request)
 
         throws ServiceException {
 
       try {
-        context.getSessionManager().touch(request.getSessionId().getId());
+        context.getSessionManager().touch(request.getId());
         GetQueryListResponse.Builder builder= GetQueryListResponse.newBuilder();
 
         Collection<QueryInProgress> queries = new ArrayList<QueryInProgress>(context.getQueryJobManager().getSubmittedQueries());
@@ -416,11 +412,11 @@ public class TajoMasterClientService extends AbstractService {
     }
 
     @Override
-    public GetQueryListResponse getFinishedQueryList(RpcController controller, GetQueryListRequest request)
+    public GetQueryListResponse getFinishedQueryList(RpcController controller, TajoIdProtos.SessionIdProto request)
         throws ServiceException {
 
       try {
-        context.getSessionManager().touch(request.getSessionId().getId());
+        context.getSessionManager().touch(request.getId());
         GetQueryListResponse.Builder builder = GetQueryListResponse.newBuilder();
 
         Collection<QueryInfo> queries
@@ -723,7 +719,7 @@ public class TajoMasterClientService extends AbstractService {
     }
 
     @Override
-    public PrimitiveProtos.StringListProto getAllDatabases(RpcController controller, TajoIdProtos.SessionIdProto
+    public StringListProto getAllDatabases(RpcController controller, TajoIdProtos.SessionIdProto
         request) throws ServiceException {
       try {
         context.getSessionManager().touch(request.getId());
@@ -749,10 +745,6 @@ public class TajoMasterClientService extends AbstractService {
           tableName = request.getValue();
         }
 
-        if (databaseName == null) {
-          System.out.println("A");
-        }
-
         if (catalog.existsTable(databaseName, tableName)) {
           return BOOL_TRUE;
         } else {
@@ -764,19 +756,19 @@ public class TajoMasterClientService extends AbstractService {
     }
 
     @Override
-    public GetTableListResponse getTableList(RpcController controller,
-                                             GetTableListRequest request) throws ServiceException {
+    public StringListProto getTableList(RpcController controller,
+                                             SessionedStringProto request) throws ServiceException {
       try {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
         String databaseName;
-        if (request.hasDatabaseName()) {
-          databaseName = request.getDatabaseName();
+        if (request.hasValue()) {
+          databaseName = request.getValue();
         } else {
           databaseName = session.getCurrentDatabase();
         }
         Collection<String> tableNames = catalog.getAllTableNames(databaseName);
-        GetTableListResponse.Builder builder = GetTableListResponse.newBuilder();
-        builder.addAllTables(tableNames);
+        StringListProto.Builder builder = StringListProto.newBuilder();
+        builder.addAllValues(tableNames);
         return builder.build();
       } catch (Throwable t) {
         throw new ServiceException(t);
@@ -784,19 +776,27 @@ public class TajoMasterClientService extends AbstractService {
     }
 
     @Override
-    public TableResponse getTableDesc(RpcController controller, GetTableDescRequest request) throws ServiceException {
+    public TableResponse getTableDesc(RpcController controller, SessionedStringProto request) throws ServiceException {
       try {
+
+        if (!request.hasValue()) {
+          return TableResponse.newBuilder()
+              .setResultCode(ResultCode.ERROR)
+              .setErrorMessage("table name is required.")
+              .build();
+        }
+
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String databaseName;
         String tableName;
-        if (CatalogUtil.isFQTableName(request.getTableName())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getTableName());
+        if (CatalogUtil.isFQTableName(request.getValue())) {
+          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
           databaseName = session.getCurrentDatabase();
-          tableName = request.getTableName();
+          tableName = request.getValue();
         }
 
         if (catalog.existsTable(databaseName, tableName)) {
@@ -807,7 +807,7 @@ public class TajoMasterClientService extends AbstractService {
         } else {
           return TableResponse.newBuilder()
               .setResultCode(ResultCode.ERROR)
-              .setErrorMessage("ERROR: no such a table: " + request.getTableName())
+              .setErrorMessage("ERROR: no such a table: " + request.getValue())
               .build();
         }
       } catch (Throwable t) {


[7/8] tajo git commit: TAJO-1642: CatalogServer need to check meta table first. (jaehwa)

Posted by ji...@apache.org.
TAJO-1642: CatalogServer need to check meta table first. (jaehwa)

Closes #600


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

Branch: refs/heads/index_support
Commit: b24d18f5b3cf9ed3c4a4a41bff654c965521542f
Parents: 0f7ff8f
Author: JaeHwa Jung <bl...@apache.org>
Authored: Wed Jun 24 10:27:38 2015 +0900
Committer: JaeHwa Jung <bl...@apache.org>
Committed: Wed Jun 24 10:27:38 2015 +0900

----------------------------------------------------------------------
 CHANGES                                         |  2 ++
 .../tajo/catalog/store/AbstractDBStore.java     | 33 +++++++++++++-------
 .../catalog/store/XMLCatalogSchemaManager.java  | 30 ++++++++++++++++++
 3 files changed, 53 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/b24d18f5/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index d64022a..170b928 100644
--- a/CHANGES
+++ b/CHANGES
@@ -162,6 +162,8 @@ Release 0.11.0 - unreleased
 
   BUG FIXES
 
+    TAJO-1642: CatalogServer need to check meta table first. (jaehwa)
+
     TAJO-1650: TestQueryResource.testGetAllQueries() occasionally fails.
     (Contributed by jinho, Committed by jaehwa)
  

http://git-wip-us.apache.org/repos/asf/tajo/blob/b24d18f5/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
----------------------------------------------------------------------
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 7fe6ef3..34740c0 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
@@ -80,6 +80,10 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     return catalogSchemaManager.isInitialized(getConnection());
   }
 
+  protected boolean catalogAlreadyExists() throws CatalogException {
+    return catalogSchemaManager.catalogAlreadyExists(getConnection());
+  }
+
   protected void createBaseTable() throws CatalogException {
     createDatabaseDependants();
     
@@ -142,22 +146,27 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     }
     
     try {
-      if (isInitialized()) {
-        LOG.info("The base tables of CatalogServer already is initialized.");
+      if (catalogAlreadyExists()) {
+        LOG.info("The meta table of CatalogServer already is created.");
         verifySchemaVersion();
       } else {
-        try {
-          createBaseTable();
-          LOG.info("The base tables of CatalogServer are created.");
-        } catch (CatalogException ce) {
+        if (isInitialized()) {
+          LOG.info("The base tables of CatalogServer already is initialized.");
+          verifySchemaVersion();
+        } else {
           try {
-            dropBaseTable();
-          } catch (Throwable t) {
-            LOG.error(t, t);
+            createBaseTable();
+            LOG.info("The base tables of CatalogServer are created.");
+          } catch (CatalogException ce) {
+            try {
+              dropBaseTable();
+            } catch (Throwable t) {
+              LOG.error(t, t);
+            }
+            throw ce;
           }
-          throw ce;
         }
-      }
+     }
     } catch (Exception se) {
       throw new CatalogException("Cannot initialize the persistent storage of Catalog", se);
     }
@@ -245,7 +254,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       LOG.error("| You might downgrade or upgrade Apache Tajo. Downgrading or upgrading |");
       LOG.error("| Tajo without migration process is only available in some versions. |");
       LOG.error("| In order to learn how to migration Apache Tajo instance, |");
-      LOG.error("| please refer http://s.apache.org/0_8_migration. |");
+      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.");
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/b24d18f5/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/XMLCatalogSchemaManager.java
----------------------------------------------------------------------
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 1ea812c..9173cb8 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
@@ -51,9 +51,11 @@ import javax.xml.stream.XMLStreamReader;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.catalog.CatalogConstants;
 import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.exception.CatalogException;
 import org.apache.tajo.catalog.store.object.*;
+import org.apache.tajo.util.TUtil;
 
 public class XMLCatalogSchemaManager {
   protected final Log LOG = LogFactory.getLog(getClass());
@@ -344,6 +346,34 @@ public class XMLCatalogSchemaManager {
     CatalogUtil.closeQuietly(stmt);
   }
 
+  public boolean catalogAlreadyExists(Connection conn) throws CatalogException {
+    boolean result = false;
+    try {
+      List<String> constants = TUtil.newList();
+      constants.add(CatalogConstants.TB_META);
+      constants.add(CatalogConstants.TB_SPACES);
+      constants.add(CatalogConstants.TB_DATABASES);
+      constants.add(CatalogConstants.TB_TABLES);
+      constants.add(CatalogConstants.TB_COLUMNS);
+      constants.add(CatalogConstants.TB_OPTIONS);
+      constants.add(CatalogConstants.TB_INDEXES);
+      constants.add(CatalogConstants.TB_STATISTICS);
+      constants.add(CatalogConstants.TB_PARTITION_METHODS);
+      constants.add(CatalogConstants.TB_PARTTIONS);
+      constants.add(CatalogConstants.TB_PARTTION_KEYS);
+
+      for (String constant : constants) {
+        if (checkExistence(conn, DatabaseObjectType.TABLE, constant)) {
+          return true;
+        }
+      }
+
+    } catch (SQLException e) {
+      throw new CatalogException(e.getMessage(), e);
+    }
+    return result;
+  }
+
   public boolean isInitialized(Connection conn) throws CatalogException {
     if (!isLoaded()) {
       throw new CatalogException("Database schema files are not loaded.");


[4/8] tajo git commit: TAJO-1649: Change Rest API /databases/{database-name}/functions to /functions.

Posted by ji...@apache.org.
TAJO-1649: Change Rest API /databases/{database-name}/functions to /functions.

Signed-off-by: Hyunsik Choi <hy...@apache.org>


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

Branch: refs/heads/index_support
Commit: b0df5e0df1be78cd93b60db014a51a6dc6fed02e
Parents: ec46798
Author: clark.kang <cl...@kakao.com>
Authored: Wed Jun 17 23:22:07 2015 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Thu Jun 18 19:32:42 2015 -0700

----------------------------------------------------------------------
 CHANGES                                         |  3 ++
 .../tajo/ws/rs/resources/FunctionsResource.java | 41 ++++++--------------
 .../ws/rs/resources/TestFunctionsResource.java  | 18 ++++-----
 3 files changed, 24 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/b0df5e0d/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 0440302..f8440b9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,9 @@ Release 0.11.0 - unreleased
 
   IMPROVEMENT
 
+    TAJO-1649: Change Rest API /databases/{database-name}/functions to 
+    /functions. (Contributed by DaeMyung Kang, Committed by hyunsik)
+
     TAJO-1646: Add extlib directory for third-party libraries. (hyunsik)
 
     TAJO-1636: query rest api uri should change

http://git-wip-us.apache.org/repos/asf/tajo/blob/b0df5e0d/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/FunctionsResource.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/FunctionsResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/FunctionsResource.java
index 9545b1a..ead4b71 100644
--- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/FunctionsResource.java
+++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/FunctionsResource.java
@@ -18,33 +18,23 @@
 
 package org.apache.tajo.ws.rs.resources;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.tajo.catalog.FunctionDesc;
 import org.apache.tajo.function.FunctionSignature;
 import org.apache.tajo.master.TajoMaster.MasterContext;
-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.*;
 
-@Path("/databases/{databaseName}/functions")
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.Status;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@Path("/functions")
 public class FunctionsResource {
   
   private static final Log LOG = LogFactory.getLog(TablesResource.class);
@@ -54,10 +44,7 @@ public class FunctionsResource {
   
   @Context
   Application application;
-  
-  @PathParam("databaseName")
-  String databaseName;
-  
+
   JerseyResourceDelegateContext context;
   
   private static final String databaseNameKeyName = "databaseName";
@@ -79,10 +66,6 @@ public class FunctionsResource {
     Response response = null;
     try {
       initializeContext();
-      JerseyResourceDelegateContextKey<String> databaseNameKey =
-          JerseyResourceDelegateContextKey.valueOf(databaseNameKeyName, String.class);
-      context.put(databaseNameKey, databaseName);
-      
       response = JerseyResourceDelegateUtil.runJerseyResourceDelegate(
           new GetAllFunctionsDelegate(),
           application,

http://git-wip-us.apache.org/repos/asf/tajo/blob/b0df5e0d/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
index 2794ded..7c7aeae 100644
--- a/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
+++ b/tajo-core/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
@@ -18,13 +18,6 @@
 
 package org.apache.tajo.ws.rs.resources;
 
-import java.net.URI;
-import java.util.List;
-
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.core.GenericType;
-
 import org.apache.tajo.QueryTestCaseBase;
 import org.apache.tajo.TajoConstants;
 import org.apache.tajo.conf.TajoConf.ConfVars;
@@ -36,7 +29,14 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.GenericType;
+import java.net.URI;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class TestFunctionsResource extends QueryTestCaseBase {
   
@@ -52,7 +52,7 @@ public class TestFunctionsResource extends QueryTestCaseBase {
   public void setUp() throws Exception {
     int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
     restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
-    functionsURI = new URI(restServiceURI + "/databases/" + TajoConstants.DEFAULT_DATABASE_NAME + "/functions");
+    functionsURI = new URI(restServiceURI + "/functions");
     restClient = ClientBuilder.newBuilder()
         .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
         .register(LoggingFilter.class)


[5/8] tajo git commit: TAJO-1650: TestQueryResource.testGetAllQueries() occasionally fails.

Posted by ji...@apache.org.
TAJO-1650: TestQueryResource.testGetAllQueries() occasionally fails.

Closes #607

Signed-off-by: JaeHwa Jung <bl...@apache.org>


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

Branch: refs/heads/index_support
Commit: fc92be782c9375b80c9cc4edfbb6cc8d7eb241b4
Parents: b0df5e0
Author: Jinho Kim <jh...@apache.org>
Authored: Sun Jun 21 18:11:46 2015 +0900
Committer: JaeHwa Jung <bl...@apache.org>
Committed: Sun Jun 21 18:11:46 2015 +0900

----------------------------------------------------------------------
 CHANGES                                                     | 3 +++
 .../java/org/apache/tajo/ws/rs/resources/QueryResource.java | 9 ++-------
 2 files changed, 5 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/fc92be78/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index f8440b9..6c54511 100644
--- a/CHANGES
+++ b/CHANGES
@@ -159,6 +159,9 @@ Release 0.11.0 - unreleased
 
   BUG FIXES
 
+    TAJO-1650: TestQueryResource.testGetAllQueries() occasionally fails.
+    (Contributed by jinho, Committed by jaehwa)
+ 
     TAJO-1634: REST API: fix error when offset is zero.
     (Contributed by DaeMyung Kang, Committed by jaehwa)
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/fc92be78/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java
----------------------------------------------------------------------
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 a662c4d..abecc3a 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
@@ -155,13 +155,8 @@ public class QueryResource {
       for (QueryInProgress queryInProgress: queryManager.getRunningQueries()) {
         queriesInfo.add(queryInProgress.getQueryInfo());
       }
-      
-      try {
-        queriesInfo.addAll(masterContext.getHistoryReader().getQueries(null));
-      } catch (Exception e) {
-        LOG.error(e.getMessage(), e);
-        return ResourcesUtil.createExceptionResponse(LOG, e.getMessage());
-      }
+
+      queriesInfo.addAll(queryManager.getFinishedQueries());
       
       if (state != null) {
         queriesInfo = selectQueriesInfoByState(queriesInfo, queryState);


[3/8] tajo git commit: TAJO-1646: Add extlib directory for third-party libraries.

Posted by ji...@apache.org.
TAJO-1646: Add extlib directory for third-party libraries.

Closes #603


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

Branch: refs/heads/index_support
Commit: ec46798c117130593ecbc0ec236ec9351f2aa1c3
Parents: d926247
Author: Hyunsik Choi <hy...@apache.org>
Authored: Thu Jun 18 19:21:53 2015 -0700
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Thu Jun 18 19:21:53 2015 -0700

----------------------------------------------------------------------
 CHANGES                     | 2 ++
 tajo-dist/pom.xml           | 2 ++
 tajo-dist/src/main/bin/tajo | 3 +++
 3 files changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/ec46798c/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 57b8baa..0440302 100644
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,8 @@ Release 0.11.0 - unreleased
 
   IMPROVEMENT
 
+    TAJO-1646: Add extlib directory for third-party libraries. (hyunsik)
+
     TAJO-1636: query rest api uri should change
     from /databases/{database_name}/queies to /queries.
     (Contributed by DaeMyung Kang, Committed by jaehwa)

http://git-wip-us.apache.org/repos/asf/tajo/blob/ec46798c/tajo-dist/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-dist/pom.xml b/tajo-dist/pom.xml
index 0cc61aa..cd08b3d 100644
--- a/tajo-dist/pom.xml
+++ b/tajo-dist/pom.xml
@@ -151,6 +151,8 @@
                       run mkdir -p share/jdbc-dist
                       run cp -r $ROOT/tajo-jdbc/target/tajo-jdbc-${project.version}-jar-with-dependencies.jar ./share/jdbc-dist/tajo-jdbc-${project.version}.jar
 
+                      run mkdir -p extlib
+
                       if [ -f $ROOT/tajo-catalog/tajo-catalog-drivers/tajo-hive/target/lib/parquet-hive-bundle-*.jar ]
                       then
                       run cp -r $ROOT/tajo-catalog/tajo-catalog-drivers/tajo-hive/target/lib/parquet-hive-bundle-*.jar lib/

http://git-wip-us.apache.org/repos/asf/tajo/blob/ec46798c/tajo-dist/src/main/bin/tajo
----------------------------------------------------------------------
diff --git a/tajo-dist/src/main/bin/tajo b/tajo-dist/src/main/bin/tajo
index f06d6a8..58d06fb 100755
--- a/tajo-dist/src/main/bin/tajo
+++ b/tajo-dist/src/main/bin/tajo
@@ -339,6 +339,9 @@ for d in $TAJO_JAR_DIRS; do
   done
 done
 
+# add CLASSPATH for common UDFs and third-party libraries like JDBC.
+TAJO_BASE_CLASSPATH=${TAJO_BASE_CLASSPATH}:$TAJO_HOME/extlib
+
 # add user-specified CLASSPATH last
 if [ "$TAJO_CLASSPATH" != "" ]; then
   if [ "$TAJO_USER_CLASSPATH_FIRST" != "" ]; then


[8/8] tajo git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/tajo into index_support

Posted by ji...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/tajo into index_support

Conflicts:
	CHANGES
	tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java
	tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java


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

Branch: refs/heads/index_support
Commit: 00a8c658e2798dfd41fb263edf365cfadc9fd2d7
Parents: f674fa8 b24d18f
Author: Jihoon Son <ji...@apache.org>
Authored: Wed Jun 24 11:23:42 2015 +0900
Committer: Jihoon Son <ji...@apache.org>
Committed: Wed Jun 24 11:23:42 2015 +0900

----------------------------------------------------------------------
 CHANGES                                         |  16 ++
 .../tajo/catalog/store/AbstractDBStore.java     |  33 ++-
 .../catalog/store/XMLCatalogSchemaManager.java  |  30 ++
 .../tajo/client/CatalogAdminClientImpl.java     | 154 +----------
 .../org/apache/tajo/client/QueryClientImpl.java |  20 +-
 .../apache/tajo/client/SessionConnection.java   |  18 +-
 .../java/org/apache/tajo/client/TajoClient.java |   3 +
 .../org/apache/tajo/client/TajoClientUtil.java  |  21 +-
 .../org/apache/tajo/jdbc/FetchResultSet.java    |  15 +-
 .../apache/tajo/jdbc/TajoMemoryResultSet.java   |  10 +-
 .../org/apache/tajo/jdbc/TajoResultSetBase.java |  19 +-
 .../org/apache/tajo/jdbc/WaitingResultSet.java  |  71 +++++
 tajo-client/src/main/proto/ClientProtos.proto   |  16 +-
 .../main/proto/TajoMasterClientProtocol.proto   |   8 +-
 .../java/org/apache/tajo/OverridableConf.java   |   4 +
 .../src/main/java/org/apache/tajo/QueryId.java  |   4 +
 .../main/java/org/apache/tajo/SessionVars.java  |   4 +-
 .../java/org/apache/tajo/conf/TajoConf.java     |   1 +
 .../java/org/apache/tajo/util/KeyValueSet.java  |  59 +++-
 .../planner/physical/BSTIndexScanExec.java      |   5 -
 .../org/apache/tajo/master/QueryInProgress.java |  10 +-
 .../tajo/master/TajoMasterClientService.java    |  62 +++--
 .../apache/tajo/querymaster/Repartitioner.java  |   4 +-
 .../tajo/ws/rs/resources/FunctionsResource.java |  41 +--
 .../tajo/ws/rs/resources/QueryResource.java     |   9 +-
 .../ws/rs/resources/QueryResultResource.java    |   2 +-
 .../java/org/apache/tajo/jdbc/TestTajoJdbc.java |  37 ++-
 .../ws/rs/resources/TestFunctionsResource.java  |  18 +-
 .../TestTajoCli/testHelpSessionVars.result      |   1 +
 tajo-dist/pom.xml                               |   2 +
 tajo-dist/src/main/bin/tajo                     |   3 +
 .../org/apache/tajo/jdbc/JdbcConnection.java    |   6 +-
 .../apache/tajo/jdbc/TajoMetaDataResultSet.java |   9 +-
 .../apache/tajo/jdbc/TajoPreparedStatement.java | 276 ++-----------------
 .../org/apache/tajo/jdbc/TajoStatement.java     | 199 ++++++++-----
 35 files changed, 539 insertions(+), 651 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/CHANGES
----------------------------------------------------------------------
diff --cc CHANGES
index f883771,170b928..32e07b1
--- a/CHANGES
+++ b/CHANGES
@@@ -154,10 -162,14 +162,18 @@@ Release 0.11.0 - unrelease
  
    BUG FIXES
  
 +    TAJO-1608: Fix test failure in index_support branch. (jihoon)
 +
 +    TAJO-1594: Catalog schema is invalid for some databases. (jihoon)
 +
+     TAJO-1642: CatalogServer need to check meta table first. (jaehwa)
+ 
+     TAJO-1650: TestQueryResource.testGetAllQueries() occasionally fails.
+     (Contributed by jinho, Committed by jaehwa)
+  
+     TAJO-1634: REST API: fix error when offset is zero.
+     (Contributed by DaeMyung Kang, Committed by jaehwa)
+ 
      TAJO-1630: Test failure after TAJO-1130. (jihoon)
  
      TAJO-1623: INSERT INTO with wrong target columns causes NPE. (hyunsik)

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java
----------------------------------------------------------------------
diff --cc tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java
index 5a04892,1fe856a..e6566dc
--- a/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/CatalogAdminClientImpl.java
@@@ -20,15 -20,17 +20,18 @@@ package org.apache.tajo.client
  
  import com.google.protobuf.ServiceException;
  import org.apache.tajo.annotation.Nullable;
- import org.apache.tajo.catalog.*;
+ import org.apache.tajo.catalog.CatalogUtil;
+ import org.apache.tajo.catalog.Schema;
+ 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.IndexDescProto;
  import org.apache.tajo.ipc.ClientProtos;
 -import org.apache.tajo.ipc.ClientProtos.SessionedStringProto;
 +import org.apache.tajo.ipc.ClientProtos.*;
- import org.apache.tajo.ipc.TajoMasterClientProtocol;
  import org.apache.tajo.jdbc.SQLStates;
  import org.apache.tajo.rpc.NettyClientBase;
+ import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos;
  
  import java.io.IOException;
  import java.net.URI;
@@@ -111,43 -113,11 +114,11 @@@ public class CatalogAdminClientImpl imp
        builder.setPartition(partitionMethodDesc.getProto());
      }
      ClientProtos.TableResponse res = tajoMasterService.createExternalTable(null, builder.build());
 -    if (res.getResultCode() == ClientProtos.ResultCode.OK) {
 +    if (res.getResult().getResultCode() == ClientProtos.ResultCode.OK) {
        return CatalogUtil.newTableDesc(res.getTableDesc());
      } else {
 -      throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
 +      throw new SQLException(res.getResult().getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
      }
- 
- //<<<<<<< HEAD
- //    return new ServerCallable<TableDesc>(connection.manager, connection.getTajoMasterAddr(),
- //        TajoMasterClientProtocol.class, false) {
- //
- //      public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
- //
- //
- //      }
- //
- //    }.withRetries();
- //=======
- //    NettyClientBase client = connection.getTajoMasterConnection();
- //    connection.checkSessionAndGet(client);
- //    BlockingInterface tajoMasterService = client.getStub();
- //
- //    ClientProtos.CreateTableRequest.Builder builder = ClientProtos.CreateTableRequest.newBuilder();
- //    builder.setSessionId(connection.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());
- //    if (res.getResultCode() == ClientProtos.ResultCode.OK) {
- //      return CatalogUtil.newTableDesc(res.getTableDesc());
- //    } else {
- //      throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
- //    }
- //>>>>>>> 9b3824b5f0c64af42bfcf0a6bb8d3555c22c5746
    }
  
    @Override
@@@ -192,42 -163,15 +163,16 @@@
      connection.checkSessionAndGet(client);
      BlockingInterface tajoMasterService = client.getStub();
  
-     ClientProtos.GetTableDescRequest.Builder builder = ClientProtos.GetTableDescRequest.newBuilder();
+     SessionedStringProto.Builder builder = SessionedStringProto.newBuilder();
      builder.setSessionId(connection.sessionId);
-     builder.setTableName(tableName);
+     builder.setValue(tableName);
      ClientProtos.TableResponse res = tajoMasterService.getTableDesc(null, builder.build());
 -    if (res.getResultCode() == ClientProtos.ResultCode.OK) {
 +    if (res.getResult().getResultCode() == ClientProtos.ResultCode.OK) {
        return CatalogUtil.newTableDesc(res.getTableDesc());
      } else {
 -      throw new ServiceException(new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState()));
 +      throw new ServiceException(new SQLException(res.getResult().getErrorMessage(),
 +          SQLStates.ER_NO_SUCH_TABLE.getState()));
      }
- 
- //<<<<<<< HEAD
- //    return new ServerCallable<TableDesc>(connection.manager, connection.getTajoMasterAddr(),
- //        TajoMasterClientProtocol.class, false) {
- //
- //      public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
- //
- //
- //      }
- //
- //    }.withRetries();
- //=======
- //    NettyClientBase client = connection.getTajoMasterConnection();
- //    connection.checkSessionAndGet(client);
- //    BlockingInterface tajoMasterService = client.getStub();
- //
- //    ClientProtos.GetTableDescRequest.Builder builder = ClientProtos.GetTableDescRequest.newBuilder();
- //    builder.setSessionId(connection.sessionId);
- //    builder.setTableName(tableName);
- //    ClientProtos.TableResponse res = tajoMasterService.getTableDesc(null, builder.build());
- //    if (res.getResultCode() == ClientProtos.ResultCode.OK) {
- //      return CatalogUtil.newTableDesc(res.getTableDesc());
- //    } else {
- //      throw new ServiceException(new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState()));
- //    }
- //>>>>>>> 9b3824b5f0c64af42bfcf0a6bb8d3555c22c5746
    }
  
    @Override
@@@ -239,171 -184,11 +184,94 @@@
      String paramFunctionName = functionName == null ? "" : functionName;
      ClientProtos.FunctionResponse res = tajoMasterService.getFunctionList(null,
          connection.convertSessionedString(paramFunctionName));
 -    if (res.getResultCode() == ClientProtos.ResultCode.OK) {
 +    if (res.getResult().getResultCode() == ClientProtos.ResultCode.OK) {
        return res.getFunctionsList();
      } else {
 -      throw new ServiceException(new SQLException(res.getErrorMessage()));
 +      throw new ServiceException(res.getResult().getErrorMessage());
 +    }
- 
- //<<<<<<< HEAD
- //    return new ServerCallable<List<CatalogProtos.FunctionDescProto>>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      public List<CatalogProtos.FunctionDescProto> call(NettyClientBase client) throws ServiceException, SQLException {
- //
- //
- //      }
- //
- //    }.withRetries();
- //=======
- //    NettyClientBase client = connection.getTajoMasterConnection();
- //    connection.checkSessionAndGet(client);
- //    BlockingInterface tajoMasterService = client.getStub();
- //
- //    String paramFunctionName = functionName == null ? "" : functionName;
- //    ClientProtos.FunctionResponse res = tajoMasterService.getFunctionList(null,
- //        connection.convertSessionedString(paramFunctionName));
- //    if (res.getResultCode() == ClientProtos.ResultCode.OK) {
- //      return res.getFunctionsList();
- //    } else {
- //      throw new ServiceException(new SQLException(res.getErrorMessage()));
- //    }
- //>>>>>>> 9b3824b5f0c64af42bfcf0a6bb8d3555c22c5746
 +  }
 +
 +  @Override
 +  public IndexDescProto getIndex(final String indexName) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    return tajoMasterService.getIndexWithName(null,
 +        connection.convertSessionedString(indexName));
 +  }
 +
 +  @Override
 +  public boolean existIndex(final String indexName) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    return tajoMasterService.existIndexWithName(null,
 +        connection.convertSessionedString(indexName)).getValue();
- //    return new ServerCallable<Boolean>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      @Override
- //      public Boolean call(NettyClientBase client) throws Exception {
- //
- //      }
- //    }.withRetries();
 +  }
 +
 +  @Override
 +  public List<IndexDescProto> getIndexes(final String tableName) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    GetIndexesResponse response = tajoMasterService.getIndexesForTable(null,
 +        connection.convertSessionedString(tableName));
 +    if (response.getResult().getResultCode() == ResultCode.OK) {
 +      return response.getIndexesList();
 +    } else {
 +      throw new ServiceException(response.getResult().getErrorMessage());
 +    }
- //    return new ServerCallable<List<IndexDescProto>>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      @Override
- //      public List<IndexDescProto> call(NettyClientBase client) throws Exception {
- //
- //      }
- //    }.withRetries();
 +  }
 +
 +  @Override
 +  public boolean hasIndexes(final String tableName) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    return tajoMasterService.existIndexesForTable(null,
 +        connection.convertSessionedString(tableName)).getValue();
- 
- //    return new ServerCallable<Boolean>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      @Override
- //      public Boolean call(NettyClientBase client) throws Exception {
- //
- //      }
- //    }.withRetries();
 +  }
 +
 +  @Override
 +  public IndexDescProto getIndex(final String tableName, final String[] columnNames) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    GetIndexWithColumnsRequest.Builder builder = GetIndexWithColumnsRequest.newBuilder();
 +    builder.setSessionId(connection.sessionId);
 +    builder.setTableName(tableName);
 +    for (String eachColumnName : columnNames) {
 +      builder.addColumnNames(eachColumnName);
 +    }
 +    GetIndexWithColumnsResponse response = tajoMasterService.getIndexWithColumns(null, builder.build());
 +    if (response.getResult().getResultCode() == ResultCode.OK) {
 +      return response.getIndexDesc();
 +    } else {
 +      throw new ServiceException(response.getResult().getErrorMessage());
 +    }
- 
- //    return new ServerCallable<IndexDescProto>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      @Override
- //      public IndexDescProto call(NettyClientBase client) throws Exception {
- //
- //      }
- //    }.withRetries();
 +  }
 +
 +  @Override
 +  public boolean existIndex(final String tableName, final String[] columnName) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    GetIndexWithColumnsRequest.Builder builder = GetIndexWithColumnsRequest.newBuilder();
 +    builder.setSessionId(connection.sessionId);
 +    builder.setTableName(tableName);
 +    for (String eachColumnName : columnName) {
 +      builder.addColumnNames(eachColumnName);
      }
 +    return tajoMasterService.existIndexWithColumns(null, builder.build()).getValue();
- 
- //    return new ServerCallable<Boolean>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      @Override
- //      public Boolean call(NettyClientBase client) throws Exception {
- //
- //      }
- //    }.withRetries();
 +  }
 +
 +  @Override
 +  public boolean dropIndex(final String indexName) throws ServiceException {
 +    NettyClientBase client = connection.getTajoMasterConnection();
 +    connection.checkSessionAndGet(client);
 +    BlockingInterface tajoMasterService = client.getStub();
 +    return tajoMasterService.dropIndex(null,
 +        connection.convertSessionedString(indexName)).getValue();
- 
- //    return new ServerCallable<Boolean>(connection.manager,
- //        connection.getTajoMasterAddr(), TajoMasterClientProtocol.class, false) {
- //
- //      @Override
- //      public Boolean call(NettyClientBase client) throws Exception {
- //
- //      }
- //    }.withRetries();
    }
  
    @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-client/src/main/proto/ClientProtos.proto
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
----------------------------------------------------------------------
diff --cc tajo-client/src/main/proto/TajoMasterClientProtocol.proto
index 586f9ab,468a998..9c7755a
--- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
+++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
@@@ -65,16 -65,7 +65,16 @@@ service TajoMasterClientProtocolServic
    rpc createExternalTable(CreateTableRequest) returns (TableResponse);
    rpc existTable(SessionedStringProto) returns (BoolProto);
    rpc dropTable(DropTableRequest) returns (BoolProto);
-   rpc getTableList(GetTableListRequest) returns (GetTableListResponse);
-   rpc getTableDesc(GetTableDescRequest) returns (TableResponse);
+   rpc getTableList(SessionedStringProto) returns (StringListProto);
+   rpc getTableDesc(SessionedStringProto) returns (TableResponse);
    rpc getFunctionList(SessionedStringProto) returns (FunctionResponse);
 +
 +  // Index Management APIs
 +  rpc getIndexWithName(SessionedStringProto) returns (IndexDescProto);
 +  rpc existIndexWithName(SessionedStringProto) returns (BoolProto);
 +  rpc getIndexesForTable(SessionedStringProto) returns (GetIndexesResponse);
 +  rpc existIndexesForTable(SessionedStringProto) returns (BoolProto);
 +  rpc getIndexWithColumns(GetIndexWithColumnsRequest) returns (GetIndexWithColumnsResponse);
 +  rpc existIndexWithColumns(GetIndexWithColumnsRequest) returns (BoolProto);
 +  rpc dropIndex(SessionedStringProto) returns (BoolProto);
  }

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
----------------------------------------------------------------------
diff --cc tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
index 32d7fe7,c22f054..0062c43
--- a/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
+++ b/tajo-common/src/main/java/org/apache/tajo/OverridableConf.java
@@@ -173,8 -176,9 +176,9 @@@ public class OverridableConf extends Ke
      }
    }
  
+   @Override
    public float getFloat(ConfigKey key) {
 -    return getLong(key, null);
 +    return getFloat(key, null);
    }
  
    public void put(ConfigKey key, String val) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-common/src/main/java/org/apache/tajo/SessionVars.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
----------------------------------------------------------------------
diff --cc tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
index 4ed1313,bc6975a..34e6f5c
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
@@@ -18,29 -18,17 +18,27 @@@
  
  package org.apache.tajo.engine.planner.physical;
  
 -import org.apache.hadoop.fs.FileSystem;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
  import org.apache.hadoop.fs.Path;
  import org.apache.hadoop.io.IOUtils;
 +import org.apache.tajo.catalog.Column;
  import org.apache.tajo.catalog.Schema;
 +import org.apache.tajo.catalog.SortSpec;
 +import org.apache.tajo.catalog.TableMeta;
 +import org.apache.tajo.catalog.proto.CatalogProtos;
 +import org.apache.tajo.catalog.statistics.TableStats;
  import org.apache.tajo.datum.Datum;
  import org.apache.tajo.engine.planner.Projector;
 +import org.apache.tajo.plan.Target;
  import org.apache.tajo.plan.expr.EvalNode;
 -import org.apache.tajo.plan.logical.ScanNode;
 +import org.apache.tajo.plan.expr.EvalTreeUtil;
 +import org.apache.tajo.plan.logical.IndexScanNode;
 +import org.apache.tajo.plan.rewrite.rules.IndexScanInfo.SimplePredicate;
 +import org.apache.tajo.plan.util.PlannerUtil;
  import org.apache.tajo.storage.*;
--import org.apache.tajo.storage.fragment.FileFragment;
- import org.apache.tajo.storage.fragment.FragmentConvertor;
  import org.apache.tajo.storage.index.bst.BSTIndex;
 +import org.apache.tajo.util.TUtil;
  import org.apache.tajo.worker.TaskAttemptContext;
  
  import java.io.IOException;
@@@ -239,13 -119,8 +236,11 @@@ public class BSTIndexScanExec extends P
             return outTuple;
           } else {
             long offset = reader.next();
-            LOG.info("offset: " + offset);
 -           if (offset == -1) return null;
 +           if (offset == -1) {
 +             return null;
 +           }
             else fileScanner.seek(offset);
 +           return null;
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
----------------------------------------------------------------------
diff --cc tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
index 01c5894,31eecdc..c6732b3
--- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
@@@ -52,16 -53,13 +54,14 @@@ import org.apache.tajo.plan.LogicalPlan
  import org.apache.tajo.plan.logical.PartitionedTableScanNode;
  import org.apache.tajo.plan.logical.ScanNode;
  import org.apache.tajo.querymaster.QueryJobEvent;
- import org.apache.tajo.master.rm.Worker;
- import org.apache.tajo.master.rm.WorkerResource;
- import org.apache.tajo.session.InvalidSessionException;
- import org.apache.tajo.session.NoSuchSessionVariableException;
- import org.apache.tajo.session.Session;
  import org.apache.tajo.rpc.BlockingRpcServer;
- import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos;
  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.IPCUtil;
  import org.apache.tajo.util.KeyValueSet;
  import org.apache.tajo.util.NetUtils;
  import org.apache.tajo.util.ProtoUtil;
@@@ -770,8 -781,16 +772,16 @@@ public class TajoMasterClientService ex
      }
  
      @Override
-     public TableResponse getTableDesc(RpcController controller, GetTableDescRequest request) throws ServiceException {
+     public TableResponse getTableDesc(RpcController controller, SessionedStringProto request) throws ServiceException {
        try {
+ 
+         if (!request.hasValue()) {
+           return TableResponse.newBuilder()
 -              .setResultCode(ResultCode.ERROR)
 -              .setErrorMessage("table name is required.")
 -              .build();
++              .setResult(
++                  IPCUtil.buildRequestResult(ResultCode.ERROR, "table name is required.", null)
++              ).build();
+         }
+ 
          Session session = context.getSessionManager().getSession(request.getSessionId().getId());
  
          String databaseName;
@@@ -792,8 -811,8 +802,8 @@@
                .build();
          } else {
            return TableResponse.newBuilder()
 -              .setResultCode(ResultCode.ERROR)
 -              .setErrorMessage("ERROR: no such a table: " + request.getValue())
 +              .setResult(IPCUtil.buildRequestResult(ResultCode.ERROR,
-                   "ERROR: no such a table: " + request.getTableName(), null))
++                  "ERROR: no such a table: " + request.getValue(), null))
                .build();
          }
        } catch (Throwable t) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/QueryResource.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
----------------------------------------------------------------------
diff --cc tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
index 6f48164,137b0de..46c879c
--- a/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
+++ b/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
@@@ -35,8 -35,7 +35,9 @@@ Available Session Variables
  \set MAX_OUTPUT_FILE_SIZE [int value] - Maximum per-output file size (mb). 0 means infinite.
  \set NULL_CHAR [text value] - null char of text file output
  \set CODEGEN [true or false] - Runtime code generation enabled (experiment)
 +\set INDEX_ENABLED [true or false] - index scan enabled
 +\set INDEX_SELECTIVITY_THRESHOLD [real value] - the selectivity threshold for index scan
  \set ARITHABORT [true or false] - If true, a running query will be terminated when an overflow or divide-by-zero occurs.
  \set FETCH_ROWNUM [int value] - Sets the number of rows at a time from Master
+ \set BLOCK_ON_RESULT [true or false] - Whether to block result set on query execution
  \set DEBUG_ENABLED [true or false] - (debug only) debug mode enabled

http://git-wip-us.apache.org/repos/asf/tajo/blob/00a8c658/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
----------------------------------------------------------------------
diff --cc tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
index 820e350,0f80ddf..e1242a9
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
@@@ -128,6 -154,46 +154,46 @@@ public class TajoStatement implements S
      }
    }
  
+   protected ResultSet executeSQL(String sql) throws SQLException, ServiceException, IOException {
+     if (isSetVariableQuery(sql)) {
+       return setSessionVariable(tajoClient, sql);
+     }
+     if (isUnSetVariableQuery(sql)) {
+       return unSetSessionVariable(tajoClient, sql);
+     }
+ 
+     ClientProtos.SubmitQueryResponse response = tajoClient.executeQuery(sql);
 -    if (response.getResultCode() == ClientProtos.ResultCode.ERROR) {
 -      if (response.hasErrorMessage()) {
 -        throw new ServiceException(response.getErrorMessage());
++    if (response.getResult().getResultCode() == ClientProtos.ResultCode.ERROR) {
++      if (response.getResult().hasErrorMessage()) {
++        throw new ServiceException(response.getResult().getErrorMessage());
+       }
 -      if (response.hasErrorTrace()) {
 -        throw new ServiceException(response.getErrorTrace());
++      if (response.getResult().hasErrorTrace()) {
++        throw new ServiceException(response.getResult().getErrorTrace());
+       }
+       throw new ServiceException("Failed to submit query by unknown reason");
+     }
+ 
+     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);
+   }
+ 
+   protected void checkConnection(String errorMsg) throws SQLException {
+     if (isClosed) {
+       throw new SQLException(errorMsg + " after statement has been closed");
+     }
+   }
+ 
    public static boolean isSetVariableQuery(String sql) {
      if (sql == null || sql.trim().isEmpty()) {
        return false;