You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2013/12/30 10:17:57 UTC

[1/6] TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)

Updated Branches:
  refs/heads/master d39bb9980 -> b6a5ff0c3


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..6fdda0d
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
@@ -0,0 +1,658 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.client.TajoClient;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.HashMap;
+
+/**
+ * TajoPreparedStatement.
+ *
+ */
+public class TajoPreparedStatement 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 final int updateCount = 0;
+
+  /**
+   *
+   */
+  public TajoPreparedStatement(TajoClient tajoClient,
+                               String sql) {
+    this.tajoClient = tajoClient;
+    this.sql = sql;
+  }
+
+  @Override
+  public void addBatch() throws SQLException {
+    throw new SQLFeatureNotSupportedException("addBatch");
+  }
+
+  @Override
+  public void clearParameters() throws SQLException {
+    this.parameters.clear();
+  }
+
+  @Override
+  public boolean execute() throws SQLException {
+    ResultSet rs = executeImmediate(sql);
+    return rs != null;
+  }
+
+  @Override
+  public ResultSet executeQuery() throws SQLException {
+    return executeImmediate(sql);
+  }
+
+  @Override
+  public int executeUpdate() throws SQLException {
+    executeImmediate(sql);
+    return updateCount;
+  }
+
+  protected ResultSet executeImmediate(String sql) throws SQLException {
+    if (isClosed) {
+      throw new SQLFeatureNotSupportedException("Can't execute after statement has been closed");
+    }
+
+    try {
+      if (sql.contains("?")) {
+        sql = updateSql(sql, parameters);
+      }
+      resultSet = tajoClient.executeQueryAndGetResult(sql);
+    } catch (Exception e) {
+      throw new SQLFeatureNotSupportedException(e.getMessage(), e);
+    }
+    return resultSet;
+  }
+
+  /**
+   * update the SQL string with parameters set by setXXX methods of {@link java.sql.PreparedStatement}
+   *
+   * @param sql
+   * @param parameters
+   * @return updated SQL string
+   */
+  private String updateSql(final String sql, HashMap<Integer, String> parameters) {
+
+    StringBuffer newSql = new StringBuffer(sql);
+
+    int paramLoc = 1;
+    while (getCharIndexFromSqlByParamLocation(sql, '?', paramLoc) > 0) {
+      // check the user has set the needs parameters
+      if (parameters.containsKey(paramLoc)) {
+        int tt = getCharIndexFromSqlByParamLocation(newSql.toString(), '?', 1);
+        newSql.deleteCharAt(tt);
+        newSql.insert(tt, parameters.get(paramLoc));
+      }
+      paramLoc++;
+    }
+
+    return newSql.toString();
+
+  }
+
+  /**
+   * Get the index of given char from the SQL string by parameter location
+   * </br> The -1 will be return, if nothing found
+   *
+   * @param sql
+   * @param cchar
+   * @param paramLoc
+   * @return
+   */
+  private int getCharIndexFromSqlByParamLocation(final String sql, final char cchar, final int paramLoc) {
+    int signalCount = 0;
+    int charIndex = -1;
+    int num = 0;
+    for (int i = 0; i < sql.length(); i++) {
+      char c = sql.charAt(i);
+      if (c == '\'' || c == '\\')// record the count of char "'" and char "\"
+      {
+        signalCount++;
+      } else if (c == cchar && signalCount % 2 == 0) {// check if the ? is really the parameter
+        num++;
+        if (num == paramLoc) {
+          charIndex = i;
+          break;
+        }
+      }
+    }
+    return charIndex;
+  }
+
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+    if(resultSet != null) {
+      return resultSet.getMetaData();
+    } else {
+      return null;
+    }
+  }
+
+  @Override
+  public ParameterMetaData getParameterMetaData() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getParameterMetaData not supported");
+  }
+
+  @Override
+  public void setArray(int i, Array x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setArray not supported");
+  }
+
+  @Override
+  public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setAsciiStream not supported");
+  }
+
+  @Override
+  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setAsciiStream not supported");
+  }
+
+  @Override
+  public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setAsciiStream not supported");
+  }
+
+  @Override
+  public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBigDecimal not supported");
+  }
+
+  @Override
+  public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBinaryStream not supported");
+  }
+
+  @Override
+  public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBinaryStream not supported");
+  }
+
+  @Override
+  public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBinaryStream not supported");
+  }
+
+  @Override
+  public void setBlob(int i, Blob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBlob not supported");
+  }
+
+  @Override
+  public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBlob not supported");
+  }
+
+  @Override
+  public void setBlob(int parameterIndex, InputStream inputStream, long length)
+          throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBlob not supported");
+  }
+
+  @Override
+  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+    this.parameters.put(parameterIndex, "" + x);
+  }
+
+  @Override
+  public void setByte(int parameterIndex, byte x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setByte not supported");
+  }
+
+  @Override
+  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setBytes not supported");
+  }
+
+  @Override
+  public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setCharacterStream not supported");
+  }
+
+  @Override
+  public void setCharacterStream(int parameterIndex, Reader reader, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("setCharacterStream not supported");
+  }
+
+  @Override
+  public void setCharacterStream(int parameterIndex, Reader reader, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("setCharacterStream not supported");
+  }
+
+  @Override
+  public void setClob(int i, Clob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setClob not supported");
+  }
+
+  @Override
+  public void setClob(int parameterIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setClob not supported");
+  }
+
+  @Override
+  public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setClob not supported");
+  }
+
+  @Override
+  public void setDate(int parameterIndex, Date x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setDate not supported");
+  }
+
+  @Override
+  public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setDate not supported");
+  }
+
+  @Override
+  public void setDouble(int parameterIndex, double x) throws SQLException {
+    this.parameters.put(parameterIndex,"" + x);
+  }
+
+  @Override
+  public void setFloat(int parameterIndex, float x) throws SQLException {
+    this.parameters.put(parameterIndex,"" + x);
+  }
+
+  @Override
+  public void setInt(int parameterIndex, int x) throws SQLException {
+    this.parameters.put(parameterIndex,"" + x);
+  }
+
+  @Override
+  public void setLong(int parameterIndex, long x) throws SQLException {
+    this.parameters.put(parameterIndex,"" + x);
+  }
+
+  @Override
+  public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNCharacterStream not supported");
+  }
+
+  @Override
+  public void setNCharacterStream(int parameterIndex, Reader value, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNCharacterStream not supported");
+  }
+
+  @Override
+  public void setNClob(int parameterIndex, NClob value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNClob not supported");
+  }
+
+  @Override
+  public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNClob not supported");
+  }
+
+  @Override
+  public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNClob not supported");
+  }
+
+  @Override
+  public void setNString(int parameterIndex, String value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNString not supported");
+  }
+
+  @Override
+  public void setNull(int parameterIndex, int sqlType) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNull not supported");
+  }
+
+  @Override
+  public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setNull not supported");
+  }
+
+  @Override
+  public void setObject(int parameterIndex, Object x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setObject not supported");
+  }
+
+  @Override
+  public void setObject(int parameterIndex, Object x, int targetSqlType)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("setObject not supported");
+  }
+
+  @Override
+  public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("setObject not supported");
+  }
+
+  @Override
+  public void setRef(int i, Ref x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setRef not supported");
+  }
+
+  @Override
+  public void setRowId(int parameterIndex, RowId x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setRowId not supported");
+  }
+
+  @Override
+  public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setSQLXML not supported");
+  }
+
+  @Override
+  public void setShort(int parameterIndex, short x) throws SQLException {
+    this.parameters.put(parameterIndex,"" + x);
+  }
+
+  @Override
+  public void setString(int parameterIndex, String x) throws SQLException {
+     x=x.replace("'", "\\'");
+     this.parameters.put(parameterIndex,"'" + x +"'");
+  }
+
+  @Override
+  public void setTime(int parameterIndex, Time x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setTime not supported");
+  }
+
+  @Override
+  public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setTime not supported");
+  }
+
+  @Override
+  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setTimestamp not supported");
+  }
+
+  @Override
+  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("setTimestamp not supported");
+  }
+
+  @Override
+  public void setURL(int parameterIndex, URL x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setURL not supported");
+  }
+
+  @Override
+  public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+      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 {
+     warningChain=null;
+  }
+
+  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 {
+    throw new SQLFeatureNotSupportedException("getConnection not supported");
+  }
+
+  @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 warningChain;
+  }
+
+  @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/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..b3afcdb
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
@@ -0,0 +1,287 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.client.TajoClient;
+
+import java.sql.*;
+
+public class TajoStatement implements Statement {
+  private TajoClient tajoClient;
+  private int fetchSize = 200;
+
+  /**
+   * 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;
+
+  public TajoStatement(TajoClient tajoClient) {
+    this.tajoClient = tajoClient;
+  }
+
+  @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 {
+    warningChain = null;
+  }
+
+  @Override
+  public void close() throws SQLException {
+    resultSet = null;
+    isClosed = true;
+  }
+
+  public void closeOnCompletion() throws SQLException {
+     // JDK 1.7
+     throw new SQLFeatureNotSupportedException("closeOnCompletion not supported");
+  }
+
+  @Override
+  public boolean execute(String sql) throws SQLException {
+    resultSet = executeQuery(sql);
+
+    return resultSet != null;
+  }
+
+  @Override
+  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+    throw new SQLFeatureNotSupportedException("execute not supported");
+  }
+
+  @Override
+  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+    throw new SQLFeatureNotSupportedException("execute not supported");
+  }
+
+  @Override
+  public boolean execute(String sql, String[] columnNames) throws SQLException {
+    throw new SQLFeatureNotSupportedException("execute not supported");
+  }
+
+  @Override
+  public int[] executeBatch() throws SQLException {
+    throw new SQLFeatureNotSupportedException("executeBatch not supported");
+  }
+
+  @Override
+  public ResultSet executeQuery(String sql) throws SQLException {
+    if (isClosed) {
+      throw new SQLFeatureNotSupportedException("Can't execute after statement has been closed");
+    }
+
+    try {
+      return tajoClient.executeQueryAndGetResult(sql);
+    } catch (Exception e) {
+      throw new SQLFeatureNotSupportedException(e.getMessage(), e);
+    }
+  }
+
+  @Override
+  public int executeUpdate(String sql) throws SQLException {
+    try {
+      tajoClient.executeQuery(sql);
+
+      return 1;
+    } catch (Exception ex) {
+      throw new SQLFeatureNotSupportedException(ex.toString());
+    }
+  }
+
+  @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 {
+    throw new SQLFeatureNotSupportedException("getConnection not supported");
+  }
+
+  @Override
+  public int getFetchDirection() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getFetchDirection not supported");
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    return fetchSize;
+  }
+
+  @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 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 0;
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    return warningChain;
+  }
+
+  @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 {
+    fetchSize = rows;
+  }
+
+  @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/incubator-tajo/blob/b6a5ff0c/tajo-jdbc/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/resources/log4j.properties b/tajo-jdbc/src/main/resources/log4j.properties
new file mode 100644
index 0000000..606f2d4
--- /dev/null
+++ b/tajo-jdbc/src/main/resources/log4j.properties
@@ -0,0 +1,27 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# log4j configuration used during build and unit tests
+
+log4j.rootLogger=info,stdout
+log4j.threshhold=INFO
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n
+
+log4j.logger.org.apache.tajo.jdbc=FATAL
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-project/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-project/pom.xml b/tajo-project/pom.xml
index 7f2e5bb..c3a6f82 100644
--- a/tajo-project/pom.xml
+++ b/tajo-project/pom.xml
@@ -598,6 +598,16 @@
       </dependency>
       <dependency>
         <groupId>org.apache.tajo</groupId>
+        <artifactId>tajo-client</artifactId>
+        <version>${tajo.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tajo</groupId>
+        <artifactId>tajo-jdbc</artifactId>
+        <version>${tajo.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tajo</groupId>
         <artifactId>tajo-rpc</artifactId>
         <version>${tajo.version}</version>
       </dependency>
@@ -651,6 +661,7 @@
         <groupId>org.apache.hadoop</groupId>
         <artifactId>hadoop-minicluster</artifactId>
         <version>${hadoop.version}</version>
+        <scope>test</scope>
       </dependency>
       <dependency>
         <groupId>org.apache.hadoop</groupId>
@@ -664,6 +675,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-yarn-client</artifactId>
+        <version>${hadoop.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
         <artifactId>hadoop-yarn-server-nodemanager</artifactId>
         <version>${hadoop.version}</version>
         <scope>test</scope>
@@ -775,7 +791,7 @@
       <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
-        <version>13.0.1</version>
+        <version>15.0</version>
       </dependency>
       <dependency>
         <groupId>com.google.code.gson</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-rpc/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-rpc/pom.xml b/tajo-rpc/pom.xml
index 227bec1..04cf780 100644
--- a/tajo-rpc/pom.xml
+++ b/tajo-rpc/pom.xml
@@ -1,9 +1,11 @@
 <!--
-  Copyright 2012 Database Lab., Korea Univ.
-
-  Licensed 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
+  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
 
@@ -126,8 +128,40 @@
     <dependency>
       <groupId>org.apache.tajo</groupId>
       <artifactId>tajo-common</artifactId>
-      <type>jar</type>
-      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>com.google.guava</groupId>
+          <artifactId>guava</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>joda-time</groupId>
+          <artifactId>joda-time</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.code.gson</groupId>
+          <artifactId>gson</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-log4j12</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.inject</groupId>
+          <artifactId>guice</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.inject.extensions</groupId>
+          <artifactId>guice-servlet</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.contribs</groupId>
+          <artifactId>jersey-guice</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
     <dependency>
       <groupId>commons-logging</groupId>
@@ -140,11 +174,6 @@
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
     </dependency>
     <dependency>
       <groupId>commons-logging</groupId>
@@ -153,6 +182,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-lang</groupId>
@@ -215,7 +245,7 @@
             <executions>
               <execution>
                 <!-- builds source jars and attaches them to the project for publishing -->
-                <id>hadoop-java-sources</id>
+                <id>tajo-java-sources</id>
                 <phase>package</phase>
                 <goals>
                   <goal>jar-no-fork</goal>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-rpc/src/main/java/org/apache/tajo/rpc/RpcConnectionPool.java
----------------------------------------------------------------------
diff --git a/tajo-rpc/src/main/java/org/apache/tajo/rpc/RpcConnectionPool.java b/tajo-rpc/src/main/java/org/apache/tajo/rpc/RpcConnectionPool.java
index 8eacaf5..06ef408 100644
--- a/tajo-rpc/src/main/java/org/apache/tajo/rpc/RpcConnectionPool.java
+++ b/tajo-rpc/src/main/java/org/apache/tajo/rpc/RpcConnectionPool.java
@@ -18,10 +18,10 @@
 
 package org.apache.tajo.rpc;
 
-import com.google.common.collect.Maps;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.util.TUtil;
 
 import java.net.InetSocketAddress;
 import java.util.Map;
@@ -29,7 +29,7 @@ import java.util.Map;
 public class RpcConnectionPool {
   private static final Log LOG = LogFactory.getLog(RpcConnectionPool.class);
 
-  private Map<RpcConnectionKey, NettyClientBase> connections = Maps.newConcurrentMap();
+  private Map<RpcConnectionKey, NettyClientBase> connections = TUtil.newConcurrentHashMap();
 
   private static RpcConnectionPool instance;
 


[4/6] TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/QueryStatus.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/QueryStatus.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/QueryStatus.java
deleted file mode 100644
index 203f9aa..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/QueryStatus.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.client;
-
-import org.apache.tajo.QueryId;
-import org.apache.tajo.TajoProtos.QueryState;
-import org.apache.tajo.ipc.ClientProtos.GetQueryStatusResponse;
-
-public class QueryStatus {
-  private QueryId queryId;
-  private QueryState state;
-  private float progress;
-  private long submitTime;
-  private long finishTime;
-  private boolean hasResult;
-  private String errorText;
-  private String queryMasterHost;
-  private int queryMasterPort;
-
-  public QueryStatus(GetQueryStatusResponse proto) {
-    queryId = new QueryId(proto.getQueryId());
-    state = proto.getState();
-    progress = proto.getProgress();
-    submitTime = proto.getSubmitTime();
-    finishTime = proto.getFinishTime();
-    hasResult = proto.getHasResult();
-    if (proto.hasErrorMessage()) {
-      errorText = proto.getErrorMessage();
-    }
-
-    queryMasterHost = proto.getQueryMasterHost();
-    queryMasterPort = proto.getQueryMasterPort();
-  }
-
-  public String getQueryMasterHost() {
-    return queryMasterHost;
-  }
-
-  public int getQueryMasterPort() {
-    return queryMasterPort;
-  }
-
-  public QueryId getQueryId() {
-    return this.queryId;
-  }
-
-  public QueryState getState() {
-    return this.state;
-  }
-
-  public float getProgress() {
-    return progress;
-  }
-
-  public long getSubmitTime() {
-    return this.submitTime;
-  }
-
-  public long getFinishTime() {
-    return this.finishTime;
-  }
-
-  public boolean hasResult() {
-    return this.hasResult;
-  }
-
-  public String getErrorMessage() {
-    return errorText;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/ResultSetUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/ResultSetUtil.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/ResultSetUtil.java
deleted file mode 100644
index 7644e97..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/ResultSetUtil.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.client;
-
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-
-public class ResultSetUtil {
-  public static String prettyFormat(ResultSet res) throws SQLException {
-    StringBuilder sb = new StringBuilder();
-    ResultSetMetaData rsmd = res.getMetaData();
-    int numOfColumns = rsmd.getColumnCount();
-
-    for (int i = 1; i <= numOfColumns; i++) {
-      if (i > 1) sb.append(",  ");
-      String columnName = rsmd.getColumnName(i);
-      sb.append(columnName);
-    }
-    sb.append("\n-------------------------------\n");
-
-    while (res.next()) {
-      for (int i = 1; i <= numOfColumns; i++) {
-        if (i > 1) sb.append(",  ");
-        String columnValue = res.getObject(i).toString();
-        sb.append(columnValue);
-      }
-      sb.append("\n");
-    }
-
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/SQLStates.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/SQLStates.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/SQLStates.java
deleted file mode 100644
index 888170b..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/SQLStates.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.client;
-
-public enum SQLStates {
-  ER_NO_SUCH_TABLE("42S02");
-
-  private String state;
-
-  SQLStates(String state) {
-    this.state = state;
-  }
-
-  public String getState() {
-    return state;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoClient.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoClient.java
deleted file mode 100644
index 555ba16..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoClient.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.client;
-
-import com.google.protobuf.ServiceException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.fs.Path;
-import org.apache.tajo.QueryId;
-import org.apache.tajo.QueryIdFactory;
-import org.apache.tajo.TajoProtos.QueryState;
-import org.apache.tajo.annotation.ThreadSafe;
-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.conf.TajoConf;
-import org.apache.tajo.conf.TajoConf.ConfVars;
-import org.apache.tajo.ipc.ClientProtos.*;
-import org.apache.tajo.ipc.QueryMasterClientProtocol;
-import org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService;
-import org.apache.tajo.ipc.TajoMasterClientProtocol;
-import org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService;
-import org.apache.tajo.jdbc.TajoResultSet;
-import org.apache.tajo.rpc.*;
-import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto;
-import org.apache.tajo.util.NetUtils;
-import org.apache.tajo.rpc.ServerCallable;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-@ThreadSafe
-public class TajoClient {
-  private final Log LOG = LogFactory.getLog(TajoClient.class);
-
-  private final TajoConf conf;
-
-  private Map<QueryId, InetSocketAddress> queryMasterMap = new ConcurrentHashMap<QueryId, InetSocketAddress>();
-
-  private InetSocketAddress tajoMasterAddr;
-
-  private RpcConnectionPool connPool;
-
-  public TajoClient(TajoConf conf) throws IOException {
-    this(conf, NetUtils.createSocketAddr(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS)));
-  }
-
-  public TajoClient(TajoConf conf, InetSocketAddress addr) throws IOException {
-    this.conf = conf;
-    this.conf.set("tajo.disk.scheduler.report.interval", "0");
-    this.tajoMasterAddr = addr;
-
-    connPool = RpcConnectionPool.getPool(conf);
-  }
-
-  public TajoClient(InetSocketAddress addr) throws IOException {
-    this(new TajoConf(), addr);
-  }
-
-  public TajoClient(String hostname, int port) throws IOException {
-    this(new TajoConf(), NetUtils.createSocketAddr(hostname, port));
-  }
-
-  public void close() {
-    if(connPool != null) {
-      connPool.close();
-    }
-    queryMasterMap.clear();
-  }
-
-  public TajoConf getConf() {
-    return conf;
-  }
-
-  /**
-   * Call to QueryMaster closing query resources
-   * @param queryId
-   */
-  public void closeQuery(final QueryId queryId) {
-    if(queryMasterMap.containsKey(queryId)) {
-      NettyClientBase qmClient = null;
-      try {
-        qmClient = connPool.getConnection(queryMasterMap.get(queryId), QueryMasterClientProtocol.class, false);
-        QueryMasterClientProtocolService.BlockingInterface queryMasterService = qmClient.getStub();
-        queryMasterService.killQuery(null, queryId.getProto());
-      } catch (Exception e) {
-        LOG.warn("Fail to close a QueryMaster connection (qid=" + queryId + ", msg=" + e.getMessage() + ")", e);
-      } finally {
-        connPool.closeConnection(qmClient);
-        queryMasterMap.remove(queryId);
-      }
-    }
-  }
-
-  /**
-   * It submits a query statement and get a response immediately.
-   * The response only contains a query id, and submission status.
-   * In order to get the result, you should use {@link #getQueryResult(org.apache.tajo.QueryId)}
-   * or {@link #getQueryResultAndWait(org.apache.tajo.QueryId)}.
-   */
-  public GetQueryStatusResponse executeQuery(final String sql) throws ServiceException {
-    return new ServerCallable<GetQueryStatusResponse>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public GetQueryStatusResponse call(NettyClientBase client) throws ServiceException {
-        final QueryRequest.Builder builder = QueryRequest.newBuilder();
-        builder.setQuery(sql);
-
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-        return tajoMasterService.submitQuery(null, builder.build());
-      }
-    }.withRetries();
-  }
-
-  /**
-   * It submits a query statement and get a response.
-   * The main difference from {@link #executeQuery(String)}
-   * is a blocking method. So, this method is wait for
-   * the finish of the submitted query.
-   *
-   * @return If failed, return null.
-   */
-  public ResultSet executeQueryAndGetResult(final String sql)
-      throws ServiceException, IOException {
-    GetQueryStatusResponse response = new ServerCallable<GetQueryStatusResponse>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public GetQueryStatusResponse call(NettyClientBase client) throws ServiceException {
-        final QueryRequest.Builder builder = QueryRequest.newBuilder();
-        builder.setQuery(sql);
-
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-        return tajoMasterService.submitQuery(null, builder.build());
-      }
-    }.withRetries();
-
-    QueryId queryId = new QueryId(response.getQueryId());
-    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-      return this.createNullResultSet(queryId);
-    } else {
-      return this.getQueryResultAndWait(queryId);
-    }
-  }
-
-  public QueryStatus getQueryStatus(QueryId queryId) throws ServiceException {
-    GetQueryStatusRequest.Builder builder
-        = GetQueryStatusRequest.newBuilder();
-    builder.setQueryId(queryId.getProto());
-
-    GetQueryStatusResponse res = null;
-    if(queryMasterMap.containsKey(queryId)) {
-      NettyClientBase qmClient = null;
-      try {
-        qmClient = connPool.getConnection(queryMasterMap.get(queryId),
-            QueryMasterClientProtocol.class, false);
-        QueryMasterClientProtocolService.BlockingInterface queryMasterService = qmClient.getStub();
-        res = queryMasterService.getQueryStatus(null, builder.build());
-      } catch (Exception e) {
-        throw new ServiceException(e.getMessage(), e);
-      } finally {
-        connPool.closeConnection(qmClient);
-      }
-    } else {
-      NettyClientBase tmClient = null;
-      try {
-        tmClient = connPool.getConnection(tajoMasterAddr,
-            TajoMasterClientProtocol.class, false);
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub();
-        res = tajoMasterService.getQueryStatus(null, builder.build());
-
-        String queryMasterHost = res.getQueryMasterHost();
-        if(queryMasterHost != null && !queryMasterHost.isEmpty()) {
-          NettyClientBase qmClient = null;
-          try {
-            InetSocketAddress qmAddr = NetUtils.createSocketAddr(queryMasterHost, res.getQueryMasterPort());
-            qmClient = connPool.getConnection(
-                qmAddr, QueryMasterClientProtocol.class, false);
-            QueryMasterClientProtocolService.BlockingInterface queryMasterService = qmClient.getStub();
-            res = queryMasterService.getQueryStatus(null, builder.build());
-
-            queryMasterMap.put(queryId, qmAddr);
-          } catch (Exception e) {
-            throw new ServiceException(e.getMessage(), e);
-          } finally {
-            connPool.closeConnection(qmClient);
-          }
-        }
-      } catch (Exception e) {
-        throw new ServiceException(e.getMessage(), e);
-      } finally {
-        connPool.closeConnection(tmClient);
-      }
-    }
-    return new QueryStatus(res);
-  }
-
-  private static boolean isQueryRunnning(QueryState state) {
-    return state == QueryState.QUERY_NEW ||
-        state == QueryState.QUERY_RUNNING ||
-        state == QueryState.QUERY_MASTER_LAUNCHED ||
-        state == QueryState.QUERY_MASTER_INIT ||
-        state == QueryState.QUERY_NOT_ASSIGNED;
-  }
-
-  public ResultSet getQueryResult(QueryId queryId)
-      throws ServiceException, IOException {
-    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-      return createNullResultSet(queryId);
-    }
-    GetQueryResultResponse response = getResultResponse(queryId);
-    TableDesc tableDesc = CatalogUtil.newTableDesc(response.getTableDesc());
-    conf.setVar(ConfVars.USERNAME, response.getTajoUserName());
-    return new TajoResultSet(this, queryId, conf, tableDesc);
-  }
-
-  public ResultSet getQueryResultAndWait(QueryId queryId)
-      throws ServiceException, IOException {
-    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-      return createNullResultSet(queryId);
-    }
-    QueryStatus status = getQueryStatus(queryId);
-
-    while(status != null && isQueryRunnning(status.getState())) {
-      try {
-        Thread.sleep(500);
-      } catch (InterruptedException e) {
-        e.printStackTrace();
-      }
-
-      status = getQueryStatus(queryId);
-    }
-
-    if (status.getState() == QueryState.QUERY_SUCCEEDED) {
-      if (status.hasResult()) {
-        return getQueryResult(queryId);
-      } else {
-        return createNullResultSet(queryId);
-      }
-
-    } else {
-      LOG.warn("Query (" + status.getQueryId() + ") failed: " + status.getState());
-
-      //TODO throw SQLException(?)
-      return createNullResultSet(queryId);
-    }
-  }
-
-  public ResultSet createNullResultSet(QueryId queryId) throws IOException {
-    return new TajoResultSet(this, queryId);
-  }
-
-  public GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException {
-    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-      return null;
-    }
-
-    NettyClientBase client = null;
-    try {
-      InetSocketAddress queryMasterAddr = queryMasterMap.get(queryId);
-      if(queryMasterAddr == null) {
-        LOG.warn("No Connection to QueryMaster for " + queryId);
-        return null;
-      }
-      client = connPool.getConnection(queryMasterAddr, QueryMasterClientProtocol.class, false);
-      QueryMasterClientProtocolService.BlockingInterface queryMasterService = client.getStub();
-      GetQueryResultRequest.Builder builder = GetQueryResultRequest.newBuilder();
-      builder.setQueryId(queryId.getProto());
-      GetQueryResultResponse response = queryMasterService.getQueryResult(null,
-          builder.build());
-
-      return response;
-    } catch (Exception e) {
-      throw new ServiceException(e.getMessage(), e);
-    } finally {
-      connPool.closeConnection(client);
-    }
-  }
-
-  public boolean updateQuery(final String sql) throws ServiceException {
-    return new ServerCallable<Boolean>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public Boolean call(NettyClientBase client) throws ServiceException {
-        QueryRequest.Builder builder = QueryRequest.newBuilder();
-        builder.setQuery(sql);
-
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-        ResultCode resultCode =
-            tajoMasterService.updateQuery(null, builder.build()).getResultCode();
-        return resultCode == ResultCode.OK;
-      }
-    }.withRetries();
-  }
-
-  /**
-   * Test for the existence of table in catalog data.
-   * <p/>
-   * This will return true if table exists, false if not.
-   * @param name
-   * @return
-   * @throws ServiceException
-   */
-  public boolean existTable(final String name) throws ServiceException {
-    return new ServerCallable<Boolean>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public Boolean call(NettyClientBase client) throws ServiceException {
-        StringProto.Builder builder = StringProto.newBuilder();
-        builder.setValue(name);
-
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-        return tajoMasterService.existTable(null, builder.build()).getValue();
-      }
-    }.withRetries();
-  }
-
-  public TableDesc createExternalTable(final String name, final Schema schema, final Path path, final TableMeta meta)
-      throws SQLException, ServiceException {
-    return new ServerCallable<TableDesc>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-
-        CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
-        builder.setName(name);
-        builder.setSchema(schema.getProto());
-        builder.setMeta(meta.getProto());
-        builder.setPath(path.toUri().toString());
-        TableResponse res = tajoMasterService.createExternalTable(null, builder.build());
-        if (res.getResultCode() == ResultCode.OK) {
-          return CatalogUtil.newTableDesc(res.getTableDesc());
-        } else {
-          throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
-        }
-      }
-    }.withRetries();
-  }
-
-  public boolean dropTable(final String tableName) throws ServiceException {
-    return dropTable(tableName, false);
-  }
-
-  /**
-   * Deletes table schema from catalog data and deletes data file in hdfs
-   * @param tableName
-   * @return
-   * @throws ServiceException
-   */
-  public boolean dropTable(final String tableName, final boolean purge) throws ServiceException {
-    return new ServerCallable<Boolean>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public Boolean call(NettyClientBase client) throws ServiceException {
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-
-        DropTableRequest.Builder builder = DropTableRequest.newBuilder();
-        builder.setName(tableName);
-        builder.setPurge(purge);
-        return tajoMasterService.dropTable(null, builder.build()).getValue();
-      }
-    }.withRetries();
-
-  }
-
-  /**
-   * Get a list of table names. All table and column names are
-   * represented as lower-case letters.
-   */
-  public List<String> getTableList() throws ServiceException {
-    return new ServerCallable<List<String>>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public List<String> call(NettyClientBase client) throws ServiceException {
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-
-        GetTableListRequest.Builder builder = GetTableListRequest.newBuilder();
-        GetTableListResponse res = tajoMasterService.getTableList(null, builder.build());
-        return res.getTablesList();
-      }
-    }.withRetries();
-  }
-
-  public TableDesc getTableDesc(final String tableName) throws SQLException, ServiceException {
-    return new ServerCallable<TableDesc>(conf, tajoMasterAddr,
-        TajoMasterClientProtocol.class, false, true) {
-      public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-
-        GetTableDescRequest.Builder build = GetTableDescRequest.newBuilder();
-        build.setTableName(tableName);
-        TableResponse res = tajoMasterService.getTableDesc(null, build.build());
-        if (res.getResultCode() == ResultCode.OK) {
-          return CatalogUtil.newTableDesc(res.getTableDesc());
-        } else {
-          throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
-        }
-      }
-    }.withRetries();
-  }
-
-  public boolean killQuery(final QueryId queryId)
-      throws ServiceException, IOException {
-
-    QueryStatus status = getQueryStatus(queryId);
-
-    NettyClientBase tmClient = null;
-    try {
-      /* send a kill to the TM */
-      tmClient = connPool.getConnection(tajoMasterAddr, TajoMasterClientProtocol.class, false);
-      TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub();
-      tajoMasterService.killQuery(null, queryId.getProto());
-
-      long currentTimeMillis = System.currentTimeMillis();
-      long timeKillIssued = currentTimeMillis;
-      while ((currentTimeMillis < timeKillIssued + 10000L) && (status.getState()
-          != QueryState.QUERY_KILLED)) {
-        try {
-          Thread.sleep(1000L);
-        } catch(InterruptedException ie) {
-          /** interrupted, just break */
-          break;
-        }
-        currentTimeMillis = System.currentTimeMillis();
-        status = getQueryStatus(queryId);
-      }
-    } catch(Exception e) {
-      LOG.debug("Error when checking for application status", e);
-      return false;
-    } finally {
-      connPool.closeConnection(tmClient);
-    }
-
-    return true;
-  }
-
-  public static void main(String[] args) throws Exception {
-    TajoClient client = new TajoClient(new TajoConf());
-
-    client.close();
-
-    synchronized(client) {
-      client.wait();
-    }
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoDump.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoDump.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoDump.java
deleted file mode 100644
index 486ff9f..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/client/TajoDump.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.client;
-
-import com.google.common.collect.Lists;
-import com.google.protobuf.ServiceException;
-import org.apache.commons.cli.*;
-import org.apache.tajo.catalog.DDLBuilder;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.conf.TajoConf;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.sql.SQLException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.List;
-
-public class TajoDump {
-  private static final org.apache.commons.cli.Options options;
-
-  static {
-    options = new Options();
-    options.addOption("h", "host", true, "Tajo server host");
-    options.addOption("p", "port", true, "Tajo server port");
-    options.addOption("a", "all", false, "dump all table DDLs");
-  }
-
-  private static void printUsage() {
-    HelpFormatter formatter = new HelpFormatter();
-    formatter.printHelp( "tajo_dump [options] [table_name]", options );
-  }
-
-  public static void main(String [] args) throws ParseException, IOException, ServiceException, SQLException {
-    TajoConf conf = new TajoConf();
-
-    CommandLineParser parser = new PosixParser();
-    CommandLine cmd = parser.parse(options, args);
-
-    String hostName = null;
-    Integer port = null;
-    if (cmd.hasOption("h")) {
-      hostName = cmd.getOptionValue("h");
-    }
-    if (cmd.hasOption("p")) {
-      port = Integer.parseInt(cmd.getOptionValue("p"));
-    }
-
-    // if there is no "-h" option,
-    if(hostName == null) {
-      if (conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
-        // it checks if the client service address is given in configuration and distributed mode.
-        // if so, it sets entryAddr.
-        hostName = conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
-      }
-    }
-    if (port == null) {
-      if (conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
-        // it checks if the client service address is given in configuration and distributed mode.
-        // if so, it sets entryAddr.
-        port = Integer.parseInt(conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
-      }
-    }
-
-    TajoClient client = null;
-    if ((hostName == null) ^ (port == null)) {
-      System.err.println("ERROR: cannot find valid Tajo server address");
-      System.exit(-1);
-    } else if (hostName != null && port != null) {
-      conf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
-      client = new TajoClient(conf);
-    } else if (hostName == null && port == null) {
-      client = new TajoClient(conf);
-    }
-
-    List<TableDesc> tableDescList = Lists.newArrayList();
-
-    if (cmd.hasOption("a")) {
-      for (String tableName : client.getTableList()) {
-        tableDescList.add(client.getTableDesc(tableName));
-      }
-    } else if (cmd.getArgs().length > 0) {
-      for (String tableName : cmd.getArgs()) {
-        tableDescList.add(client.getTableDesc(tableName));
-      }
-    } else {
-      printUsage();
-    }
-
-
-    Writer writer = new PrintWriter(System.out);
-    writer.write("--\n");
-    writer.write("-- Tajo database dump\n");
-    writer.write("-- Dump date: " + toDateString() + "\n");
-    writer.write("--\n");
-    writer.write("\n");
-    for (TableDesc tableDesc : tableDescList) {
-      writer.write(DDLBuilder.buildDDL(tableDesc));
-      writer.write("\n\n");
-    }
-    writer.flush();
-    writer.close();
-    System.exit(0);
-  }
-
-  private static String toDateString() {
-    DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
-    java.util.Date today = Calendar.getInstance().getTime();
-    return df.format(today);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
deleted file mode 100644
index 789f761..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.datum.*;
-import org.apache.tajo.exception.UnsupportedException;
-import org.apache.tajo.storage.Tuple;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-
-public class MetaDataTuple implements Tuple {
-  List<Datum> values = new ArrayList<Datum>();
-
-  public MetaDataTuple(int size) {
-    values = new ArrayList<Datum>(size);
-    for(int i = 0; i < size; i++) {
-      values.add(NullDatum.get());
-    }
-  }
-
-  @Override
-  public int size() {
-    return values.size();
-  }
-
-  @Override
-  public boolean contains(int fieldid) {
-    return false;
-  }
-
-  @Override
-  public boolean isNull(int fieldid) {
-    return values.get(fieldid) == null || values.get(fieldid) instanceof NullDatum;
-  }
-
-  @Override
-  public void clear() {
-    values.clear();
-  }
-
-  @Override
-  public void put(int fieldId, Datum value) {
-    values.set(fieldId, value);
-  }
-
-  @Override
-  public void put(int fieldId, Datum[] values) {
-    throw new UnsupportedException("put");
-  }
-
-  @Override
-  public void put(int fieldId, Tuple tuple) {
-    throw new UnsupportedException("put");
-  }
-
-  @Override
-  public void put(Datum[] values) {
-    throw new UnsupportedException("put");
-  }
-
-  @Override
-  public Datum get(int fieldId) {
-    return getText(fieldId);
-  }
-
-  @Override
-  public void setOffset(long offset) {
-    throw new UnsupportedException("setOffset");
-  }
-
-  @Override
-  public long getOffset() {
-    throw new UnsupportedException("getOffset");
-  }
-
-  @Override
-  public BooleanDatum getBoolean(int fieldId) {
-    throw new UnsupportedException("getBoolean");
-  }
-
-  @Override
-  public BitDatum getByte(int fieldId) {
-    throw new UnsupportedException("getByte");
-  }
-
-  @Override
-  public CharDatum getChar(int fieldId) {
-    throw new UnsupportedException("getBoolean");
-  }
-
-  @Override
-  public BlobDatum getBytes(int fieldId) {
-    throw new UnsupportedException("BlobDatum");
-  }
-
-  @Override
-  public Int2Datum getShort(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new Int2Datum((short)Integer.parseInt(values.get(fieldId).toString()));
-  }
-
-  @Override
-  public Int4Datum getInt(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new Int4Datum(Integer.parseInt(values.get(fieldId).toString()));
-  }
-
-  @Override
-  public Int8Datum getLong(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new Int8Datum(Long.parseLong(values.get(fieldId).toString()));
-  }
-
-  @Override
-  public Float4Datum getFloat(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new Float4Datum(Float.parseFloat(values.get(fieldId).toString()));
-  }
-
-  @Override
-  public Float8Datum getDouble(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new Float8Datum(Float.parseFloat(values.get(fieldId).toString()));
-  }
-
-  @Override
-  public Inet4Datum getIPv4(int fieldId) {
-    throw new UnsupportedException("getIPv4");
-  }
-
-  @Override
-  public byte[] getIPv4Bytes(int fieldId) {
-    throw new UnsupportedException("getIPv4Bytes");
-  }
-
-  @Override
-  public InetAddress getIPv6(int fieldId) {
-    throw new UnsupportedException("getIPv6");
-  }
-
-  @Override
-  public byte[] getIPv6Bytes(int fieldId) {
-    throw new UnsupportedException("getIPv6Bytes");
-  }
-
-  @Override
-  public TextDatum getString(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new TextDatum(values.get(fieldId).toString());
-  }
-
-  @Override
-  public TextDatum getText(int fieldId) {
-    if(isNull(fieldId)) {
-      return null;
-    }
-    return new TextDatum(values.get(fieldId).toString());
-  }
-
-  @Override
-  public Tuple clone() throws CloneNotSupportedException {
-    throw new UnsupportedException("clone");
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoConnection.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoConnection.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoConnection.java
deleted file mode 100644
index 47c88d1..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoConnection.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.client.TajoClient;
-import org.apache.tajo.conf.TajoConf;
-
-import java.sql.*;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class TajoConnection implements Connection {
-  private TajoClient tajoClient;
-
-  private String databaseName;
-
-  private AtomicBoolean closed = new AtomicBoolean(true);
-
-  private String uri;
-
-  public TajoConnection(String uri, Properties properties) throws SQLException {
-    if (!uri.startsWith(TajoDriver.TAJO_JDBC_URL_PREFIX)) {
-      throw new SQLException("Invalid URL: " + uri, "TAJO-001");
-    }
-
-    this.uri = uri;
-
-    // remove prefix
-    uri = uri.substring(TajoDriver.TAJO_JDBC_URL_PREFIX.length());
-
-
-    if (uri.isEmpty()) {
-      throw new SQLException("Invalid URL: " + uri, "TAJO-001");
-    }
-
-    // parse uri
-    // form: hostname:port/databasename
-    String[] parts = uri.split("/");
-    if(parts.length == 0 || parts[0].trim().isEmpty()) {
-      throw new SQLException("Invalid URL(No tajo master's host:port): " + uri, "TAJO-001");
-    }
-    String[] hostAndPort = parts[0].trim().split(":");
-    String host = hostAndPort[0];
-    int port = 0;
-    try {
-      port = Integer.parseInt(hostAndPort[1]);
-    } catch (Exception e) {
-      throw new SQLException("Invalid URL(Wrong tajo master's host:port): " + uri, "TAJO-001");
-    }
-
-    if(parts.length > 1) {
-      String[] tokens = parts[1].split("\\?");
-      databaseName = tokens[0].trim();
-      if(tokens.length > 1) {
-        String[] extraParamTokens = tokens[1].split("&");
-        for(String eachExtraParam: extraParamTokens) {
-          String[] paramTokens = eachExtraParam.split("=");
-          String extraParamKey = paramTokens[0];
-          String extraParamValue = paramTokens[1];
-        }
-      }
-    }
-
-    TajoConf tajoConf = new TajoConf();
-
-    tajoConf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, host + ":" + port);
-
-    if(properties != null) {
-      for(Map.Entry<Object, Object> entry: properties.entrySet()) {
-        tajoConf.set(entry.getKey().toString(), entry.getValue().toString());
-      }
-    }
-
-    try {
-      tajoClient = new TajoClient(tajoConf);
-    } catch (Exception e) {
-      throw new SQLException("Can't create tajo client:" + e.getMessage(), "TAJO-002");
-    }
-    closed.set(false);
-  }
-
-  public String getUri() {
-    return uri;
-  }
-
-  public TajoClient getTajoClient() {
-    return tajoClient;
-  }
-
-  @Override
-  public void clearWarnings() throws SQLException {
-  }
-
-  @Override
-  public void close() throws SQLException {
-    if(!closed.get()) {
-      if(tajoClient != null) {
-        tajoClient.close();
-      }
-
-      closed.set(true);
-    }
-  }
-
-  @Override
-  public void commit() throws SQLException {
-    throw new SQLFeatureNotSupportedException("commit");
-  }
-
-  @Override
-  public Array createArrayOf(String arg0, Object[] arg1) throws SQLException {
-    throw new SQLFeatureNotSupportedException("createArrayOf");
-  }
-
-  @Override
-  public Blob createBlob() throws SQLException {
-    throw new SQLFeatureNotSupportedException("createBlob");
-  }
-
-  @Override
-  public Clob createClob() throws SQLException {
-    throw new SQLFeatureNotSupportedException("createClob");
-  }
-
-  @Override
-  public NClob createNClob() throws SQLException {
-    throw new SQLFeatureNotSupportedException("createNClob");
-  }
-
-  @Override
-  public SQLXML createSQLXML() throws SQLException {
-    throw new SQLFeatureNotSupportedException("createSQLXML");
-  }
-
-  @Override
-  public Statement createStatement() throws SQLException {
-    if (isClosed()) {
-      throw new SQLException("Can't create Statement, connection is closed");
-    }
-    return new TajoStatement(tajoClient);
-  }
-
-  @Override
-  public Statement createStatement(int resultSetType, int resultSetConcurrency)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("createStatement");
-  }
-
-  @Override
-  public Statement createStatement(int resultSetType, int resultSetConcurrency,
-                                   int resultSetHoldability) throws SQLException {
-    throw new SQLFeatureNotSupportedException("createStatement");
-  }
-
-  @Override
-  public Struct createStruct(String typeName, Object[] attributes)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("createStruct");
-  }
-
-  @Override
-  public boolean getAutoCommit() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public String getCatalog() throws SQLException {
-    return "";
-  }
-
-  @Override
-  public Properties getClientInfo() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getClientInfo");
-  }
-
-  @Override
-  public String getClientInfo(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getClientInfo");
-  }
-
-  @Override
-  public int getHoldability() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getHoldability");
-  }
-
-  @Override
-  public DatabaseMetaData getMetaData() throws SQLException {
-    return new TajoDatabaseMetaData(this);
-  }
-
-  @Override
-  public int getTransactionIsolation() throws SQLException {
-    return Connection.TRANSACTION_NONE;
-  }
-
-  @Override
-  public Map<String, Class<?>> getTypeMap() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTypeMap");
-  }
-
-  @Override
-  public SQLWarning getWarnings() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getWarnings");
-  }
-
-  @Override
-  public boolean isClosed() throws SQLException {
-    return closed.get();
-  }
-
-  @Override
-  public boolean isReadOnly() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean isValid(int timeout) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isValid");
-  }
-
-  @Override
-  public String nativeSQL(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("nativeSQL");
-  }
-
-  @Override
-  public CallableStatement prepareCall(String sql) throws SQLException {
-    throw new SQLFeatureNotSupportedException("prepareCall");
-  }
-
-  @Override
-  public CallableStatement prepareCall(String sql, int resultSetType,
-                                       int resultSetConcurrency) throws SQLException {
-    throw new SQLFeatureNotSupportedException("prepareCall");
-  }
-
-  @Override
-  public CallableStatement prepareCall(String sql, int resultSetType,
-                                       int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-    throw new SQLFeatureNotSupportedException("prepareCall");
-  }
-
-  @Override
-  public PreparedStatement prepareStatement(String sql) throws SQLException {
-    return new TajoPreparedStatement(tajoClient, sql);
-  }
-
-  @Override
-  public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
-      throws SQLException {
-    return new TajoPreparedStatement(tajoClient, sql);
-  }
-
-  @Override
-  public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("prepareStatement");
-  }
-
-  @Override
-  public PreparedStatement prepareStatement(String sql, String[] columnNames)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("prepareStatement");
-  }
-
-  @Override
-  public PreparedStatement prepareStatement(String sql, int resultSetType,
-                                            int resultSetConcurrency) throws SQLException {
-    return new TajoPreparedStatement(tajoClient, sql);
-  }
-
-  @Override
-  public PreparedStatement prepareStatement(String sql, int resultSetType,
-                                            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-    throw new SQLFeatureNotSupportedException("prepareStatement");
-  }
-
-  @Override
-  public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-    throw new SQLFeatureNotSupportedException("releaseSavepoint");
-  }
-
-  @Override
-  public void rollback() throws SQLException {
-    throw new SQLFeatureNotSupportedException("rollback");
-  }
-
-  @Override
-  public void rollback(Savepoint savepoint) throws SQLException {
-    throw new SQLFeatureNotSupportedException("rollback");
-  }
-
-  @Override
-  public void setAutoCommit(boolean autoCommit) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setAutoCommit");
-  }
-
-  @Override
-  public void setCatalog(String catalog) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setCatalog");
-  }
-
-  @Override
-  public void setClientInfo(Properties properties)
-      throws SQLClientInfoException {
-    throw new UnsupportedOperationException("setClientInfo");
-  }
-
-  @Override
-  public void setClientInfo(String name, String value)
-      throws SQLClientInfoException {
-    throw new UnsupportedOperationException("setClientInfo");
-  }
-
-  @Override
-  public void setHoldability(int holdability) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setHoldability");
-  }
-
-  @Override
-  public void setReadOnly(boolean readOnly) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setReadOnly");
-  }
-
-  @Override
-  public Savepoint setSavepoint() throws SQLException {
-    throw new SQLFeatureNotSupportedException("setSavepoint");
-  }
-
-  @Override
-  public Savepoint setSavepoint(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setSavepoint");
-  }
-
-  @Override
-  public void setTransactionIsolation(int level) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setTransactionIsolation");
-  }
-
-  @Override
-  public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setTypeMap");
-  }
-
-  @Override
-  public <T> T unwrap(Class<T> tClass) throws SQLException {
-    if (isWrapperFor(tClass)) {
-      return (T) this;
-    }
-    throw new SQLException("No wrapper for " + tClass);
-  }
-
-  @Override
-  public boolean isWrapperFor(Class<?> tClass) throws SQLException {
-    return tClass.isInstance(this);
-  }
-
-  public void abort(Executor executor) throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("abort not supported");
-  }
-
-  public int getNetworkTimeout() throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("getNetworkTimeout not supported");
-  }
-
-  public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("setNetworkTimeout not supported");
-  }
-
-  public String getSchema() throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("getSchema not supported");
-  }
-
-  public void setSchema(String schema) throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("setSchema not supported");
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
deleted file mode 100644
index 6c64ac2..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
+++ /dev/null
@@ -1,1196 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.TajoConstants;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.client.TajoClient;
-import org.apache.tajo.common.TajoDataTypes.Type;
-import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.datum.TextDatum;
-
-import java.sql.*;
-import java.util.*;
-
-/**
- * TajoDatabaseMetaData.
- */
-public class TajoDatabaseMetaData implements DatabaseMetaData {
-  private static final char SEARCH_STRING_ESCAPE = '\\';
-
-  private final TajoConnection conn;
-
-  public TajoDatabaseMetaData(TajoConnection conn) {
-    this.conn = conn;
-  }
-
-  @Override
-  public boolean allProceduresAreCallable()
-      throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean allTablesAreSelectable()
-      throws SQLException {
-    return true;
-  }
-
-  @Override
-  public String getURL()
-      throws SQLException {
-    return conn.getUri();
-  }
-
-  @Override
-  public String getUserName()
-      throws SQLException {
-    return "tajo";
-  }
-
-  @Override
-  public boolean isReadOnly()
-      throws SQLException {
-    return true;
-  }
-
-  @Override
-  public String getDatabaseProductName()
-      throws SQLException {
-    return "Tajo";
-  }
-
-  @Override
-  public String getDatabaseProductVersion()
-      throws SQLException {
-    //TODO get from tajo master
-    return TajoConstants.TAJO_VERSION;
-  }
-
-  @Override
-  public String getDriverName()
-      throws SQLException {
-    return "tajo";
-  }
-
-  @Override
-  public String getDriverVersion()
-      throws SQLException {
-    return TajoDriver.MAJOR_VERSION + "." + TajoDriver.MINOR_VERSION;
-  }
-
-  @Override
-  public int getDriverMajorVersion() {
-    return TajoDriver.MAJOR_VERSION;
-  }
-
-  @Override
-  public int getDriverMinorVersion() {
-    return TajoDriver.MINOR_VERSION;
-  }
-
-  @Override
-  public String getIdentifierQuoteString()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getIdentifierQuoteString not supported");
-  }
-
-  @Override
-  public String getSQLKeywords()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getSQLKeywords not supported");
-  }
-
-  @Override
-  public String getNumericFunctions()
-      throws SQLException {
-    return "";
-  }
-
-  @Override
-  public String getStringFunctions()
-      throws SQLException {
-    return "";
-  }
-
-  @Override
-  public String getSystemFunctions()
-      throws SQLException {
-    return "";
-  }
-
-  @Override
-  public String getTimeDateFunctions()
-      throws SQLException {
-    return "";
-  }
-
-  @Override
-  public String getSearchStringEscape()
-      throws SQLException {
-    return "\\";
-  }
-
-  @Override
-  public String getExtraNameCharacters()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getExtraNameCharacters not supported");
-  }
-
-  @Override
-  public String getSchemaTerm()
-      throws SQLException {
-    return "";
-  }
-
-  @Override
-  public String getProcedureTerm()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getProcedureTerm not supported");
-  }
-
-  @Override
-  public String getCatalogTerm()
-      throws SQLException {
-    return "database";
-  }
-
-  @Override
-  public String getCatalogSeparator()
-      throws SQLException {
-    return ".";
-  }
-
-  @Override
-  public int getMaxBinaryLiteralLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxBinaryLiteralLength not supported");
-  }
-
-  @Override
-  public int getMaxCharLiteralLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxCharLiteralLength not supported");
-  }
-
-  @Override
-  public int getMaxColumnNameLength()
-      throws SQLException {
-    return 128;
-  }
-
-  @Override
-  public int getMaxColumnsInGroupBy()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxColumnsInGroupBy not supported");
-  }
-
-  @Override
-  public int getMaxColumnsInIndex()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxColumnsInIndex not supported");
-  }
-
-  @Override
-  public int getMaxColumnsInOrderBy()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxColumnsInOrderBy not supported");
-  }
-
-  @Override
-  public int getMaxColumnsInSelect()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxColumnsInSelect not supported");
-  }
-
-  @Override
-  public int getMaxColumnsInTable()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxColumnsInTable not supported");
-  }
-
-  @Override
-  public int getMaxConnections()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxConnections not supported");
-  }
-
-  @Override
-  public int getMaxCursorNameLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxCursorNameLength not supported");
-  }
-
-  @Override
-  public int getMaxIndexLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxIndexLength not supported");
-  }
-
-  @Override
-  public int getMaxSchemaNameLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxSchemaNameLength not supported");
-  }
-
-  @Override
-  public int getMaxProcedureNameLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxProcedureNameLength not supported");
-  }
-
-  @Override
-  public int getMaxCatalogNameLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxCatalogNameLength not supported");
-  }
-
-  @Override
-  public int getMaxRowSize()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxRowSize not supported");
-  }
-
-  @Override
-  public boolean doesMaxRowSizeIncludeBlobs()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("doesMaxRowSizeIncludeBlobs not supported");
-  }
-
-  @Override
-  public int getMaxStatementLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxStatementLength not supported");
-  }
-
-  @Override
-  public int getMaxStatements()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxStatements not supported");
-  }
-
-  @Override
-  public int getMaxTableNameLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxTableNameLength not supported");
-  }
-
-  @Override
-  public int getMaxTablesInSelect()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxTablesInSelect not supported");
-  }
-
-  @Override
-  public int getMaxUserNameLength()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getMaxUserNameLength not supported");
-  }
-
-  @Override
-  public int getDefaultTransactionIsolation()
-      throws SQLException {
-    return Connection.TRANSACTION_NONE;
-  }
-
-  @Override
-  public boolean dataDefinitionCausesTransactionCommit()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("dataDefinitionCausesTransactionCommit not supported");
-  }
-
-  @Override
-  public boolean dataDefinitionIgnoredInTransactions()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("dataDefinitionIgnoredInTransactions not supported");
-  }
-
-  @Override
-  public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("stored procedures not supported");
-  }
-
-  @Override
-  public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("stored procedures not supported");
-  }
-
-  /**
-   * Convert a pattern containing JDBC catalog search wildcards into
-   * Java regex patterns.
-   *
-   * @param pattern input which may contain '%' or '_' wildcard characters, or
-   * these characters escaped using {@link #getSearchStringEscape()}.
-   * @return replace %/_ with regex search characters, also handle escaped
-   * characters.
-   */
-  private String convertPattern(final String pattern) {
-    if (pattern == null) {
-      return ".*";
-    } else {
-      StringBuilder result = new StringBuilder(pattern.length());
-
-      boolean escaped = false;
-      for (int i = 0, len = pattern.length(); i < len; i++) {
-        char c = pattern.charAt(i);
-        if (escaped) {
-          if (c != SEARCH_STRING_ESCAPE) {
-            escaped = false;
-          }
-          result.append(c);
-        } else {
-          if (c == SEARCH_STRING_ESCAPE) {
-            escaped = true;
-            continue;
-          } else if (c == '%') {
-            result.append(".*");
-          } else if (c == '_') {
-            result.append('.');
-          } else {
-            result.append(Character.toLowerCase(c));
-          }
-        }
-      }
-
-      return result.toString();
-    }
-  }
-
-  @Override
-  public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
-      throws SQLException {
-    try {
-      final List<MetaDataTuple> resultTables = new ArrayList<MetaDataTuple>();
-      final String resultCatalog;
-      if (catalog == null) {
-        resultCatalog = "default";
-      } else {
-        resultCatalog = catalog;
-      }
-
-      String regtableNamePattern = convertPattern(tableNamePattern);
-      try {
-        TajoClient tajoClient = conn.getTajoClient();
-        List<String> tableNames = tajoClient.getTableList();
-        for (String eachTableName: tableNames) {
-          if (eachTableName.matches(regtableNamePattern)) {
-            MetaDataTuple tuple = new MetaDataTuple(5);
-
-            int index = 0;
-            tuple.put(index++, new TextDatum(resultCatalog));  //TABLE_CAT
-            tuple.put(index++, NullDatum.get());   //TABLE_SCHEM
-            tuple.put(index++, new TextDatum(eachTableName));
-            tuple.put(index++, new TextDatum("TABLE"));   //TABLE_TYPE
-            tuple.put(index++, NullDatum.get());   //REMARKS
-
-            resultTables.add(tuple);
-          }
-        }
-        Collections.sort(resultTables, new Comparator<MetaDataTuple> () {
-          @Override
-          public int compare(MetaDataTuple table1, MetaDataTuple table2) {
-            return table1.getString(2).compareTo(table2.getString(2));
-          }
-        });
-      } catch (Exception e) {
-        e.printStackTrace();
-        throw new SQLException(e);
-      }
-      TajoMetaDataResultSet result = new TajoMetaDataResultSet(
-          Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE", "REMARKS"),
-          Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR),
-          resultTables);
-
-      return result;
-    } catch (Exception e) {
-      e.printStackTrace();
-      throw new SQLException(e.getMessage(), e);
-    }
-  }
-
-  @Override
-  public ResultSet getSchemas()
-      throws SQLException {
-    return getSchemas(null, null);
-  }
-
-  @Override
-  public ResultSet getCatalogs()
-      throws SQLException {
-    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
-    MetaDataTuple tuple = new MetaDataTuple(1);
-    tuple.put(0, new TextDatum("default"));
-    columns.add(tuple);
-
-    ResultSet result = new TajoMetaDataResultSet(
-        Arrays.asList("TABLE_CAT")
-        , Arrays.asList(Type.VARCHAR)
-        , columns);
-
-    return result;
-  }
-
-  @Override
-  public ResultSet getTableTypes()
-      throws SQLException {
-    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
-    MetaDataTuple tuple = new MetaDataTuple(1);
-    tuple.put(0, new TextDatum("TABLE"));
-    columns.add(tuple);
-
-    ResultSet result = new TajoMetaDataResultSet(
-        Arrays.asList("TABLE_TYPE")
-        , Arrays.asList(Type.VARCHAR)
-        , columns);
-
-    return result;
-  }
-
-  @Override
-  public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
-      throws SQLException {
-    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
-
-    return new TajoMetaDataResultSet(
-        Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "CLASS_NAME", "DATA_TYPE"
-            , "REMARKS", "BASE_TYPE")
-        , Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.INT4, Type.VARCHAR, Type.INT4)
-        , columns);
-  }
-
-  @Override
-  public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
-      throws SQLException {
-    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
-    try {
-      if (catalog == null) {
-        catalog = "default";
-      }
-
-      String regtableNamePattern = convertPattern(tableNamePattern);
-      String regcolumnNamePattern = convertPattern(columnNamePattern);
-
-      List<String> tables = conn.getTajoClient().getTableList();
-      for (String table: tables) {
-        if (table.matches(regtableNamePattern)) {
-          TableDesc tableDesc = conn.getTajoClient().getTableDesc(table);
-          int pos = 0;
-          for (Column column: tableDesc.getSchema().getColumns()) {
-            if (column.getColumnName().matches(regcolumnNamePattern)) {
-              MetaDataTuple tuple = new MetaDataTuple(22);
-
-              int index = 0;
-              tuple.put(index++, new TextDatum(catalog));  //TABLE_CAT
-              tuple.put(index++, NullDatum.get());  //TABLE_SCHEM
-              tuple.put(index++, new TextDatum(table));  //TABLE_NAME
-              tuple.put(index++, new TextDatum(column.getColumnName()));  //COLUMN_NAME
-              tuple.put(index++, new TextDatum("" + TajoDriver.tajoTypeToSqlType(column.getDataType())));  //TODO DATA_TYPE
-              tuple.put(index++, new TextDatum(TajoDriver.toSqlType(column.getDataType())));  //TYPE_NAME
-              tuple.put(index++, new TextDatum("0"));  //COLUMN_SIZE
-              tuple.put(index++, new TextDatum("0"));  //BUFFER_LENGTH
-              tuple.put(index++, new TextDatum("0"));  //DECIMAL_DIGITS
-              tuple.put(index++, new TextDatum("0"));  //NUM_PREC_RADIX
-              tuple.put(index++, new TextDatum("" + DatabaseMetaData.columnNullable));  //NULLABLE
-              tuple.put(index++, NullDatum.get());  //REMARKS
-              tuple.put(index++, NullDatum.get());  //COLUMN_DEF
-              tuple.put(index++, NullDatum.get());  //SQL_DATA_TYPE
-              tuple.put(index++, NullDatum.get());  //SQL_DATETIME_SUB
-              tuple.put(index++, new TextDatum("0"));  //CHAR_OCTET_LENGTH
-              tuple.put(index++, new TextDatum("" + pos));  //ORDINAL_POSITION
-              tuple.put(index++, new TextDatum("YES"));  //IS_NULLABLE
-              tuple.put(index++, NullDatum.get());  //SCOPE_CATLOG
-              tuple.put(index++, NullDatum.get());  //SCOPE_SCHEMA
-              tuple.put(index++, NullDatum.get());  //SCOPE_TABLE
-              tuple.put(index++, new TextDatum("0"));  //SOURCE_DATA_TYPE
-              columns.add(tuple);
-            }
-            pos++;
-          }
-        }
-      }
-
-      return new TajoMetaDataResultSet(
-          Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE"
-              , "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PREC_RADIX"
-              , "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB"
-              , "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE", "SCOPE_CATLOG", "SCOPE_SCHEMA"
-              , "SCOPE_TABLE", "SOURCE_DATA_TYPE")
-          , Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.INT4
-              , Type.VARCHAR, Type.INT4, Type.INT4, Type.INT4, Type.INT4
-              , Type.INT4, Type.VARCHAR, Type.VARCHAR, Type.INT4, Type.INT4
-              , Type.INT4, Type.INT4, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR
-              , Type.VARCHAR, Type.INT4)
-          , columns);
-    } catch (Exception e) {
-      e.printStackTrace();
-      throw new SQLException(e);
-    }
-  }
-
-  @Override
-  public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("privileges not supported");
-  }
-
-  @Override
-  public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("privileges not supported");
-  }
-
-  @Override
-  public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("row identifiers not supported");
-  }
-
-  @Override
-  public ResultSet getVersionColumns(String catalog, String schema, String table)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("version columns not supported");
-  }
-
-  @Override
-  public ResultSet getPrimaryKeys(String catalog, String schema, String table)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("primary keys not supported");
-  }
-
-  @Override
-  public ResultSet getImportedKeys(String catalog, String schema, String table)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("imported keys not supported");
-  }
-
-  @Override
-  public ResultSet getExportedKeys(String catalog, String schema, String table)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("exported keys not supported");
-  }
-
-  @Override
-  public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("cross reference not supported");
-  }
-
-  @Override
-  public ResultSet getTypeInfo()
-      throws SQLException {
-    throw new UnsupportedOperationException("getTypeInfo not supported");
-  }
-
-  @Override
-  public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("indexes not supported");
-  }
-
-  @Override
-  public boolean deletesAreDetected(int type)
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean insertsAreDetected(int type)
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public Connection getConnection()
-      throws SQLException {
-    return conn;
-  }
-
-  @Override
-  public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("type hierarchies not supported");
-  }
-
-  @Override
-  public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("type hierarchies not supported");
-  }
-
-  @Override
-  public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("user-defined types not supported");
-  }
-
-  @Override
-  public int getResultSetHoldability()
-      throws SQLException {
-    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-  }
-
-  @Override
-  public int getDatabaseMajorVersion()
-      throws SQLException {
-    return TajoDriver.MAJOR_VERSION;
-  }
-
-  @Override
-  public int getDatabaseMinorVersion()
-      throws SQLException {
-    return TajoDriver.MINOR_VERSION;
-  }
-
-  @Override
-  public int getJDBCMajorVersion()
-      throws SQLException {
-    return TajoDriver.JDBC_VERSION_MAJOR;
-  }
-
-  @Override
-  public int getJDBCMinorVersion()
-      throws SQLException {
-    return TajoDriver.JDBC_VERSION_MINOR;
-  }
-
-  @Override
-  public int getSQLStateType()
-      throws SQLException {
-    return DatabaseMetaData.sqlStateSQL;
-  }
-
-  @Override
-  public RowIdLifetime getRowIdLifetime()
-      throws SQLException {
-    return RowIdLifetime.ROWID_UNSUPPORTED;
-  }
-
-  @Override
-  public ResultSet getSchemas(String catalog, String schemaPattern)
-      throws SQLException {
-    return new TajoMetaDataResultSet(
-        Arrays.asList("TABLE_SCHEM", "TABLE_CATALOG"),
-        Arrays.asList(Type.VARCHAR, Type.VARCHAR),
-        null);
-  }
-
-  @Override
-  public boolean autoCommitFailureClosesAllResultSets()
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public ResultSet getClientInfoProperties()
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getClientInfoProperties not supported");
-  }
-
-  @Override
-  public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFunctions not supported");
-  }
-
-  @Override
-  public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFunctionColumns not supported");
-  }
-
-  @Override
-  public boolean isCatalogAtStart() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean locatorsUpdateCopy() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean nullPlusNonNullIsNull() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean nullsAreSortedAtEnd() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean nullsAreSortedAtStart() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean nullsAreSortedHigh() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean nullsAreSortedLow() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean othersDeletesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean othersInsertsAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean othersUpdatesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean ownDeletesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean ownInsertsAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean ownUpdatesAreVisible(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean storesLowerCaseIdentifiers() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean storesMixedCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean storesUpperCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsANSI92FullSQL() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsANSI92IntermediateSQL() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsAlterTableWithAddColumn() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsAlterTableWithDropColumn() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsBatchUpdates() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCatalogsInDataManipulation() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsColumnAliasing() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean supportsConvert() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsConvert(int fromType, int toType) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCoreSQLGrammar() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsCorrelatedSubqueries() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsDataDefinitionAndDataManipulationTransactions()
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsExpressionsInOrderBy() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsExtendedSQLGrammar() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsFullOuterJoins() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsGetGeneratedKeys() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsGroupBy() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean supportsGroupByBeyondSelect() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsGroupByUnrelated() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsLikeEscapeClause() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsLimitedOuterJoins() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsMinimumSQLGrammar() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsMixedCaseIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsMultipleOpenResults() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsMultipleResultSets() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsMultipleTransactions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsNamedParameters() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsNonNullableColumns() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsOrderByUnrelated() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsOuterJoins() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsPositionedDelete() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsPositionedUpdate() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsResultSetConcurrency(int type, int concurrency)
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsResultSetHoldability(int holdability)
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsResultSetType(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSavepoints() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSchemasInDataManipulation() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSchemasInProcedureCalls() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSchemasInTableDefinitions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSelectForUpdate() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsStatementPooling() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsStoredProcedures() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSubqueriesInComparisons() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSubqueriesInExists() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSubqueriesInIns() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsTableCorrelationNames() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsTransactionIsolationLevel(int level)
-      throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsTransactions() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsUnion() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean supportsUnionAll() throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean updatesAreDetected(int type) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean usesLocalFilePerTable() throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean usesLocalFiles() throws SQLException {
-    return false;
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T> T unwrap(Class<T> iface)
-      throws SQLException {
-    if (isWrapperFor(iface)) {
-      return (T) this;
-    }
-    throw new SQLFeatureNotSupportedException("No wrapper for " + iface);
-  }
-
-  @Override
-  public boolean isWrapperFor(Class<?> iface)
-      throws SQLException {
-    return iface.isInstance(this);
-  }
-
-  public boolean generatedKeyAlwaysReturned() throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("generatedKeyAlwaysReturned not supported");
-  }
-
-  public ResultSet getPseudoColumns(String catalog, String schemaPattern,
-                                    String tableNamePattern, String columnNamePattern) throws SQLException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("getPseudoColumns not supported");
-  }
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDriver.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDriver.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDriver.java
deleted file mode 100644
index ca0502f..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoDriver.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.common.TajoDataTypes;
-import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.exception.UnsupportedException;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.sql.*;
-import java.util.Properties;
-import java.util.logging.Logger;
-
-public class TajoDriver implements Driver, Closeable {
-  public static final int MAJOR_VERSION = 1;
-  public static final int MINOR_VERSION = 0;
-
-  public static final int JDBC_VERSION_MAJOR = 4;
-  public static final int JDBC_VERSION_MINOR = 0;
-
-  public static final String TAJO_JDBC_URL_PREFIX = "jdbc:tajo://";
-
-  protected static TajoConf jdbcTajoConf;
-
-  static {
-    try {
-      java.sql.DriverManager.registerDriver(new TajoDriver());
-    } catch (SQLException e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    }
-  }
-
-  public TajoDriver() {
-    jdbcTajoConf = new TajoConf();
-  }
-
-  @Override
-  public void close() throws IOException {
-  }
-
-  @Override
-  public Connection connect(String url, Properties properties) throws SQLException {
-    return new TajoConnection(url, properties);
-  }
-
-  @Override
-  public boolean acceptsURL(String url) throws SQLException {
-    return url.startsWith(TAJO_JDBC_URL_PREFIX);
-  }
-
-  @Override
-  public DriverPropertyInfo[] getPropertyInfo(String s, Properties properties) throws SQLException {
-    return new DriverPropertyInfo[0];
-  }
-
-  @Override
-  public int getMajorVersion() {
-    return MAJOR_VERSION;
-  }
-
-  @Override
-  public int getMinorVersion() {
-    return MINOR_VERSION;
-  }
-
-  @Override
-  public boolean jdbcCompliant() {
-    return false;
-  }
-
-  public static String toSqlType(TajoDataTypes.DataType type) {
-    switch (type.getType()) {
-      case BOOLEAN:
-        return "boolean";
-      case INT1:
-        return "tinyint";
-      case INT2:
-        return "smallint";
-      case INT4:
-        return "integer";
-      case INT8:
-        return "bigint";
-      case FLOAT4:
-        return "float";
-      case FLOAT8:
-        return "float8";
-      case DECIMAL:
-        return "numeric";
-      case VARBINARY:
-        return "bytea";
-      case CHAR:
-        return "character";
-      case DATE:
-        return "date";
-      case VARCHAR:
-        return "varchar";
-      case TEXT:
-        return "varchar";
-      default:
-        throw new UnsupportedException("Unrecognized column type:" + type);
-    }
-  }
-
-  public static int tajoTypeToSqlType(TajoDataTypes.DataType type) throws SQLException {
-    switch (type.getType()) {
-      case BOOLEAN:
-        return Types.BOOLEAN;
-      case INT1:
-        return Types.TINYINT;
-      case INT2:
-        return Types.SMALLINT;
-      case INT4:
-        return Types.INTEGER;
-      case INT8:
-        return Types.BIGINT;
-      case FLOAT4:
-        return Types.FLOAT;
-      case FLOAT8:
-        return Types.DOUBLE;
-      case DECIMAL:
-        return Types.DECIMAL;
-      case DATE:
-        return Types.TIMESTAMP;
-      case VARCHAR:
-        return Types.VARCHAR;
-      case TEXT:
-        return Types.VARCHAR;
-      default:
-        throw new SQLException("Unrecognized column type: " + type);
-    }
-  }
-
-  static int columnDisplaySize(int columnType) throws SQLException {
-    // according to hiveTypeToSqlType possible options are:
-    switch(columnType) {
-      case Types.BOOLEAN:
-        return columnPrecision(columnType);
-      case Types.VARCHAR:
-        return Integer.MAX_VALUE; // hive has no max limit for strings
-      case Types.TINYINT:
-      case Types.SMALLINT:
-      case Types.INTEGER:
-      case Types.BIGINT:
-        return columnPrecision(columnType) + 1; // allow +/-
-      case Types.TIMESTAMP:
-        return columnPrecision(columnType);
-      // see http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Float.MAX_EXPONENT
-      case Types.FLOAT:
-        return 24; // e.g. -(17#).e-###
-      // see http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Double.MAX_EXPONENT
-      case Types.DOUBLE:
-        return 25; // e.g. -(17#).e-####
-      case Types.DECIMAL:
-        return Integer.MAX_VALUE;
-      default:
-        throw new SQLException("Invalid column type: " + columnType);
-    }
-  }
-
-  static int columnPrecision(int columnType) throws SQLException {
-    // according to hiveTypeToSqlType possible options are:
-    switch(columnType) {
-      case Types.BOOLEAN:
-        return 1;
-      case Types.VARCHAR:
-        return Integer.MAX_VALUE; // hive has no max limit for strings
-      case Types.TINYINT:
-        return 3;
-      case Types.SMALLINT:
-        return 5;
-      case Types.INTEGER:
-        return 10;
-      case Types.BIGINT:
-        return 19;
-      case Types.FLOAT:
-        return 7;
-      case Types.DOUBLE:
-        return 15;
-      case Types.TIMESTAMP:
-        return 29;
-      case Types.DECIMAL:
-        return Integer.MAX_VALUE;
-      default:
-        throw new SQLException("Invalid column type: " + columnType);
-    }
-  }
-
-  static int columnScale(int columnType) throws SQLException {
-    // according to hiveTypeToSqlType possible options are:
-    switch(columnType) {
-      case Types.BOOLEAN:
-      case Types.VARCHAR:
-      case Types.TINYINT:
-      case Types.SMALLINT:
-      case Types.INTEGER:
-      case Types.BIGINT:
-        return 0;
-      case Types.FLOAT:
-        return 7;
-      case Types.DOUBLE:
-        return 15;
-      case Types.TIMESTAMP:
-        return 9;
-      case Types.DECIMAL:
-        return Integer.MAX_VALUE;
-      default:
-        throw new SQLException("Invalid column type: " + columnType);
-    }
-  }
-
-  public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-    // JDK 1.7
-    throw new SQLFeatureNotSupportedException("getParentLogger not supported");
-  }
-}


[5/6] TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..f4d685f
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
@@ -0,0 +1,1129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.storage.Tuple;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.Map;
+
+public abstract class TajoResultSetBase implements ResultSet {
+  protected int curRow;
+  protected long totalRow;
+  protected boolean wasNull;
+  protected Schema schema;
+  protected Tuple cur;
+
+  protected void init() {
+    cur = null;
+    curRow = 0;
+    totalRow = 0;
+    wasNull = false;
+  }
+
+  private void handleNull(Datum d) {
+    wasNull = (d instanceof NullDatum);
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    init();
+  }
+
+  @Override
+  public boolean getBoolean(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asBool();
+  }
+
+  @Override
+  public boolean getBoolean(String colName) throws SQLException {
+    Datum datum = cur.get(findColumn(colName));
+    handleNull(datum);
+    return datum.asBool();
+  }
+
+  @Override
+  public byte getByte(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asByte();
+  }
+
+  @Override
+  public byte getByte(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asByte();
+  }
+
+  @Override
+  public byte[] getBytes(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asByteArray();
+  }
+
+  @Override
+  public byte[] getBytes(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asByteArray();
+  }
+
+  @Override
+  public double getDouble(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asFloat8();
+  }
+
+  @Override
+  public double getDouble(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asFloat8();
+  }
+
+  @Override
+  public float getFloat(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asFloat4();
+  }
+
+  @Override
+  public float getFloat(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asFloat4();
+  }
+
+  @Override
+  public int getInt(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asInt4();
+  }
+
+  @Override
+  public int getInt(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asInt4();
+  }
+
+  @Override
+  public long getLong(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asInt8();
+  }
+
+  @Override
+  public long getLong(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asInt8();
+  }
+
+  @Override
+  public Object getObject(int fieldId) throws SQLException {
+    Datum d = cur.get(fieldId - 1);
+    handleNull(d);
+
+    TajoDataTypes.Type dataType = schema.getColumn(fieldId - 1).getDataType().getType();
+
+    switch(dataType) {
+      case BOOLEAN:  return d.asBool();
+      case INT1:
+      case INT2: return d.asInt2();
+      case INT4: return d.asInt4();
+      case INT8: return d.asInt8();
+      case TEXT:
+      case CHAR:
+      case DATE:
+      case VARCHAR:  return d.asChars();
+      case FLOAT4:  return d.asFloat4();
+      case FLOAT8:  return d.asFloat8();
+      case DECIMAL:
+      case NUMERIC:  return d.asFloat8();
+      default: return d.asChars();
+    }
+  }
+
+  @Override
+  public Object getObject(String name) throws SQLException {
+    return getObject(findColumn(name));
+  }
+
+  @Override
+  public short getShort(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asInt2();
+  }
+
+  @Override
+  public short getShort(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asInt2();
+  }
+
+  @Override
+  public String getString(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    handleNull(datum);
+    return datum.asChars();
+  }
+
+  @Override
+  public String getString(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    handleNull(datum);
+    return datum.asChars();
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> clazz) throws SQLException {
+    throw new SQLFeatureNotSupportedException("isWrapperFor not supported");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> clazz) throws SQLException {
+    throw new SQLFeatureNotSupportedException("unwrap not supported");
+  }
+
+  @Override
+  public boolean absolute(int row) throws SQLException {
+    throw new SQLFeatureNotSupportedException("absolute not supported");
+  }
+
+  @Override
+  public void afterLast() throws SQLException {
+    while (this.next())
+      ;
+  }
+
+  @Override
+  public void cancelRowUpdates() throws SQLException {
+    throw new SQLFeatureNotSupportedException("cancelRowUpdates not supported");
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+    throw new SQLFeatureNotSupportedException("clearWarnings not supported");
+  }
+
+  @Override
+  public void deleteRow() throws SQLException {
+    throw new SQLFeatureNotSupportedException("deleteRow not supported");
+  }
+
+  @Override
+  public int findColumn(String colName) throws SQLException {
+    return schema.getColumnIdByName(colName);
+  }
+
+  @Override
+  public boolean first() throws SQLException {
+    this.beforeFirst();
+    return this.next();
+  }
+
+  @Override
+  public Array getArray(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getArray not supported");
+  }
+
+  @Override
+  public Array getArray(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getArray not supported");
+  }
+
+  @Override
+  public InputStream getAsciiStream(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getAsciiStream not supported");
+  }
+
+  @Override
+  public InputStream getAsciiStream(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getAsciiStream not supported");
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(int index, int x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(String name, int x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
+  }
+
+  @Override
+  public InputStream getBinaryStream(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBinaryStream not supported");
+  }
+
+  @Override
+  public InputStream getBinaryStream(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBinaryStream not supported");
+  }
+
+  @Override
+  public Blob getBlob(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBlob not supported");
+  }
+
+  @Override
+  public Blob getBlob(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getBlob not supported");
+  }
+
+  @Override
+  public Reader getCharacterStream(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getCharacterStream not supported");
+  }
+
+  @Override
+  public Reader getCharacterStream(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getCharacterStream not supported");
+  }
+
+  @Override
+  public Clob getClob(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getClob not supported");
+  }
+
+  @Override
+  public Clob getClob(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getClob not supported");
+  }
+
+  @Override
+  public int getConcurrency() throws SQLException {
+    return ResultSet.CONCUR_READ_ONLY;
+  }
+
+  @Override
+  public String getCursorName() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getCursorName not supported");
+  }
+
+  @Override
+  public Date getDate(int index) throws SQLException {
+    Object obj = getObject(index);
+    if (obj == null) {
+      return null;
+    }
+
+    try {
+      return Date.valueOf((String) obj);
+    } catch (Exception e) {
+      throw new SQLException("Cannot convert column " + index
+          + " to date: " + e.toString());
+    }
+  }
+
+  @Override
+  public Date getDate(String name) throws SQLException {
+    return getDate(findColumn(name));
+  }
+
+  @Override
+  public Date getDate(int index, Calendar x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getDate not supported");
+  }
+
+  @Override
+  public Date getDate(String name, Calendar x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getDate not supported");
+  }
+
+  @Override
+  public int getFetchDirection() throws SQLException {
+    return ResultSet.FETCH_FORWARD;
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getFetchSize not supported");
+  }
+
+  @Override
+  public int getHoldability() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getHoldability not supported");
+  }
+
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+    return new TajoResultSetMetaData(schema);
+  }
+
+  @Override
+  public Reader getNCharacterStream(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getNCharacterStream not supported");
+  }
+
+  @Override
+  public Reader getNCharacterStream(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getNCharacterStream not supported");
+  }
+
+  @Override
+  public NClob getNClob(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getNClob not supported");
+  }
+
+  @Override
+  public NClob getNClob(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getNClob not supported");
+  }
+
+  @Override
+  public String getNString(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getNString not supported");
+  }
+
+  @Override
+  public String getNString(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getNString not supported");
+  }
+
+  @Override
+  public Object getObject(int index, Map<String, Class<?>> x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getObject not supported");
+  }
+
+  @Override
+  public Object getObject(String name, Map<String, Class<?>> x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getObject not supported");
+  }
+
+  public <T> T getObject(String name, Class<T> x)
+      throws SQLException {
+    //JDK 1.7
+    throw new SQLFeatureNotSupportedException("getObject not supported");
+  }
+
+  public <T> T getObject(int index, Class<T> x)
+      throws SQLException {
+    //JDK 1.7
+    throw new SQLFeatureNotSupportedException("getObject not supported");
+  }
+
+  @Override
+  public Ref getRef(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getRef not supported");
+  }
+
+  @Override
+  public Ref getRef(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getRef not supported");
+  }
+
+  @Override
+  public int getRow() throws SQLException {
+    return curRow;
+  }
+
+  @Override
+  public RowId getRowId(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getRowId not supported");
+  }
+
+  @Override
+  public RowId getRowId(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getRowId not supported");
+  }
+
+  @Override
+  public SQLXML getSQLXML(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getSQLXML not supported");
+  }
+
+  @Override
+  public SQLXML getSQLXML(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getSQLXML not supported");
+  }
+
+  @Override
+  public Statement getStatement() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getStatement not supported");
+  }
+
+  @Override
+  public Time getTime(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTime not supported");
+  }
+
+  @Override
+  public Time getTime(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTime not supported");
+  }
+
+  @Override
+  public Time getTime(int index, Calendar x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTime not supported");
+  }
+
+  @Override
+  public Time getTime(String name, Calendar x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTime not supported");
+  }
+
+  @Override
+  public Timestamp getTimestamp(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
+  }
+
+  @Override
+  public Timestamp getTimestamp(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
+  }
+
+  @Override
+  public Timestamp getTimestamp(int index, Calendar x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
+  }
+
+  @Override
+  public Timestamp getTimestamp(String name, Calendar x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
+  }
+
+  @Override
+  public int getType() throws SQLException {
+    return ResultSet.TYPE_FORWARD_ONLY;
+  }
+
+  @Override
+  public URL getURL(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getURL not supported");
+  }
+
+  @Override
+  public URL getURL(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getURL not supported");
+  }
+
+  @Override
+  public InputStream getUnicodeStream(int index) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getUnicodeStream not supported");
+  }
+
+  @Override
+  public InputStream getUnicodeStream(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getUnicodeStream not supported");
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getWarnings not supported");
+  }
+
+  @Override
+  public void insertRow() throws SQLException {
+    throw new SQLFeatureNotSupportedException("insertRow not supported");
+  }
+
+  @Override
+  public boolean isAfterLast() throws SQLException {
+    return this.curRow > this.totalRow;
+  }
+
+  @Override
+  public boolean isBeforeFirst() throws SQLException {
+    return this.curRow == 0;
+  }
+
+  @Override
+  public boolean isClosed() throws SQLException {
+    return this.curRow == -1;
+  }
+
+  @Override
+  public boolean isFirst() throws SQLException {
+    return this.curRow == 1;
+  }
+
+  @Override
+  public boolean isLast() throws SQLException {
+    return this.curRow == this.totalRow;
+  }
+
+  @Override
+  public boolean last() throws SQLException {
+    Tuple last = null;
+    while (this.next()) {
+      last = cur;
+    }
+    cur = last;
+    return true;
+  }
+
+  @Override
+  public void moveToCurrentRow() throws SQLException {
+    throw new SQLFeatureNotSupportedException("moveToCurrentRow not supported");
+  }
+
+  @Override
+  public void moveToInsertRow() throws SQLException {
+    throw new SQLFeatureNotSupportedException("moveToInsertRow not supported");
+  }
+
+  @Override
+  public boolean next() throws SQLException {
+    try {
+      if (totalRow <= 0) {
+        return false;
+      }
+
+      cur = nextTuple();
+      curRow++;
+      if (cur != null) {
+        return true;
+      }
+    } catch (IOException e) {
+      throw new SQLException(e.getMessage());
+    }
+    return false;
+  }
+
+  protected abstract Tuple nextTuple() throws IOException;
+
+  @Override
+  public boolean previous() throws SQLException {
+    throw new SQLFeatureNotSupportedException("previous not supported");
+  }
+
+  @Override
+  public void refreshRow() throws SQLException {
+    throw new SQLFeatureNotSupportedException("refreshRow not supported");
+  }
+
+  @Override
+  public boolean relative(int rows) throws SQLException {
+    throw new SQLFeatureNotSupportedException("relative not supported");
+  }
+
+  @Override
+  public boolean rowDeleted() throws SQLException {
+    throw new SQLFeatureNotSupportedException("rowDeleted not supported");
+  }
+
+  @Override
+  public boolean rowInserted() throws SQLException {
+    throw new SQLFeatureNotSupportedException("rowInserted not supported");
+  }
+
+  @Override
+  public boolean rowUpdated() throws SQLException {
+    throw new SQLFeatureNotSupportedException("rowUpdated not supported");
+  }
+
+  @Override
+  public void setFetchDirection(int direction) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setFetchDirection not supported");
+  }
+
+  @Override
+  public void setFetchSize(int size) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setFetchSize not supported");
+  }
+
+  @Override
+  public void updateArray(int index, Array x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateArray not supported");
+  }
+
+  @Override
+  public void updateArray(String name, Array x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateArray not supported");
+  }
+
+  @Override
+  public void updateAsciiStream(int index, InputStream x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
+  }
+
+  @Override
+  public void updateAsciiStream(String name, InputStream x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
+  }
+
+  @Override
+  public void updateAsciiStream(int index, InputStream x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
+  }
+
+  @Override
+  public void updateAsciiStream(String name, InputStream x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
+  }
+
+  @Override
+  public void updateAsciiStream(int index, InputStream x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
+  }
+
+  @Override
+  public void updateAsciiStream(String name, InputStream x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
+  }
+
+  @Override
+  public void updateBigDecimal(int index, BigDecimal x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBigDecimal not supported");
+  }
+
+  @Override
+  public void updateBigDecimal(String name, BigDecimal x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBigDecimal not supported");
+  }
+
+  @Override
+  public void updateBinaryStream(int index, InputStream x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
+  }
+
+  @Override
+  public void updateBinaryStream(String name, InputStream x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
+  }
+
+  @Override
+  public void updateBinaryStream(int index, InputStream x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
+  }
+
+  @Override
+  public void updateBinaryStream(String name, InputStream x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
+  }
+
+  @Override
+  public void updateBinaryStream(int index, InputStream x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
+  }
+
+  @Override
+  public void updateBinaryStream(String name, InputStream x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
+  }
+
+  @Override
+  public void updateBlob(int index, Blob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBlob not supported");
+  }
+
+  @Override
+  public void updateBlob(String name, Blob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBlob not supported");
+  }
+
+  @Override
+  public void updateBlob(int index, InputStream x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBlob not supported");
+  }
+
+  @Override
+  public void updateBlob(String name, InputStream x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBlob not supported");
+  }
+
+  @Override
+  public void updateBlob(int index, InputStream x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBlob not supported");
+  }
+
+  @Override
+  public void updateBlob(String name, InputStream x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBlob not supported");
+  }
+
+  @Override
+  public void updateBoolean(int index, boolean x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBoolean not supported");
+  }
+
+  @Override
+  public void updateBoolean(String name, boolean x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateBoolean not supported");
+  }
+
+  @Override
+  public void updateByte(int index, byte x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateByte not supported");
+  }
+
+  @Override
+  public void updateByte(String name, byte x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateByte not supported");
+  }
+
+  @Override
+  public void updateBytes(int index, byte[] x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateByte not supported");
+  }
+
+  @Override
+  public void updateBytes(String name, byte[] x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateByte not supported");
+  }
+
+  @Override
+  public void updateCharacterStream(int index, Reader x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
+  }
+
+  @Override
+  public void updateCharacterStream(String name, Reader x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
+  }
+
+  @Override
+  public void updateCharacterStream(int index, Reader x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
+  }
+
+  @Override
+  public void updateCharacterStream(String name, Reader x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
+  }
+
+  @Override
+  public void updateCharacterStream(int index, Reader x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
+  }
+
+  @Override
+  public void updateCharacterStream(String name, Reader x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
+  }
+
+  @Override
+  public void updateClob(int index, Clob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateClob not supported");
+  }
+
+  @Override
+  public void updateClob(String name, Clob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateClob not supported");
+  }
+
+  @Override
+  public void updateClob(int index, Reader x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateClob not supported");
+  }
+
+  @Override
+  public void updateClob(String name, Reader x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateClob not supported");
+  }
+
+  @Override
+  public void updateClob(int index, Reader x, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateClob not supported");
+  }
+
+  @Override
+  public void updateClob(String name, Reader x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateClob not supported");
+  }
+
+  @Override
+  public void updateDate(int index, Date x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateDate not supported");
+  }
+
+  @Override
+  public void updateDate(String name, Date x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateDate not supported");
+  }
+
+  @Override
+  public void updateDouble(int index, double x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateDouble not supported");
+  }
+
+  @Override
+  public void updateDouble(String name, double x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateDouble not supported");
+  }
+
+  @Override
+  public void updateFloat(int index, float x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateFloat not supported");
+  }
+
+  @Override
+  public void updateFloat(String name, float x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateFloat not supported");
+  }
+
+  @Override
+  public void updateInt(int index, int x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateInt not supported");
+  }
+
+  @Override
+  public void updateInt(String name, int x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateInt not supported");
+  }
+
+  @Override
+  public void updateLong(int index, long x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateLong not supported");
+  }
+
+  @Override
+  public void updateLong(String name, long x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateLong not supported");
+  }
+
+  @Override
+  public void updateNCharacterStream(int index, Reader x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
+  }
+
+  @Override
+  public void updateNCharacterStream(String name, Reader x)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
+  }
+
+  @Override
+  public void updateNCharacterStream(int index, Reader x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
+  }
+
+  @Override
+  public void updateNCharacterStream(String name, Reader x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
+  }
+
+  @Override
+  public void updateNClob(int index, NClob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNClob not supported");
+  }
+
+  @Override
+  public void updateNClob(String name, NClob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNClob not supported");
+  }
+
+  @Override
+  public void updateNClob(int index, Reader x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNClob not supported");
+  }
+
+  @Override
+  public void updateNClob(String name, Reader x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNClob not supported");
+  }
+
+  @Override
+  public void updateNClob(int index, Reader x, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNClob not supported");
+  }
+
+  @Override
+  public void updateNClob(String name, Reader x, long length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNClob not supported");
+  }
+
+  @Override
+  public void updateNString(int arg0, String x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNString not supported");
+  }
+
+  @Override
+  public void updateNString(String name, String x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNString not supported");
+  }
+
+  @Override
+  public void updateNull(int arg0) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNull not supported");
+  }
+
+  @Override
+  public void updateNull(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateNull not supported");
+  }
+
+  @Override
+  public void updateObject(int index, Object x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateObject not supported");
+  }
+
+  @Override
+  public void updateObject(String name, Object x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateObject not supported");
+  }
+
+  @Override
+  public void updateObject(int index, Object x, int length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateObject not supported");
+  }
+
+  @Override
+  public void updateObject(String name, Object x, int length)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateObject not supported");
+  }
+
+  @Override
+  public void updateRef(int index, Ref x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateRef not supported");
+  }
+
+  @Override
+  public void updateRef(String name, Ref x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateRef not supported");
+  }
+
+  @Override
+  public void updateRow() throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateRow not supported");
+  }
+
+  @Override
+  public void updateRowId(int index, RowId arg1) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateRowId not supported");
+  }
+
+  @Override
+  public void updateRowId(String name, RowId x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateRowId not supported");
+  }
+
+  @Override
+  public void updateSQLXML(int index, SQLXML arg1) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateSQLXML not supported");
+  }
+
+  @Override
+  public void updateSQLXML(String name, SQLXML x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateSQLXML not supported");
+
+  }
+
+  @Override
+  public void updateShort(int index, short x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateShort not supported");
+
+  }
+
+  @Override
+  public void updateShort(String name, short x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateShort not supported");
+
+  }
+
+  @Override
+  public void updateString(int index, String x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateString not supported");
+
+  }
+
+  @Override
+  public void updateString(String name, String arg1) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateString not supported");
+
+  }
+
+  @Override
+  public void updateTime(int index, Time x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateTime not supported");
+
+  }
+
+  @Override
+  public void updateTime(String name, Time x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateTime not supported");
+
+  }
+
+  @Override
+  public void updateTimestamp(int index, Timestamp x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateTimestamp not supported");
+
+  }
+
+  @Override
+  public void updateTimestamp(String name, Timestamp x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("updateTimestamp not supported");
+
+  }
+
+  @Override
+  public boolean wasNull() throws SQLException {
+    return wasNull;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
new file mode 100644
index 0000000..98df048
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 
+ */
+package org.apache.tajo.jdbc;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.client.ResultSetUtil;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+
+public class TajoResultSetMetaData implements ResultSetMetaData {
+  Schema schema;
+
+  
+  public TajoResultSetMetaData(Schema schema) {
+    this.schema = schema;
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> clazz) throws SQLException {
+    throw new SQLFeatureNotSupportedException("isWrapperFor not supported");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> clazz) throws SQLException {
+    throw new SQLFeatureNotSupportedException("unwrap not supported");
+  }
+
+  @Override
+  public String getCatalogName(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getCatalogName not supported");
+  }
+
+  @Override
+  public String getColumnClassName(int column) throws SQLException {
+    return schema.getColumn(column - 1).getClass().getName();
+  }
+
+  @Override
+  public int getColumnCount() throws SQLException {
+    if(schema == null) {
+      return 0;
+    }
+    return schema.getColumnNum();
+  }
+
+  @Override
+  public int getColumnDisplaySize(int column) throws SQLException {
+    return ResultSetUtil.columnDisplaySize(getColumnType(column));
+  }
+
+  @Override
+  public String getColumnLabel(int column) throws SQLException {
+    return schema.getColumn(column - 1).getQualifiedName();
+  }
+
+  @Override
+  public String getColumnName(int column) throws SQLException {
+    return schema.getColumn(column - 1).getColumnName();
+  }
+
+  @Override
+  public int getColumnType(int column) throws SQLException {
+    DataType type = schema.getColumn(column - 1).getDataType();
+
+    return ResultSetUtil.tajoTypeToSqlType(type);
+  }
+
+  @Override
+  public String getColumnTypeName(int column) throws SQLException {
+    DataType type = schema.getColumn(column - 1).getDataType();
+
+    return ResultSetUtil.toSqlType(type);
+  }
+
+  @Override
+  public int getPrecision(int column) throws SQLException {
+    return ResultSetUtil.columnDisplaySize(getColumnType(column));
+  }
+
+  @Override
+  public int getScale(int column) throws SQLException {
+    return ResultSetUtil.columnScale(getColumnType(column));
+  }
+
+  @Override
+  public String getSchemaName(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getSchemaName not supported");
+  }
+
+  @Override
+  public String getTableName(int column) throws SQLException {
+    return schema.getColumn(column - 1).getQualifier();
+  }
+
+  @Override
+  public boolean isAutoIncrement(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isCaseSensitive(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isCurrency(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("isCurrency not supported");
+  }
+
+  @Override
+  public boolean isDefinitelyWritable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public int isNullable(int column) throws SQLException {
+    return ResultSetMetaData.columnNullable;
+  }
+
+  @Override
+  public boolean isReadOnly(int column) throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean isSearchable(int column) throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean isSigned(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("isSigned not supported");
+  }
+
+  @Override
+  public boolean isWritable(int column) throws SQLException {
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..8c4b880
--- /dev/null
+++ b/tajo-client/src/main/proto/ClientProtos.proto
@@ -0,0 +1,138 @@
+/**
+ * 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.
+ */
+
+option java_package = "org.apache.tajo.ipc";
+option java_outer_classname = "ClientProtos";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+
+import "tajo_protos.proto";
+import "TajoIdProtos.proto";
+import "CatalogProtos.proto";
+import "PrimitiveProtos.proto";
+
+enum ResultCode {
+  OK = 0;
+  ERROR = 1;
+}
+
+message UpdateSessionVariableRequest {
+  optional SessionIdProto sessionId = 1;
+  repeated KeyValueProto setVariables = 2;
+  repeated string unsetVariables = 3;
+}
+
+message QueryRequest {
+  optional SessionIdProto sessionId = 1;
+  required string query = 2;
+  repeated KeyValueProto setVariables = 3;
+}
+
+message UpdateQueryResponse {
+  required ResultCode resultCode = 1;
+  optional string errorMessage = 2;
+}
+
+message SubmitQueryResponse {
+  required ResultCode resultCode = 1;
+  optional QueryIdProto queryId = 2;
+  optional string errorMessage = 3;
+}
+
+message GetQueryResultRequest {
+  optional SessionIdProto sessionId = 1;
+  required QueryIdProto queryId = 2;
+}
+
+message GetQueryResultResponse {
+  optional TableDescProto tableDesc = 1;
+  optional string errorMessage = 2;
+  required string tajoUserName = 3;
+}
+
+message GetQueryListRequest {
+  optional SessionIdProto sessionId = 1;
+}
+
+message BriefQueryStatus {
+  required QueryIdProto queryId = 1;
+  required QueryState state = 2;
+  required int32 executionTime = 3;
+}
+
+message GetQueryListResponse {
+  repeated BriefQueryStatus queryList = 1;
+}
+
+message GetQueryStatusRequest {
+  optional SessionIdProto sessionId = 1;
+  required QueryIdProto queryId = 2;
+}
+
+message GetQueryStatusResponse {
+  required ResultCode resultCode = 1;
+  required QueryIdProto queryId = 2;
+  optional QueryState state = 3;
+  optional float progress = 4;
+  optional int64 submitTime = 5;
+  optional int64 finishTime = 7;
+  optional bool hasResult = 8;
+  optional string errorMessage = 9;
+  optional string queryMasterHost = 10;
+  optional int32 queryMasterPort = 11;
+}
+
+message GetClusterInfoRequest {
+  optional SessionIdProto sessionId = 1;
+}
+
+message GetClusterInfoResponse {
+  repeated string serverName = 1;
+}
+
+message GetTableListRequest {
+  optional SessionIdProto sessionId = 1;
+}
+
+message GetTableListResponse {
+  repeated string tables = 1;
+}
+
+message GetTableDescRequest {
+  optional SessionIdProto sessionId = 1;
+  required string tableName = 2;
+}
+
+message CreateTableRequest {
+  required string name = 1;
+  required SchemaProto schema = 2;
+  required TableProto meta = 3;
+  required string path = 4;
+  optional PartitionDescProto partitions = 5;
+}
+
+message DropTableRequest {
+  required string name = 1;
+  optional bool purge = 2 [default = false];
+}
+
+message TableResponse {
+  required ResultCode resultCode = 1;
+  optional TableDescProto tableDesc = 2;
+  optional string errorMessage = 3;
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/proto/QueryMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/QueryMasterClientProtocol.proto b/tajo-client/src/main/proto/QueryMasterClientProtocol.proto
new file mode 100644
index 0000000..d20301f
--- /dev/null
+++ b/tajo-client/src/main/proto/QueryMasterClientProtocol.proto
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+option java_package = "org.apache.tajo.ipc";
+option java_outer_classname = "QueryMasterClientProtocol";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+
+import "tajo_protos.proto";
+import "TajoIdProtos.proto";
+import "CatalogProtos.proto";
+import "PrimitiveProtos.proto";
+import "ClientProtos.proto";
+
+service QueryMasterClientProtocolService {
+  rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto);
+  rpc getQueryResult(GetQueryResultRequest) returns (GetQueryResultResponse);
+  rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
+  rpc killQuery(QueryIdProto) returns (BoolProto);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..dbdd911
--- /dev/null
+++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+
+//TajoClient -> TajoMaster Protocol
+option java_package = "org.apache.tajo.ipc";
+option java_outer_classname = "TajoMasterClientProtocol";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+
+import "tajo_protos.proto";
+import "TajoIdProtos.proto";
+import "CatalogProtos.proto";
+import "PrimitiveProtos.proto";
+import "ClientProtos.proto";
+
+service TajoMasterClientProtocolService {
+  rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto);
+  rpc submitQuery(QueryRequest) returns (GetQueryStatusResponse);
+  rpc updateQuery(QueryRequest) returns (UpdateQueryResponse);
+  rpc getQueryResult(GetQueryResultRequest) returns (GetQueryResultResponse);
+  rpc getQueryList(GetQueryListRequest) returns (GetQueryListResponse);
+  rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
+  rpc killQuery(QueryIdProto) returns (BoolProto);
+  rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse);
+  rpc existTable(StringProto) returns (BoolProto);
+  rpc getTableList(GetTableListRequest) returns (GetTableListResponse);
+  rpc getTableDesc(GetTableDescRequest) returns (TableResponse);
+  rpc createExternalTable(CreateTableRequest) returns (TableResponse);
+  rpc dropTable(DropTableRequest) returns (BoolProto);
+
+
+  // TODO - to be implemented
+  //
+  // authenticate
+  //
+  // getSessionVariableList
+  // dropTable
+  // detachTable
+  // createIndex
+  // dropIndex
+  // registerUDF
+  // dropUDF
+  // listUdfs
+  // getUDFDesc
+  // registerJars
+  // getListRegisteredJars
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/resources/log4j.properties b/tajo-client/src/main/resources/log4j.properties
new file mode 100644
index 0000000..11d9ad2
--- /dev/null
+++ b/tajo-client/src/main/resources/log4j.properties
@@ -0,0 +1,27 @@
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# log4j configuration used during build and unit tests
+
+log4j.rootLogger=info,stdout
+log4j.threshhold=INFO
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n
+
+log4j.logger.org.apache.tajo.cli=FATAL
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-common/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-common/pom.xml b/tajo-common/pom.xml
index f83b30e..00e2448 100644
--- a/tajo-common/pom.xml
+++ b/tajo-common/pom.xml
@@ -91,6 +91,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
                 <argument>src/main/proto/TajoIdProtos.proto</argument>
                 <argument>src/main/proto/DataTypes.proto</argument>
                 <argument>src/main/proto/PrimitiveProtos.proto</argument>
+                <argument>src/main/proto/tajo_protos.proto</argument>
               </arguments>
             </configuration>
             <goals>
@@ -130,6 +131,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>com.google.protobuf</groupId>
@@ -140,10 +142,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
       <artifactId>hadoop-common</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-common</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
     </dependency>
@@ -210,7 +208,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
             <executions>
               <execution>
                 <!-- builds source jars and attaches them to the project for publishing -->
-                <id>hadoop-java-sources</id>
+                <id>tajo-java-sources</id>
                 <phase>package</phase>
                 <goals>
                   <goal>jar-no-fork</goal>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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 c20e683..b7171c3 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
@@ -19,19 +19,18 @@
 package org.apache.tajo.conf;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.tajo.TajoConstants;
 import org.apache.tajo.util.NetUtils;
+import org.apache.tajo.util.TUtil;
 
 import java.io.PrintStream;
 import java.net.InetSocketAddress;
 import java.util.Map;
 
-public class TajoConf extends YarnConfiguration {
+public class TajoConf extends Configuration {
 
   static {
     Configuration.addDefaultResource("catalog-default.xml");
@@ -44,7 +43,7 @@ public class TajoConf extends YarnConfiguration {
 
   private static final String EMPTY_VALUE = "";
 
-  private static final Map<String, ConfVars> vars = Maps.newHashMap();
+  private static final Map<String, ConfVars> vars = TUtil.newHashMap();
 
   public TajoConf() {
     super();

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-common/src/main/java/org/apache/tajo/storage/Tuple.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/storage/Tuple.java b/tajo-common/src/main/java/org/apache/tajo/storage/Tuple.java
deleted file mode 100644
index 711666f..0000000
--- a/tajo-common/src/main/java/org/apache/tajo/storage/Tuple.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.storage;
-
-import org.apache.tajo.datum.*;
-
-import java.net.InetAddress;
-
-public interface Tuple extends Cloneable {
-
-  public int size();
-
-  public boolean contains(int fieldid);
-
-  public boolean isNull(int fieldid);
-
-  public void clear();
-
-  public void put(int fieldId, Datum value);
-
-  public void put(int fieldId, Datum [] values);
-
-  public void put(int fieldId, Tuple tuple);
-
-  public void put(Datum [] values);
-
-  public Datum get(int fieldId);
-
-  public void setOffset(long offset);
-
-  public long getOffset();
-
-  public BooleanDatum getBoolean(int fieldId);
-
-  public BitDatum getByte(int fieldId);
-
-  public CharDatum getChar(int fieldId);
-
-  public BlobDatum getBytes(int fieldId);
-
-  public Int2Datum getShort(int fieldId);
-
-  public Int4Datum getInt(int fieldId);
-
-  public Int8Datum getLong(int fieldId);
-
-  public Float4Datum getFloat(int fieldId);
-
-  public Float8Datum getDouble(int fieldId);
-
-  public Inet4Datum getIPv4(int fieldId);
-
-  public byte [] getIPv4Bytes(int fieldId);
-
-  public InetAddress getIPv6(int fieldId);
-
-  public byte [] getIPv6Bytes(int fieldId);
-
-  public TextDatum getString(int fieldId);
-
-  public TextDatum getText(int fieldId);
-
-  public Tuple clone() throws CloneNotSupportedException;
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-common/src/main/java/org/apache/tajo/util/TUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/TUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/TUtil.java
index 2f81ef4..df7c79f 100644
--- a/tajo-common/src/main/java/org/apache/tajo/util/TUtil.java
+++ b/tajo-common/src/main/java/org/apache/tajo/util/TUtil.java
@@ -19,6 +19,7 @@
 package org.apache.tajo.util;
 
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * It provides miscellaneous and useful util methods.
@@ -113,6 +114,10 @@ public class TUtil {
     return newMap;
   }
 
+  public static <K,V> Map<K,V> newConcurrentHashMap() {
+    return new ConcurrentHashMap<K, V>();
+  }
+
   public static <T> List<T> newList() {
     return new ArrayList<T>();
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-common/src/main/proto/tajo_protos.proto
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/proto/tajo_protos.proto b/tajo-common/src/main/proto/tajo_protos.proto
new file mode 100644
index 0000000..d337315
--- /dev/null
+++ b/tajo-common/src/main/proto/tajo_protos.proto
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+
+option java_package = "org.apache.tajo";
+option java_outer_classname = "TajoProtos";
+option java_generic_services = false;
+option java_generate_equals_and_hash = true;
+
+enum QueryState {
+  QUERY_MASTER_INIT = 0;
+  QUERY_MASTER_LAUNCHED = 1;
+  QUERY_NEW = 2;
+  QUERY_INIT = 3;
+  QUERY_RUNNING = 4;
+  QUERY_SUCCEEDED = 5;
+  QUERY_FAILED = 6;
+  QUERY_KILLED = 7;
+  QUERY_ERROR = 8;
+  QUERY_NOT_ASSIGNED = 9;
+}
+
+enum TaskAttemptState {
+  TA_NEW = 0;
+  TA_UNASSIGNED = 1;
+  TA_ASSIGNED = 2;
+  TA_PENDING = 3;
+  TA_RUNNING = 4;
+  TA_SUCCEEDED = 5;
+  TA_FAILED = 6;
+  TA_KILLED = 7;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-core/pom.xml b/tajo-core/pom.xml
index d72c0e8..2d7a53a 100644
--- a/tajo-core/pom.xml
+++ b/tajo-core/pom.xml
@@ -38,9 +38,6 @@
 	  <module>tajo-core-pullserver</module>
   </modules>
 
-  <repositories>
-  </repositories>
-
   <build>
     <plugins>
       <plugin>
@@ -164,7 +161,6 @@
                       run rm -rf ${project.artifactId}-${project.version}
                       run mkdir ${project.artifactId}-${project.version}
                       run cd ${project.artifactId}-${project.version}
-                      run cp -r ${basedir}/${project.artifactId}-storage/target/${project.artifactId}-storage-${project.version}*.jar .
                       run cp -r ${basedir}/${project.artifactId}-pullserver/target/${project.artifactId}-pullserver-${project.version}*.jar .
                       run cp -r ${basedir}/${project.artifactId}-backend/target/${project.artifactId}-backend-${project.version}*.jar .
                       run cp -r ${basedir}/${project.artifactId}-backend/target/lib .

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/pom.xml b/tajo-core/tajo-core-backend/pom.xml
index ff59935..55ab186 100644
--- a/tajo-core/tajo-core-backend/pom.xml
+++ b/tajo-core/tajo-core-backend/pom.xml
@@ -127,14 +127,11 @@
                 <argument>-Isrc/main/proto/</argument>
                 <argument>--proto_path=../../tajo-common/src/main/proto</argument>
                 <argument>--proto_path=../../tajo-catalog/tajo-catalog-common/src/main/proto</argument>
+                <argument>--proto_path=../../tajo-client/src/main/proto</argument>
                 <argument>--java_out=target/generated-sources/proto</argument>
-                <argument>src/main/proto/tajo_protos.proto</argument>
-                <argument>src/main/proto/ClientProtos.proto</argument>
                 <argument>src/main/proto/QueryMasterProtocol.proto</argument>
-                <argument>src/main/proto/QueryMasterClientProtocol.proto</argument>
                 <argument>src/main/proto/TajoMasterProtocol.proto</argument>
                 <argument>src/main/proto/TajoWorkerProtocol.proto</argument>
-                <argument>src/main/proto/TajoMasterClientProtocol.proto</argument>
                 <argument>src/main/proto/InternalTypes.proto</argument>
               </arguments>
             </configuration>
@@ -224,6 +221,14 @@
     </dependency>
     <dependency>
       <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-jdbc</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
       <artifactId>tajo-rpc</artifactId>
     </dependency>
 
@@ -234,6 +239,7 @@
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
@@ -250,6 +256,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-yarn-server-nodemanager</artifactId>
       <scope>compile</scope>
     </dependency>
@@ -281,6 +291,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.antlr</groupId>
@@ -324,21 +335,10 @@
       <artifactId>commons-lang</artifactId>
       <version>2.6</version>
     </dependency>
-    <!--
-    <dependency>
-      <groupId>org.jboss.netty</groupId>
-      <artifactId>netty</artifactId>
-    </dependency>
-    -->
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty</artifactId>
     </dependency>
-    <dependency>
-      <groupId>jline</groupId>
-      <artifactId>jline</artifactId>
-      <version>2.11</version>
-    </dependency>
 
     <dependency>
       <groupId>org.dspace.dependencies</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/cli/TajoCli.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/cli/TajoCli.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/cli/TajoCli.java
deleted file mode 100644
index 6889227..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/cli/TajoCli.java
+++ /dev/null
@@ -1,724 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import jline.console.ConsoleReader;
-import jline.console.history.FileHistory;
-import jline.console.history.PersistentHistory;
-import org.apache.commons.cli.*;
-import org.apache.commons.lang.StringUtils;
-import org.apache.tajo.QueryId;
-import org.apache.tajo.QueryIdFactory;
-import org.apache.tajo.TajoConstants;
-import org.apache.tajo.TajoProtos.QueryState;
-import org.apache.tajo.algebra.CreateTable;
-import org.apache.tajo.catalog.CatalogUtil;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.catalog.partition.Specifier;
-import org.apache.tajo.catalog.statistics.TableStats;
-import org.apache.tajo.client.QueryStatus;
-import org.apache.tajo.client.TajoClient;
-import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.conf.TajoConf.ConfVars;
-import org.apache.tajo.ipc.ClientProtos;
-import org.apache.tajo.jdbc.TajoResultSet;
-import org.apache.tajo.util.FileUtil;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-public class TajoCli {
-  private final TajoConf conf;
-  private static final Options options;
-
-  private TajoClient client;
-
-  private final ConsoleReader reader;
-  private final InputStream sin;
-  private final PrintWriter sout;
-
-  private static final int PRINT_LIMIT = 24;
-  private final Map<String, Command> commands = new TreeMap<String, Command>();
-
-  private static final Class [] registeredCommands = {
-      DescTableCommand.class,
-      HelpCommand.class,
-      ExitCommand.class,
-      Copyright.class,
-      Version.class
-  };
-
-  private static final String HOME_DIR = System.getProperty("user.home");
-  private static final String HISTORY_FILE = ".tajo_history";
-
-  static {
-    options = new Options();
-    options.addOption("c", "command", true, "execute only single command, then exit");
-    options.addOption("f", "file", true, "execute commands from file, then exit");
-    options.addOption("h", "host", true, "Tajo server host");
-    options.addOption("p", "port", true, "Tajo server port");
-  }
-
-  public TajoCli(TajoConf c, String [] args,
-                 InputStream in, OutputStream out) throws Exception {
-    this.conf = new TajoConf(c);
-    this.sin = in;
-    this.reader = new ConsoleReader(sin, out);
-    this.sout = new PrintWriter(reader.getOutput());
-
-    CommandLineParser parser = new PosixParser();
-    CommandLine cmd = parser.parse(options, args);
-
-    String hostName = null;
-    Integer port = null;
-    if (cmd.hasOption("h")) {
-      hostName = cmd.getOptionValue("h");
-    }
-    if (cmd.hasOption("p")) {
-      port = Integer.parseInt(cmd.getOptionValue("p"));
-    }
-
-    // if there is no "-h" option,
-    if(hostName == null) {
-      if (conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
-        // it checks if the client service address is given in configuration and distributed mode.
-        // if so, it sets entryAddr.
-        hostName = conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
-      }
-    }
-    if (port == null) {
-      if (conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
-        // it checks if the client service address is given in configuration and distributed mode.
-        // if so, it sets entryAddr.
-        port = Integer.parseInt(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
-      }
-    }
-
-    if ((hostName == null) ^ (port == null)) {
-      System.err.println("ERROR: cannot find valid Tajo server address");
-      System.exit(-1);
-    } else if (hostName != null && port != null) {
-      conf.setVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
-      client = new TajoClient(conf);
-    } else if (hostName == null && port == null) {
-      client = new TajoClient(conf);
-    }
-
-    initHistory();
-    initCommands();
-
-    if (cmd.hasOption("c")) {
-      executeStatements(cmd.getOptionValue("c"));
-      sout.flush();
-      System.exit(0);
-    }
-    if (cmd.hasOption("f")) {
-      File sqlFile = new File(cmd.getOptionValue("f"));
-      if (sqlFile.exists()) {
-        String contents = FileUtil.readTextFile(new File(cmd.getOptionValue("f")));
-        executeStatements(contents);
-        sout.flush();
-        System.exit(0);
-      } else {
-        System.err.println("No such a file \"" + cmd.getOptionValue("f") + "\"");
-        System.exit(-1);
-      }
-    }
-  }
-
-  private void initHistory() {
-    try {
-      String historyPath = HOME_DIR + File.separator + HISTORY_FILE;
-      if ((new File(HOME_DIR)).exists()) {
-        reader.setHistory(new FileHistory(new File(historyPath)));
-      } else {
-        System.err.println("ERROR: home directory : '" + HOME_DIR +"' does not exist.");
-      }
-    } catch (Exception e) {
-      System.err.println(e.getMessage());
-    }
-  }
-
-  private void initCommands() {
-    for (Class clazz : registeredCommands) {
-      Command cmd = null;
-      try {
-         Constructor cons = clazz.getConstructor(new Class[] {TajoCli.class});
-         cmd = (Command) cons.newInstance(this);
-      } catch (Exception e) {
-        System.err.println(e.getMessage());
-        System.exit(-1);
-      }
-      commands.put(cmd.getCommand(), cmd);
-    }
-  }
-
-  public int runShell() throws Exception {
-
-    String raw;
-    String line;
-    String accumulatedLine = "";
-    String prompt = "tajo";
-    String curPrompt = prompt;
-    boolean newStatement = true;
-    int code = 0;
-
-    sout.write("Try \\? for help.\n");
-    while((raw = reader.readLine(curPrompt + "> ")) != null) {
-      // each accumulated line has a space delimiter
-      if (!accumulatedLine.equals("")) {
-        accumulatedLine += ' ';
-      }
-
-      line = raw.trim();
-
-      if (line.length() == 0) { // if empty line
-        continue;
-
-      } else if (line.charAt(0) == '/') { // warning for legacy usage
-        printInvalidCommand(line);
-        continue;
-
-      } else if (line.charAt(0) == '\\') { // command mode
-        executeCommand(line);
-        ((PersistentHistory)reader.getHistory()).flush();
-
-      } else if (line.endsWith(";") && !line.endsWith("\\;")) {
-
-        // remove a trailing newline
-        line = StringUtils.chomp(line).trim();
-
-        // get a punctuated statement
-        String punctuated = accumulatedLine + line;
-
-        if (!newStatement) {
-          // why do two lines are removed?
-          // First history line indicates an accumulated line.
-          // Second history line is a just typed line.
-          reader.getHistory().removeLast();
-          reader.getHistory().removeLast();
-          reader.getHistory().add(punctuated);
-          ((PersistentHistory)reader.getHistory()).flush();
-        }
-
-        code = executeStatements(punctuated);
-
-        // reset accumulated lines
-        newStatement = true;
-        accumulatedLine = "";
-        curPrompt = prompt;
-
-      } else {
-        line = StringUtils.chomp(raw).trim();
-
-        // accumulate a line
-        accumulatedLine = accumulatedLine + line;
-
-        // replace the latest line with a accumulated line
-        if (!newStatement) { // if this is not first line, remove one more line.
-          reader.getHistory().removeLast();
-        } else {
-          newStatement = false;
-        }
-        reader.getHistory().removeLast();
-        reader.getHistory().add(accumulatedLine);
-
-        // use an alternative prompt during accumulating lines
-        curPrompt = StringUtils.repeat(" ", prompt.length());
-        continue;
-      }
-    }
-    return code;
-  }
-
-  private void invokeCommand(String [] cmds) {
-    // this command should be moved to GlobalEngine
-    Command invoked;
-    try {
-      invoked = commands.get(cmds[0]);
-      invoked.invoke(cmds);
-    } catch (Throwable t) {
-      sout.println(t.getMessage());
-    }
-  }
-
-  public int executeStatements(String line) throws Exception {
-
-    // TODO - comment handling and multi line queries should be improved
-    // remove comments
-    String filtered = line.replaceAll("--[^\\r\\n]*", "").trim();
-
-    String stripped;
-    for (String statement : filtered.split(";")) {
-      stripped = StringUtils.chomp(statement);
-      if (StringUtils.isBlank(stripped)) {
-        continue;
-      }
-
-      String [] cmds = stripped.split(" ");
-      if (cmds[0].equalsIgnoreCase("exit") || cmds[0].equalsIgnoreCase("quit")) {
-        sout.println("\n\nbye!");
-        sout.flush();
-        ((PersistentHistory)this.reader.getHistory()).flush();
-        System.exit(0);
-      } else if (cmds[0].equalsIgnoreCase("detach") && cmds.length > 1 && cmds[1].equalsIgnoreCase("table")) {
-        // this command should be moved to GlobalEngine
-        invokeCommand(cmds);
-
-      } else { // submit a query to TajoMaster
-        ClientProtos.GetQueryStatusResponse response = client.executeQuery(stripped);
-        if (response == null) {
-          sout.println("response is null");
-        }
-        else if (response.getResultCode() == ClientProtos.ResultCode.OK) {
-          QueryId queryId = null;
-          try {
-            queryId = new QueryId(response.getQueryId());
-            if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-              sout.println("OK");
-            } else {
-              getQueryResult(queryId);
-            }
-          } finally {
-            if(queryId != null) {
-              client.closeQuery(queryId);
-            }
-          }
-        } else {
-          if (response.hasErrorMessage()) {
-            sout.println(response.getErrorMessage());
-          }
-        }
-      }
-    }
-    return 0;
-  }
-
-  private boolean isFailed(QueryState state) {
-    return state == QueryState.QUERY_ERROR || state == QueryState.QUERY_FAILED;
-  }
-
-  private void getQueryResult(QueryId queryId) {
-    // if query is empty string
-    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-      return;
-    }
-
-    // query execute
-    try {
-
-      QueryStatus status;
-      while (true) {
-        // TODO - configurable
-        Thread.sleep(1000);
-        status = client.getQueryStatus(queryId);
-        if(status.getState() == QueryState.QUERY_MASTER_INIT || status.getState() == QueryState.QUERY_MASTER_LAUNCHED) {
-          continue;
-        }
-
-        if (status.getState() == QueryState.QUERY_RUNNING ||
-            status.getState() == QueryState.QUERY_SUCCEEDED) {
-          sout.println("Progress: " + (int)(status.getProgress() * 100.0f)
-              + "%, response time: " + ((float)(status.getFinishTime() - status.getSubmitTime()) / 1000.0) + " sec");
-          sout.flush();
-        }
-
-        if (status.getState() != QueryState.QUERY_RUNNING && status.getState() != QueryState.QUERY_NOT_ASSIGNED) {
-          break;
-        }
-      }
-
-      if (status.getState() == QueryState.QUERY_ERROR) {
-        sout.println("Internal error!");
-      } else if (status.getState() == QueryState.QUERY_FAILED) {
-        sout.println("Query failed!");
-      } else if (status.getState() == QueryState.QUERY_KILLED) {
-        sout.println(queryId + " is killed.");
-      } else {
-        if (status.getState() == QueryState.QUERY_SUCCEEDED) {
-          sout.println("final state: " + status.getState()
-              + ", response time: " + (((float)(status.getFinishTime() - status.getSubmitTime()) / 1000.0)
-              + " sec"));
-          if (status.hasResult()) {
-            ResultSet res = null;
-            TableDesc desc = null;
-            if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-              res = client.createNullResultSet(queryId);
-            } else {
-              ClientProtos.GetQueryResultResponse response = client.getResultResponse(queryId);
-              desc = CatalogUtil.newTableDesc(response.getTableDesc());
-              conf.setVar(ConfVars.USERNAME, response.getTajoUserName());
-              res = new TajoResultSet(client, queryId, conf, desc);
-            }
-            try {
-              if (res == null) {
-                sout.println("OK");
-                return;
-              }
-
-              ResultSetMetaData rsmd = res.getMetaData();
-
-              TableStats stat = desc.getStats();
-              String volume = FileUtil.humanReadableByteCount(stat.getNumBytes(), false);
-              long resultRows = stat.getNumRows();
-              sout.println("result: " + desc.getPath() + ", " + resultRows + " rows (" + volume + ")");
-
-              int numOfColumns = rsmd.getColumnCount();
-              for (int i = 1; i <= numOfColumns; i++) {
-                if (i > 1) sout.print(",  ");
-                String columnName = rsmd.getColumnName(i);
-                sout.print(columnName);
-              }
-              sout.println("\n-------------------------------");
-
-              int numOfPrintedRows = 0;
-              while (res.next()) {
-                // TODO - to be improved to print more formatted text
-                for (int i = 1; i <= numOfColumns; i++) {
-                  if (i > 1) sout.print(",  ");
-                  String columnValue = res.getObject(i).toString();
-                  if(res.wasNull()){
-                    sout.print("null");
-                  } else {
-                    sout.print(columnValue);
-                  }
-                }
-                sout.println();
-                sout.flush();
-                numOfPrintedRows++;
-                if (numOfPrintedRows >= PRINT_LIMIT) {
-                  sout.print("continue... ('q' is quit)");
-                  sout.flush();
-                  if (sin.read() == 'q') {
-                    break;
-                  }
-                  numOfPrintedRows = 0;
-                  sout.println();
-                }
-              }
-            } finally {
-              if(res != null) {
-                res.close();
-              }
-            }
-          } else {
-            sout.println("OK");
-          }
-        }
-      }
-    } catch (Throwable t) {
-      t.printStackTrace();
-      System.err.println(t.getMessage());
-    }
-  }
-
-  private void printUsage() {
-    HelpFormatter formatter = new HelpFormatter();
-    formatter.printHelp( "tajo cli [options]", options );
-  }
-
-  public static abstract class Command {
-    public abstract String getCommand();
-    public abstract void invoke(String [] command) throws Exception;
-    public abstract String getUsage();
-    public abstract String getDescription();
-  }
-
-  private String toFormattedString(TableDesc desc) {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\ntable name: ").append(desc.getName()).append("\n");
-    sb.append("table path: ").append(desc.getPath()).append("\n");
-    sb.append("store type: ").append(desc.getMeta().getStoreType()).append("\n");
-    if (desc.getStats() != null) {
-      sb.append("number of rows: ").append(desc.getStats().getNumRows()).append("\n");
-      sb.append("volume: ").append(
-          FileUtil.humanReadableByteCount(desc.getStats().getNumBytes(),
-              true)).append("\n");
-    }
-    sb.append("Options: \n");
-    for(Map.Entry<String, String> entry : desc.getMeta().toMap().entrySet()){
-      sb.append("\t").append("'").append(entry.getKey()).append("'").append("=")
-          .append("'").append(entry.getValue()).append("'").append("\n");
-    }
-    sb.append("\n");
-    sb.append("schema: \n");
-
-    for(int i = 0; i < desc.getSchema().getColumnNum(); i++) {
-      Column col = desc.getSchema().getColumn(i);
-      sb.append(col.getColumnName()).append("\t").append(col.getDataType().getType());
-      if (col.getDataType().hasLength()) {
-        sb.append("(").append(col.getDataType().getLength()).append(")");
-      }
-      sb.append("\n");
-    }
-
-    sb.append("\n");
-    sb.append("Partitions: \n");
-    if (desc.getPartitions() != null) {
-      sb.append("type:").append(desc.getPartitions().getPartitionsType().name()).append("\n");
-      if (desc.getPartitions().getNumPartitions() > 0)
-        sb.append("numbers:").append(desc.getPartitions().getNumPartitions()).append("\n");
-
-      sb.append("columns:").append("\n");
-      for(Column eachColumn: desc.getPartitions().getColumns()) {
-        sb.append("  ");
-        sb.append(eachColumn.getColumnName()).append("\t").append(eachColumn.getDataType().getType());
-        if (eachColumn.getDataType().hasLength()) {
-          sb.append("(").append(eachColumn.getDataType().getLength()).append(")");
-        }
-        sb.append("\n");
-      }
-
-      if (desc.getPartitions().getSpecifiers() != null) {
-        sb.append("specifier:").append("\n");
-        for(Specifier specifier :desc.getPartitions().getSpecifiers()) {
-          sb.append("  ");
-          sb.append("name:").append(specifier.getName());
-          if (!specifier.getExpressions().equals("")) {
-            sb.append(", expressions:").append(specifier.getExpressions());
-          } else {
-            if (desc.getPartitions().getPartitionsType().name().equals(CreateTable.PartitionType.RANGE))
-              sb.append(" expressions: MAXVALUE");
-          }
-          sb.append("\n");
-        }
-      }
-    }
-
-    return sb.toString();
-  }
-
-  public class DescTableCommand extends Command {
-    public DescTableCommand() {}
-
-    @Override
-    public String getCommand() {
-      return "\\d";
-    }
-
-    @Override
-    public void invoke(String[] cmd) throws Exception {
-      if (cmd.length == 2) {
-        TableDesc desc = client.getTableDesc(cmd[1]);
-        if (desc == null) {
-          sout.println("Did not find any relation named \"" + cmd[1] + "\"");
-        } else {
-          sout.println(toFormattedString(desc));
-        }
-      } else if (cmd.length == 1) {
-        List<String> tableList = client.getTableList();
-        if (tableList.size() == 0) {
-          sout.println("No Relation Found");
-        }
-        for (String table : tableList) {
-          sout.println(table);
-        }
-      } else {
-        throw new IllegalArgumentException();
-      }
-    }
-
-    @Override
-    public String getUsage() {
-      return "[table_name]";
-    }
-
-    @Override
-    public String getDescription() {
-      return "show table description";
-    }
-  }
-
-  public class HelpCommand extends Command {
-
-    @Override
-    public String getCommand() {
-      return "\\?";
-    }
-
-    @Override
-    public void invoke(String[] cmd) throws Exception {
-      sout.println();
-
-      sout.println("General");
-      sout.println("  \\copyright  show Apache License 2.0");
-      sout.println("  \\version    show Tajo version");
-      sout.println("  \\?          show help");
-      sout.println("  \\q          quit tsql");
-      sout.println();
-      sout.println();
-
-      sout.println("Informational");
-      sout.println("  \\d         list tables");
-      sout.println("  \\d  NAME   describe table");
-      sout.println();
-      sout.println();
-
-      sout.println("Documentations");
-      sout.println("  tsql guide        http://wiki.apache.org/tajo/tsql");
-      sout.println("  Query language    http://wiki.apache.org/tajo/QueryLanguage");
-      sout.println("  Functions         http://wiki.apache.org/tajo/Functions");
-      sout.println("  Backup & restore  http://wiki.apache.org/tajo/BackupAndRestore");
-      sout.println("  Configuration     http://wiki.apache.org/tajo/Configuration");
-      sout.println();
-    }
-
-    @Override
-    public String getUsage() {
-      return "";
-    }
-
-    @Override
-    public String getDescription() {
-      return "show command lists and their usages";
-    }
-  }
-
-  public class Version extends Command {
-
-    @Override
-    public String getCommand() {
-      return "\\version";
-    }
-
-    @Override
-    public void invoke(String[] cmd) throws Exception {
-      sout.println(TajoConstants.TAJO_VERSION);
-    }
-
-    @Override
-    public String getUsage() {
-      return "";
-    }
-
-    @Override
-    public String getDescription() {
-      return "show Apache License 2.0";
-    }
-  }
-
-  public class Copyright extends Command {
-
-    @Override
-    public String getCommand() {
-      return "\\copyright";
-    }
-
-    @Override
-    public void invoke(String[] cmd) throws Exception {
-      sout.println();
-      sout.println(
-      "  Licensed to the Apache Software Foundation (ASF) under one\n" +
-      "  or more contributor license agreements.  See the NOTICE file\n" +
-      "  distributed with this work for additional information\n" +
-      "  regarding copyright ownership.  The ASF licenses this file\n" +
-      "  to you under the Apache License, Version 2.0 (the\n" +
-      "  \"License\"); you may not use this file except in compliance\n" +
-      "  with the License.  You may obtain a copy of the License at\n" +
-      "\n" +
-      "       http://www.apache.org/licenses/LICENSE-2.0\n" +
-      "\n" +
-      "   Unless required by applicable law or agreed to in writing, software\n" +
-      "   distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
-      "   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
-      "   See the License for the specific language governing permissions and\n" +
-      "   limitations under the License.");
-      sout.println();
-    }
-
-    @Override
-    public String getUsage() {
-      return "";
-    }
-
-    @Override
-    public String getDescription() {
-      return "show Apache License 2.0";
-    }
-  }
-
-  public class ExitCommand extends Command {
-
-    @Override
-    public String getCommand() {
-      return "\\q";
-    }
-
-    @Override
-    public void invoke(String[] cmd) throws Exception {
-      sout.println("bye!");
-      System.exit(0);
-    }
-
-    @Override
-    public String getUsage() {
-      return "";
-    }
-
-    @Override
-    public String getDescription() {
-      return "quit";
-    }
-  }
-
-  public int executeCommand(String line) throws Exception {
-    String [] metaCommands = line.split(";");
-    for (String metaCommand : metaCommands) {
-      String arguments [];
-      arguments = metaCommand.split(" ");
-
-      Command invoked = commands.get(arguments[0]);
-      if (invoked == null) {
-        printInvalidCommand(arguments[0]);
-        return -1;
-      }
-
-      try {
-        invoked.invoke(arguments);
-      } catch (IllegalArgumentException ige) {
-        sout.println(ige.getMessage());
-      } catch (Exception e) {
-        sout.println(e.getMessage());
-      }
-    }
-
-    return 0;
-  }
-
-  private void printInvalidCommand(String command) {
-    sout.println("Invalid command " + command +". Try \\? for help.");
-  }
-
-  public static void main(String [] args) throws Exception {
-    TajoConf conf = new TajoConf();
-    TajoCli shell = new TajoCli(conf, args, System.in, System.out);
-    System.out.println();
-    int status = shell.runShell();
-    System.exit(status);
-  }
-}


[6/6] git commit: TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)

Posted by hy...@apache.org.
TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)


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

Branch: refs/heads/master
Commit: b6a5ff0c39e3fd50fc27c2a3804218fc884135f5
Parents: d39bb99
Author: Hyunsik Choi <hy...@apache.org>
Authored: Mon Dec 30 18:17:07 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Mon Dec 30 18:17:42 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |    2 +
 pom.xml                                         |    2 +
 tajo-catalog/tajo-catalog-client/pom.xml        |    6 +-
 tajo-catalog/tajo-catalog-common/pom.xml        |    6 +-
 tajo-catalog/tajo-catalog-server/pom.xml        |    1 +
 tajo-client/pom.xml                             |  399 ++++++
 .../main/java/org/apache/tajo/cli/TajoCli.java  |  723 +++++++++++
 .../org/apache/tajo/client/QueryStatus.java     |   86 ++
 .../org/apache/tajo/client/ResultSetUtil.java   |  193 +++
 .../java/org/apache/tajo/client/TajoClient.java |  462 +++++++
 .../java/org/apache/tajo/client/TajoDump.java   |  129 ++
 .../java/org/apache/tajo/jdbc/SQLStates.java    |   33 +
 .../org/apache/tajo/jdbc/TajoResultSet.java     |  152 +++
 .../org/apache/tajo/jdbc/TajoResultSetBase.java | 1129 +++++++++++++++++
 .../apache/tajo/jdbc/TajoResultSetMetaData.java |  161 +++
 tajo-client/src/main/proto/ClientProtos.proto   |  138 ++
 .../main/proto/QueryMasterClientProtocol.proto  |   35 +
 .../main/proto/TajoMasterClientProtocol.proto   |   62 +
 tajo-client/src/main/resources/log4j.properties |   27 +
 tajo-common/pom.xml                             |    8 +-
 .../java/org/apache/tajo/conf/TajoConf.java     |    7 +-
 .../java/org/apache/tajo/storage/Tuple.java     |   80 --
 .../main/java/org/apache/tajo/util/TUtil.java   |    5 +
 tajo-common/src/main/proto/tajo_protos.proto    |   46 +
 tajo-core/pom.xml                               |    4 -
 tajo-core/tajo-core-backend/pom.xml             |   30 +-
 .../main/java/org/apache/tajo/cli/TajoCli.java  |  724 -----------
 .../org/apache/tajo/client/QueryStatus.java     |   86 --
 .../org/apache/tajo/client/ResultSetUtil.java   |   49 -
 .../java/org/apache/tajo/client/SQLStates.java  |   33 -
 .../java/org/apache/tajo/client/TajoClient.java |  461 -------
 .../java/org/apache/tajo/client/TajoDump.java   |  129 --
 .../org/apache/tajo/jdbc/MetaDataTuple.java     |  194 ---
 .../org/apache/tajo/jdbc/TajoConnection.java    |  400 ------
 .../apache/tajo/jdbc/TajoDatabaseMetaData.java  | 1196 ------------------
 .../java/org/apache/tajo/jdbc/TajoDriver.java   |  233 ----
 .../apache/tajo/jdbc/TajoMetaDataResultSet.java |   77 --
 .../apache/tajo/jdbc/TajoPreparedStatement.java |  660 ----------
 .../org/apache/tajo/jdbc/TajoResultSet.java     |  152 ---
 .../org/apache/tajo/jdbc/TajoResultSetBase.java | 1129 -----------------
 .../apache/tajo/jdbc/TajoResultSetMetaData.java |  160 ---
 .../org/apache/tajo/jdbc/TajoStatement.java     |  289 -----
 .../src/main/proto/ClientProtos.proto           |  139 --
 .../main/proto/QueryMasterClientProtocol.proto  |   36 -
 .../main/proto/TajoMasterClientProtocol.proto   |   63 -
 .../src/main/proto/tajo_protos.proto            |   46 -
 tajo-core/tajo-core-pullserver/pom.xml          |    4 +-
 .../java/org/apache/tajo/storage/Tuple.java     |   80 ++
 tajo-core/tajo-core-storage/pom.xml             |   42 +-
 tajo-dist/pom.xml                               |    6 +
 tajo-jdbc/pom.xml                               |  191 +++
 .../org/apache/tajo/jdbc/MetaDataTuple.java     |  192 +++
 .../org/apache/tajo/jdbc/TajoConnection.java    |  398 ++++++
 .../apache/tajo/jdbc/TajoDatabaseMetaData.java  | 1196 ++++++++++++++++++
 .../java/org/apache/tajo/jdbc/TajoDriver.java   |   89 ++
 .../apache/tajo/jdbc/TajoMetaDataResultSet.java |   75 ++
 .../apache/tajo/jdbc/TajoPreparedStatement.java |  658 ++++++++++
 .../org/apache/tajo/jdbc/TajoStatement.java     |  287 +++++
 tajo-jdbc/src/main/resources/log4j.properties   |   27 +
 tajo-project/pom.xml                            |   18 +-
 tajo-rpc/pom.xml                                |   56 +-
 .../org/apache/tajo/rpc/RpcConnectionPool.java  |    4 +-
 62 files changed, 7073 insertions(+), 6432 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index fae9d1d..76b0acc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -110,6 +110,8 @@ Release 0.8.0 - unreleased
 
   IMPROVEMENTS
 
+    TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)
+
     TAJO-432: Add shuffle phase for column-partitioned table store. (Min Zhou via jihoon)
 
     TAJO-135: Bump up hadoop to 2.2.0. (jihoon)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index c485119..5b0effb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -83,6 +83,8 @@
     <module>tajo-core</module>
     <module>tajo-rpc</module>
     <module>tajo-catalog</module>
+    <module>tajo-client</module>
+    <module>tajo-jdbc</module>
     <module>tajo-dist</module>
   </modules>
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-catalog/tajo-catalog-client/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/pom.xml b/tajo-catalog/tajo-catalog-client/pom.xml
index 41e7bbe..b511739 100644
--- a/tajo-catalog/tajo-catalog-client/pom.xml
+++ b/tajo-catalog/tajo-catalog-client/pom.xml
@@ -136,6 +136,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-logging</groupId>
@@ -145,11 +146,6 @@
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging-api</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.derby</groupId>
-      <artifactId>derby</artifactId>
-      <version>10.8.2.2</version>
-    </dependency>
   </dependencies>
 
   <profiles>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-catalog/tajo-catalog-common/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/pom.xml b/tajo-catalog/tajo-catalog-common/pom.xml
index f424110..a4db647 100644
--- a/tajo-catalog/tajo-catalog-common/pom.xml
+++ b/tajo-catalog/tajo-catalog-common/pom.xml
@@ -150,6 +150,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-logging</groupId>
@@ -159,11 +160,6 @@
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging-api</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.derby</groupId>
-      <artifactId>derby</artifactId>
-      <version>10.8.2.2</version>
-    </dependency>
   </dependencies>
 
   <profiles>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-catalog/tajo-catalog-server/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/pom.xml b/tajo-catalog/tajo-catalog-server/pom.xml
index ab3139b..03e92ec 100644
--- a/tajo-catalog/tajo-catalog-server/pom.xml
+++ b/tajo-catalog/tajo-catalog-server/pom.xml
@@ -135,6 +135,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-logging</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-client/pom.xml b/tajo-client/pom.xml
new file mode 100644
index 0000000..797ad3a
--- /dev/null
+++ b/tajo-client/pom.xml
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tajo-project</artifactId>
+    <groupId>org.apache.tajo</groupId>
+    <version>0.8.0-SNAPSHOT</version>
+    <relativePath>../tajo-project</relativePath>
+  </parent>
+  <artifactId>tajo-client</artifactId>
+  <packaging>jar</packaging>
+  <name>Tajo Client</name>
+  <version>0.8.0-SNAPSHOT</version>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <metrics.version>3.0.1</metrics.version>
+  </properties>
+
+  <repositories>
+    <repository>
+      <id>repository.jboss.org</id>
+      <url>https://repository.jboss.org/nexus/content/repositories/releases/
+      </url>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <encoding>${project.build.sourceEncoding}</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.12.4</version>
+        <configuration>
+          <systemProperties>
+            <tajo.test>TRUE</tajo.test>
+          </systemProperties>
+          <argLine>-Xms512m -Xmx1024m -Dfile.encoding=UTF-8</argLine>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.2</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>create-protobuf-generated-sources-directory</id>
+            <phase>initialize</phase>
+            <configuration>
+              <target>
+                <mkdir dir="target/generated-sources/proto" />
+              </target>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.2</version>
+        <executions>
+          <execution>
+            <id>generate-sources</id>
+            <phase>generate-sources</phase>
+            <configuration>
+              <executable>protoc</executable>
+              <arguments>
+                <argument>-Isrc/main/proto/</argument>
+                <argument>--proto_path=../tajo-common/src/main/proto</argument>
+                <argument>--proto_path=../tajo-catalog/tajo-catalog-common/src/main/proto</argument>
+                <argument>--proto_path=../tajo-core/tajo-core-backend/src/main/proto</argument>
+                <argument>--java_out=target/generated-sources/proto</argument>
+                <argument>src/main/proto/ClientProtos.proto</argument>
+                <argument>src/main/proto/TajoMasterClientProtocol.proto</argument>
+                <argument>src/main/proto/QueryMasterClientProtocol.proto</argument>
+              </arguments>
+            </configuration>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+          <execution>
+            <id>add-source</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>target/generated-sources/proto</source>
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>false</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+              <excludeGroupIds>org.apache.hadoop</excludeGroupIds>
+              <excludeScope>provided</excludeScope>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>2.7.1</version>
+      </plugin>
+    </plugins>
+  </build>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-common</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>com.google.code.gson</groupId>
+          <artifactId>gson</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>joda-time</groupId>
+          <artifactId>joda-time</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-core-storage</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-rpc</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-el</groupId>
+          <artifactId>commons-el</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-runtime</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-compiler</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>joda-time</groupId>
+          <artifactId>joda-time</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.mortbay.jetty</groupId>
+          <artifactId>jsp-2.1-jetty</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>jline</groupId>
+      <artifactId>jline</artifactId>
+      <version>2.11</version>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>docs</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <executions>
+              <execution>
+                <!-- build javadoc jars per jar for publishing to maven -->
+                <id>module-javadocs</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+                <configuration>
+                  <destDir>${project.build.directory}</destDir>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>src</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-source-plugin</artifactId>
+            <executions>
+              <execution>
+                <!-- builds source jars and attaches them to the project for publishing -->
+                <id>tajo-java-sources</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>jar-no-fork</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>dist</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+        <property>
+          <name>tar|rpm|deb</name>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>dist</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <echo file="${project.build.directory}/dist-layout-stitching.sh">
+                      run() {
+                      echo "\$ ${@}"
+                      "${@}"
+                      res=$?
+                      if [ $res != 0 ]; then
+                      echo
+                      echo "Failed!"
+                      echo
+                      exit $res
+                      fi
+                      }
+
+                      ROOT=`cd ${basedir}/..;pwd`
+                      echo
+                      echo "Current directory `pwd`"
+                      echo
+                      run rm -rf ${project.artifactId}-${project.version}
+                      run mkdir ${project.artifactId}-${project.version}
+                      run cd ${project.artifactId}-${project.version}
+                      run cp -r ${basedir}/target/${project.artifactId}-${project.version}*.jar .
+                      echo
+                      echo "Tajo Client dist layout available at: ${project.build.directory}/${project.artifactId}-${project.version}"
+                      echo
+                    </echo>
+                    <exec executable="sh" dir="${project.build.directory}" failonerror="true">
+                      <arg line="./dist-layout-stitching.sh"/>
+                    </exec>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>2.4</version>
+        <configuration>
+          <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+        <version>2.15</version>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
+

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
new file mode 100644
index 0000000..2e7a92c
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
@@ -0,0 +1,723 @@
+/**
+ * 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.cli;
+
+import jline.console.ConsoleReader;
+import jline.console.history.FileHistory;
+import jline.console.history.PersistentHistory;
+import org.apache.commons.cli.*;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.partition.Specifier;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ipc.ClientProtos;
+import org.apache.tajo.jdbc.TajoResultSet;
+import org.apache.tajo.util.FileUtil;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class TajoCli {
+  private final TajoConf conf;
+  private static final Options options;
+
+  private TajoClient client;
+
+  private final ConsoleReader reader;
+  private final InputStream sin;
+  private final PrintWriter sout;
+
+  private static final int PRINT_LIMIT = 24;
+  private final Map<String, Command> commands = new TreeMap<String, Command>();
+
+  private static final Class [] registeredCommands = {
+      DescTableCommand.class,
+      HelpCommand.class,
+      ExitCommand.class,
+      Copyright.class,
+      Version.class
+  };
+
+  private static final String HOME_DIR = System.getProperty("user.home");
+  private static final String HISTORY_FILE = ".tajo_history";
+
+  static {
+    options = new Options();
+    options.addOption("c", "command", true, "execute only single command, then exit");
+    options.addOption("f", "file", true, "execute commands from file, then exit");
+    options.addOption("h", "host", true, "Tajo server host");
+    options.addOption("p", "port", true, "Tajo server port");
+  }
+
+  public TajoCli(TajoConf c, String [] args,
+                 InputStream in, OutputStream out) throws Exception {
+    this.conf = new TajoConf(c);
+    this.sin = in;
+    this.reader = new ConsoleReader(sin, out);
+    this.sout = new PrintWriter(reader.getOutput());
+
+    CommandLineParser parser = new PosixParser();
+    CommandLine cmd = parser.parse(options, args);
+
+    String hostName = null;
+    Integer port = null;
+    if (cmd.hasOption("h")) {
+      hostName = cmd.getOptionValue("h");
+    }
+    if (cmd.hasOption("p")) {
+      port = Integer.parseInt(cmd.getOptionValue("p"));
+    }
+
+    // if there is no "-h" option,
+    if(hostName == null) {
+      if (conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        hostName = conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
+      }
+    }
+    if (port == null) {
+      if (conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        port = Integer.parseInt(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
+      }
+    }
+
+    if ((hostName == null) ^ (port == null)) {
+      System.err.println("ERROR: cannot find valid Tajo server address");
+      System.exit(-1);
+    } else if (hostName != null && port != null) {
+      conf.setVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
+      client = new TajoClient(conf);
+    } else if (hostName == null && port == null) {
+      client = new TajoClient(conf);
+    }
+
+    initHistory();
+    initCommands();
+
+    if (cmd.hasOption("c")) {
+      executeStatements(cmd.getOptionValue("c"));
+      sout.flush();
+      System.exit(0);
+    }
+    if (cmd.hasOption("f")) {
+      File sqlFile = new File(cmd.getOptionValue("f"));
+      if (sqlFile.exists()) {
+        String contents = FileUtil.readTextFile(new File(cmd.getOptionValue("f")));
+        executeStatements(contents);
+        sout.flush();
+        System.exit(0);
+      } else {
+        System.err.println("No such a file \"" + cmd.getOptionValue("f") + "\"");
+        System.exit(-1);
+      }
+    }
+  }
+
+  private void initHistory() {
+    try {
+      String historyPath = HOME_DIR + File.separator + HISTORY_FILE;
+      if ((new File(HOME_DIR)).exists()) {
+        reader.setHistory(new FileHistory(new File(historyPath)));
+      } else {
+        System.err.println("ERROR: home directory : '" + HOME_DIR +"' does not exist.");
+      }
+    } catch (Exception e) {
+      System.err.println(e.getMessage());
+    }
+  }
+
+  private void initCommands() {
+    for (Class clazz : registeredCommands) {
+      Command cmd = null;
+      try {
+         Constructor cons = clazz.getConstructor(new Class[] {TajoCli.class});
+         cmd = (Command) cons.newInstance(this);
+      } catch (Exception e) {
+        System.err.println(e.getMessage());
+        System.exit(-1);
+      }
+      commands.put(cmd.getCommand(), cmd);
+    }
+  }
+
+  public int runShell() throws Exception {
+
+    String raw;
+    String line;
+    String accumulatedLine = "";
+    String prompt = "tajo";
+    String curPrompt = prompt;
+    boolean newStatement = true;
+    int code = 0;
+
+    sout.write("Try \\? for help.\n");
+    while((raw = reader.readLine(curPrompt + "> ")) != null) {
+      // each accumulated line has a space delimiter
+      if (!accumulatedLine.equals("")) {
+        accumulatedLine += ' ';
+      }
+
+      line = raw.trim();
+
+      if (line.length() == 0) { // if empty line
+        continue;
+
+      } else if (line.charAt(0) == '/') { // warning for legacy usage
+        printInvalidCommand(line);
+        continue;
+
+      } else if (line.charAt(0) == '\\') { // command mode
+        executeCommand(line);
+        ((PersistentHistory)reader.getHistory()).flush();
+
+      } else if (line.endsWith(";") && !line.endsWith("\\;")) {
+
+        // remove a trailing newline
+        line = StringUtils.chomp(line).trim();
+
+        // get a punctuated statement
+        String punctuated = accumulatedLine + line;
+
+        if (!newStatement) {
+          // why do two lines are removed?
+          // First history line indicates an accumulated line.
+          // Second history line is a just typed line.
+          reader.getHistory().removeLast();
+          reader.getHistory().removeLast();
+          reader.getHistory().add(punctuated);
+          ((PersistentHistory)reader.getHistory()).flush();
+        }
+
+        code = executeStatements(punctuated);
+
+        // reset accumulated lines
+        newStatement = true;
+        accumulatedLine = "";
+        curPrompt = prompt;
+
+      } else {
+        line = StringUtils.chomp(raw).trim();
+
+        // accumulate a line
+        accumulatedLine = accumulatedLine + line;
+
+        // replace the latest line with a accumulated line
+        if (!newStatement) { // if this is not first line, remove one more line.
+          reader.getHistory().removeLast();
+        } else {
+          newStatement = false;
+        }
+        reader.getHistory().removeLast();
+        reader.getHistory().add(accumulatedLine);
+
+        // use an alternative prompt during accumulating lines
+        curPrompt = StringUtils.repeat(" ", prompt.length());
+        continue;
+      }
+    }
+    return code;
+  }
+
+  private void invokeCommand(String [] cmds) {
+    // this command should be moved to GlobalEngine
+    Command invoked;
+    try {
+      invoked = commands.get(cmds[0]);
+      invoked.invoke(cmds);
+    } catch (Throwable t) {
+      sout.println(t.getMessage());
+    }
+  }
+
+  public int executeStatements(String line) throws Exception {
+
+    // TODO - comment handling and multi line queries should be improved
+    // remove comments
+    String filtered = line.replaceAll("--[^\\r\\n]*", "").trim();
+
+    String stripped;
+    for (String statement : filtered.split(";")) {
+      stripped = StringUtils.chomp(statement);
+      if (StringUtils.isBlank(stripped)) {
+        continue;
+      }
+
+      String [] cmds = stripped.split(" ");
+      if (cmds[0].equalsIgnoreCase("exit") || cmds[0].equalsIgnoreCase("quit")) {
+        sout.println("\n\nbye!");
+        sout.flush();
+        ((PersistentHistory)this.reader.getHistory()).flush();
+        System.exit(0);
+      } else if (cmds[0].equalsIgnoreCase("detach") && cmds.length > 1 && cmds[1].equalsIgnoreCase("table")) {
+        // this command should be moved to GlobalEngine
+        invokeCommand(cmds);
+
+      } else { // submit a query to TajoMaster
+        ClientProtos.GetQueryStatusResponse response = client.executeQuery(stripped);
+        if (response == null) {
+          sout.println("response is null");
+        }
+        else if (response.getResultCode() == ClientProtos.ResultCode.OK) {
+          QueryId queryId = null;
+          try {
+            queryId = new QueryId(response.getQueryId());
+            if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+              sout.println("OK");
+            } else {
+              getQueryResult(queryId);
+            }
+          } finally {
+            if(queryId != null) {
+              client.closeQuery(queryId);
+            }
+          }
+        } else {
+          if (response.hasErrorMessage()) {
+            sout.println(response.getErrorMessage());
+          }
+        }
+      }
+    }
+    return 0;
+  }
+
+  private boolean isFailed(QueryState state) {
+    return state == QueryState.QUERY_ERROR || state == QueryState.QUERY_FAILED;
+  }
+
+  private void getQueryResult(QueryId queryId) {
+    // if query is empty string
+    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+      return;
+    }
+
+    // query execute
+    try {
+
+      QueryStatus status;
+      while (true) {
+        // TODO - configurable
+        Thread.sleep(1000);
+        status = client.getQueryStatus(queryId);
+        if(status.getState() == QueryState.QUERY_MASTER_INIT || status.getState() == QueryState.QUERY_MASTER_LAUNCHED) {
+          continue;
+        }
+
+        if (status.getState() == QueryState.QUERY_RUNNING ||
+            status.getState() == QueryState.QUERY_SUCCEEDED) {
+          sout.println("Progress: " + (int)(status.getProgress() * 100.0f)
+              + "%, response time: " + ((float)(status.getFinishTime() - status.getSubmitTime()) / 1000.0) + " sec");
+          sout.flush();
+        }
+
+        if (status.getState() != QueryState.QUERY_RUNNING && status.getState() != QueryState.QUERY_NOT_ASSIGNED) {
+          break;
+        }
+      }
+
+      if (status.getState() == QueryState.QUERY_ERROR) {
+        sout.println("Internal error!");
+      } else if (status.getState() == QueryState.QUERY_FAILED) {
+        sout.println("Query failed!");
+      } else if (status.getState() == QueryState.QUERY_KILLED) {
+        sout.println(queryId + " is killed.");
+      } else {
+        if (status.getState() == QueryState.QUERY_SUCCEEDED) {
+          sout.println("final state: " + status.getState()
+              + ", response time: " + (((float)(status.getFinishTime() - status.getSubmitTime()) / 1000.0)
+              + " sec"));
+          if (status.hasResult()) {
+            ResultSet res = null;
+            TableDesc desc = null;
+            if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+              res = client.createNullResultSet(queryId);
+            } else {
+              ClientProtos.GetQueryResultResponse response = client.getResultResponse(queryId);
+              desc = CatalogUtil.newTableDesc(response.getTableDesc());
+              conf.setVar(ConfVars.USERNAME, response.getTajoUserName());
+              res = new TajoResultSet(client, queryId, conf, desc);
+            }
+            try {
+              if (res == null) {
+                sout.println("OK");
+                return;
+              }
+
+              ResultSetMetaData rsmd = res.getMetaData();
+
+              TableStats stat = desc.getStats();
+              String volume = FileUtil.humanReadableByteCount(stat.getNumBytes(), false);
+              long resultRows = stat.getNumRows();
+              sout.println("result: " + desc.getPath() + ", " + resultRows + " rows (" + volume + ")");
+
+              int numOfColumns = rsmd.getColumnCount();
+              for (int i = 1; i <= numOfColumns; i++) {
+                if (i > 1) sout.print(",  ");
+                String columnName = rsmd.getColumnName(i);
+                sout.print(columnName);
+              }
+              sout.println("\n-------------------------------");
+
+              int numOfPrintedRows = 0;
+              while (res.next()) {
+                // TODO - to be improved to print more formatted text
+                for (int i = 1; i <= numOfColumns; i++) {
+                  if (i > 1) sout.print(",  ");
+                  String columnValue = res.getObject(i).toString();
+                  if(res.wasNull()){
+                    sout.print("null");
+                  } else {
+                    sout.print(columnValue);
+                  }
+                }
+                sout.println();
+                sout.flush();
+                numOfPrintedRows++;
+                if (numOfPrintedRows >= PRINT_LIMIT) {
+                  sout.print("continue... ('q' is quit)");
+                  sout.flush();
+                  if (sin.read() == 'q') {
+                    break;
+                  }
+                  numOfPrintedRows = 0;
+                  sout.println();
+                }
+              }
+            } finally {
+              if(res != null) {
+                res.close();
+              }
+            }
+          } else {
+            sout.println("OK");
+          }
+        }
+      }
+    } catch (Throwable t) {
+      t.printStackTrace();
+      System.err.println(t.getMessage());
+    }
+  }
+
+  private void printUsage() {
+    HelpFormatter formatter = new HelpFormatter();
+    formatter.printHelp( "tajo cli [options]", options );
+  }
+
+  public static abstract class Command {
+    public abstract String getCommand();
+    public abstract void invoke(String [] command) throws Exception;
+    public abstract String getUsage();
+    public abstract String getDescription();
+  }
+
+  private String toFormattedString(TableDesc desc) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("\ntable name: ").append(desc.getName()).append("\n");
+    sb.append("table path: ").append(desc.getPath()).append("\n");
+    sb.append("store type: ").append(desc.getMeta().getStoreType()).append("\n");
+    if (desc.getStats() != null) {
+      sb.append("number of rows: ").append(desc.getStats().getNumRows()).append("\n");
+      sb.append("volume: ").append(
+          FileUtil.humanReadableByteCount(desc.getStats().getNumBytes(),
+              true)).append("\n");
+    }
+    sb.append("Options: \n");
+    for(Map.Entry<String, String> entry : desc.getMeta().toMap().entrySet()){
+      sb.append("\t").append("'").append(entry.getKey()).append("'").append("=")
+          .append("'").append(entry.getValue()).append("'").append("\n");
+    }
+    sb.append("\n");
+    sb.append("schema: \n");
+
+    for(int i = 0; i < desc.getSchema().getColumnNum(); i++) {
+      Column col = desc.getSchema().getColumn(i);
+      sb.append(col.getColumnName()).append("\t").append(col.getDataType().getType());
+      if (col.getDataType().hasLength()) {
+        sb.append("(").append(col.getDataType().getLength()).append(")");
+      }
+      sb.append("\n");
+    }
+
+    sb.append("\n");
+    sb.append("Partitions: \n");
+    if (desc.getPartitions() != null) {
+      sb.append("type:").append(desc.getPartitions().getPartitionsType().name()).append("\n");
+      if (desc.getPartitions().getNumPartitions() > 0)
+        sb.append("numbers:").append(desc.getPartitions().getNumPartitions()).append("\n");
+
+      sb.append("columns:").append("\n");
+      for(Column eachColumn: desc.getPartitions().getColumns()) {
+        sb.append("  ");
+        sb.append(eachColumn.getColumnName()).append("\t").append(eachColumn.getDataType().getType());
+        if (eachColumn.getDataType().hasLength()) {
+          sb.append("(").append(eachColumn.getDataType().getLength()).append(")");
+        }
+        sb.append("\n");
+      }
+
+      if (desc.getPartitions().getSpecifiers() != null) {
+        sb.append("specifier:").append("\n");
+        for(Specifier specifier :desc.getPartitions().getSpecifiers()) {
+          sb.append("  ");
+          sb.append("name:").append(specifier.getName());
+          if (!specifier.getExpressions().equals("")) {
+            sb.append(", expressions:").append(specifier.getExpressions());
+          } else {
+            if (desc.getPartitions().getPartitionsType().name().equals("RANGE"));
+              sb.append(" expressions: MAXVALUE");
+          }
+          sb.append("\n");
+        }
+      }
+    }
+
+    return sb.toString();
+  }
+
+  public class DescTableCommand extends Command {
+    public DescTableCommand() {}
+
+    @Override
+    public String getCommand() {
+      return "\\d";
+    }
+
+    @Override
+    public void invoke(String[] cmd) throws Exception {
+      if (cmd.length == 2) {
+        TableDesc desc = client.getTableDesc(cmd[1]);
+        if (desc == null) {
+          sout.println("Did not find any relation named \"" + cmd[1] + "\"");
+        } else {
+          sout.println(toFormattedString(desc));
+        }
+      } else if (cmd.length == 1) {
+        List<String> tableList = client.getTableList();
+        if (tableList.size() == 0) {
+          sout.println("No Relation Found");
+        }
+        for (String table : tableList) {
+          sout.println(table);
+        }
+      } else {
+        throw new IllegalArgumentException();
+      }
+    }
+
+    @Override
+    public String getUsage() {
+      return "[table_name]";
+    }
+
+    @Override
+    public String getDescription() {
+      return "show table description";
+    }
+  }
+
+  public class HelpCommand extends Command {
+
+    @Override
+    public String getCommand() {
+      return "\\?";
+    }
+
+    @Override
+    public void invoke(String[] cmd) throws Exception {
+      sout.println();
+
+      sout.println("General");
+      sout.println("  \\copyright  show Apache License 2.0");
+      sout.println("  \\version    show Tajo version");
+      sout.println("  \\?          show help");
+      sout.println("  \\q          quit tsql");
+      sout.println();
+      sout.println();
+
+      sout.println("Informational");
+      sout.println("  \\d         list tables");
+      sout.println("  \\d  NAME   describe table");
+      sout.println();
+      sout.println();
+
+      sout.println("Documentations");
+      sout.println("  tsql guide        http://wiki.apache.org/tajo/tsql");
+      sout.println("  Query language    http://wiki.apache.org/tajo/QueryLanguage");
+      sout.println("  Functions         http://wiki.apache.org/tajo/Functions");
+      sout.println("  Backup & restore  http://wiki.apache.org/tajo/BackupAndRestore");
+      sout.println("  Configuration     http://wiki.apache.org/tajo/Configuration");
+      sout.println();
+    }
+
+    @Override
+    public String getUsage() {
+      return "";
+    }
+
+    @Override
+    public String getDescription() {
+      return "show command lists and their usages";
+    }
+  }
+
+  public class Version extends Command {
+
+    @Override
+    public String getCommand() {
+      return "\\version";
+    }
+
+    @Override
+    public void invoke(String[] cmd) throws Exception {
+      sout.println(TajoConstants.TAJO_VERSION);
+    }
+
+    @Override
+    public String getUsage() {
+      return "";
+    }
+
+    @Override
+    public String getDescription() {
+      return "show Apache License 2.0";
+    }
+  }
+
+  public class Copyright extends Command {
+
+    @Override
+    public String getCommand() {
+      return "\\copyright";
+    }
+
+    @Override
+    public void invoke(String[] cmd) throws Exception {
+      sout.println();
+      sout.println(
+      "  Licensed to the Apache Software Foundation (ASF) under one\n" +
+      "  or more contributor license agreements.  See the NOTICE file\n" +
+      "  distributed with this work for additional information\n" +
+      "  regarding copyright ownership.  The ASF licenses this file\n" +
+      "  to you under the Apache License, Version 2.0 (the\n" +
+      "  \"License\"); you may not use this file except in compliance\n" +
+      "  with the License.  You may obtain a copy of the License at\n" +
+      "\n" +
+      "       http://www.apache.org/licenses/LICENSE-2.0\n" +
+      "\n" +
+      "   Unless required by applicable law or agreed to in writing, software\n" +
+      "   distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
+      "   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
+      "   See the License for the specific language governing permissions and\n" +
+      "   limitations under the License.");
+      sout.println();
+    }
+
+    @Override
+    public String getUsage() {
+      return "";
+    }
+
+    @Override
+    public String getDescription() {
+      return "show Apache License 2.0";
+    }
+  }
+
+  public class ExitCommand extends Command {
+
+    @Override
+    public String getCommand() {
+      return "\\q";
+    }
+
+    @Override
+    public void invoke(String[] cmd) throws Exception {
+      sout.println("bye!");
+      System.exit(0);
+    }
+
+    @Override
+    public String getUsage() {
+      return "";
+    }
+
+    @Override
+    public String getDescription() {
+      return "quit";
+    }
+  }
+
+  public int executeCommand(String line) throws Exception {
+    String [] metaCommands = line.split(";");
+    for (String metaCommand : metaCommands) {
+      String arguments [];
+      arguments = metaCommand.split(" ");
+
+      Command invoked = commands.get(arguments[0]);
+      if (invoked == null) {
+        printInvalidCommand(arguments[0]);
+        return -1;
+      }
+
+      try {
+        invoked.invoke(arguments);
+      } catch (IllegalArgumentException ige) {
+        sout.println(ige.getMessage());
+      } catch (Exception e) {
+        sout.println(e.getMessage());
+      }
+    }
+
+    return 0;
+  }
+
+  private void printInvalidCommand(String command) {
+    sout.println("Invalid command " + command +". Try \\? for help.");
+  }
+
+  public static void main(String [] args) throws Exception {
+    TajoConf conf = new TajoConf();
+    TajoCli shell = new TajoCli(conf, args, System.in, System.out);
+    System.out.println();
+    int status = shell.runShell();
+    System.exit(status);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
new file mode 100644
index 0000000..203f9aa
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryStatus.java
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.client;
+
+import org.apache.tajo.QueryId;
+import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.ipc.ClientProtos.GetQueryStatusResponse;
+
+public class QueryStatus {
+  private QueryId queryId;
+  private QueryState state;
+  private float progress;
+  private long submitTime;
+  private long finishTime;
+  private boolean hasResult;
+  private String errorText;
+  private String queryMasterHost;
+  private int queryMasterPort;
+
+  public QueryStatus(GetQueryStatusResponse proto) {
+    queryId = new QueryId(proto.getQueryId());
+    state = proto.getState();
+    progress = proto.getProgress();
+    submitTime = proto.getSubmitTime();
+    finishTime = proto.getFinishTime();
+    hasResult = proto.getHasResult();
+    if (proto.hasErrorMessage()) {
+      errorText = proto.getErrorMessage();
+    }
+
+    queryMasterHost = proto.getQueryMasterHost();
+    queryMasterPort = proto.getQueryMasterPort();
+  }
+
+  public String getQueryMasterHost() {
+    return queryMasterHost;
+  }
+
+  public int getQueryMasterPort() {
+    return queryMasterPort;
+  }
+
+  public QueryId getQueryId() {
+    return this.queryId;
+  }
+
+  public QueryState getState() {
+    return this.state;
+  }
+
+  public float getProgress() {
+    return progress;
+  }
+
+  public long getSubmitTime() {
+    return this.submitTime;
+  }
+
+  public long getFinishTime() {
+    return this.finishTime;
+  }
+
+  public boolean hasResult() {
+    return this.hasResult;
+  }
+
+  public String getErrorMessage() {
+    return errorText;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java
new file mode 100644
index 0000000..1573978
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java
@@ -0,0 +1,193 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.client;
+
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.exception.UnsupportedException;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+
+public class ResultSetUtil {
+  public static String prettyFormat(ResultSet res) throws SQLException {
+    StringBuilder sb = new StringBuilder();
+    ResultSetMetaData rsmd = res.getMetaData();
+    int numOfColumns = rsmd.getColumnCount();
+
+    for (int i = 1; i <= numOfColumns; i++) {
+      if (i > 1) sb.append(",  ");
+      String columnName = rsmd.getColumnName(i);
+      sb.append(columnName);
+    }
+    sb.append("\n-------------------------------\n");
+
+    while (res.next()) {
+      for (int i = 1; i <= numOfColumns; i++) {
+        if (i > 1) sb.append(",  ");
+        String columnValue = res.getObject(i).toString();
+        sb.append(columnValue);
+      }
+      sb.append("\n");
+    }
+
+    return sb.toString();
+  }
+
+  public static String toSqlType(TajoDataTypes.DataType type) {
+    switch (type.getType()) {
+    case BOOLEAN:
+      return "boolean";
+    case INT1:
+      return "tinyint";
+    case INT2:
+      return "smallint";
+    case INT4:
+      return "integer";
+    case INT8:
+      return "bigint";
+    case FLOAT4:
+      return "float";
+    case FLOAT8:
+      return "float8";
+    case DECIMAL:
+      return "numeric";
+    case VARBINARY:
+      return "bytea";
+    case CHAR:
+      return "character";
+    case DATE:
+      return "date";
+    case VARCHAR:
+      return "varchar";
+    case TEXT:
+      return "varchar";
+    default:
+      throw new UnsupportedException("Unrecognized column type:" + type);
+    }
+  }
+
+  public static int tajoTypeToSqlType(TajoDataTypes.DataType type) throws SQLException {
+    switch (type.getType()) {
+    case BOOLEAN:
+      return Types.BOOLEAN;
+    case INT1:
+      return Types.TINYINT;
+    case INT2:
+      return Types.SMALLINT;
+    case INT4:
+      return Types.INTEGER;
+    case INT8:
+      return Types.BIGINT;
+    case FLOAT4:
+      return Types.FLOAT;
+    case FLOAT8:
+      return Types.DOUBLE;
+    case DECIMAL:
+      return Types.DECIMAL;
+    case DATE:
+      return Types.TIMESTAMP;
+    case VARCHAR:
+      return Types.VARCHAR;
+    case TEXT:
+      return Types.VARCHAR;
+    default:
+      throw new SQLException("Unrecognized column type: " + type);
+    }
+  }
+
+  public static int columnDisplaySize(int columnType) throws SQLException {
+    // according to hiveTypeToSqlType possible options are:
+    switch(columnType) {
+    case Types.BOOLEAN:
+      return columnPrecision(columnType);
+    case Types.VARCHAR:
+      return Integer.MAX_VALUE; // hive has no max limit for strings
+    case Types.TINYINT:
+    case Types.SMALLINT:
+    case Types.INTEGER:
+    case Types.BIGINT:
+      return columnPrecision(columnType) + 1; // allow +/-
+    case Types.TIMESTAMP:
+      return columnPrecision(columnType);
+    // see http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Float.MAX_EXPONENT
+    case Types.FLOAT:
+      return 24; // e.g. -(17#).e-###
+    // see http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Double.MAX_EXPONENT
+    case Types.DOUBLE:
+      return 25; // e.g. -(17#).e-####
+    case Types.DECIMAL:
+      return Integer.MAX_VALUE;
+    default:
+      throw new SQLException("Invalid column type: " + columnType);
+    }
+  }
+
+  public static int columnPrecision(int columnType) throws SQLException {
+    // according to hiveTypeToSqlType possible options are:
+    switch(columnType) {
+    case Types.BOOLEAN:
+      return 1;
+    case Types.VARCHAR:
+      return Integer.MAX_VALUE; // hive has no max limit for strings
+    case Types.TINYINT:
+      return 3;
+    case Types.SMALLINT:
+      return 5;
+    case Types.INTEGER:
+      return 10;
+    case Types.BIGINT:
+      return 19;
+    case Types.FLOAT:
+      return 7;
+    case Types.DOUBLE:
+      return 15;
+    case Types.TIMESTAMP:
+      return 29;
+    case Types.DECIMAL:
+      return Integer.MAX_VALUE;
+    default:
+      throw new SQLException("Invalid column type: " + columnType);
+    }
+  }
+
+  public static int columnScale(int columnType) throws SQLException {
+    // according to hiveTypeToSqlType possible options are:
+    switch(columnType) {
+    case Types.BOOLEAN:
+    case Types.VARCHAR:
+    case Types.TINYINT:
+    case Types.SMALLINT:
+    case Types.INTEGER:
+    case Types.BIGINT:
+      return 0;
+    case Types.FLOAT:
+      return 7;
+    case Types.DOUBLE:
+      return 15;
+    case Types.TIMESTAMP:
+      return 9;
+    case Types.DECIMAL:
+      return Integer.MAX_VALUE;
+    default:
+      throw new SQLException("Invalid column type: " + columnType);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..05a5eff
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
@@ -0,0 +1,462 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.client;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.annotation.ThreadSafe;
+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.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ipc.ClientProtos.*;
+import org.apache.tajo.ipc.QueryMasterClientProtocol;
+import org.apache.tajo.ipc.QueryMasterClientProtocol.QueryMasterClientProtocolService;
+import org.apache.tajo.ipc.TajoMasterClientProtocol;
+import org.apache.tajo.ipc.TajoMasterClientProtocol.TajoMasterClientProtocolService;
+import org.apache.tajo.jdbc.SQLStates;
+import org.apache.tajo.jdbc.TajoResultSet;
+import org.apache.tajo.rpc.*;
+import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto;
+import org.apache.tajo.util.NetUtils;
+import org.apache.tajo.rpc.ServerCallable;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@ThreadSafe
+public class TajoClient {
+  private final Log LOG = LogFactory.getLog(TajoClient.class);
+
+  private final TajoConf conf;
+
+  private Map<QueryId, InetSocketAddress> queryMasterMap = new ConcurrentHashMap<QueryId, InetSocketAddress>();
+
+  private InetSocketAddress tajoMasterAddr;
+
+  private RpcConnectionPool connPool;
+
+  public TajoClient(TajoConf conf) throws IOException {
+    this(conf, NetUtils.createSocketAddr(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS)));
+  }
+
+  public TajoClient(TajoConf conf, InetSocketAddress addr) throws IOException {
+    this.conf = conf;
+    this.conf.set("tajo.disk.scheduler.report.interval", "0");
+    this.tajoMasterAddr = addr;
+
+    connPool = RpcConnectionPool.getPool(conf);
+  }
+
+  public TajoClient(InetSocketAddress addr) throws IOException {
+    this(new TajoConf(), addr);
+  }
+
+  public TajoClient(String hostname, int port) throws IOException {
+    this(new TajoConf(), NetUtils.createSocketAddr(hostname, port));
+  }
+
+  public void close() {
+    if(connPool != null) {
+      connPool.close();
+    }
+    queryMasterMap.clear();
+  }
+
+  public TajoConf getConf() {
+    return conf;
+  }
+
+  /**
+   * Call to QueryMaster closing query resources
+   * @param queryId
+   */
+  public void closeQuery(final QueryId queryId) {
+    if(queryMasterMap.containsKey(queryId)) {
+      NettyClientBase qmClient = null;
+      try {
+        qmClient = connPool.getConnection(queryMasterMap.get(queryId), QueryMasterClientProtocol.class, false);
+        QueryMasterClientProtocolService.BlockingInterface queryMasterService = qmClient.getStub();
+        queryMasterService.killQuery(null, queryId.getProto());
+      } catch (Exception e) {
+        LOG.warn("Fail to close a QueryMaster connection (qid=" + queryId + ", msg=" + e.getMessage() + ")", e);
+      } finally {
+        connPool.closeConnection(qmClient);
+        queryMasterMap.remove(queryId);
+      }
+    }
+  }
+
+  /**
+   * It submits a query statement and get a response immediately.
+   * The response only contains a query id, and submission status.
+   * In order to get the result, you should use {@link #getQueryResult(org.apache.tajo.QueryId)}
+   * or {@link #getQueryResultAndWait(org.apache.tajo.QueryId)}.
+   */
+  public GetQueryStatusResponse executeQuery(final String sql) throws ServiceException {
+    return new ServerCallable<GetQueryStatusResponse>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public GetQueryStatusResponse call(NettyClientBase client) throws ServiceException {
+        final QueryRequest.Builder builder = QueryRequest.newBuilder();
+        builder.setQuery(sql);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.submitQuery(null, builder.build());
+      }
+    }.withRetries();
+  }
+
+  /**
+   * It submits a query statement and get a response.
+   * The main difference from {@link #executeQuery(String)}
+   * is a blocking method. So, this method is wait for
+   * the finish of the submitted query.
+   *
+   * @return If failed, return null.
+   */
+  public ResultSet executeQueryAndGetResult(final String sql)
+      throws ServiceException, IOException {
+    GetQueryStatusResponse response = new ServerCallable<GetQueryStatusResponse>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public GetQueryStatusResponse call(NettyClientBase client) throws ServiceException {
+        final QueryRequest.Builder builder = QueryRequest.newBuilder();
+        builder.setQuery(sql);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.submitQuery(null, builder.build());
+      }
+    }.withRetries();
+
+    QueryId queryId = new QueryId(response.getQueryId());
+    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+      return this.createNullResultSet(queryId);
+    } else {
+      return this.getQueryResultAndWait(queryId);
+    }
+  }
+
+  public QueryStatus getQueryStatus(QueryId queryId) throws ServiceException {
+    GetQueryStatusRequest.Builder builder
+        = GetQueryStatusRequest.newBuilder();
+    builder.setQueryId(queryId.getProto());
+
+    GetQueryStatusResponse res = null;
+    if(queryMasterMap.containsKey(queryId)) {
+      NettyClientBase qmClient = null;
+      try {
+        qmClient = connPool.getConnection(queryMasterMap.get(queryId),
+            QueryMasterClientProtocol.class, false);
+        QueryMasterClientProtocolService.BlockingInterface queryMasterService = qmClient.getStub();
+        res = queryMasterService.getQueryStatus(null, builder.build());
+      } catch (Exception e) {
+        throw new ServiceException(e.getMessage(), e);
+      } finally {
+        connPool.closeConnection(qmClient);
+      }
+    } else {
+      NettyClientBase tmClient = null;
+      try {
+        tmClient = connPool.getConnection(tajoMasterAddr,
+            TajoMasterClientProtocol.class, false);
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub();
+        res = tajoMasterService.getQueryStatus(null, builder.build());
+
+        String queryMasterHost = res.getQueryMasterHost();
+        if(queryMasterHost != null && !queryMasterHost.isEmpty()) {
+          NettyClientBase qmClient = null;
+          try {
+            InetSocketAddress qmAddr = NetUtils.createSocketAddr(queryMasterHost, res.getQueryMasterPort());
+            qmClient = connPool.getConnection(
+                qmAddr, QueryMasterClientProtocol.class, false);
+            QueryMasterClientProtocolService.BlockingInterface queryMasterService = qmClient.getStub();
+            res = queryMasterService.getQueryStatus(null, builder.build());
+
+            queryMasterMap.put(queryId, qmAddr);
+          } catch (Exception e) {
+            throw new ServiceException(e.getMessage(), e);
+          } finally {
+            connPool.closeConnection(qmClient);
+          }
+        }
+      } catch (Exception e) {
+        throw new ServiceException(e.getMessage(), e);
+      } finally {
+        connPool.closeConnection(tmClient);
+      }
+    }
+    return new QueryStatus(res);
+  }
+
+  private static boolean isQueryRunnning(QueryState state) {
+    return state == QueryState.QUERY_NEW ||
+        state == QueryState.QUERY_RUNNING ||
+        state == QueryState.QUERY_MASTER_LAUNCHED ||
+        state == QueryState.QUERY_MASTER_INIT ||
+        state == QueryState.QUERY_NOT_ASSIGNED;
+  }
+
+  public ResultSet getQueryResult(QueryId queryId)
+      throws ServiceException, IOException {
+    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+      return createNullResultSet(queryId);
+    }
+    GetQueryResultResponse response = getResultResponse(queryId);
+    TableDesc tableDesc = CatalogUtil.newTableDesc(response.getTableDesc());
+    conf.setVar(ConfVars.USERNAME, response.getTajoUserName());
+    return new TajoResultSet(this, queryId, conf, tableDesc);
+  }
+
+  public ResultSet getQueryResultAndWait(QueryId queryId)
+      throws ServiceException, IOException {
+    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+      return createNullResultSet(queryId);
+    }
+    QueryStatus status = getQueryStatus(queryId);
+
+    while(status != null && isQueryRunnning(status.getState())) {
+      try {
+        Thread.sleep(500);
+      } catch (InterruptedException e) {
+        e.printStackTrace();
+      }
+
+      status = getQueryStatus(queryId);
+    }
+
+    if (status.getState() == QueryState.QUERY_SUCCEEDED) {
+      if (status.hasResult()) {
+        return getQueryResult(queryId);
+      } else {
+        return createNullResultSet(queryId);
+      }
+
+    } else {
+      LOG.warn("Query (" + status.getQueryId() + ") failed: " + status.getState());
+
+      //TODO throw SQLException(?)
+      return createNullResultSet(queryId);
+    }
+  }
+
+  public ResultSet createNullResultSet(QueryId queryId) throws IOException {
+    return new TajoResultSet(this, queryId);
+  }
+
+  public GetQueryResultResponse getResultResponse(QueryId queryId) throws ServiceException {
+    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
+      return null;
+    }
+
+    NettyClientBase client = null;
+    try {
+      InetSocketAddress queryMasterAddr = queryMasterMap.get(queryId);
+      if(queryMasterAddr == null) {
+        LOG.warn("No Connection to QueryMaster for " + queryId);
+        return null;
+      }
+      client = connPool.getConnection(queryMasterAddr, QueryMasterClientProtocol.class, false);
+      QueryMasterClientProtocolService.BlockingInterface queryMasterService = client.getStub();
+      GetQueryResultRequest.Builder builder = GetQueryResultRequest.newBuilder();
+      builder.setQueryId(queryId.getProto());
+      GetQueryResultResponse response = queryMasterService.getQueryResult(null,
+          builder.build());
+
+      return response;
+    } catch (Exception e) {
+      throw new ServiceException(e.getMessage(), e);
+    } finally {
+      connPool.closeConnection(client);
+    }
+  }
+
+  public boolean updateQuery(final String sql) throws ServiceException {
+    return new ServerCallable<Boolean>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        QueryRequest.Builder builder = QueryRequest.newBuilder();
+        builder.setQuery(sql);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        ResultCode resultCode =
+            tajoMasterService.updateQuery(null, builder.build()).getResultCode();
+        return resultCode == ResultCode.OK;
+      }
+    }.withRetries();
+  }
+
+  /**
+   * Test for the existence of table in catalog data.
+   * <p/>
+   * This will return true if table exists, false if not.
+   * @param name
+   * @return
+   * @throws ServiceException
+   */
+  public boolean existTable(final String name) throws ServiceException {
+    return new ServerCallable<Boolean>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        StringProto.Builder builder = StringProto.newBuilder();
+        builder.setValue(name);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.existTable(null, builder.build()).getValue();
+      }
+    }.withRetries();
+  }
+
+  public TableDesc createExternalTable(final String name, final Schema schema, final Path path, final TableMeta meta)
+      throws SQLException, ServiceException {
+    return new ServerCallable<TableDesc>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+
+        CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
+        builder.setName(name);
+        builder.setSchema(schema.getProto());
+        builder.setMeta(meta.getProto());
+        builder.setPath(path.toUri().toString());
+        TableResponse res = tajoMasterService.createExternalTable(null, builder.build());
+        if (res.getResultCode() == ResultCode.OK) {
+          return CatalogUtil.newTableDesc(res.getTableDesc());
+        } else {
+          throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
+        }
+      }
+    }.withRetries();
+  }
+
+  public boolean dropTable(final String tableName) throws ServiceException {
+    return dropTable(tableName, false);
+  }
+
+  /**
+   * Deletes table schema from catalog data and deletes data file in hdfs
+   * @param tableName
+   * @return
+   * @throws ServiceException
+   */
+  public boolean dropTable(final String tableName, final boolean purge) throws ServiceException {
+    return new ServerCallable<Boolean>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+
+        DropTableRequest.Builder builder = DropTableRequest.newBuilder();
+        builder.setName(tableName);
+        builder.setPurge(purge);
+        return tajoMasterService.dropTable(null, builder.build()).getValue();
+      }
+    }.withRetries();
+
+  }
+
+  /**
+   * Get a list of table names. All table and column names are
+   * represented as lower-case letters.
+   */
+  public List<String> getTableList() throws ServiceException {
+    return new ServerCallable<List<String>>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public List<String> call(NettyClientBase client) throws ServiceException {
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+
+        GetTableListRequest.Builder builder = GetTableListRequest.newBuilder();
+        GetTableListResponse res = tajoMasterService.getTableList(null, builder.build());
+        return res.getTablesList();
+      }
+    }.withRetries();
+  }
+
+  public TableDesc getTableDesc(final String tableName) throws SQLException, ServiceException {
+    return new ServerCallable<TableDesc>(conf, tajoMasterAddr,
+        TajoMasterClientProtocol.class, false, true) {
+      public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+
+        GetTableDescRequest.Builder build = GetTableDescRequest.newBuilder();
+        build.setTableName(tableName);
+        TableResponse res = tajoMasterService.getTableDesc(null, build.build());
+        if (res.getResultCode() == ResultCode.OK) {
+          return CatalogUtil.newTableDesc(res.getTableDesc());
+        } else {
+          throw new SQLException(res.getErrorMessage(), SQLStates.ER_NO_SUCH_TABLE.getState());
+        }
+      }
+    }.withRetries();
+  }
+
+  public boolean killQuery(final QueryId queryId)
+      throws ServiceException, IOException {
+
+    QueryStatus status = getQueryStatus(queryId);
+
+    NettyClientBase tmClient = null;
+    try {
+      /* send a kill to the TM */
+      tmClient = connPool.getConnection(tajoMasterAddr, TajoMasterClientProtocol.class, false);
+      TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub();
+      tajoMasterService.killQuery(null, queryId.getProto());
+
+      long currentTimeMillis = System.currentTimeMillis();
+      long timeKillIssued = currentTimeMillis;
+      while ((currentTimeMillis < timeKillIssued + 10000L) && (status.getState()
+          != QueryState.QUERY_KILLED)) {
+        try {
+          Thread.sleep(1000L);
+        } catch(InterruptedException ie) {
+          /** interrupted, just break */
+          break;
+        }
+        currentTimeMillis = System.currentTimeMillis();
+        status = getQueryStatus(queryId);
+      }
+    } catch(Exception e) {
+      LOG.debug("Error when checking for application status", e);
+      return false;
+    } finally {
+      connPool.closeConnection(tmClient);
+    }
+
+    return true;
+  }
+
+  public static void main(String[] args) throws Exception {
+    TajoClient client = new TajoClient(new TajoConf());
+
+    client.close();
+
+    synchronized(client) {
+      client.wait();
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/client/TajoDump.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoDump.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoDump.java
new file mode 100644
index 0000000..486ff9f
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoDump.java
@@ -0,0 +1,129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.client;
+
+import com.google.common.collect.Lists;
+import com.google.protobuf.ServiceException;
+import org.apache.commons.cli.*;
+import org.apache.tajo.catalog.DDLBuilder;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.conf.TajoConf;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.sql.SQLException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.List;
+
+public class TajoDump {
+  private static final org.apache.commons.cli.Options options;
+
+  static {
+    options = new Options();
+    options.addOption("h", "host", true, "Tajo server host");
+    options.addOption("p", "port", true, "Tajo server port");
+    options.addOption("a", "all", false, "dump all table DDLs");
+  }
+
+  private static void printUsage() {
+    HelpFormatter formatter = new HelpFormatter();
+    formatter.printHelp( "tajo_dump [options] [table_name]", options );
+  }
+
+  public static void main(String [] args) throws ParseException, IOException, ServiceException, SQLException {
+    TajoConf conf = new TajoConf();
+
+    CommandLineParser parser = new PosixParser();
+    CommandLine cmd = parser.parse(options, args);
+
+    String hostName = null;
+    Integer port = null;
+    if (cmd.hasOption("h")) {
+      hostName = cmd.getOptionValue("h");
+    }
+    if (cmd.hasOption("p")) {
+      port = Integer.parseInt(cmd.getOptionValue("p"));
+    }
+
+    // if there is no "-h" option,
+    if(hostName == null) {
+      if (conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        hostName = conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
+      }
+    }
+    if (port == null) {
+      if (conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        port = Integer.parseInt(conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
+      }
+    }
+
+    TajoClient client = null;
+    if ((hostName == null) ^ (port == null)) {
+      System.err.println("ERROR: cannot find valid Tajo server address");
+      System.exit(-1);
+    } else if (hostName != null && port != null) {
+      conf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
+      client = new TajoClient(conf);
+    } else if (hostName == null && port == null) {
+      client = new TajoClient(conf);
+    }
+
+    List<TableDesc> tableDescList = Lists.newArrayList();
+
+    if (cmd.hasOption("a")) {
+      for (String tableName : client.getTableList()) {
+        tableDescList.add(client.getTableDesc(tableName));
+      }
+    } else if (cmd.getArgs().length > 0) {
+      for (String tableName : cmd.getArgs()) {
+        tableDescList.add(client.getTableDesc(tableName));
+      }
+    } else {
+      printUsage();
+    }
+
+
+    Writer writer = new PrintWriter(System.out);
+    writer.write("--\n");
+    writer.write("-- Tajo database dump\n");
+    writer.write("-- Dump date: " + toDateString() + "\n");
+    writer.write("--\n");
+    writer.write("\n");
+    for (TableDesc tableDesc : tableDescList) {
+      writer.write(DDLBuilder.buildDDL(tableDesc));
+      writer.write("\n\n");
+    }
+    writer.flush();
+    writer.close();
+    System.exit(0);
+  }
+
+  private static String toDateString() {
+    DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+    java.util.Date today = Calendar.getInstance().getTime();
+    return df.format(today);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java
new file mode 100644
index 0000000..32ab19c
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/SQLStates.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+public enum SQLStates {
+  ER_NO_SUCH_TABLE("42S02");
+
+  private String state;
+
+  SQLStates(String state) {
+    this.state = state;
+  }
+
+  public String getState() {
+    return state;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
new file mode 100644
index 0000000..1005765
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
@@ -0,0 +1,152 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.PathFilter;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.storage.FileScanner;
+import org.apache.tajo.storage.MergeScanner;
+import org.apache.tajo.storage.Scanner;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.fragment.FileFragment;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+
+public class TajoResultSet extends TajoResultSetBase {
+  private FileSystem fs;
+  private Scanner scanner;
+  private TajoClient tajoClient;
+  QueryId queryId;
+
+  public TajoResultSet(TajoClient tajoClient, QueryId queryId) {
+    this.tajoClient = tajoClient;
+    this.queryId = queryId;
+    init();
+  }
+
+  public TajoResultSet(TajoClient tajoClient, QueryId queryId,
+                       Configuration conf, TableDesc desc) throws IOException {
+    this.schema = desc.getSchema();
+    this.tajoClient = tajoClient;
+    this.queryId = queryId;
+    if(desc != null) {
+      fs = FileScanner.getFileSystem((TajoConf)conf, desc.getPath());
+      this.totalRow = desc.getStats() != null ? desc.getStats().getNumRows() : 0;
+
+      Collection<FileFragment> frags = getFragments(desc.getMeta(), desc.getPath());
+      scanner = new MergeScanner(conf, schema, desc.getMeta(), frags);
+    }
+    init();
+  }
+
+  @Override
+  protected void init() {
+    cur = null;
+    curRow = 0;
+  }
+
+  class FileNameComparator implements Comparator<FileStatus> {
+
+    @Override
+    public int compare(FileStatus f1, FileStatus f2) {
+      return f2.getPath().getName().compareTo(f1.getPath().getName());
+    }
+  }
+
+  private Collection<FileFragment> getFragments(TableMeta meta, Path tablePath)
+      throws IOException {
+    List<FileFragment> fraglist = Lists.newArrayList();
+    FileStatus[] files = fs.listStatus(tablePath, new PathFilter() {
+      @Override
+      public boolean accept(Path path) {
+        return path.getName().charAt(0) != '.';
+      }
+    });
+    Arrays.sort(files, new FileNameComparator());
+
+    String tbname = tablePath.getName();
+    for (int i = 0; i < files.length; i++) {
+      if (files[i].getLen() == 0) {
+        continue;
+      }
+      fraglist.add(new FileFragment(tbname + "_" + i, files[i].getPath(), 0l, files[i].getLen()));
+    }
+    return fraglist;
+  }
+
+  @Override
+  public void close() throws SQLException {
+    try {
+      if(tajoClient != null) {
+        this.tajoClient.closeQuery(queryId);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    try {
+      if(scanner != null) {
+        this.scanner.close();
+      }
+      //TODO clean temp result file
+      cur = null;
+      curRow = -1;
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    try {
+      if(scanner != null) {
+        scanner.reset();
+      }
+      init();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+
+  @Override
+  protected Tuple nextTuple() throws IOException {
+    if(scanner == null) {
+      return null;
+    }
+    return scanner.next();
+  }
+
+  public boolean hasResult() {
+    return scanner != null;
+  }
+}


[2/6] TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-pullserver/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-pullserver/pom.xml b/tajo-core/tajo-core-pullserver/pom.xml
index d4f50f4..8c6d4fe 100644
--- a/tajo-core/tajo-core-pullserver/pom.xml
+++ b/tajo-core/tajo-core-pullserver/pom.xml
@@ -51,12 +51,12 @@
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-yarn-server-nodemanager</artifactId>
-      <scope>compile</scope>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-yarn-common</artifactId>
-      <scope>compile</scope>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-pullserver/src/main/java/org/apache/tajo/storage/Tuple.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-pullserver/src/main/java/org/apache/tajo/storage/Tuple.java b/tajo-core/tajo-core-pullserver/src/main/java/org/apache/tajo/storage/Tuple.java
new file mode 100644
index 0000000..711666f
--- /dev/null
+++ b/tajo-core/tajo-core-pullserver/src/main/java/org/apache/tajo/storage/Tuple.java
@@ -0,0 +1,80 @@
+/**
+ * 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.storage;
+
+import org.apache.tajo.datum.*;
+
+import java.net.InetAddress;
+
+public interface Tuple extends Cloneable {
+
+  public int size();
+
+  public boolean contains(int fieldid);
+
+  public boolean isNull(int fieldid);
+
+  public void clear();
+
+  public void put(int fieldId, Datum value);
+
+  public void put(int fieldId, Datum [] values);
+
+  public void put(int fieldId, Tuple tuple);
+
+  public void put(Datum [] values);
+
+  public Datum get(int fieldId);
+
+  public void setOffset(long offset);
+
+  public long getOffset();
+
+  public BooleanDatum getBoolean(int fieldId);
+
+  public BitDatum getByte(int fieldId);
+
+  public CharDatum getChar(int fieldId);
+
+  public BlobDatum getBytes(int fieldId);
+
+  public Int2Datum getShort(int fieldId);
+
+  public Int4Datum getInt(int fieldId);
+
+  public Int8Datum getLong(int fieldId);
+
+  public Float4Datum getFloat(int fieldId);
+
+  public Float8Datum getDouble(int fieldId);
+
+  public Inet4Datum getIPv4(int fieldId);
+
+  public byte [] getIPv4Bytes(int fieldId);
+
+  public InetAddress getIPv6(int fieldId);
+
+  public byte [] getIPv6Bytes(int fieldId);
+
+  public TextDatum getString(int fieldId);
+
+  public TextDatum getText(int fieldId);
+
+  public Tuple clone() throws CloneNotSupportedException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-storage/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-storage/pom.xml b/tajo-core/tajo-core-storage/pom.xml
index 176dd14..26a6e94 100644
--- a/tajo-core/tajo-core-storage/pom.xml
+++ b/tajo-core/tajo-core-storage/pom.xml
@@ -170,41 +170,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-minicluster</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-hdfs</artifactId>
-      <type>test-jar</type>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-server-nodemanager</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-server-resourcemanager</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-server-common</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-yarn-server-tests</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
     </dependency>
 
     <dependency>
@@ -214,6 +180,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-logging</groupId>
@@ -227,11 +194,6 @@
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <scope>test</scope>
-    </dependency>
 
     <dependency>
       <groupId>com.google.code.gson</groupId>
@@ -287,7 +249,7 @@
             <executions>
               <execution>
                 <!-- builds source jars and attaches them to the project for publishing -->
-                <id>hadoop-java-sources</id>
+                <id>tajo-java-sources</id>
                 <phase>package</phase>
                 <goals>
                   <goal>jar-no-fork</goal>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-dist/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-dist/pom.xml b/tajo-dist/pom.xml
index 562f21a..0712d01 100644
--- a/tajo-dist/pom.xml
+++ b/tajo-dist/pom.xml
@@ -102,11 +102,17 @@
                       run cp -r $ROOT/tajo-common/target/tajo-common-${project.version}/* .
                       run cp -r $ROOT/tajo-rpc/target/tajo-rpc-${project.version}/* .
                       run cp -r $ROOT/tajo-algebra/target/tajo-algebra-${project.version}/* .
+                      run cp -r $ROOT/tajo-client/target/tajo-client-${project.version}/* .
                       run cp -r $ROOT/tajo-catalog/target/tajo-catalog-${project.version}/* .
                       run cp -r $ROOT/tajo-core/target/tajo-core-${project.version}/* .
                       run cp -r ${project.basedir}/src/main/bin .
                       run cp -r ${project.basedir}/src/main/conf .
                       run rm -rf lib/tajo-*-${project.version}.jar
+
+                      run mkdir -p share/jdbc-dist
+                      run cp -r $ROOT/tajo-jdbc/target/tajo-jdbc-${project.version}.jar ./share/jdbc-dist
+                      run cp -r $ROOT/tajo-jdbc/target/lib/* ./share/jdbc-dist
+
                       echo
                       echo "Tajo dist layout available at: ${project.build.directory}/tajo-${project.version}"
                       echo

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-jdbc/pom.xml b/tajo-jdbc/pom.xml
new file mode 100644
index 0000000..52f9bbb
--- /dev/null
+++ b/tajo-jdbc/pom.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tajo-project</artifactId>
+    <groupId>org.apache.tajo</groupId>
+    <version>0.8.0-SNAPSHOT</version>
+    <relativePath>../tajo-project</relativePath>
+  </parent>
+  <artifactId>tajo-jdbc</artifactId>
+  <packaging>jar</packaging>
+  <name>Tajo JDBC Driver</name>
+  <version>0.8.0-SNAPSHOT</version>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+  </properties>
+
+  <repositories>
+    <repository>
+      <id>repository.jboss.org</id>
+      <url>https://repository.jboss.org/nexus/content/repositories/releases/
+      </url>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <encoding>${project.build.sourceEncoding}</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>false</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+              <includeGroupIds>org.apache.tajo,joda-time</includeGroupIds>
+              <excludeScope>provided</excludeScope>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-core-storage</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-rpc</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-client</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>docs</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <executions>
+              <execution>
+                <!-- build javadoc jars per jar for publishing to maven -->
+                <id>module-javadocs</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+                <configuration>
+                  <destDir>${project.build.directory}</destDir>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>src</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-source-plugin</artifactId>
+            <executions>
+              <execution>
+                <!-- builds source jars and attaches them to the project for publishing -->
+                <id>tajo-java-sources</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>jar-no-fork</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>2.4</version>
+        <configuration>
+          <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+        <version>2.15</version>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
+

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
new file mode 100644
index 0000000..ba32962
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
@@ -0,0 +1,192 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.datum.*;
+import org.apache.tajo.exception.UnsupportedException;
+import org.apache.tajo.storage.Tuple;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MetaDataTuple implements Tuple {
+  List<Datum> values = new ArrayList<Datum>();
+
+  public MetaDataTuple(int size) {
+    values = new ArrayList<Datum>(size);
+    for(int i = 0; i < size; i++) {
+      values.add(NullDatum.get());
+    }
+  }
+
+  @Override
+  public int size() {
+    return values.size();
+  }
+
+  @Override
+  public boolean contains(int fieldid) {
+    return false;
+  }
+
+  @Override
+  public boolean isNull(int fieldid) {
+    return values.get(fieldid) == null || values.get(fieldid) instanceof NullDatum;
+  }
+
+  @Override
+  public void clear() {
+    values.clear();
+  }
+
+  @Override
+  public void put(int fieldId, Datum value) {
+    values.set(fieldId, value);
+  }
+
+  @Override
+  public void put(int fieldId, Datum[] values) {
+    throw new UnsupportedException("put");
+  }
+
+  @Override
+  public void put(int fieldId, Tuple tuple) {
+    throw new UnsupportedException("put");
+  }
+
+  @Override
+  public void put(Datum[] values) {
+    throw new UnsupportedException("put");
+  }
+
+  @Override
+  public Datum get(int fieldId) {
+    return getText(fieldId);
+  }
+
+  @Override
+  public void setOffset(long offset) {
+    throw new UnsupportedException("setOffset");
+  }
+
+  @Override
+  public long getOffset() {
+    throw new UnsupportedException("getOffset");
+  }
+
+  @Override
+  public BooleanDatum getBoolean(int fieldId) {
+    throw new UnsupportedException("getBoolean");
+  }
+
+  @Override
+  public BitDatum getByte(int fieldId) {
+    throw new UnsupportedException("getByte");
+  }
+
+  @Override
+  public CharDatum getChar(int fieldId) {
+    throw new UnsupportedException("getBoolean");
+  }
+
+  @Override
+  public BlobDatum getBytes(int fieldId) {
+    throw new UnsupportedException("BlobDatum");
+  }
+
+  @Override
+  public Int2Datum getShort(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new Int2Datum((short)Integer.parseInt(values.get(fieldId).toString()));
+  }
+
+  @Override
+  public Int4Datum getInt(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new Int4Datum(Integer.parseInt(values.get(fieldId).toString()));
+  }
+
+  @Override
+  public Int8Datum getLong(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new Int8Datum(Long.parseLong(values.get(fieldId).toString()));
+  }
+
+  @Override
+  public Float4Datum getFloat(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new Float4Datum(Float.parseFloat(values.get(fieldId).toString()));
+  }
+
+  @Override
+  public Float8Datum getDouble(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new Float8Datum(Float.parseFloat(values.get(fieldId).toString()));
+  }
+
+  @Override
+  public Inet4Datum getIPv4(int fieldId) {
+    throw new UnsupportedException("getIPv4");
+  }
+
+  @Override
+  public byte[] getIPv4Bytes(int fieldId) {
+    throw new UnsupportedException("getIPv4Bytes");
+  }
+
+  @Override
+  public InetAddress getIPv6(int fieldId) {
+    throw new UnsupportedException("getIPv6");
+  }
+
+  @Override
+  public byte[] getIPv6Bytes(int fieldId) {
+    throw new UnsupportedException("getIPv6Bytes");
+  }
+
+  @Override
+  public TextDatum getString(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new TextDatum(values.get(fieldId).toString());
+  }
+
+  @Override
+  public TextDatum getText(int fieldId) {
+    if(isNull(fieldId)) {
+      return null;
+    }
+    return new TextDatum(values.get(fieldId).toString());
+  }
+
+  @Override
+  public Tuple clone() throws CloneNotSupportedException {
+    throw new UnsupportedException("clone");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoConnection.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoConnection.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoConnection.java
new file mode 100644
index 0000000..b751d5d
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoConnection.java
@@ -0,0 +1,398 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class TajoConnection implements Connection {
+  private TajoClient tajoClient;
+
+  private String databaseName;
+
+  private AtomicBoolean closed = new AtomicBoolean(true);
+
+  private String uri;
+
+  public TajoConnection(String uri, Properties properties) throws SQLException {
+    if (!uri.startsWith(TajoDriver.TAJO_JDBC_URL_PREFIX)) {
+      throw new SQLException("Invalid URL: " + uri, "TAJO-001");
+    }
+
+    this.uri = uri;
+
+    // remove prefix
+    uri = uri.substring(TajoDriver.TAJO_JDBC_URL_PREFIX.length());
+
+
+    if (uri.isEmpty()) {
+      throw new SQLException("Invalid URL: " + uri, "TAJO-001");
+    }
+
+    // parse uri
+    // form: hostname:port/databasename
+    String[] parts = uri.split("/");
+    if(parts.length == 0 || parts[0].trim().isEmpty()) {
+      throw new SQLException("Invalid URL(No tajo master's host:port): " + uri, "TAJO-001");
+    }
+    String[] hostAndPort = parts[0].trim().split(":");
+    String host = hostAndPort[0];
+    int port = 0;
+    try {
+      port = Integer.parseInt(hostAndPort[1]);
+    } catch (Exception e) {
+      throw new SQLException("Invalid URL(Wrong tajo master's host:port): " + uri, "TAJO-001");
+    }
+
+    if(parts.length > 1) {
+      String[] tokens = parts[1].split("\\?");
+      databaseName = tokens[0].trim();
+      if(tokens.length > 1) {
+        String[] extraParamTokens = tokens[1].split("&");
+        for(String eachExtraParam: extraParamTokens) {
+          String[] paramTokens = eachExtraParam.split("=");
+          String extraParamKey = paramTokens[0];
+          String extraParamValue = paramTokens[1];
+        }
+      }
+    }
+
+    TajoConf tajoConf = new TajoConf();
+
+    tajoConf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, host + ":" + port);
+
+    if(properties != null) {
+      for(Map.Entry<Object, Object> entry: properties.entrySet()) {
+        tajoConf.set(entry.getKey().toString(), entry.getValue().toString());
+      }
+    }
+
+    try {
+      tajoClient = new TajoClient(tajoConf);
+    } catch (Exception e) {
+      throw new SQLException("Can't create tajo client:" + e.getMessage(), "TAJO-002");
+    }
+    closed.set(false);
+  }
+
+  public String getUri() {
+    return uri;
+  }
+
+  public TajoClient getTajoClient() {
+    return tajoClient;
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+  }
+
+  @Override
+  public void close() throws SQLException {
+    if(!closed.get()) {
+      if(tajoClient != null) {
+        tajoClient.close();
+      }
+
+      closed.set(true);
+    }
+  }
+
+  @Override
+  public void commit() throws SQLException {
+    throw new SQLFeatureNotSupportedException("commit");
+  }
+
+  @Override
+  public Array createArrayOf(String arg0, Object[] arg1) throws SQLException {
+    throw new SQLFeatureNotSupportedException("createArrayOf");
+  }
+
+  @Override
+  public Blob createBlob() throws SQLException {
+    throw new SQLFeatureNotSupportedException("createBlob");
+  }
+
+  @Override
+  public Clob createClob() throws SQLException {
+    throw new SQLFeatureNotSupportedException("createClob");
+  }
+
+  @Override
+  public NClob createNClob() throws SQLException {
+    throw new SQLFeatureNotSupportedException("createNClob");
+  }
+
+  @Override
+  public SQLXML createSQLXML() throws SQLException {
+    throw new SQLFeatureNotSupportedException("createSQLXML");
+  }
+
+  @Override
+  public Statement createStatement() throws SQLException {
+    if (isClosed()) {
+      throw new SQLException("Can't create Statement, connection is closed");
+    }
+    return new TajoStatement(tajoClient);
+  }
+
+  @Override
+  public Statement createStatement(int resultSetType, int resultSetConcurrency)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("createStatement");
+  }
+
+  @Override
+  public Statement createStatement(int resultSetType, int resultSetConcurrency,
+                                   int resultSetHoldability) throws SQLException {
+    throw new SQLFeatureNotSupportedException("createStatement");
+  }
+
+  @Override
+  public Struct createStruct(String typeName, Object[] attributes)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("createStruct");
+  }
+
+  @Override
+  public boolean getAutoCommit() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public String getCatalog() throws SQLException {
+    return "";
+  }
+
+  @Override
+  public Properties getClientInfo() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getClientInfo");
+  }
+
+  @Override
+  public String getClientInfo(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("getClientInfo");
+  }
+
+  @Override
+  public int getHoldability() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getHoldability");
+  }
+
+  @Override
+  public DatabaseMetaData getMetaData() throws SQLException {
+    return new TajoDatabaseMetaData(this);
+  }
+
+  @Override
+  public int getTransactionIsolation() throws SQLException {
+    return Connection.TRANSACTION_NONE;
+  }
+
+  @Override
+  public Map<String, Class<?>> getTypeMap() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getTypeMap");
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    throw new SQLFeatureNotSupportedException("getWarnings");
+  }
+
+  @Override
+  public boolean isClosed() throws SQLException {
+    return closed.get();
+  }
+
+  @Override
+  public boolean isReadOnly() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isValid(int timeout) throws SQLException {
+    throw new SQLFeatureNotSupportedException("isValid");
+  }
+
+  @Override
+  public String nativeSQL(String sql) throws SQLException {
+    throw new SQLFeatureNotSupportedException("nativeSQL");
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql) throws SQLException {
+    throw new SQLFeatureNotSupportedException("prepareCall");
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql, int resultSetType,
+                                       int resultSetConcurrency) throws SQLException {
+    throw new SQLFeatureNotSupportedException("prepareCall");
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql, int resultSetType,
+                                       int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+    throw new SQLFeatureNotSupportedException("prepareCall");
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql) throws SQLException {
+    return new TajoPreparedStatement(tajoClient, sql);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+      throws SQLException {
+    return new TajoPreparedStatement(tajoClient, sql);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("prepareStatement");
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, String[] columnNames)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("prepareStatement");
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int resultSetType,
+                                            int resultSetConcurrency) throws SQLException {
+    return new TajoPreparedStatement(tajoClient, sql);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int resultSetType,
+                                            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+    throw new SQLFeatureNotSupportedException("prepareStatement");
+  }
+
+  @Override
+  public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+    throw new SQLFeatureNotSupportedException("releaseSavepoint");
+  }
+
+  @Override
+  public void rollback() throws SQLException {
+    throw new SQLFeatureNotSupportedException("rollback");
+  }
+
+  @Override
+  public void rollback(Savepoint savepoint) throws SQLException {
+    throw new SQLFeatureNotSupportedException("rollback");
+  }
+
+  @Override
+  public void setAutoCommit(boolean autoCommit) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setAutoCommit");
+  }
+
+  @Override
+  public void setCatalog(String catalog) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setCatalog");
+  }
+
+  @Override
+  public void setClientInfo(Properties properties)
+      throws SQLClientInfoException {
+    throw new UnsupportedOperationException("setClientInfo");
+  }
+
+  @Override
+  public void setClientInfo(String name, String value)
+      throws SQLClientInfoException {
+    throw new UnsupportedOperationException("setClientInfo");
+  }
+
+  @Override
+  public void setHoldability(int holdability) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setHoldability");
+  }
+
+  @Override
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setReadOnly");
+  }
+
+  @Override
+  public Savepoint setSavepoint() throws SQLException {
+    throw new SQLFeatureNotSupportedException("setSavepoint");
+  }
+
+  @Override
+  public Savepoint setSavepoint(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setSavepoint");
+  }
+
+  @Override
+  public void setTransactionIsolation(int level) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setTransactionIsolation");
+  }
+
+  @Override
+  public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+    throw new SQLFeatureNotSupportedException("setTypeMap");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> tClass) throws SQLException {
+    if (isWrapperFor(tClass)) {
+      return (T) this;
+    }
+    throw new SQLException("No wrapper for " + tClass);
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> tClass) throws SQLException {
+    return tClass.isInstance(this);
+  }
+
+  public void abort(Executor executor) throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("abort not supported");
+  }
+
+  public int getNetworkTimeout() throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("getNetworkTimeout not supported");
+  }
+
+  public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("setNetworkTimeout not supported");
+  }
+
+  public String getSchema() throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("getSchema not supported");
+  }
+
+  public void setSchema(String schema) throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("setSchema not supported");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
new file mode 100644
index 0000000..e868701
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
@@ -0,0 +1,1196 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.ResultSetUtil;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.TextDatum;
+
+import java.sql.*;
+import java.util.*;
+
+/**
+ * TajoDatabaseMetaData.
+ */
+public class TajoDatabaseMetaData implements DatabaseMetaData {
+  private static final char SEARCH_STRING_ESCAPE = '\\';
+
+  private final TajoConnection conn;
+
+  public TajoDatabaseMetaData(TajoConnection conn) {
+    this.conn = conn;
+  }
+
+  @Override
+  public boolean allProceduresAreCallable()
+      throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean allTablesAreSelectable()
+      throws SQLException {
+    return true;
+  }
+
+  @Override
+  public String getURL()
+      throws SQLException {
+    return conn.getUri();
+  }
+
+  @Override
+  public String getUserName()
+      throws SQLException {
+    return "tajo";
+  }
+
+  @Override
+  public boolean isReadOnly()
+      throws SQLException {
+    return true;
+  }
+
+  @Override
+  public String getDatabaseProductName()
+      throws SQLException {
+    return "Tajo";
+  }
+
+  @Override
+  public String getDatabaseProductVersion()
+      throws SQLException {
+    //TODO get from tajo master
+    return TajoConstants.TAJO_VERSION;
+  }
+
+  @Override
+  public String getDriverName()
+      throws SQLException {
+    return "tajo";
+  }
+
+  @Override
+  public String getDriverVersion()
+      throws SQLException {
+    return TajoDriver.MAJOR_VERSION + "." + TajoDriver.MINOR_VERSION;
+  }
+
+  @Override
+  public int getDriverMajorVersion() {
+    return TajoDriver.MAJOR_VERSION;
+  }
+
+  @Override
+  public int getDriverMinorVersion() {
+    return TajoDriver.MINOR_VERSION;
+  }
+
+  @Override
+  public String getIdentifierQuoteString()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getIdentifierQuoteString not supported");
+  }
+
+  @Override
+  public String getSQLKeywords()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getSQLKeywords not supported");
+  }
+
+  @Override
+  public String getNumericFunctions()
+      throws SQLException {
+    return "";
+  }
+
+  @Override
+  public String getStringFunctions()
+      throws SQLException {
+    return "";
+  }
+
+  @Override
+  public String getSystemFunctions()
+      throws SQLException {
+    return "";
+  }
+
+  @Override
+  public String getTimeDateFunctions()
+      throws SQLException {
+    return "";
+  }
+
+  @Override
+  public String getSearchStringEscape()
+      throws SQLException {
+    return "\\";
+  }
+
+  @Override
+  public String getExtraNameCharacters()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getExtraNameCharacters not supported");
+  }
+
+  @Override
+  public String getSchemaTerm()
+      throws SQLException {
+    return "";
+  }
+
+  @Override
+  public String getProcedureTerm()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getProcedureTerm not supported");
+  }
+
+  @Override
+  public String getCatalogTerm()
+      throws SQLException {
+    return "database";
+  }
+
+  @Override
+  public String getCatalogSeparator()
+      throws SQLException {
+    return ".";
+  }
+
+  @Override
+  public int getMaxBinaryLiteralLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxBinaryLiteralLength not supported");
+  }
+
+  @Override
+  public int getMaxCharLiteralLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxCharLiteralLength not supported");
+  }
+
+  @Override
+  public int getMaxColumnNameLength()
+      throws SQLException {
+    return 128;
+  }
+
+  @Override
+  public int getMaxColumnsInGroupBy()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxColumnsInGroupBy not supported");
+  }
+
+  @Override
+  public int getMaxColumnsInIndex()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxColumnsInIndex not supported");
+  }
+
+  @Override
+  public int getMaxColumnsInOrderBy()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxColumnsInOrderBy not supported");
+  }
+
+  @Override
+  public int getMaxColumnsInSelect()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxColumnsInSelect not supported");
+  }
+
+  @Override
+  public int getMaxColumnsInTable()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxColumnsInTable not supported");
+  }
+
+  @Override
+  public int getMaxConnections()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxConnections not supported");
+  }
+
+  @Override
+  public int getMaxCursorNameLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxCursorNameLength not supported");
+  }
+
+  @Override
+  public int getMaxIndexLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxIndexLength not supported");
+  }
+
+  @Override
+  public int getMaxSchemaNameLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxSchemaNameLength not supported");
+  }
+
+  @Override
+  public int getMaxProcedureNameLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxProcedureNameLength not supported");
+  }
+
+  @Override
+  public int getMaxCatalogNameLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxCatalogNameLength not supported");
+  }
+
+  @Override
+  public int getMaxRowSize()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxRowSize not supported");
+  }
+
+  @Override
+  public boolean doesMaxRowSizeIncludeBlobs()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("doesMaxRowSizeIncludeBlobs not supported");
+  }
+
+  @Override
+  public int getMaxStatementLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxStatementLength not supported");
+  }
+
+  @Override
+  public int getMaxStatements()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxStatements not supported");
+  }
+
+  @Override
+  public int getMaxTableNameLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxTableNameLength not supported");
+  }
+
+  @Override
+  public int getMaxTablesInSelect()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxTablesInSelect not supported");
+  }
+
+  @Override
+  public int getMaxUserNameLength()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getMaxUserNameLength not supported");
+  }
+
+  @Override
+  public int getDefaultTransactionIsolation()
+      throws SQLException {
+    return Connection.TRANSACTION_NONE;
+  }
+
+  @Override
+  public boolean dataDefinitionCausesTransactionCommit()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("dataDefinitionCausesTransactionCommit not supported");
+  }
+
+  @Override
+  public boolean dataDefinitionIgnoredInTransactions()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("dataDefinitionIgnoredInTransactions not supported");
+  }
+
+  @Override
+  public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("stored procedures not supported");
+  }
+
+  @Override
+  public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("stored procedures not supported");
+  }
+
+  /**
+   * Convert a pattern containing JDBC catalog search wildcards into
+   * Java regex patterns.
+   *
+   * @param pattern input which may contain '%' or '_' wildcard characters, or
+   * these characters escaped using {@link #getSearchStringEscape()}.
+   * @return replace %/_ with regex search characters, also handle escaped
+   * characters.
+   */
+  private String convertPattern(final String pattern) {
+    if (pattern == null) {
+      return ".*";
+    } else {
+      StringBuilder result = new StringBuilder(pattern.length());
+
+      boolean escaped = false;
+      for (int i = 0, len = pattern.length(); i < len; i++) {
+        char c = pattern.charAt(i);
+        if (escaped) {
+          if (c != SEARCH_STRING_ESCAPE) {
+            escaped = false;
+          }
+          result.append(c);
+        } else {
+          if (c == SEARCH_STRING_ESCAPE) {
+            escaped = true;
+            continue;
+          } else if (c == '%') {
+            result.append(".*");
+          } else if (c == '_') {
+            result.append('.');
+          } else {
+            result.append(Character.toLowerCase(c));
+          }
+        }
+      }
+
+      return result.toString();
+    }
+  }
+
+  @Override
+  public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
+      throws SQLException {
+    try {
+      final List<MetaDataTuple> resultTables = new ArrayList<MetaDataTuple>();
+      final String resultCatalog;
+      if (catalog == null) {
+        resultCatalog = "default";
+      } else {
+        resultCatalog = catalog;
+      }
+
+      String regtableNamePattern = convertPattern(tableNamePattern);
+      try {
+        TajoClient tajoClient = conn.getTajoClient();
+        List<String> tableNames = tajoClient.getTableList();
+        for (String eachTableName: tableNames) {
+          if (eachTableName.matches(regtableNamePattern)) {
+            MetaDataTuple tuple = new MetaDataTuple(5);
+
+            int index = 0;
+            tuple.put(index++, new TextDatum(resultCatalog));  //TABLE_CAT
+            tuple.put(index++, NullDatum.get());   //TABLE_SCHEM
+            tuple.put(index++, new TextDatum(eachTableName));
+            tuple.put(index++, new TextDatum("TABLE"));   //TABLE_TYPE
+            tuple.put(index++, NullDatum.get());   //REMARKS
+
+            resultTables.add(tuple);
+          }
+        }
+        Collections.sort(resultTables, new Comparator<MetaDataTuple> () {
+          @Override
+          public int compare(MetaDataTuple table1, MetaDataTuple table2) {
+            return table1.getString(2).compareTo(table2.getString(2));
+          }
+        });
+      } catch (Exception e) {
+        e.printStackTrace();
+        throw new SQLException(e);
+      }
+      TajoMetaDataResultSet result = new TajoMetaDataResultSet(
+          Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE", "REMARKS"),
+          Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR),
+          resultTables);
+
+      return result;
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new SQLException(e.getMessage(), e);
+    }
+  }
+
+  @Override
+  public ResultSet getSchemas()
+      throws SQLException {
+    return getSchemas(null, null);
+  }
+
+  @Override
+  public ResultSet getCatalogs()
+      throws SQLException {
+    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
+    MetaDataTuple tuple = new MetaDataTuple(1);
+    tuple.put(0, new TextDatum("default"));
+    columns.add(tuple);
+
+    ResultSet result = new TajoMetaDataResultSet(
+        Arrays.asList("TABLE_CAT")
+        , Arrays.asList(Type.VARCHAR)
+        , columns);
+
+    return result;
+  }
+
+  @Override
+  public ResultSet getTableTypes()
+      throws SQLException {
+    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
+    MetaDataTuple tuple = new MetaDataTuple(1);
+    tuple.put(0, new TextDatum("TABLE"));
+    columns.add(tuple);
+
+    ResultSet result = new TajoMetaDataResultSet(
+        Arrays.asList("TABLE_TYPE")
+        , Arrays.asList(Type.VARCHAR)
+        , columns);
+
+    return result;
+  }
+
+  @Override
+  public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
+      throws SQLException {
+    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
+
+    return new TajoMetaDataResultSet(
+        Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "CLASS_NAME", "DATA_TYPE"
+            , "REMARKS", "BASE_TYPE")
+        , Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.INT4, Type.VARCHAR, Type.INT4)
+        , columns);
+  }
+
+  @Override
+  public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
+      throws SQLException {
+    List<MetaDataTuple> columns = new ArrayList<MetaDataTuple>();
+    try {
+      if (catalog == null) {
+        catalog = "default";
+      }
+
+      String regtableNamePattern = convertPattern(tableNamePattern);
+      String regcolumnNamePattern = convertPattern(columnNamePattern);
+
+      List<String> tables = conn.getTajoClient().getTableList();
+      for (String table: tables) {
+        if (table.matches(regtableNamePattern)) {
+          TableDesc tableDesc = conn.getTajoClient().getTableDesc(table);
+          int pos = 0;
+          for (Column column: tableDesc.getSchema().getColumns()) {
+            if (column.getColumnName().matches(regcolumnNamePattern)) {
+              MetaDataTuple tuple = new MetaDataTuple(22);
+
+              int index = 0;
+              tuple.put(index++, new TextDatum(catalog));  //TABLE_CAT
+              tuple.put(index++, NullDatum.get());  //TABLE_SCHEM
+              tuple.put(index++, new TextDatum(table));  //TABLE_NAME
+              tuple.put(index++, new TextDatum(column.getColumnName()));  //COLUMN_NAME
+              // TODO - DATA_TYPE
+              tuple.put(index++, new TextDatum("" + ResultSetUtil.tajoTypeToSqlType(column.getDataType())));
+              tuple.put(index++, new TextDatum(ResultSetUtil.toSqlType(column.getDataType())));  //TYPE_NAME
+              tuple.put(index++, new TextDatum("0"));  //COLUMN_SIZE
+              tuple.put(index++, new TextDatum("0"));  //BUFFER_LENGTH
+              tuple.put(index++, new TextDatum("0"));  //DECIMAL_DIGITS
+              tuple.put(index++, new TextDatum("0"));  //NUM_PREC_RADIX
+              tuple.put(index++, new TextDatum("" + DatabaseMetaData.columnNullable));  //NULLABLE
+              tuple.put(index++, NullDatum.get());  //REMARKS
+              tuple.put(index++, NullDatum.get());  //COLUMN_DEF
+              tuple.put(index++, NullDatum.get());  //SQL_DATA_TYPE
+              tuple.put(index++, NullDatum.get());  //SQL_DATETIME_SUB
+              tuple.put(index++, new TextDatum("0"));  //CHAR_OCTET_LENGTH
+              tuple.put(index++, new TextDatum("" + pos));  //ORDINAL_POSITION
+              tuple.put(index++, new TextDatum("YES"));  //IS_NULLABLE
+              tuple.put(index++, NullDatum.get());  //SCOPE_CATLOG
+              tuple.put(index++, NullDatum.get());  //SCOPE_SCHEMA
+              tuple.put(index++, NullDatum.get());  //SCOPE_TABLE
+              tuple.put(index++, new TextDatum("0"));  //SOURCE_DATA_TYPE
+              columns.add(tuple);
+            }
+            pos++;
+          }
+        }
+      }
+
+      return new TajoMetaDataResultSet(
+          Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE"
+              , "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PREC_RADIX"
+              , "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB"
+              , "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE", "SCOPE_CATLOG", "SCOPE_SCHEMA"
+              , "SCOPE_TABLE", "SOURCE_DATA_TYPE")
+          , Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.INT4
+              , Type.VARCHAR, Type.INT4, Type.INT4, Type.INT4, Type.INT4
+              , Type.INT4, Type.VARCHAR, Type.VARCHAR, Type.INT4, Type.INT4
+              , Type.INT4, Type.INT4, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR
+              , Type.VARCHAR, Type.INT4)
+          , columns);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new SQLException(e);
+    }
+  }
+
+  @Override
+  public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("privileges not supported");
+  }
+
+  @Override
+  public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("privileges not supported");
+  }
+
+  @Override
+  public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("row identifiers not supported");
+  }
+
+  @Override
+  public ResultSet getVersionColumns(String catalog, String schema, String table)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("version columns not supported");
+  }
+
+  @Override
+  public ResultSet getPrimaryKeys(String catalog, String schema, String table)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("primary keys not supported");
+  }
+
+  @Override
+  public ResultSet getImportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("imported keys not supported");
+  }
+
+  @Override
+  public ResultSet getExportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("exported keys not supported");
+  }
+
+  @Override
+  public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("cross reference not supported");
+  }
+
+  @Override
+  public ResultSet getTypeInfo()
+      throws SQLException {
+    throw new UnsupportedOperationException("getTypeInfo not supported");
+  }
+
+  @Override
+  public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("indexes not supported");
+  }
+
+  @Override
+  public boolean deletesAreDetected(int type)
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean insertsAreDetected(int type)
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public Connection getConnection()
+      throws SQLException {
+    return conn;
+  }
+
+  @Override
+  public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("type hierarchies not supported");
+  }
+
+  @Override
+  public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("type hierarchies not supported");
+  }
+
+  @Override
+  public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("user-defined types not supported");
+  }
+
+  @Override
+  public int getResultSetHoldability()
+      throws SQLException {
+    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  @Override
+  public int getDatabaseMajorVersion()
+      throws SQLException {
+    return TajoDriver.MAJOR_VERSION;
+  }
+
+  @Override
+  public int getDatabaseMinorVersion()
+      throws SQLException {
+    return TajoDriver.MINOR_VERSION;
+  }
+
+  @Override
+  public int getJDBCMajorVersion()
+      throws SQLException {
+    return TajoDriver.JDBC_VERSION_MAJOR;
+  }
+
+  @Override
+  public int getJDBCMinorVersion()
+      throws SQLException {
+    return TajoDriver.JDBC_VERSION_MINOR;
+  }
+
+  @Override
+  public int getSQLStateType()
+      throws SQLException {
+    return DatabaseMetaData.sqlStateSQL;
+  }
+
+  @Override
+  public RowIdLifetime getRowIdLifetime()
+      throws SQLException {
+    return RowIdLifetime.ROWID_UNSUPPORTED;
+  }
+
+  @Override
+  public ResultSet getSchemas(String catalog, String schemaPattern)
+      throws SQLException {
+    return new TajoMetaDataResultSet(
+        Arrays.asList("TABLE_SCHEM", "TABLE_CATALOG"),
+        Arrays.asList(Type.VARCHAR, Type.VARCHAR),
+        null);
+  }
+
+  @Override
+  public boolean autoCommitFailureClosesAllResultSets()
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public ResultSet getClientInfoProperties()
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getClientInfoProperties not supported");
+  }
+
+  @Override
+  public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getFunctions not supported");
+  }
+
+  @Override
+  public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern)
+      throws SQLException {
+    throw new SQLFeatureNotSupportedException("getFunctionColumns not supported");
+  }
+
+  @Override
+  public boolean isCatalogAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean locatorsUpdateCopy() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullPlusNonNullIsNull() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedAtEnd() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean nullsAreSortedAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedHigh() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean nullsAreSortedLow() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean othersDeletesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean othersInsertsAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean othersUpdatesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean ownDeletesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean ownInsertsAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean ownUpdatesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesLowerCaseIdentifiers() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesMixedCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesUpperCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsANSI92FullSQL() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsANSI92IntermediateSQL() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsAlterTableWithAddColumn() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsAlterTableWithDropColumn() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsBatchUpdates() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsColumnAliasing() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean supportsConvert() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsConvert(int fromType, int toType) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCoreSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCorrelatedSubqueries() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDataDefinitionAndDataManipulationTransactions()
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsExpressionsInOrderBy() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsExtendedSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsFullOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGetGeneratedKeys() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGroupBy() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean supportsGroupByBeyondSelect() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGroupByUnrelated() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsLikeEscapeClause() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsLimitedOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMinimumSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMultipleOpenResults() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMultipleResultSets() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMultipleTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsNamedParameters() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsNonNullableColumns() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOrderByUnrelated() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsPositionedDelete() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsPositionedUpdate() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsResultSetConcurrency(int type, int concurrency)
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsResultSetHoldability(int holdability)
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsResultSetType(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSavepoints() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSelectForUpdate() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsStatementPooling() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsStoredProcedures() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInComparisons() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInExists() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInIns() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTableCorrelationNames() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTransactionIsolationLevel(int level)
+      throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsUnion() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsUnionAll() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean updatesAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean usesLocalFilePerTable() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean usesLocalFiles() throws SQLException {
+    return false;
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> T unwrap(Class<T> iface)
+      throws SQLException {
+    if (isWrapperFor(iface)) {
+      return (T) this;
+    }
+    throw new SQLFeatureNotSupportedException("No wrapper for " + iface);
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface)
+      throws SQLException {
+    return iface.isInstance(this);
+  }
+
+  public boolean generatedKeyAlwaysReturned() throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("generatedKeyAlwaysReturned not supported");
+  }
+
+  public ResultSet getPseudoColumns(String catalog, String schemaPattern,
+                                    String tableNamePattern, String columnNamePattern) throws SQLException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("getPseudoColumns not supported");
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDriver.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDriver.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDriver.java
new file mode 100644
index 0000000..03b45a6
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDriver.java
@@ -0,0 +1,89 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.conf.TajoConf;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.sql.*;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+public class TajoDriver implements Driver, Closeable {
+  public static final int MAJOR_VERSION = 1;
+  public static final int MINOR_VERSION = 0;
+
+  public static final int JDBC_VERSION_MAJOR = 4;
+  public static final int JDBC_VERSION_MINOR = 0;
+
+  public static final String TAJO_JDBC_URL_PREFIX = "jdbc:tajo://";
+
+  protected static TajoConf jdbcTajoConf;
+
+  static {
+    try {
+      DriverManager.registerDriver(new TajoDriver());
+    } catch (SQLException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+  }
+
+  public TajoDriver() {
+    jdbcTajoConf = new TajoConf();
+  }
+
+  @Override
+  public void close() throws IOException {
+  }
+
+  @Override
+  public Connection connect(String url, Properties properties) throws SQLException {
+    return new TajoConnection(url, properties);
+  }
+
+  @Override
+  public boolean acceptsURL(String url) throws SQLException {
+    return url.startsWith(TAJO_JDBC_URL_PREFIX);
+  }
+
+  @Override
+  public DriverPropertyInfo[] getPropertyInfo(String s, Properties properties) throws SQLException {
+    return new DriverPropertyInfo[0];
+  }
+
+  @Override
+  public int getMajorVersion() {
+    return MAJOR_VERSION;
+  }
+
+  @Override
+  public int getMinorVersion() {
+    return MINOR_VERSION;
+  }
+
+  @Override
+  public boolean jdbcCompliant() {
+    return false;
+  }
+
+  public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+    // JDK 1.7
+    throw new SQLFeatureNotSupportedException("getParentLogger not supported");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/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
new file mode 100644
index 0000000..fb0a834
--- /dev/null
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
@@ -0,0 +1,75 @@
+package org.apache.tajo.jdbc; /**
+ * 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.
+ */
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.storage.Tuple;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+
+public class TajoMetaDataResultSet extends TajoResultSetBase {
+  private List<MetaDataTuple> values;
+
+  public TajoMetaDataResultSet(List<String> columns, List<Type> types, List<MetaDataTuple> values) {
+    init();
+    schema = new Schema();
+
+    int index = 0;
+    if(columns != null) {
+      for(String columnName: columns) {
+        schema.addColumn(columnName, types.get(index++));
+      }
+    }
+    this.values = values;
+    totalRow = values == null ? 0 : values.size();
+  }
+
+  @Override
+  protected Tuple nextTuple() throws IOException {
+    if(curRow >= totalRow) {
+      return null;
+    }
+    return values.get(curRow);
+  }
+
+  @Override
+  public void close() throws SQLException {
+  }
+
+  @Override
+  public String getString(int fieldId) throws SQLException {
+    Datum datum = cur.get(fieldId - 1);
+    if(datum == null) {
+      return null;
+    }
+
+    return datum.asChars();
+  }
+
+  @Override
+  public String getString(String name) throws SQLException {
+    Datum datum = cur.get(findColumn(name));
+    if(datum == null) {
+      return null;
+    }
+    return datum.asChars();
+  }
+}


[3/6] TAJO-456: Separate tajo-jdbc and tajo-client from tajo-core-backend. (hyunsik)

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
deleted file mode 100644
index 1e75424..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoMetaDataResultSet.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.common.TajoDataTypes.Type;
-import org.apache.tajo.datum.Datum;
-import org.apache.tajo.storage.Tuple;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import java.util.List;
-
-public class TajoMetaDataResultSet extends TajoResultSetBase {
-  private List<MetaDataTuple> values;
-
-  public TajoMetaDataResultSet(List<String> columns, List<Type> types, List<MetaDataTuple> values) {
-    init();
-    schema = new Schema();
-
-    int index = 0;
-    if(columns != null) {
-      for(String columnName: columns) {
-        schema.addColumn(columnName, types.get(index++));
-      }
-    }
-    this.values = values;
-    totalRow = values == null ? 0 : values.size();
-  }
-
-  @Override
-  protected Tuple nextTuple() throws IOException {
-    if(curRow >= totalRow) {
-      return null;
-    }
-    return values.get(curRow);
-  }
-
-  @Override
-  public void close() throws SQLException {
-  }
-
-  @Override
-  public String getString(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    if(datum == null) {
-      return null;
-    }
-
-    return datum.asChars();
-  }
-
-  @Override
-  public String getString(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    if(datum == null) {
-      return null;
-    }
-    return datum.asChars();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
deleted file mode 100644
index a6e3bbf..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoPreparedStatement.java
+++ /dev/null
@@ -1,660 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.client.TajoClient;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.*;
-import java.util.Calendar;
-import java.util.HashMap;
-
-/**
- * TajoPreparedStatement.
- *
- */
-public class TajoPreparedStatement 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 final int updateCount = 0;
-
-  /**
-   *
-   */
-  public TajoPreparedStatement(TajoClient tajoClient,
-                               String sql) {
-    this.tajoClient = tajoClient;
-    this.sql = sql;
-  }
-
-  @Override
-  public void addBatch() throws SQLException {
-    throw new SQLFeatureNotSupportedException("addBatch");
-  }
-
-  @Override
-  public void clearParameters() throws SQLException {
-    this.parameters.clear();
-  }
-
-  @Override
-  public boolean execute() throws SQLException {
-    ResultSet rs = executeImmediate(sql);
-    return rs != null;
-  }
-
-  @Override
-  public ResultSet executeQuery() throws SQLException {
-    return executeImmediate(sql);
-  }
-
-  @Override
-  public int executeUpdate() throws SQLException {
-    executeImmediate(sql);
-    return updateCount;
-  }
-
-  protected ResultSet executeImmediate(String sql) throws SQLException {
-    if (isClosed) {
-      throw new SQLFeatureNotSupportedException("Can't execute after statement has been closed");
-    }
-
-    try {
-      if (sql.contains("?")) {
-        sql = updateSql(sql, parameters);
-      }
-      resultSet = tajoClient.executeQueryAndGetResult(sql);
-    } catch (Exception e) {
-      throw new SQLFeatureNotSupportedException(e.getMessage(), e);
-    }
-    return resultSet;
-  }
-
-  /**
-   * update the SQL string with parameters set by setXXX methods of {@link java.sql.PreparedStatement}
-   *
-   * @param sql
-   * @param parameters
-   * @return updated SQL string
-   */
-  private String updateSql(final String sql, HashMap<Integer, String> parameters) {
-
-    StringBuffer newSql = new StringBuffer(sql);
-
-    int paramLoc = 1;
-    while (getCharIndexFromSqlByParamLocation(sql, '?', paramLoc) > 0) {
-      // check the user has set the needs parameters
-      if (parameters.containsKey(paramLoc)) {
-        int tt = getCharIndexFromSqlByParamLocation(newSql.toString(), '?', 1);
-        newSql.deleteCharAt(tt);
-        newSql.insert(tt, parameters.get(paramLoc));
-      }
-      paramLoc++;
-    }
-
-    return newSql.toString();
-
-  }
-
-  /**
-   * Get the index of given char from the SQL string by parameter location
-   * </br> The -1 will be return, if nothing found
-   *
-   * @param sql
-   * @param cchar
-   * @param paramLoc
-   * @return
-   */
-  private int getCharIndexFromSqlByParamLocation(final String sql, final char cchar, final int paramLoc) {
-    int signalCount = 0;
-    int charIndex = -1;
-    int num = 0;
-    for (int i = 0; i < sql.length(); i++) {
-      char c = sql.charAt(i);
-      if (c == '\'' || c == '\\')// record the count of char "'" and char "\"
-      {
-        signalCount++;
-      } else if (c == cchar && signalCount % 2 == 0) {// check if the ? is really the parameter
-        num++;
-        if (num == paramLoc) {
-          charIndex = i;
-          break;
-        }
-      }
-    }
-    return charIndex;
-  }
-
-  @Override
-  public ResultSetMetaData getMetaData() throws SQLException {
-    if(resultSet != null) {
-      return resultSet.getMetaData();
-    } else {
-      return null;
-    }
-  }
-
-  @Override
-  public ParameterMetaData getParameterMetaData() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getParameterMetaData not supported");
-  }
-
-  @Override
-  public void setArray(int i, Array x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setArray not supported");
-  }
-
-  @Override
-  public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setAsciiStream not supported");
-  }
-
-  @Override
-  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setAsciiStream not supported");
-  }
-
-  @Override
-  public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setAsciiStream not supported");
-  }
-
-  @Override
-  public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBigDecimal not supported");
-  }
-
-  @Override
-  public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBinaryStream not supported");
-  }
-
-  @Override
-  public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBinaryStream not supported");
-  }
-
-  @Override
-  public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBinaryStream not supported");
-  }
-
-  @Override
-  public void setBlob(int i, Blob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBlob not supported");
-  }
-
-  @Override
-  public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBlob not supported");
-  }
-
-  @Override
-  public void setBlob(int parameterIndex, InputStream inputStream, long length)
-          throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBlob not supported");
-  }
-
-  @Override
-  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
-    this.parameters.put(parameterIndex, "" + x);
-  }
-
-  @Override
-  public void setByte(int parameterIndex, byte x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setByte not supported");
-  }
-
-  @Override
-  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setBytes not supported");
-  }
-
-  @Override
-  public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setCharacterStream not supported");
-  }
-
-  @Override
-  public void setCharacterStream(int parameterIndex, Reader reader, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("setCharacterStream not supported");
-  }
-
-  @Override
-  public void setCharacterStream(int parameterIndex, Reader reader, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("setCharacterStream not supported");
-  }
-
-  @Override
-  public void setClob(int i, Clob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setClob not supported");
-  }
-
-  @Override
-  public void setClob(int parameterIndex, Reader reader) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setClob not supported");
-  }
-
-  @Override
-  public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setClob not supported");
-  }
-
-  @Override
-  public void setDate(int parameterIndex, Date x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setDate not supported");
-  }
-
-  @Override
-  public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setDate not supported");
-  }
-
-  @Override
-  public void setDouble(int parameterIndex, double x) throws SQLException {
-    this.parameters.put(parameterIndex,"" + x);
-  }
-
-  @Override
-  public void setFloat(int parameterIndex, float x) throws SQLException {
-    this.parameters.put(parameterIndex,"" + x);
-  }
-
-  @Override
-  public void setInt(int parameterIndex, int x) throws SQLException {
-    this.parameters.put(parameterIndex,"" + x);
-  }
-
-  @Override
-  public void setLong(int parameterIndex, long x) throws SQLException {
-    this.parameters.put(parameterIndex,"" + x);
-  }
-
-  @Override
-  public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNCharacterStream not supported");
-  }
-
-  @Override
-  public void setNCharacterStream(int parameterIndex, Reader value, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNCharacterStream not supported");
-  }
-
-  @Override
-  public void setNClob(int parameterIndex, NClob value) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNClob not supported");
-  }
-
-  @Override
-  public void setNClob(int parameterIndex, Reader reader) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNClob not supported");
-  }
-
-  @Override
-  public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNClob not supported");
-  }
-
-  @Override
-  public void setNString(int parameterIndex, String value) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNString not supported");
-  }
-
-  @Override
-  public void setNull(int parameterIndex, int sqlType) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNull not supported");
-  }
-
-  @Override
-  public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setNull not supported");
-  }
-
-  @Override
-  public void setObject(int parameterIndex, Object x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setObject not supported");
-  }
-
-  @Override
-  public void setObject(int parameterIndex, Object x, int targetSqlType)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("setObject not supported");
-  }
-
-  @Override
-  public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("setObject not supported");
-  }
-
-  @Override
-  public void setRef(int i, Ref x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setRef not supported");
-  }
-
-  @Override
-  public void setRowId(int parameterIndex, RowId x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setRowId not supported");
-  }
-
-  @Override
-  public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setSQLXML not supported");
-  }
-
-  @Override
-  public void setShort(int parameterIndex, short x) throws SQLException {
-    this.parameters.put(parameterIndex,"" + x);
-  }
-
-  @Override
-  public void setString(int parameterIndex, String x) throws SQLException {
-     x=x.replace("'", "\\'");
-     this.parameters.put(parameterIndex,"'" + x +"'");
-  }
-
-  @Override
-  public void setTime(int parameterIndex, Time x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setTime not supported");
-  }
-
-  @Override
-  public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setTime not supported");
-  }
-
-  @Override
-  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setTimestamp not supported");
-  }
-
-  @Override
-  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("setTimestamp not supported");
-  }
-
-  @Override
-  public void setURL(int parameterIndex, URL x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setURL not supported");
-  }
-
-  @Override
-  public void setUnicodeStream(int parameterIndex, InputStream x, int length)
-      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 {
-     warningChain=null;
-  }
-
-  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 {
-    throw new SQLFeatureNotSupportedException("getConnection not supported");
-  }
-
-  @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 warningChain;
-  }
-
-  @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/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
deleted file mode 100644
index 1005765..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import com.google.common.collect.Lists;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileStatus;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.fs.PathFilter;
-import org.apache.tajo.QueryId;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.catalog.TableMeta;
-import org.apache.tajo.client.TajoClient;
-import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.storage.FileScanner;
-import org.apache.tajo.storage.MergeScanner;
-import org.apache.tajo.storage.Scanner;
-import org.apache.tajo.storage.Tuple;
-import org.apache.tajo.storage.fragment.FileFragment;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-
-public class TajoResultSet extends TajoResultSetBase {
-  private FileSystem fs;
-  private Scanner scanner;
-  private TajoClient tajoClient;
-  QueryId queryId;
-
-  public TajoResultSet(TajoClient tajoClient, QueryId queryId) {
-    this.tajoClient = tajoClient;
-    this.queryId = queryId;
-    init();
-  }
-
-  public TajoResultSet(TajoClient tajoClient, QueryId queryId,
-                       Configuration conf, TableDesc desc) throws IOException {
-    this.schema = desc.getSchema();
-    this.tajoClient = tajoClient;
-    this.queryId = queryId;
-    if(desc != null) {
-      fs = FileScanner.getFileSystem((TajoConf)conf, desc.getPath());
-      this.totalRow = desc.getStats() != null ? desc.getStats().getNumRows() : 0;
-
-      Collection<FileFragment> frags = getFragments(desc.getMeta(), desc.getPath());
-      scanner = new MergeScanner(conf, schema, desc.getMeta(), frags);
-    }
-    init();
-  }
-
-  @Override
-  protected void init() {
-    cur = null;
-    curRow = 0;
-  }
-
-  class FileNameComparator implements Comparator<FileStatus> {
-
-    @Override
-    public int compare(FileStatus f1, FileStatus f2) {
-      return f2.getPath().getName().compareTo(f1.getPath().getName());
-    }
-  }
-
-  private Collection<FileFragment> getFragments(TableMeta meta, Path tablePath)
-      throws IOException {
-    List<FileFragment> fraglist = Lists.newArrayList();
-    FileStatus[] files = fs.listStatus(tablePath, new PathFilter() {
-      @Override
-      public boolean accept(Path path) {
-        return path.getName().charAt(0) != '.';
-      }
-    });
-    Arrays.sort(files, new FileNameComparator());
-
-    String tbname = tablePath.getName();
-    for (int i = 0; i < files.length; i++) {
-      if (files[i].getLen() == 0) {
-        continue;
-      }
-      fraglist.add(new FileFragment(tbname + "_" + i, files[i].getPath(), 0l, files[i].getLen()));
-    }
-    return fraglist;
-  }
-
-  @Override
-  public void close() throws SQLException {
-    try {
-      if(tajoClient != null) {
-        this.tajoClient.closeQuery(queryId);
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-    try {
-      if(scanner != null) {
-        this.scanner.close();
-      }
-      //TODO clean temp result file
-      cur = null;
-      curRow = -1;
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-  }
-
-  @Override
-  public void beforeFirst() throws SQLException {
-    try {
-      if(scanner != null) {
-        scanner.reset();
-      }
-      init();
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-  }
-
-
-  @Override
-  protected Tuple nextTuple() throws IOException {
-    if(scanner == null) {
-      return null;
-    }
-    return scanner.next();
-  }
-
-  public boolean hasResult() {
-    return scanner != null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
deleted file mode 100644
index f4d685f..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.common.TajoDataTypes;
-import org.apache.tajo.datum.Datum;
-import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.storage.Tuple;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.*;
-import java.util.Calendar;
-import java.util.Map;
-
-public abstract class TajoResultSetBase implements ResultSet {
-  protected int curRow;
-  protected long totalRow;
-  protected boolean wasNull;
-  protected Schema schema;
-  protected Tuple cur;
-
-  protected void init() {
-    cur = null;
-    curRow = 0;
-    totalRow = 0;
-    wasNull = false;
-  }
-
-  private void handleNull(Datum d) {
-    wasNull = (d instanceof NullDatum);
-  }
-
-  @Override
-  public void beforeFirst() throws SQLException {
-    init();
-  }
-
-  @Override
-  public boolean getBoolean(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asBool();
-  }
-
-  @Override
-  public boolean getBoolean(String colName) throws SQLException {
-    Datum datum = cur.get(findColumn(colName));
-    handleNull(datum);
-    return datum.asBool();
-  }
-
-  @Override
-  public byte getByte(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asByte();
-  }
-
-  @Override
-  public byte getByte(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asByte();
-  }
-
-  @Override
-  public byte[] getBytes(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asByteArray();
-  }
-
-  @Override
-  public byte[] getBytes(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asByteArray();
-  }
-
-  @Override
-  public double getDouble(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asFloat8();
-  }
-
-  @Override
-  public double getDouble(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asFloat8();
-  }
-
-  @Override
-  public float getFloat(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asFloat4();
-  }
-
-  @Override
-  public float getFloat(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asFloat4();
-  }
-
-  @Override
-  public int getInt(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asInt4();
-  }
-
-  @Override
-  public int getInt(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asInt4();
-  }
-
-  @Override
-  public long getLong(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asInt8();
-  }
-
-  @Override
-  public long getLong(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asInt8();
-  }
-
-  @Override
-  public Object getObject(int fieldId) throws SQLException {
-    Datum d = cur.get(fieldId - 1);
-    handleNull(d);
-
-    TajoDataTypes.Type dataType = schema.getColumn(fieldId - 1).getDataType().getType();
-
-    switch(dataType) {
-      case BOOLEAN:  return d.asBool();
-      case INT1:
-      case INT2: return d.asInt2();
-      case INT4: return d.asInt4();
-      case INT8: return d.asInt8();
-      case TEXT:
-      case CHAR:
-      case DATE:
-      case VARCHAR:  return d.asChars();
-      case FLOAT4:  return d.asFloat4();
-      case FLOAT8:  return d.asFloat8();
-      case DECIMAL:
-      case NUMERIC:  return d.asFloat8();
-      default: return d.asChars();
-    }
-  }
-
-  @Override
-  public Object getObject(String name) throws SQLException {
-    return getObject(findColumn(name));
-  }
-
-  @Override
-  public short getShort(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asInt2();
-  }
-
-  @Override
-  public short getShort(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asInt2();
-  }
-
-  @Override
-  public String getString(int fieldId) throws SQLException {
-    Datum datum = cur.get(fieldId - 1);
-    handleNull(datum);
-    return datum.asChars();
-  }
-
-  @Override
-  public String getString(String name) throws SQLException {
-    Datum datum = cur.get(findColumn(name));
-    handleNull(datum);
-    return datum.asChars();
-  }
-
-  @Override
-  public boolean isWrapperFor(Class<?> clazz) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isWrapperFor not supported");
-  }
-
-  @Override
-  public <T> T unwrap(Class<T> clazz) throws SQLException {
-    throw new SQLFeatureNotSupportedException("unwrap not supported");
-  }
-
-  @Override
-  public boolean absolute(int row) throws SQLException {
-    throw new SQLFeatureNotSupportedException("absolute not supported");
-  }
-
-  @Override
-  public void afterLast() throws SQLException {
-    while (this.next())
-      ;
-  }
-
-  @Override
-  public void cancelRowUpdates() throws SQLException {
-    throw new SQLFeatureNotSupportedException("cancelRowUpdates not supported");
-  }
-
-  @Override
-  public void clearWarnings() throws SQLException {
-    throw new SQLFeatureNotSupportedException("clearWarnings not supported");
-  }
-
-  @Override
-  public void deleteRow() throws SQLException {
-    throw new SQLFeatureNotSupportedException("deleteRow not supported");
-  }
-
-  @Override
-  public int findColumn(String colName) throws SQLException {
-    return schema.getColumnIdByName(colName);
-  }
-
-  @Override
-  public boolean first() throws SQLException {
-    this.beforeFirst();
-    return this.next();
-  }
-
-  @Override
-  public Array getArray(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getArray not supported");
-  }
-
-  @Override
-  public Array getArray(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getArray not supported");
-  }
-
-  @Override
-  public InputStream getAsciiStream(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getAsciiStream not supported");
-  }
-
-  @Override
-  public InputStream getAsciiStream(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getAsciiStream not supported");
-  }
-
-  @Override
-  public BigDecimal getBigDecimal(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
-  }
-
-  @Override
-  public BigDecimal getBigDecimal(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
-  }
-
-  @Override
-  public BigDecimal getBigDecimal(int index, int x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
-  }
-
-  @Override
-  public BigDecimal getBigDecimal(String name, int x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBigDecimal not supported");
-  }
-
-  @Override
-  public InputStream getBinaryStream(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBinaryStream not supported");
-  }
-
-  @Override
-  public InputStream getBinaryStream(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBinaryStream not supported");
-  }
-
-  @Override
-  public Blob getBlob(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBlob not supported");
-  }
-
-  @Override
-  public Blob getBlob(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getBlob not supported");
-  }
-
-  @Override
-  public Reader getCharacterStream(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getCharacterStream not supported");
-  }
-
-  @Override
-  public Reader getCharacterStream(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getCharacterStream not supported");
-  }
-
-  @Override
-  public Clob getClob(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getClob not supported");
-  }
-
-  @Override
-  public Clob getClob(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getClob not supported");
-  }
-
-  @Override
-  public int getConcurrency() throws SQLException {
-    return ResultSet.CONCUR_READ_ONLY;
-  }
-
-  @Override
-  public String getCursorName() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getCursorName not supported");
-  }
-
-  @Override
-  public Date getDate(int index) throws SQLException {
-    Object obj = getObject(index);
-    if (obj == null) {
-      return null;
-    }
-
-    try {
-      return Date.valueOf((String) obj);
-    } catch (Exception e) {
-      throw new SQLException("Cannot convert column " + index
-          + " to date: " + e.toString());
-    }
-  }
-
-  @Override
-  public Date getDate(String name) throws SQLException {
-    return getDate(findColumn(name));
-  }
-
-  @Override
-  public Date getDate(int index, Calendar x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getDate not supported");
-  }
-
-  @Override
-  public Date getDate(String name, Calendar x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getDate not supported");
-  }
-
-  @Override
-  public int getFetchDirection() throws SQLException {
-    return ResultSet.FETCH_FORWARD;
-  }
-
-  @Override
-  public int getFetchSize() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFetchSize not supported");
-  }
-
-  @Override
-  public int getHoldability() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getHoldability not supported");
-  }
-
-  @Override
-  public ResultSetMetaData getMetaData() throws SQLException {
-    return new TajoResultSetMetaData(schema);
-  }
-
-  @Override
-  public Reader getNCharacterStream(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getNCharacterStream not supported");
-  }
-
-  @Override
-  public Reader getNCharacterStream(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getNCharacterStream not supported");
-  }
-
-  @Override
-  public NClob getNClob(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getNClob not supported");
-  }
-
-  @Override
-  public NClob getNClob(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getNClob not supported");
-  }
-
-  @Override
-  public String getNString(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getNString not supported");
-  }
-
-  @Override
-  public String getNString(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getNString not supported");
-  }
-
-  @Override
-  public Object getObject(int index, Map<String, Class<?>> x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getObject not supported");
-  }
-
-  @Override
-  public Object getObject(String name, Map<String, Class<?>> x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("getObject not supported");
-  }
-
-  public <T> T getObject(String name, Class<T> x)
-      throws SQLException {
-    //JDK 1.7
-    throw new SQLFeatureNotSupportedException("getObject not supported");
-  }
-
-  public <T> T getObject(int index, Class<T> x)
-      throws SQLException {
-    //JDK 1.7
-    throw new SQLFeatureNotSupportedException("getObject not supported");
-  }
-
-  @Override
-  public Ref getRef(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getRef not supported");
-  }
-
-  @Override
-  public Ref getRef(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getRef not supported");
-  }
-
-  @Override
-  public int getRow() throws SQLException {
-    return curRow;
-  }
-
-  @Override
-  public RowId getRowId(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getRowId not supported");
-  }
-
-  @Override
-  public RowId getRowId(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getRowId not supported");
-  }
-
-  @Override
-  public SQLXML getSQLXML(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getSQLXML not supported");
-  }
-
-  @Override
-  public SQLXML getSQLXML(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getSQLXML not supported");
-  }
-
-  @Override
-  public Statement getStatement() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getStatement not supported");
-  }
-
-  @Override
-  public Time getTime(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTime not supported");
-  }
-
-  @Override
-  public Time getTime(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTime not supported");
-  }
-
-  @Override
-  public Time getTime(int index, Calendar x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTime not supported");
-  }
-
-  @Override
-  public Time getTime(String name, Calendar x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTime not supported");
-  }
-
-  @Override
-  public Timestamp getTimestamp(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
-  }
-
-  @Override
-  public Timestamp getTimestamp(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
-  }
-
-  @Override
-  public Timestamp getTimestamp(int index, Calendar x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
-  }
-
-  @Override
-  public Timestamp getTimestamp(String name, Calendar x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getTimestamp not supported");
-  }
-
-  @Override
-  public int getType() throws SQLException {
-    return ResultSet.TYPE_FORWARD_ONLY;
-  }
-
-  @Override
-  public URL getURL(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getURL not supported");
-  }
-
-  @Override
-  public URL getURL(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getURL not supported");
-  }
-
-  @Override
-  public InputStream getUnicodeStream(int index) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getUnicodeStream not supported");
-  }
-
-  @Override
-  public InputStream getUnicodeStream(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getUnicodeStream not supported");
-  }
-
-  @Override
-  public SQLWarning getWarnings() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getWarnings not supported");
-  }
-
-  @Override
-  public void insertRow() throws SQLException {
-    throw new SQLFeatureNotSupportedException("insertRow not supported");
-  }
-
-  @Override
-  public boolean isAfterLast() throws SQLException {
-    return this.curRow > this.totalRow;
-  }
-
-  @Override
-  public boolean isBeforeFirst() throws SQLException {
-    return this.curRow == 0;
-  }
-
-  @Override
-  public boolean isClosed() throws SQLException {
-    return this.curRow == -1;
-  }
-
-  @Override
-  public boolean isFirst() throws SQLException {
-    return this.curRow == 1;
-  }
-
-  @Override
-  public boolean isLast() throws SQLException {
-    return this.curRow == this.totalRow;
-  }
-
-  @Override
-  public boolean last() throws SQLException {
-    Tuple last = null;
-    while (this.next()) {
-      last = cur;
-    }
-    cur = last;
-    return true;
-  }
-
-  @Override
-  public void moveToCurrentRow() throws SQLException {
-    throw new SQLFeatureNotSupportedException("moveToCurrentRow not supported");
-  }
-
-  @Override
-  public void moveToInsertRow() throws SQLException {
-    throw new SQLFeatureNotSupportedException("moveToInsertRow not supported");
-  }
-
-  @Override
-  public boolean next() throws SQLException {
-    try {
-      if (totalRow <= 0) {
-        return false;
-      }
-
-      cur = nextTuple();
-      curRow++;
-      if (cur != null) {
-        return true;
-      }
-    } catch (IOException e) {
-      throw new SQLException(e.getMessage());
-    }
-    return false;
-  }
-
-  protected abstract Tuple nextTuple() throws IOException;
-
-  @Override
-  public boolean previous() throws SQLException {
-    throw new SQLFeatureNotSupportedException("previous not supported");
-  }
-
-  @Override
-  public void refreshRow() throws SQLException {
-    throw new SQLFeatureNotSupportedException("refreshRow not supported");
-  }
-
-  @Override
-  public boolean relative(int rows) throws SQLException {
-    throw new SQLFeatureNotSupportedException("relative not supported");
-  }
-
-  @Override
-  public boolean rowDeleted() throws SQLException {
-    throw new SQLFeatureNotSupportedException("rowDeleted not supported");
-  }
-
-  @Override
-  public boolean rowInserted() throws SQLException {
-    throw new SQLFeatureNotSupportedException("rowInserted not supported");
-  }
-
-  @Override
-  public boolean rowUpdated() throws SQLException {
-    throw new SQLFeatureNotSupportedException("rowUpdated not supported");
-  }
-
-  @Override
-  public void setFetchDirection(int direction) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setFetchDirection not supported");
-  }
-
-  @Override
-  public void setFetchSize(int size) throws SQLException {
-    throw new SQLFeatureNotSupportedException("setFetchSize not supported");
-  }
-
-  @Override
-  public void updateArray(int index, Array x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateArray not supported");
-  }
-
-  @Override
-  public void updateArray(String name, Array x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateArray not supported");
-  }
-
-  @Override
-  public void updateAsciiStream(int index, InputStream x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
-  }
-
-  @Override
-  public void updateAsciiStream(String name, InputStream x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
-  }
-
-  @Override
-  public void updateAsciiStream(int index, InputStream x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
-  }
-
-  @Override
-  public void updateAsciiStream(String name, InputStream x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
-  }
-
-  @Override
-  public void updateAsciiStream(int index, InputStream x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
-  }
-
-  @Override
-  public void updateAsciiStream(String name, InputStream x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateAsciiStream not supported");
-  }
-
-  @Override
-  public void updateBigDecimal(int index, BigDecimal x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBigDecimal not supported");
-  }
-
-  @Override
-  public void updateBigDecimal(String name, BigDecimal x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBigDecimal not supported");
-  }
-
-  @Override
-  public void updateBinaryStream(int index, InputStream x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
-  }
-
-  @Override
-  public void updateBinaryStream(String name, InputStream x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
-  }
-
-  @Override
-  public void updateBinaryStream(int index, InputStream x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
-  }
-
-  @Override
-  public void updateBinaryStream(String name, InputStream x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
-  }
-
-  @Override
-  public void updateBinaryStream(int index, InputStream x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
-  }
-
-  @Override
-  public void updateBinaryStream(String name, InputStream x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBinaryStream not supported");
-  }
-
-  @Override
-  public void updateBlob(int index, Blob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBlob not supported");
-  }
-
-  @Override
-  public void updateBlob(String name, Blob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBlob not supported");
-  }
-
-  @Override
-  public void updateBlob(int index, InputStream x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBlob not supported");
-  }
-
-  @Override
-  public void updateBlob(String name, InputStream x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBlob not supported");
-  }
-
-  @Override
-  public void updateBlob(int index, InputStream x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBlob not supported");
-  }
-
-  @Override
-  public void updateBlob(String name, InputStream x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBlob not supported");
-  }
-
-  @Override
-  public void updateBoolean(int index, boolean x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBoolean not supported");
-  }
-
-  @Override
-  public void updateBoolean(String name, boolean x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateBoolean not supported");
-  }
-
-  @Override
-  public void updateByte(int index, byte x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateByte not supported");
-  }
-
-  @Override
-  public void updateByte(String name, byte x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateByte not supported");
-  }
-
-  @Override
-  public void updateBytes(int index, byte[] x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateByte not supported");
-  }
-
-  @Override
-  public void updateBytes(String name, byte[] x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateByte not supported");
-  }
-
-  @Override
-  public void updateCharacterStream(int index, Reader x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
-  }
-
-  @Override
-  public void updateCharacterStream(String name, Reader x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
-  }
-
-  @Override
-  public void updateCharacterStream(int index, Reader x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
-  }
-
-  @Override
-  public void updateCharacterStream(String name, Reader x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
-  }
-
-  @Override
-  public void updateCharacterStream(int index, Reader x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
-  }
-
-  @Override
-  public void updateCharacterStream(String name, Reader x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateCharacterStream not supported");
-  }
-
-  @Override
-  public void updateClob(int index, Clob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateClob not supported");
-  }
-
-  @Override
-  public void updateClob(String name, Clob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateClob not supported");
-  }
-
-  @Override
-  public void updateClob(int index, Reader x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateClob not supported");
-  }
-
-  @Override
-  public void updateClob(String name, Reader x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateClob not supported");
-  }
-
-  @Override
-  public void updateClob(int index, Reader x, long length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateClob not supported");
-  }
-
-  @Override
-  public void updateClob(String name, Reader x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateClob not supported");
-  }
-
-  @Override
-  public void updateDate(int index, Date x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateDate not supported");
-  }
-
-  @Override
-  public void updateDate(String name, Date x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateDate not supported");
-  }
-
-  @Override
-  public void updateDouble(int index, double x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateDouble not supported");
-  }
-
-  @Override
-  public void updateDouble(String name, double x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateDouble not supported");
-  }
-
-  @Override
-  public void updateFloat(int index, float x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateFloat not supported");
-  }
-
-  @Override
-  public void updateFloat(String name, float x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateFloat not supported");
-  }
-
-  @Override
-  public void updateInt(int index, int x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateInt not supported");
-  }
-
-  @Override
-  public void updateInt(String name, int x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateInt not supported");
-  }
-
-  @Override
-  public void updateLong(int index, long x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateLong not supported");
-  }
-
-  @Override
-  public void updateLong(String name, long x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateLong not supported");
-  }
-
-  @Override
-  public void updateNCharacterStream(int index, Reader x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
-  }
-
-  @Override
-  public void updateNCharacterStream(String name, Reader x)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
-  }
-
-  @Override
-  public void updateNCharacterStream(int index, Reader x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
-  }
-
-  @Override
-  public void updateNCharacterStream(String name, Reader x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNCharacterStream not supported");
-  }
-
-  @Override
-  public void updateNClob(int index, NClob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNClob not supported");
-  }
-
-  @Override
-  public void updateNClob(String name, NClob x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNClob not supported");
-  }
-
-  @Override
-  public void updateNClob(int index, Reader x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNClob not supported");
-  }
-
-  @Override
-  public void updateNClob(String name, Reader x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNClob not supported");
-  }
-
-  @Override
-  public void updateNClob(int index, Reader x, long length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNClob not supported");
-  }
-
-  @Override
-  public void updateNClob(String name, Reader x, long length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNClob not supported");
-  }
-
-  @Override
-  public void updateNString(int arg0, String x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNString not supported");
-  }
-
-  @Override
-  public void updateNString(String name, String x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNString not supported");
-  }
-
-  @Override
-  public void updateNull(int arg0) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNull not supported");
-  }
-
-  @Override
-  public void updateNull(String name) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateNull not supported");
-  }
-
-  @Override
-  public void updateObject(int index, Object x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateObject not supported");
-  }
-
-  @Override
-  public void updateObject(String name, Object x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateObject not supported");
-  }
-
-  @Override
-  public void updateObject(int index, Object x, int length) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateObject not supported");
-  }
-
-  @Override
-  public void updateObject(String name, Object x, int length)
-      throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateObject not supported");
-  }
-
-  @Override
-  public void updateRef(int index, Ref x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateRef not supported");
-  }
-
-  @Override
-  public void updateRef(String name, Ref x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateRef not supported");
-  }
-
-  @Override
-  public void updateRow() throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateRow not supported");
-  }
-
-  @Override
-  public void updateRowId(int index, RowId arg1) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateRowId not supported");
-  }
-
-  @Override
-  public void updateRowId(String name, RowId x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateRowId not supported");
-  }
-
-  @Override
-  public void updateSQLXML(int index, SQLXML arg1) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateSQLXML not supported");
-  }
-
-  @Override
-  public void updateSQLXML(String name, SQLXML x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateSQLXML not supported");
-
-  }
-
-  @Override
-  public void updateShort(int index, short x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateShort not supported");
-
-  }
-
-  @Override
-  public void updateShort(String name, short x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateShort not supported");
-
-  }
-
-  @Override
-  public void updateString(int index, String x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateString not supported");
-
-  }
-
-  @Override
-  public void updateString(String name, String arg1) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateString not supported");
-
-  }
-
-  @Override
-  public void updateTime(int index, Time x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateTime not supported");
-
-  }
-
-  @Override
-  public void updateTime(String name, Time x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateTime not supported");
-
-  }
-
-  @Override
-  public void updateTimestamp(int index, Timestamp x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateTimestamp not supported");
-
-  }
-
-  @Override
-  public void updateTimestamp(String name, Timestamp x) throws SQLException {
-    throw new SQLFeatureNotSupportedException("updateTimestamp not supported");
-
-  }
-
-  @Override
-  public boolean wasNull() throws SQLException {
-    return wasNull;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
deleted file mode 100644
index 5a04ad0..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * 
- */
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.common.TajoDataTypes.DataType;
-
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-
-public class TajoResultSetMetaData implements ResultSetMetaData {
-  Schema schema;
-
-  
-  public TajoResultSetMetaData(Schema schema) {
-    this.schema = schema;
-  }
-
-  @Override
-  public boolean isWrapperFor(Class<?> clazz) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isWrapperFor not supported");
-  }
-
-  @Override
-  public <T> T unwrap(Class<T> clazz) throws SQLException {
-    throw new SQLFeatureNotSupportedException("unwrap not supported");
-  }
-
-  @Override
-  public String getCatalogName(int column) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getCatalogName not supported");
-  }
-
-  @Override
-  public String getColumnClassName(int column) throws SQLException {
-    return schema.getColumn(column - 1).getClass().getName();
-  }
-
-  @Override
-  public int getColumnCount() throws SQLException {
-    if(schema == null) {
-      return 0;
-    }
-    return schema.getColumnNum();
-  }
-
-  @Override
-  public int getColumnDisplaySize(int column) throws SQLException {
-    return TajoDriver.columnDisplaySize(getColumnType(column));
-  }
-
-  @Override
-  public String getColumnLabel(int column) throws SQLException {
-    return schema.getColumn(column - 1).getQualifiedName();
-  }
-
-  @Override
-  public String getColumnName(int column) throws SQLException {
-    return schema.getColumn(column - 1).getColumnName();
-  }
-
-  @Override
-  public int getColumnType(int column) throws SQLException {
-    DataType type = schema.getColumn(column - 1).getDataType();
-
-    return TajoDriver.tajoTypeToSqlType(type);
-  }
-
-  @Override
-  public String getColumnTypeName(int column) throws SQLException {
-    DataType type = schema.getColumn(column - 1).getDataType();
-
-    return TajoDriver.toSqlType(type);
-  }
-
-  @Override
-  public int getPrecision(int column) throws SQLException {
-    return TajoDriver.columnDisplaySize(getColumnType(column));
-  }
-
-  @Override
-  public int getScale(int column) throws SQLException {
-    return TajoDriver.columnScale(getColumnType(column));
-  }
-
-  @Override
-  public String getSchemaName(int column) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getSchemaName not supported");
-  }
-
-  @Override
-  public String getTableName(int column) throws SQLException {
-    return schema.getColumn(column - 1).getQualifier();
-  }
-
-  @Override
-  public boolean isAutoIncrement(int column) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean isCaseSensitive(int column) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public boolean isCurrency(int column) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isCurrency not supported");
-  }
-
-  @Override
-  public boolean isDefinitelyWritable(int column) throws SQLException {
-    return false;
-  }
-
-  @Override
-  public int isNullable(int column) throws SQLException {
-    return ResultSetMetaData.columnNullable;
-  }
-
-  @Override
-  public boolean isReadOnly(int column) throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean isSearchable(int column) throws SQLException {
-    return true;
-  }
-
-  @Override
-  public boolean isSigned(int column) throws SQLException {
-    throw new SQLFeatureNotSupportedException("isSigned not supported");
-  }
-
-  @Override
-  public boolean isWritable(int column) throws SQLException {
-    return false;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoStatement.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
deleted file mode 100644
index 6002fcd..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/jdbc/TajoStatement.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.jdbc;
-
-import org.apache.tajo.client.TajoClient;
-
-import java.sql.*;
-
-public class TajoStatement implements Statement {
-  private TajoClient tajoClient;
-  private int fetchSize = 200;
-
-  /**
-   * 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;
-
-  public TajoStatement(TajoClient tajoClient) {
-    this.tajoClient = tajoClient;
-  }
-
-  @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 {
-    warningChain = null;
-  }
-
-  @Override
-  public void close() throws SQLException {
-    resultSet = null;
-    isClosed = true;
-  }
-
-  public void closeOnCompletion() throws SQLException {
-     // JDK 1.7
-     throw new SQLFeatureNotSupportedException("closeOnCompletion not supported");
-  }
-
-  @Override
-  public boolean execute(String sql) throws SQLException {
-    resultSet = executeQuery(sql);
-
-    return resultSet != null;
-  }
-
-  @Override
-  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute not supported");
-  }
-
-  @Override
-  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute not supported");
-  }
-
-  @Override
-  public boolean execute(String sql, String[] columnNames) throws SQLException {
-    throw new SQLFeatureNotSupportedException("execute not supported");
-  }
-
-  @Override
-  public int[] executeBatch() throws SQLException {
-    throw new SQLFeatureNotSupportedException("executeBatch not supported");
-  }
-
-  @Override
-  public ResultSet executeQuery(String sql) throws SQLException {
-    if (isClosed) {
-      throw new SQLFeatureNotSupportedException("Can't execute after statement has been closed");
-    }
-
-    try {
-      return tajoClient.executeQueryAndGetResult(sql);
-    } catch (Exception e) {
-      throw new SQLFeatureNotSupportedException(e.getMessage(), e);
-    }
-  }
-
-  @Override
-  public int executeUpdate(String sql) throws SQLException {
-    try {
-      tajoClient.executeQuery(sql);
-
-      return 1;
-    } catch (Exception ex) {
-      throw new SQLFeatureNotSupportedException(ex.toString());
-    }
-  }
-
-  @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 {
-    throw new SQLFeatureNotSupportedException("getConnection not supported");
-  }
-
-  @Override
-  public int getFetchDirection() throws SQLException {
-    throw new SQLFeatureNotSupportedException("getFetchDirection not supported");
-  }
-
-  @Override
-  public int getFetchSize() throws SQLException {
-    return fetchSize;
-  }
-
-  @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 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 0;
-  }
-
-  @Override
-  public SQLWarning getWarnings() throws SQLException {
-    return warningChain;
-  }
-
-  @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 {
-    fetchSize = rows;
-  }
-
-  @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/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/proto/ClientProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/proto/ClientProtos.proto b/tajo-core/tajo-core-backend/src/main/proto/ClientProtos.proto
deleted file mode 100644
index 0637023..0000000
--- a/tajo-core/tajo-core-backend/src/main/proto/ClientProtos.proto
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-option java_package = "org.apache.tajo.ipc";
-option java_outer_classname = "ClientProtos";
-option java_generic_services = true;
-option java_generate_equals_and_hash = true;
-
-import "yarn_protos.proto";
-import "tajo_protos.proto";
-import "TajoIdProtos.proto";
-import "CatalogProtos.proto";
-import "PrimitiveProtos.proto";
-
-enum ResultCode {
-  OK = 0;
-  ERROR = 1;
-}
-
-message UpdateSessionVariableRequest {
-  optional SessionIdProto sessionId = 1;
-  repeated KeyValueProto setVariables = 2;
-  repeated string unsetVariables = 3;
-}
-
-message QueryRequest {
-  optional SessionIdProto sessionId = 1;
-  required string query = 2;
-  repeated KeyValueProto setVariables = 3;
-}
-
-message UpdateQueryResponse {
-  required ResultCode resultCode = 1;
-  optional string errorMessage = 2;
-}
-
-message SubmitQueryResponse {
-  required ResultCode resultCode = 1;
-  optional QueryIdProto queryId = 2;
-  optional string errorMessage = 3;
-}
-
-message GetQueryResultRequest {
-  optional SessionIdProto sessionId = 1;
-  required QueryIdProto queryId = 2;
-}
-
-message GetQueryResultResponse {
-  optional TableDescProto tableDesc = 1;
-  optional string errorMessage = 2;
-  required string tajoUserName = 3;
-}
-
-message GetQueryListRequest {
-  optional SessionIdProto sessionId = 1;
-}
-
-message BriefQueryStatus {
-  required QueryIdProto queryId = 1;
-  required QueryState state = 2;
-  required int32 executionTime = 3;
-}
-
-message GetQueryListResponse {
-  repeated BriefQueryStatus queryList = 1;
-}
-
-message GetQueryStatusRequest {
-  optional SessionIdProto sessionId = 1;
-  required QueryIdProto queryId = 2;
-}
-
-message GetQueryStatusResponse {
-  required ResultCode resultCode = 1;
-  required QueryIdProto queryId = 2;
-  optional QueryState state = 3;
-  optional float progress = 4;
-  optional int64 submitTime = 5;
-  optional int64 finishTime = 7;
-  optional bool hasResult = 8;
-  optional string errorMessage = 9;
-  optional string queryMasterHost = 10;
-  optional int32 queryMasterPort = 11;
-}
-
-message GetClusterInfoRequest {
-  optional SessionIdProto sessionId = 1;
-}
-
-message GetClusterInfoResponse {
-  repeated string serverName = 1;
-}
-
-message GetTableListRequest {
-  optional SessionIdProto sessionId = 1;
-}
-
-message GetTableListResponse {
-  repeated string tables = 1;
-}
-
-message GetTableDescRequest {
-  optional SessionIdProto sessionId = 1;
-  required string tableName = 2;
-}
-
-message CreateTableRequest {
-  required string name = 1;
-  required SchemaProto schema = 2;
-  required TableProto meta = 3;
-  required string path = 4;
-  optional PartitionDescProto partitions = 5;
-}
-
-message DropTableRequest {
-  required string name = 1;
-  optional bool purge = 2 [default = false];
-}
-
-message TableResponse {
-  required ResultCode resultCode = 1;
-  optional TableDescProto tableDesc = 2;
-  optional string errorMessage = 3;
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/proto/QueryMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/proto/QueryMasterClientProtocol.proto b/tajo-core/tajo-core-backend/src/main/proto/QueryMasterClientProtocol.proto
deleted file mode 100644
index 7da83bc..0000000
--- a/tajo-core/tajo-core-backend/src/main/proto/QueryMasterClientProtocol.proto
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-option java_package = "org.apache.tajo.ipc";
-option java_outer_classname = "QueryMasterClientProtocol";
-option java_generic_services = true;
-option java_generate_equals_and_hash = true;
-
-import "yarn_protos.proto";
-import "tajo_protos.proto";
-import "TajoIdProtos.proto";
-import "CatalogProtos.proto";
-import "PrimitiveProtos.proto";
-import "ClientProtos.proto";
-
-service QueryMasterClientProtocolService {
-  rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto);
-  rpc getQueryResult(GetQueryResultRequest) returns (GetQueryResultResponse);
-  rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
-  rpc killQuery(QueryIdProto) returns (BoolProto);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/proto/TajoMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/proto/TajoMasterClientProtocol.proto b/tajo-core/tajo-core-backend/src/main/proto/TajoMasterClientProtocol.proto
deleted file mode 100644
index 94ea7bf..0000000
--- a/tajo-core/tajo-core-backend/src/main/proto/TajoMasterClientProtocol.proto
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//TajoClient -> TajoMaster Protocol
-option java_package = "org.apache.tajo.ipc";
-option java_outer_classname = "TajoMasterClientProtocol";
-option java_generic_services = true;
-option java_generate_equals_and_hash = true;
-
-import "yarn_protos.proto";
-import "tajo_protos.proto";
-import "TajoIdProtos.proto";
-import "CatalogProtos.proto";
-import "PrimitiveProtos.proto";
-import "ClientProtos.proto";
-
-service TajoMasterClientProtocolService {
-  rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto);
-  rpc submitQuery(QueryRequest) returns (GetQueryStatusResponse);
-  rpc updateQuery(QueryRequest) returns (UpdateQueryResponse);
-  rpc getQueryResult(GetQueryResultRequest) returns (GetQueryResultResponse);
-  rpc getQueryList(GetQueryListRequest) returns (GetQueryListResponse);
-  rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
-  rpc killQuery(QueryIdProto) returns (BoolProto);
-  rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse);
-  rpc existTable(StringProto) returns (BoolProto);
-  rpc getTableList(GetTableListRequest) returns (GetTableListResponse);
-  rpc getTableDesc(GetTableDescRequest) returns (TableResponse);
-  rpc createExternalTable(CreateTableRequest) returns (TableResponse);
-  rpc dropTable(DropTableRequest) returns (BoolProto);
-
-
-  // TODO - to be implemented
-  //
-  // authenticate
-  //
-  // getSessionVariableList
-  // dropTable
-  // detachTable
-  // createIndex
-  // dropIndex
-  // registerUDF
-  // dropUDF
-  // listUdfs
-  // getUDFDesc
-  // registerJars
-  // getListRegisteredJars
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/b6a5ff0c/tajo-core/tajo-core-backend/src/main/proto/tajo_protos.proto
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/proto/tajo_protos.proto b/tajo-core/tajo-core-backend/src/main/proto/tajo_protos.proto
deleted file mode 100644
index d337315..0000000
--- a/tajo-core/tajo-core-backend/src/main/proto/tajo_protos.proto
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-option java_package = "org.apache.tajo";
-option java_outer_classname = "TajoProtos";
-option java_generic_services = false;
-option java_generate_equals_and_hash = true;
-
-enum QueryState {
-  QUERY_MASTER_INIT = 0;
-  QUERY_MASTER_LAUNCHED = 1;
-  QUERY_NEW = 2;
-  QUERY_INIT = 3;
-  QUERY_RUNNING = 4;
-  QUERY_SUCCEEDED = 5;
-  QUERY_FAILED = 6;
-  QUERY_KILLED = 7;
-  QUERY_ERROR = 8;
-  QUERY_NOT_ASSIGNED = 9;
-}
-
-enum TaskAttemptState {
-  TA_NEW = 0;
-  TA_UNASSIGNED = 1;
-  TA_ASSIGNED = 2;
-  TA_PENDING = 3;
-  TA_RUNNING = 4;
-  TA_SUCCEEDED = 5;
-  TA_FAILED = 6;
-  TA_KILLED = 7;
-}
\ No newline at end of file