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:18:01 UTC

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

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);
-  }
-}