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 2014/03/25 02:36:23 UTC

[08/13] TAJO-353: Add Database support to Tajo. (hyunsik)

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
index 7fc6780..bf77f03 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
@@ -22,15 +22,16 @@ 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.hadoop.security.UserGroupInformation;
 import org.apache.tajo.QueryId;
 import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.TajoIdProtos;
 import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.annotation.Nullable;
 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.catalog.*;
 import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.cli.InvalidClientSessionException;
 import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.conf.TajoConf.ConfVars;
 import org.apache.tajo.ipc.ClientProtos.*;
@@ -40,11 +41,12 @@ 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.NettyClientBase;
+import org.apache.tajo.rpc.RpcConnectionPool;
 import org.apache.tajo.rpc.ServerCallable;
+import org.apache.tajo.util.NetUtils;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.sql.ResultSet;
@@ -54,39 +56,69 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 @ThreadSafe
-public class TajoClient {
+public class TajoClient implements Closeable {
   private final Log LOG = LogFactory.getLog(TajoClient.class);
 
   private final TajoConf conf;
 
-  private Map<QueryId, InetSocketAddress> queryMasterMap = new ConcurrentHashMap<QueryId, InetSocketAddress>();
+  private final Map<QueryId, InetSocketAddress> queryMasterMap = new ConcurrentHashMap<QueryId, InetSocketAddress>();
+
+  private final InetSocketAddress tajoMasterAddr;
+
+  private final RpcConnectionPool connPool;
 
-  private InetSocketAddress tajoMasterAddr;
+  private final String baseDatabase;
 
-  private RpcConnectionPool connPool;
+  private final UserGroupInformation userInfo;
+
+  private volatile TajoIdProtos.SessionIdProto sessionId;
 
   public TajoClient(TajoConf conf) throws IOException {
-    this(conf, NetUtils.createSocketAddr(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS)));
+    this(conf, NetUtils.createSocketAddr(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS)), null);
+  }
+
+  public TajoClient(TajoConf conf, String baseDatabase) throws IOException {
+    this(conf, NetUtils.createSocketAddr(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS)), baseDatabase);
   }
 
-  public TajoClient(TajoConf conf, InetSocketAddress addr) throws IOException {
+  public TajoClient(TajoConf conf, InetSocketAddress addr, @Nullable String baseDatabase) throws IOException {
     this.conf = conf;
     this.conf.set("tajo.disk.scheduler.report.interval", "0");
     this.tajoMasterAddr = addr;
     int workerNum = conf.getIntVar(TajoConf.ConfVars.RPC_CLIENT_WORKER_THREAD_NUM);
     //Don't share connection pool per client
     connPool = RpcConnectionPool.newPool(conf, getClass().getSimpleName(), workerNum);
+    userInfo = UserGroupInformation.getCurrentUser();
+    this.baseDatabase = baseDatabase;
+  }
+
+  public boolean isConnected() {
+    try {
+      return connPool.getConnection(tajoMasterAddr, TajoMasterClientProtocol.class, false).isConnected();
+    } catch (Exception e) {
+      return false;
+    }
   }
 
   public TajoClient(InetSocketAddress addr) throws IOException {
-    this(new TajoConf(), addr);
+    this(new TajoConf(), addr, null);
   }
 
-  public TajoClient(String hostname, int port) throws IOException {
-    this(new TajoConf(), NetUtils.createSocketAddr(hostname, port));
+  public TajoClient(String hostname, int port, String baseDatabase) throws IOException {
+    this(new TajoConf(), NetUtils.createSocketAddr(hostname, port), baseDatabase);
   }
 
+  @Override
   public void close() {
+    // remove session
+    try {
+      NettyClientBase client = connPool.getConnection(tajoMasterAddr, TajoMasterClientProtocol.class, false);
+      TajoMasterClientProtocolService.BlockingInterface tajoMaster = client.getStub();
+      tajoMaster.removeSession(null, sessionId);
+    } catch (Exception e) {
+      LOG.error(e);
+    }
+
     if(connPool != null) {
       connPool.shutdown();
     }
@@ -97,6 +129,10 @@ public class TajoClient {
     return conf;
   }
 
+  public UserGroupInformation getUserInfo() {
+    return userInfo;
+  }
+
   /**
    * Call to QueryMaster closing query resources
    * @param queryId
@@ -117,15 +153,134 @@ public class TajoClient {
     }
   }
 
+  private void checkSessionAndGet(NettyClientBase client) throws ServiceException {
+    if (sessionId == null) {
+      TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+      CreateSessionRequest.Builder builder = CreateSessionRequest.newBuilder();
+      builder.setUsername(userInfo.getUserName()).build();
+      if (baseDatabase != null) {
+        builder.setBaseDatabaseName(baseDatabase);
+      }
+      CreateSessionResponse response = tajoMasterService.createSession(null, builder.build());
+      if (response.getState() == CreateSessionResponse.ResultState.SUCCESS) {
+        sessionId = response.getSessionId();
+        LOG.info(String.format("Got session %s as a user '%s'.", sessionId.getId(), userInfo.getUserName()));
+      } else {
+        throw new InvalidClientSessionException(response.getMessage());
+      }
+    }
+  }
+
+  private SessionedStringProto convertSessionedString(String str) {
+    SessionedStringProto.Builder builder = SessionedStringProto.newBuilder();
+    builder.setSessionId(sessionId);
+    builder.setValue(str);
+    return builder.build();
+  }
+
+  public String getCurrentDatabase() throws ServiceException {
+    return new ServerCallable<String>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+
+      public String call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.getCurrentDatabase(null, sessionId).getValue();
+      }
+    }.withRetries();
+  }
+
+  public Boolean selectDatabase(final String databaseName) throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.selectDatabase(null, convertSessionedString(databaseName)).getValue();
+      }
+    }.withRetries();
+  }
+
+  public Boolean updateSessionVariables(final Map<String, String> variables) throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        Options options = new Options();
+        options.putAll(variables);
+        UpdateSessionVariableRequest request = UpdateSessionVariableRequest.newBuilder()
+            .setSessionId(sessionId)
+            .setSetVariables(options.getProto()).build();
+
+        return tajoMasterService.updateSessionVariables(null, request).getValue();
+      }
+    }.withRetries();
+  }
+
+  public Boolean unsetSessionVariables(final List<String> variables)  throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        UpdateSessionVariableRequest request = UpdateSessionVariableRequest.newBuilder()
+            .setSessionId(sessionId)
+            .addAllUnsetVariables(variables).build();
+        return tajoMasterService.updateSessionVariables(null, request).getValue();
+      }
+    }.withRetries();
+  }
+
+  public String getSessionVariable(final String varname) throws ServiceException {
+    return new ServerCallable<String>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+
+      public String call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.getSessionVariable(null, convertSessionedString(varname)).getValue();
+      }
+    }.withRetries();
+  }
+
+  public Boolean existSessionVariable(final String varname) throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.existSessionVariable(null, convertSessionedString(varname)).getValue();
+      }
+    }.withRetries();
+  }
+
+  public Map<String, String> getAllSessionVariables() throws ServiceException {
+    return new ServerCallable<Map<String, String>>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class,
+        false, true) {
+
+      public Map<String, String> call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        Options options = new Options(tajoMasterService.getAllSessionVariables(null, sessionId));
+        return options.getAllKeyValus();
+      }
+    }.withRetries();
+  }
+
   public ExplainQueryResponse explainQuery(final String sql) throws ServiceException {
     return new ServerCallable<ExplainQueryResponse>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public ExplainQueryResponse call(NettyClientBase client) throws ServiceException {
-        final ExplainQueryRequest.Builder builder = ExplainQueryRequest.newBuilder();
-        builder.setQuery(sql);
+        checkSessionAndGet(client);
 
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-        return tajoMasterService.explainQuery(null, builder.build());
+        return tajoMasterService.explainQuery(null, convertSessionedString(sql));
       }
     }.withRetries();
   }
@@ -140,9 +295,11 @@ public class TajoClient {
     return new ServerCallable<GetQueryStatusResponse>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public GetQueryStatusResponse call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
         final QueryRequest.Builder builder = QueryRequest.newBuilder();
+        builder.setSessionId(sessionId);
         builder.setQuery(sql);
-
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
         return tajoMasterService.submitQuery(null, builder.build());
       }
@@ -162,7 +319,10 @@ public class TajoClient {
     GetQueryStatusResponse response = new ServerCallable<GetQueryStatusResponse>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public GetQueryStatusResponse call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
         final QueryRequest.Builder builder = QueryRequest.newBuilder();
+        builder.setSessionId(sessionId);
         builder.setQuery(sql);
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
         return tajoMasterService.submitQuery(null, builder.build());
@@ -178,8 +338,7 @@ public class TajoClient {
   }
 
   public QueryStatus getQueryStatus(QueryId queryId) throws ServiceException {
-    GetQueryStatusRequest.Builder builder
-        = GetQueryStatusRequest.newBuilder();
+    GetQueryStatusRequest.Builder builder = GetQueryStatusRequest.newBuilder();
     builder.setQueryId(queryId.getProto());
 
     GetQueryStatusResponse res = null;
@@ -198,8 +357,11 @@ public class TajoClient {
     } else {
       NettyClientBase tmClient = null;
       try {
-        tmClient = connPool.getConnection(tajoMasterAddr,
-            TajoMasterClientProtocol.class, false);
+        tmClient = connPool.getConnection(tajoMasterAddr, TajoMasterClientProtocol.class, false);
+
+        checkSessionAndGet(tmClient);
+        builder.setSessionId(sessionId);
+
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub();
         res = tajoMasterService.getQueryStatus(null, builder.build());
 
@@ -315,9 +477,11 @@ public class TajoClient {
     return new ServerCallable<Boolean>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
         QueryRequest.Builder builder = QueryRequest.newBuilder();
+        builder.setSessionId(sessionId);
         builder.setQuery(sql);
-
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
         UpdateQueryResponse response = tajoMasterService.updateQuery(null, builder.build());
         if (response.getResultCode() == ResultCode.OK) {
@@ -332,6 +496,46 @@ public class TajoClient {
     }.withRetries();
   }
 
+  public boolean createDatabase(final String databaseName) throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.createDatabase(null, convertSessionedString(databaseName)).getValue();
+      }
+    }.withRetries();
+  }
+
+  public boolean existDatabase(final String databaseName) throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.existDatabase(null, convertSessionedString(databaseName)).getValue();
+      }
+    }.withRetries();
+  }
+
+  public boolean dropDatabase(final String databaseName) throws ServiceException {
+    return new ServerCallable<Boolean>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+      public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.dropDatabase(null, convertSessionedString(databaseName)).getValue();
+      }
+    }.withRetries();
+  }
+
+  public List<String> getAllDatabaseNames() throws ServiceException {
+    return new ServerCallable<List<String>>(connPool, tajoMasterAddr, TajoMasterClientProtocol.class, false, true) {
+      public List<String> call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        return tajoMasterService.getAllDatabases(null, sessionId).getValuesList();
+      }
+    }.withRetries();
+  }
+
   /**
    * Test for the existence of table in catalog data.
    * <p/>
@@ -344,11 +548,9 @@ public class TajoClient {
     return new ServerCallable<Boolean>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public Boolean call(NettyClientBase client) throws ServiceException {
-        StringProto.Builder builder = StringProto.newBuilder();
-        builder.setValue(name);
-
+        checkSessionAndGet(client);
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
-        return tajoMasterService.existTable(null, builder.build()).getValue();
+        return tajoMasterService.existTable(null, convertSessionedString(name)).getValue();
       }
     }.withRetries();
   }
@@ -358,9 +560,12 @@ public class TajoClient {
     return new ServerCallable<TableDesc>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
+        checkSessionAndGet(client);
+
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
         CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
+        builder.setSessionId(sessionId);
         builder.setName(name);
         builder.setSchema(schema.getProto());
         builder.setMeta(meta.getProto());
@@ -389,9 +594,12 @@ public class TajoClient {
     return new ServerCallable<Boolean>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public Boolean call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
         DropTableRequest.Builder builder = DropTableRequest.newBuilder();
+        builder.setSessionId(sessionId);
         builder.setName(tableName);
         builder.setPurge(purge);
         return tajoMasterService.dropTable(null, builder.build()).getValue();
@@ -404,9 +612,11 @@ public class TajoClient {
     return new ServerCallable<List<BriefQueryInfo>>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public List<BriefQueryInfo> call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
         GetQueryListRequest.Builder builder = GetQueryListRequest.newBuilder();
+        builder.setSessionId(sessionId);
         GetQueryListResponse res = tajoMasterService.getRunningQueryList(null, builder.build());
         return res.getQueryListList();
       }
@@ -420,6 +630,7 @@ public class TajoClient {
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
         GetQueryListRequest.Builder builder = GetQueryListRequest.newBuilder();
+        builder.setSessionId(sessionId);
         GetQueryListResponse res = tajoMasterService.getFinishedQueryList(null, builder.build());
         return res.getQueryListList();
       }
@@ -430,9 +641,12 @@ public class TajoClient {
     return new ServerCallable<List<WorkerResourceInfo>>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public List<WorkerResourceInfo> call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
         GetClusterInfoRequest.Builder builder = GetClusterInfoRequest.newBuilder();
+        builder.setSessionId(sessionId);
         GetClusterInfoResponse res = tajoMasterService.getClusterInfo(null, builder.build());
         return res.getWorkerListList();
       }
@@ -442,29 +656,41 @@ public class TajoClient {
   /**
    * Get a list of table names. All table and column names are
    * represented as lower-case letters.
+   *
+   * @param databaseName The database name to show all tables. If it is null, this method will show all tables
+   *                     in the current database of this session.
    */
-  public List<String> getTableList() throws ServiceException {
+  public List<String> getTableList(@Nullable final String databaseName) throws ServiceException {
     return new ServerCallable<List<String>>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public List<String> call(NettyClientBase client) throws ServiceException {
+        checkSessionAndGet(client);
+
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
         GetTableListRequest.Builder builder = GetTableListRequest.newBuilder();
+        builder.setSessionId(sessionId);
+        if (databaseName != null) {
+          builder.setDatabaseName(databaseName);
+        }
         GetTableListResponse res = tajoMasterService.getTableList(null, builder.build());
         return res.getTablesList();
       }
     }.withRetries();
   }
 
-  public TableDesc getTableDesc(final String tableName) throws SQLException, ServiceException {
+  public TableDesc getTableDesc(final String tableName) throws ServiceException {
     return new ServerCallable<TableDesc>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public TableDesc call(NettyClientBase client) throws ServiceException, SQLException {
+        checkSessionAndGet(client);
+
         TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
 
-        GetTableDescRequest.Builder build = GetTableDescRequest.newBuilder();
-        build.setTableName(tableName);
-        TableResponse res = tajoMasterService.getTableDesc(null, build.build());
+        GetTableDescRequest.Builder builder = GetTableDescRequest.newBuilder();
+        builder.setSessionId(sessionId);
+        builder.setTableName(tableName);
+        TableResponse res = tajoMasterService.getTableDesc(null, builder.build());
         if (res.getResultCode() == ResultCode.OK) {
           return CatalogUtil.newTableDesc(res.getTableDesc());
         } else {
@@ -484,7 +710,13 @@ public class TajoClient {
       /* send a kill to the TM */
       tmClient = connPool.getConnection(tajoMasterAddr, TajoMasterClientProtocol.class, false);
       TajoMasterClientProtocolService.BlockingInterface tajoMasterService = tmClient.getStub();
-      tajoMasterService.killQuery(null, queryId.getProto());
+
+      checkSessionAndGet(tmClient);
+
+      KillQueryRequest.Builder builder = KillQueryRequest.newBuilder();
+      builder.setSessionId(sessionId);
+      builder.setQueryId(queryId.getProto());
+      tajoMasterService.killQuery(null, builder.build());
 
       long currentTimeMillis = System.currentTimeMillis();
       long timeKillIssued = currentTimeMillis;
@@ -510,12 +742,11 @@ public class TajoClient {
     return new ServerCallable<List<CatalogProtos.FunctionDescProto>>(connPool, tajoMasterAddr,
         TajoMasterClientProtocol.class, false, true) {
       public List<CatalogProtos.FunctionDescProto> call(NettyClientBase client) throws ServiceException, SQLException {
-        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
+        checkSessionAndGet(client);
 
+        TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub();
         String paramFunctionName = functionName == null ? "" : functionName;
-
-        FunctionResponse res = tajoMasterService.getFunctionList(null,
-            StringProto.newBuilder().setValue(paramFunctionName).build());
+        FunctionResponse res = tajoMasterService.getFunctionList(null,convertSessionedString(paramFunctionName));
         if (res.getResultCode() == ResultCode.OK) {
           return res.getFunctionsList();
         } else {

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/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
index 486ff9f..9aaef8e 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/TajoDump.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoDump.java
@@ -18,21 +18,21 @@
 
 package org.apache.tajo.client;
 
-import com.google.common.collect.Lists;
 import com.google.protobuf.ServiceException;
 import org.apache.commons.cli.*;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.DDLBuilder;
 import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.util.Pair;
 
 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;
@@ -46,15 +46,10 @@ public class TajoDump {
 
   private static void printUsage() {
     HelpFormatter formatter = new HelpFormatter();
-    formatter.printHelp( "tajo_dump [options] [table_name]", options );
+    formatter.printHelp( "tajo_dump [options] [database 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);
-
+  private static Pair<String, Integer> getConnectionAddr(TajoConf conf, CommandLine cmd) {
     String hostName = null;
     Integer port = null;
     if (cmd.hasOption("h")) {
@@ -64,25 +59,44 @@ public class TajoDump {
       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]);
       }
     }
+    return new Pair<String, Integer>(hostName, port);
+  }
+
+  public static void main(String [] args) throws ParseException, IOException, ServiceException, SQLException {
+    final TajoConf conf = new TajoConf();
+    final CommandLineParser parser = new PosixParser();
+    final CommandLine cmd = parser.parse(options, args);
+    final Pair<String, Integer> hostAndPort = getConnectionAddr(conf, cmd);
+    final String hostName = hostAndPort.getFirst();
+    final Integer port = hostAndPort.getSecond();
+    final UserGroupInformation userInfo = UserGroupInformation.getCurrentUser();
+
+    String baseDatabaseName = null;
+    if (cmd.getArgList().size() > 0) {
+      baseDatabaseName = (String) cmd.getArgList().get(0);
+    }
+
+    boolean isDumpingAllDatabases = cmd.hasOption('a');
+
+    // Neither two choices
+    if (!isDumpingAllDatabases && baseDatabaseName == null) {
+      printUsage();
+      System.exit(-1);
+    }
 
     TajoClient client = null;
     if ((hostName == null) ^ (port == null)) {
-      System.err.println("ERROR: cannot find valid Tajo server address");
+      System.err.println("ERROR: cannot find any TajoMaster rpc address in arguments and tajo-site.xml.");
       System.exit(-1);
     } else if (hostName != null && port != null) {
       conf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
@@ -91,34 +105,53 @@ public class TajoDump {
       client = new TajoClient(conf);
     }
 
-    List<TableDesc> tableDescList = Lists.newArrayList();
+    PrintWriter writer = new PrintWriter(System.out);
 
-    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));
+    printHeader(writer, userInfo);
+
+    if (isDumpingAllDatabases) {
+      for (String databaseName : client.getAllDatabaseNames()) {
+        dumpDatabase(client, databaseName, writer);
       }
     } else {
-      printUsage();
+      dumpDatabase(client, baseDatabaseName, writer);
     }
+    client.close();
 
+    writer.flush();
+    writer.close();
+    System.exit(0);
+  }
 
-    Writer writer = new PrintWriter(System.out);
+  private static void printHeader(PrintWriter writer, UserGroupInformation userInfo) {
     writer.write("--\n");
     writer.write("-- Tajo database dump\n");
+    writer.write("--\n");
+    writer.write("-- Dump user: " + userInfo.getUserName() + "\n");
     writer.write("-- Dump date: " + toDateString() + "\n");
     writer.write("--\n");
     writer.write("\n");
-    for (TableDesc tableDesc : tableDescList) {
-      writer.write(DDLBuilder.buildDDL(tableDesc));
+  }
+
+  private static void dumpDatabase(TajoClient client, String databaseName, PrintWriter writer)
+      throws SQLException, ServiceException {
+    writer.write("\n");
+    writer.write("--\n");
+    writer.write(String.format("-- Database name: %s%n", databaseName));
+    writer.write("--\n");
+    writer.write("\n");
+    writer.write(String.format("CREATE DATABASE IF NOT EXISTS %s;", databaseName));
+    writer.write("\n");
+
+    for (String tableName : client.getTableList(databaseName)) {
+      TableDesc table = client.getTableDesc(CatalogUtil.buildFQName(databaseName, tableName));
+      if (table.isExternal()) {
+        writer.write(DDLBuilder.buildDDLForExternalTable(table));
+      } else {
+        writer.write(DDLBuilder.buildDDLForBaseTable(table));
+      }
       writer.write("\n\n");
     }
-    writer.flush();
-    writer.close();
-    System.exit(0);
   }
 
   private static String toDateString() {

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
index f4d685f..577fe0e 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java
@@ -51,6 +51,10 @@ public abstract class TajoResultSetBase implements ResultSet {
     wasNull = (d instanceof NullDatum);
   }
 
+  public Tuple getCurrentTuple() {
+    return cur;
+  }
+
   @Override
   public void beforeFirst() throws SQLException {
     init();

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/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
index 4f2e586..5b7f822 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java
@@ -21,6 +21,8 @@
  */
 package org.apache.tajo.jdbc;
 
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.client.ResultSetUtil;
 import org.apache.tajo.common.TajoDataTypes.DataType;
@@ -32,7 +34,7 @@ import java.sql.SQLFeatureNotSupportedException;
 public class TajoResultSetMetaData implements ResultSetMetaData {
   Schema schema;
 
-  
+
   public TajoResultSetMetaData(Schema schema) {
     this.schema = schema;
   }
@@ -49,7 +51,11 @@ public class TajoResultSetMetaData implements ResultSetMetaData {
 
   @Override
   public String getCatalogName(int column) throws SQLException {
-    throw new SQLFeatureNotSupportedException("getCatalogName not supported");
+    Column c = schema.getColumn(column - 1);
+    if (CatalogUtil.isFQColumnName(c.getQualifiedName())) {
+      return CatalogUtil.splitFQTableName(c.getQualifier())[0];
+    }
+    return "";
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-client/src/main/proto/ClientProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto
index c0c9462..6e69a66 100644
--- a/tajo-client/src/main/proto/ClientProtos.proto
+++ b/tajo-client/src/main/proto/ClientProtos.proto
@@ -31,14 +31,30 @@ enum ResultCode {
   ERROR = 1;
 }
 
+message CreateSessionRequest {
+  required string username = 1;
+  optional string baseDatabaseName = 2;
+}
+
+message CreateSessionResponse {
+  enum ResultState {
+      SUCCESS = 0;
+      FAILED = 1;
+  }
+  required ResultState state = 1;
+  optional SessionIdProto sessionId = 2;
+  optional string message = 3;
+}
+
 message UpdateSessionVariableRequest {
   optional SessionIdProto sessionId = 1;
-  repeated KeyValueProto setVariables = 2;
+  optional KeyValueSetProto setVariables = 2;
   repeated string unsetVariables = 3;
 }
 
-message ExplainQueryRequest {
-  required string query = 1;
+message SessionedStringProto {
+  optional SessionIdProto sessionId = 1;
+  required string value = 2;
 }
 
 message ExplainQueryResponse {
@@ -75,6 +91,11 @@ message GetQueryResultResponse {
   required string tajoUserName = 3;
 }
 
+message KillQueryRequest {
+  optional SessionIdProto sessionId = 1;
+  required QueryIdProto queryId = 2;
+}
+
 message GetQueryListRequest {
   optional SessionIdProto sessionId = 1;
 }
@@ -146,6 +167,7 @@ message GetClusterInfoResponse {
 
 message GetTableListRequest {
   optional SessionIdProto sessionId = 1;
+  optional string databaseName = 2;
 }
 
 message GetTableListResponse {
@@ -158,16 +180,18 @@ message GetTableDescRequest {
 }
 
 message CreateTableRequest {
-  required string name = 1;
-  required SchemaProto schema = 2;
-  required TableProto meta = 3;
-  required string path = 4;
-  optional PartitionMethodProto partition = 5;
+  optional SessionIdProto sessionId = 1;
+  required string name = 2;
+  required SchemaProto schema = 3;
+  required TableProto meta = 4;
+  required string path = 5;
+  optional PartitionMethodProto partition = 6;
 }
 
 message DropTableRequest {
-  required string name = 1;
-  optional bool purge = 2 [default = false];
+  optional SessionIdProto sessionId = 1;
+  required string name = 2;
+  optional bool purge = 3 [default = false];
 }
 
 message TableResponse {

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
index 93e5af9..3bfd9df 100644
--- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
+++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto
@@ -29,34 +29,41 @@ import "PrimitiveProtos.proto";
 import "ClientProtos.proto";
 
 service TajoMasterClientProtocolService {
+
+  // Session APIs
+  rpc createSession(CreateSessionRequest) returns (CreateSessionResponse);
+  rpc removeSession(SessionIdProto) returns (BoolProto);
   rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto);
+  rpc existSessionVariable(SessionedStringProto) returns (BoolProto);
+  rpc getSessionVariable(SessionedStringProto) returns (StringProto);
+  rpc getAllSessionVariables(SessionIdProto) returns (KeyValueSetProto);
+
+  // Query Submission and Result APIs
+  rpc explainQuery(SessionedStringProto) returns (ExplainQueryResponse);
   rpc submitQuery(QueryRequest) returns (GetQueryStatusResponse);
   rpc updateQuery(QueryRequest) returns (UpdateQueryResponse);
-  rpc explainQuery(ExplainQueryRequest) returns (ExplainQueryResponse);
   rpc getQueryResult(GetQueryResultRequest) returns (GetQueryResultResponse);
+
+  // Query And Resource Management APIs
+  rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
   rpc getRunningQueryList(GetQueryListRequest) returns (GetQueryListResponse);
   rpc getFinishedQueryList(GetQueryListRequest) returns (GetQueryListResponse);
-  rpc getQueryStatus(GetQueryStatusRequest) returns (GetQueryStatusResponse);
-  rpc killQuery(QueryIdProto) returns (BoolProto);
+  rpc killQuery(KillQueryRequest) returns (BoolProto);
   rpc getClusterInfo(GetClusterInfoRequest) returns (GetClusterInfoResponse);
-  rpc existTable(StringProto) returns (BoolProto);
-  rpc getTableList(GetTableListRequest) returns (GetTableListResponse);
-  rpc getTableDesc(GetTableDescRequest) returns (TableResponse);
+
+  // Database Management APIs
+  rpc createDatabase(SessionedStringProto) returns (BoolProto);
+  rpc existDatabase(SessionedStringProto) returns (BoolProto);
+  rpc dropDatabase(SessionedStringProto) returns (BoolProto);
+  rpc getAllDatabases(SessionIdProto) returns (StringListProto);
+  rpc getCurrentDatabase(SessionIdProto) returns (StringProto);
+  rpc selectDatabase(SessionedStringProto) returns (BoolProto);
+
+  // Table Management APIs
   rpc createExternalTable(CreateTableRequest) returns (TableResponse);
+  rpc existTable(SessionedStringProto) returns (BoolProto);
   rpc dropTable(DropTableRequest) returns (BoolProto);
-  rpc getFunctionList(StringProto) returns (FunctionResponse);
-
-  // TODO - to be implemented
-  //
-  // authenticate
-  //
-  // getSessionVariableList
-  // detachTable
-  // createIndex
-  // dropIndex
-  // registerUDF
-  // dropUDF
-  // getUDFDesc
-  // registerJars
-  // getListRegisteredJars
+  rpc getTableList(GetTableListRequest) returns (GetTableListResponse);
+  rpc getTableDesc(GetTableDescRequest) returns (TableResponse);
+  rpc getFunctionList(SessionedStringProto) returns (FunctionResponse);
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/TajoConstants.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/TajoConstants.java b/tajo-common/src/main/java/org/apache/tajo/TajoConstants.java
index d4ce48f..61eecd1 100644
--- a/tajo-common/src/main/java/org/apache/tajo/TajoConstants.java
+++ b/tajo-common/src/main/java/org/apache/tajo/TajoConstants.java
@@ -27,6 +27,11 @@ public class TajoConstants {
   public static final String SYSTEM_RESOURCE_DIR_NAME = "resource";
   public static final String RESULT_DIR_NAME="RESULT";
 
+  public static final String DEFAULT_TABLESPACE_NAME = "default";
+  public static final String DEFAULT_DATABASE_NAME = "default";
+  public static final String DEFAULT_SCHEMA_NAME = "public";
+
+
   public static final String EMPTY_STRING = "";
 
   private TajoConstants() {}

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/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 3ca17a0..befaa98 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
@@ -234,6 +234,11 @@ public class TajoConf extends Configuration {
     TASK_DEFAULT_SIZE("tajo.task.size-mb", 128),
     //////////////////////////////////
 
+    //////////////////////////////////
+    // User Session Configuration
+    //////////////////////////////////
+    CLIENT_SESSION_EXPIRY_TIME("tajo.client.session.expiry-time-sec", 3600), // default time is one hour.
+
     // Metrics
     METRICS_PROPERTY_FILENAME("tajo.metrics.property.file", "tajo-metrics.properties"),
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/util/CommonTestingUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/CommonTestingUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/CommonTestingUtil.java
index cae7129..8dd8bfe 100644
--- a/tajo-common/src/main/java/org/apache/tajo/util/CommonTestingUtil.java
+++ b/tajo-common/src/main/java/org/apache/tajo/util/CommonTestingUtil.java
@@ -55,8 +55,9 @@ public class CommonTestingUtil {
     String randomStr = UUID.randomUUID().toString();
     Path path = new Path("target/test-data", randomStr);
     FileSystem fs = FileSystem.getLocal(new Configuration());
-    if(fs.exists(path))
+    if(fs.exists(path)) {
       fs.delete(path, true);
+    }
 
     fs.mkdirs(path);
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/FileUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/FileUtil.java
index 778bcbb..6bbce04 100644
--- a/tajo-common/src/main/java/org/apache/tajo/util/FileUtil.java
+++ b/tajo-common/src/main/java/org/apache/tajo/util/FileUtil.java
@@ -19,13 +19,11 @@
 package org.apache.tajo.util;
 
 import com.google.protobuf.Message;
-import org.apache.hadoop.fs.FSDataInputStream;
-import org.apache.hadoop.fs.FSDataOutputStream;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.*;
 import org.apache.hadoop.io.IOUtils;
 
 import java.io.*;
+import java.nio.charset.Charset;
 
 public class FileUtil {
   public static void writeProto(File file, Message proto) throws IOException {
@@ -83,6 +81,22 @@ public class FileUtil {
     return new File(path);
   }
 
+  public static String readTextFileFromResource(String resource) throws IOException {
+    StringBuilder fileData = new StringBuilder(1000);
+    InputStream inputStream = ClassLoader.getSystemResourceAsStream(resource);
+    byte[] buf = new byte[1024];
+    int numRead;
+    try {
+      while ((numRead = inputStream.read(buf)) != -1) {
+        String readData = new String(buf, 0, numRead, Charset.defaultCharset());
+        fileData.append(readData);
+      }
+    } finally {
+      IOUtils.cleanup(null, inputStream);
+    }
+    return fileData.toString();
+  }
+
   public static String readTextFile(File file) throws IOException {
     StringBuilder fileData = new StringBuilder(1000);
     BufferedReader reader = new BufferedReader(new FileReader(file));

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/util/Pair.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/Pair.java b/tajo-common/src/main/java/org/apache/tajo/util/Pair.java
new file mode 100644
index 0000000..72cfc5c
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/util/Pair.java
@@ -0,0 +1,37 @@
+/**
+ * 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.util;
+
+public class Pair<T1, T2> {
+  private final T1 value1;
+  private final T2 value2;
+
+  public Pair(T1 value1, T2 value2) {
+    this.value1 = value1;
+    this.value2 = value2;
+  }
+
+  public T1 getFirst() {
+    return value1;
+  }
+
+  public T2 getSecond() {
+    return value2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/util/ProtoBufUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/ProtoBufUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/ProtoBufUtil.java
deleted file mode 100644
index 0dc7f24..0000000
--- a/tajo-common/src/main/java/org/apache/tajo/util/ProtoBufUtil.java
+++ /dev/null
@@ -1,26 +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.util;
-
-import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.BoolProto;
-
-public class ProtoBufUtil {
-  public static final BoolProto TRUE = BoolProto.newBuilder().setValue(true).build();
-  public static final BoolProto FALSE = BoolProto.newBuilder().setValue(true).build();
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java
new file mode 100644
index 0000000..90ffb64
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java
@@ -0,0 +1,42 @@
+/**
+ * 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.util;
+
+import java.util.Collection;
+
+import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.*;
+
+public class ProtoUtil {
+  public static final BoolProto TRUE = BoolProto.newBuilder().setValue(true).build();
+  public static final BoolProto FALSE = BoolProto.newBuilder().setValue(false).build();
+
+  public static final NullProto NULL_PROTO = NullProto.newBuilder().build();
+
+  public static StringProto convertString(String value) {
+    return StringProto.newBuilder().setValue(value).build();
+  }
+
+  public static StringListProto convertStrings(Collection<String> strings) {
+    return StringListProto.newBuilder().addAllValues(strings).build();
+  }
+
+  public static Collection<String> convertStrings(StringListProto strings) {
+    return strings.getValuesList();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
index b5aa61c..ad60a50 100644
--- a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
+++ b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
@@ -54,4 +54,12 @@ public class StringUtils {
     }
     return buf.toString();
   }
+
+  public static String quote(String str) {
+    return "'" + str + "'";
+  }
+
+  public static String doubleQuote(String str) {
+    return "\"" + str + "\"";
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/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 1eb55bc..e116000 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
@@ -213,4 +213,16 @@ public class TUtil {
     T array = (T) Array.newInstance(type, collection.size());
     return collection.toArray((T[]) array);
   }
+
+  /**
+   * It returns the exact code point at which this running thread is executed.
+   *
+   * @param depth in the call stack (0 means current method, 1 means call method, ...)
+   * @return A string including class name, method, and line.
+   */
+  public static String getCurrentCodePoint(final int depth) {
+    final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
+    StackTraceElement element = ste[2 + depth];
+    return element.getClassName() + ":" + element.getMethodName() + "(" + element.getLineNumber() +")";
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/proto/PrimitiveProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/proto/PrimitiveProtos.proto b/tajo-common/src/main/proto/PrimitiveProtos.proto
index e722190..820f96c 100644
--- a/tajo-common/src/main/proto/PrimitiveProtos.proto
+++ b/tajo-common/src/main/proto/PrimitiveProtos.proto
@@ -39,3 +39,7 @@ message BoolProto {
 
 message NullProto {
 }
+
+message StringListProto {
+  repeated string values = 1;
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-common/src/main/proto/TajoIdProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/proto/TajoIdProtos.proto b/tajo-common/src/main/proto/TajoIdProtos.proto
index a87c825..1fb8bbd 100644
--- a/tajo-common/src/main/proto/TajoIdProtos.proto
+++ b/tajo-common/src/main/proto/TajoIdProtos.proto
@@ -42,5 +42,5 @@ message QueryUnitAttemptIdProto {
 }
 
 message SessionIdProto {
-  required string sid = 1;
+  required string id = 1;
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/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 d073736..1a67fa7 100644
--- a/tajo-core/tajo-core-backend/pom.xml
+++ b/tajo-core/tajo-core-backend/pom.xml
@@ -68,7 +68,7 @@
           <systemProperties>
             <tajo.test>TRUE</tajo.test>
           </systemProperties>
-          <argLine>-Xms512m -Xmx1024m -Dfile.encoding=UTF-8</argLine>
+          <argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=128m -Dfile.encoding=UTF-8</argLine>
         </configuration>
       </plugin>
       <plugin>
@@ -501,6 +501,214 @@
         </plugins>
       </build>
     </profile>
+    <profile>
+      <id>hcatalog-0.12.0</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>org.apache.thrift</groupId>
+          <artifactId>libfb303</artifactId>
+          <version>0.9.0</version>
+          <scope>test</scope>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.thrift</groupId>
+          <artifactId>libthrift</artifactId>
+          <version>0.9.0</version>
+          <scope>test</scope>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.tajo</groupId>
+          <artifactId>tajo-hcatalog</artifactId>
+          <scope>test</scope>
+          <version>${tajo.version}</version>
+          <exclusions>
+            <exclusion>
+              <groupId>com.google.protobuf</groupId>
+              <artifactId>protobuf-java</artifactId>
+            </exclusion>
+          </exclusions>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.hive</groupId>
+          <artifactId>hive-exec</artifactId>
+          <version>0.12.0</version>
+          <scope>provided</scope>
+          <exclusions>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-common</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-contrib</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-hbase-handler</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-metastore</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-serde</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-shims</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-testutils</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.thrift</groupId>
+              <artifactId>libfb303</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.thrift</groupId>
+              <artifactId>libthrift</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.jolbox</groupId>
+              <artifactId>bonecp</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hbase</groupId>
+              <artifactId>hbase</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.google.protobuf</groupId>
+              <artifactId>protobuf-java</artifactId>
+            </exclusion>
+          </exclusions>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.hive</groupId>
+          <artifactId>hive-metastore</artifactId>
+          <version>0.12.0</version>
+          <scope>provided</scope>
+          <exclusions>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-common</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-serde</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-shimss</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.thrift</groupId>
+              <artifactId>libfb303</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.thrift</groupId>
+              <artifactId>libthrift</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.jolbox</groupId>
+              <artifactId>bonecp</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.google.protobuf</groupId>
+              <artifactId>protobuf-java</artifactId>
+            </exclusion>
+          </exclusions>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.hive</groupId>
+          <artifactId>hive-cli</artifactId>
+          <version>0.12.0</version>
+          <scope>provided</scope>
+          <exclusions>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-common</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-exec</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-metastore</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-serde</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-service</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-shims</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.jolbox</groupId>
+              <artifactId>bonecp</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.google.protobuf</groupId>
+              <artifactId>protobuf-java</artifactId>
+            </exclusion>
+          </exclusions>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.hive.hcatalog</groupId>
+          <artifactId>hcatalog-core</artifactId>
+          <version>0.12.0</version>
+          <scope>provided</scope>
+          <exclusions>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-cli</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-common</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-exec</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-metastore</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-serde</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-service</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>org.apache.hive</groupId>
+              <artifactId>hive-shims</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.jolbox</groupId>
+              <artifactId>bonecp</artifactId>
+            </exclusion>
+            <exclusion>
+              <groupId>com.google.protobuf</groupId>
+              <artifactId>protobuf-java</artifactId>
+            </exclusion>
+          </exclusions>
+        </dependency>
+      </dependencies>
+    </profile>
   </profiles>
 
   <reporting>

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
index 1ceaca8..8966fd3 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
@@ -202,6 +202,7 @@ COUNT : C O U N T;
 CUBE : C U B E;
 
 DAY : D A Y;
+DATABASE : D A T A B A S E;
 DEC : D E C;
 DECADE : D E C A D E;
 DOW : D O W;
@@ -225,6 +226,7 @@ GROUPING : G R O U P I N G;
 HASH : H A S H;
 HOUR : H O U R;
 
+IF : I F;
 INDEX : I N D E X;
 INSERT : I N S E R T;
 INTERSECTION : I N T E R S E C T I O N;

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
index 71c16f2..4dada45 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
@@ -54,7 +54,9 @@ data_change_statement
   ;
 
 schema_statement
-  : create_table_statement
+  : database_definition
+  | drop_database_statement
+  | create_table_statement
   | drop_table_statement
   ;
 
@@ -63,12 +65,28 @@ index_statement
     LEFT_PAREN s=sort_specifier_list RIGHT_PAREN p=param_clause?
   ;
 
+database_definition
+  : CREATE DATABASE (if_not_exists)? dbname = identifier
+  ;
+
+if_not_exists
+  : IF NOT EXISTS
+  ;
+
+drop_database_statement
+  : DROP DATABASE (if_exists)? dbname = identifier
+  ;
+
+if_exists
+  : IF EXISTS
+  ;
+
 create_table_statement
-  : CREATE EXTERNAL TABLE table_name table_elements USING file_type=identifier
+  : CREATE EXTERNAL TABLE (if_not_exists)? table_name table_elements USING file_type=identifier
     (param_clause)? (table_partitioning_clauses)? (LOCATION path=Character_String_Literal)
-  | CREATE TABLE table_name table_elements (USING file_type=identifier)?
+  | CREATE TABLE (if_not_exists)? table_name table_elements (USING file_type=identifier)?
     (param_clause)? (table_partitioning_clauses)? (AS query_expression)?
-  | CREATE TABLE table_name (USING file_type=identifier)?
+  | CREATE TABLE (if_not_exists)? table_name (USING file_type=identifier)?
     (param_clause)? (table_partitioning_clauses)? AS query_expression
   ;
 
@@ -168,7 +186,7 @@ partition_name
 */
 
 drop_table_statement
-  : DROP TABLE table_name (PURGE)?
+  : DROP TABLE (if_exists)? table_name (PURGE)?
   ;
 
 /*

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
index 6d95fe1..afd0ce9 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
@@ -1419,7 +1419,7 @@ public class HiveQLAnalyzer extends HiveQLParserBaseVisitor<Expr> {
     Map<String, String> params = new HashMap<String, String>();
 
     if (ctx.name != null) {
-      createTable = new CreateTable(ctx.name.getText());
+      createTable = new CreateTable(ctx.name.getText(), ctx.ifNotExists() != null);
       if (ctx.KW_EXTERNAL() != null) {
         createTable.setExternal();
       }
@@ -1511,7 +1511,7 @@ public class HiveQLAnalyzer extends HiveQLParserBaseVisitor<Expr> {
 
   @Override
   public Expr visitDropTableStatement(HiveQLParser.DropTableStatementContext ctx) {
-    DropTable dropTable = new DropTable(ctx.tableName().getText(), false);
+    DropTable dropTable = new DropTable(ctx.tableName().getText(), false, ctx.ifExists() != null);
     return dropTable;
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
index a8407fd..784e737 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
@@ -962,9 +962,19 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   }
 
   @Override
+  public Expr visitDatabase_definition(@NotNull SQLParser.Database_definitionContext ctx) {
+    return new CreateDatabase(ctx.identifier().getText(), null, checkIfExist(ctx.if_not_exists()));
+  }
+
+  @Override
+  public Expr visitDrop_database_statement(@NotNull SQLParser.Drop_database_statementContext ctx) {
+    return new DropDatabase(ctx.identifier().getText(), checkIfExist(ctx.if_exists()));
+  }
+
+  @Override
   public Expr visitCreate_table_statement(SQLParser.Create_table_statementContext ctx) {
     String tableName = ctx.table_name().getText();
-    CreateTable createTable = new CreateTable(tableName);
+    CreateTable createTable = new CreateTable(tableName, checkIfExist(ctx.if_not_exists()));
 
     if (checkIfExist(ctx.EXTERNAL())) {
       createTable.setExternal();
@@ -1265,7 +1275,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
   @Override
   public Expr visitDrop_table_statement(SQLParser.Drop_table_statementContext ctx) {
-    return new DropTable(ctx.table_name().getText(), checkIfExist(ctx.PURGE()));
+    return new DropTable(ctx.table_name().getText(), checkIfExist(ctx.if_exists()), checkIfExist(ctx.PURGE()));
   }
 
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
index acb9008..84cdc08 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
@@ -41,6 +41,8 @@ public interface AlgebraVisitor<CONTEXT, RESULT> {
   RESULT visitScalarSubQuery(CONTEXT ctx, Stack<Expr> stack, ScalarSubQuery expr) throws PlanningException;
 
   // Data definition language
+  RESULT visitCreateDatabase(CONTEXT ctx, Stack<Expr> stack, CreateDatabase expr) throws PlanningException;
+  RESULT visitDropDatabase(CONTEXT ctx, Stack<Expr> stack, DropDatabase expr) throws PlanningException;
   RESULT visitCreateTable(CONTEXT ctx, Stack<Expr> stack, CreateTable expr) throws PlanningException;
   RESULT visitDropTable(CONTEXT ctx, Stack<Expr> stack, DropTable expr) throws PlanningException;
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
index cf36539..62cee57 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
@@ -97,6 +97,12 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
       current = visitScalarSubQuery(ctx, stack, (ScalarSubQuery) expr);
       break;
 
+    case CreateDatabase:
+      current = visitCreateDatabase(ctx, stack, (CreateDatabase) expr);
+      break;
+    case DropDatabase:
+      current = visitDropDatabase(ctx, stack, (DropDatabase) expr);
+      break;
     case CreateTable:
       current = visitCreateTable(ctx, stack, (CreateTable) expr);
       break;
@@ -403,6 +409,16 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
   @Override
+  public RESULT visitCreateDatabase(CONTEXT ctx, Stack<Expr> stack, CreateDatabase expr) throws PlanningException {
+    return null;
+  }
+
+  @Override
+  public RESULT visitDropDatabase(CONTEXT ctx, Stack<Expr> stack, DropDatabase expr) throws PlanningException {
+    return null;
+  }
+
+  @Override
   public RESULT visitCreateTable(CONTEXT ctx, Stack<Expr> stack, CreateTable expr) throws PlanningException {
     stack.push(expr);
     RESULT child = null;

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
index 94e2482..772e5fb 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
@@ -104,6 +104,12 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi
       case INSERT:
         current = visitInsert(context, plan, block, (InsertNode) node, stack);
         break;
+      case CREATE_DATABASE:
+        current = visitCreateDatabase(context, plan, block, (CreateDatabaseNode) node, stack);
+        break;
+      case DROP_DATABASE:
+        current = visitDropDatabase(context, plan, block, (DropDatabaseNode) node, stack);
+        break;
       case CREATE_TABLE:
         current = visitCreateTable(context, plan, block, (CreateTableNode) node, stack);
         break;
@@ -265,6 +271,17 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi
   }
 
   @Override
+  public RESULT visitCreateDatabase(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block,
+                                    CreateDatabaseNode node, Stack<LogicalNode> stack) throws PlanningException {
+    return null;
+  }
+
+  @Override
+  public RESULT visitDropDatabase(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, DropDatabaseNode node, Stack<LogicalNode> stack) throws PlanningException {
+    return null;
+  }
+
+  @Override
   public RESULT visitCreateTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, CreateTableNode node,
                                  Stack<LogicalNode> stack) throws PlanningException {
     RESULT result = null;

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
index e2f65ad..9dd8700 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
@@ -166,7 +166,7 @@ public class ExplainLogicalPlanVisitor extends BasicLogicalPlanVisitor<ExplainLo
                                         TableSubQueryNode node, Stack<LogicalNode> stack) throws PlanningException {
     context.depth++;
     stack.push(node);
-    super.visitTableSubQuery(context, plan, block, node, stack);
+    visit(context, plan, block, node.getSubQuery(), new Stack<LogicalNode>());
     stack.pop();
     context.depth--;
     context.add(context.depth, node.getPlanString());
@@ -195,6 +195,18 @@ public class ExplainLogicalPlanVisitor extends BasicLogicalPlanVisitor<ExplainLo
     return visitUnaryNode(context, plan, block, node, stack);
   }
 
+  public LogicalNode visitCreateDatabase(Context context, LogicalPlan plan, LogicalPlan.QueryBlock block,
+                                         CreateDatabaseNode node, Stack<LogicalNode> stack) throws PlanningException {
+    context.add(context.depth, node.getPlanString());
+    return node;
+  }
+
+  public LogicalNode visitDropDatabase(Context context, LogicalPlan plan, LogicalPlan.QueryBlock block,
+                                         DropDatabaseNode node, Stack<LogicalNode> stack) throws PlanningException {
+    context.add(context.depth, node.getPlanString());
+    return node;
+  }
+
   @Override
   public LogicalNode visitInsert(Context context, LogicalPlan plan, LogicalPlan.QueryBlock block, InsertNode node,
                                  Stack<LogicalNode> stack) throws PlanningException {

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprNormalizer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprNormalizer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprNormalizer.java
index 0dc8f82..5c24192 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprNormalizer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprNormalizer.java
@@ -19,6 +19,7 @@
 package org.apache.tajo.engine.planner;
 
 import org.apache.tajo.algebra.*;
+import org.apache.tajo.catalog.CatalogUtil;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -245,7 +246,7 @@ class ExprNormalizer extends SimpleAlgebraVisitor<ExprNormalizer.ExprNormalizedR
   public Expr visitColumnReference(ExprNormalizedResult ctx, Stack<Expr> stack, ColumnReferenceExpr expr)
       throws PlanningException {
     // normalize column references.
-    if (!expr.hasQualifier()) {
+    if (!(expr.hasQualifier() && CatalogUtil.isFQTableName(expr.getQualifier()))) {
       if (ctx.block.namedExprsMgr.contains(expr.getCanonicalName())) {
         NamedExpr namedExpr = ctx.block.namedExprsMgr.getNamedExpr(expr.getCanonicalName());
         return new ColumnReferenceExpr(namedExpr.getAlias());

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
index 8280d3e..c3bca66 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
@@ -66,7 +66,10 @@ public class LogicalPlan {
   private List<String> planingHistory = Lists.newArrayList();
   LogicalPlanner planner;
 
-  public LogicalPlan(LogicalPlanner planner) {
+  private final String currentDatabase;
+
+  public LogicalPlan(String currentDatabase, LogicalPlanner planner) {
+    this.currentDatabase = currentDatabase;
     this.planner = planner;
   }
 
@@ -257,27 +260,40 @@ public class LogicalPlan {
 
     if (columnRef.hasQualifier()) { // if a column reference is qualified
 
-      RelationNode relationOp = block.getRelation(columnRef.getQualifier());
+      String qualifier;
+      String canonicalName;
+      String qualifiedName;
+
+      if (CatalogUtil.isFQTableName(columnRef.getQualifier())) {
+        qualifier = columnRef.getQualifier();
+        canonicalName = columnRef.getCanonicalName();
+      } else {
+        qualifier = CatalogUtil.buildFQName(currentDatabase, columnRef.getQualifier());
+        canonicalName = CatalogUtil.buildFQName(currentDatabase, columnRef.getCanonicalName());
+      }
+      qualifiedName = CatalogUtil.buildFQName(qualifier, columnRef.getName());
+
+      RelationNode relationOp = block.getRelation(qualifier);
 
       // if a column name is outside of this query block
       if (relationOp == null) {
         // TODO - nested query can only refer outer query block? or not?
         for (QueryBlock eachBlock : queryBlocks.values()) {
-          if (eachBlock.existsRelation(columnRef.getQualifier())) {
-            relationOp = eachBlock.getRelation(columnRef.getQualifier());
+          if (eachBlock.existsRelation(qualifier)) {
+            relationOp = eachBlock.getRelation(qualifier);
           }
         }
       }
 
       // If we cannot find any relation against a qualified column name
       if (relationOp == null) {
-        throw new NoSuchColumnException(columnRef.getCanonicalName());
+        throw new NoSuchColumnException(canonicalName);
       }
 
       Schema schema = relationOp.getTableSchema();
-      Column column = schema.getColumn(columnRef.getCanonicalName());
+      Column column = schema.getColumn(canonicalName);
       if (column == null) {
-        throw new NoSuchColumnException(columnRef.getCanonicalName());
+        throw new NoSuchColumnException(canonicalName);
       }
 
       // If code reach here, a column is found.
@@ -292,8 +308,8 @@ public class LogicalPlan {
       // the column can be used at the current node. So, we don't need to find aliase name.
       if (currentNode != null && !currentNode.getInSchema().contains(column)) {
         List<Column> candidates = TUtil.newList();
-        if (block.namedExprsMgr.isAliased(column.getQualifiedName())) {
-          String alias = block.namedExprsMgr.getAlias(columnRef.getCanonicalName());
+        if (block.namedExprsMgr.isAliased(qualifiedName)) {
+          String alias = block.namedExprsMgr.getAlias(canonicalName);
           Column found = resolveColumn(block, new ColumnReferenceExpr(alias));
           if (found != null) {
             candidates.add(found);

http://git-wip-us.apache.org/repos/asf/tajo/blob/3ba26241/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
index b08109d..1ac416f 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
@@ -19,10 +19,7 @@
 package org.apache.tajo.engine.planner;
 
 import org.apache.tajo.algebra.*;
-import org.apache.tajo.catalog.CatalogService;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.*;
 import org.apache.tajo.engine.eval.EvalNode;
 import org.apache.tajo.engine.eval.EvalType;
 import org.apache.tajo.engine.eval.FieldEval;
@@ -30,6 +27,7 @@ import org.apache.tajo.engine.exception.NoSuchColumnException;
 import org.apache.tajo.engine.planner.LogicalPlan.QueryBlock;
 import org.apache.tajo.engine.planner.logical.*;
 import org.apache.tajo.engine.utils.SchemaUtil;
+import org.apache.tajo.master.session.Session;
 import org.apache.tajo.util.TUtil;
 
 import java.util.*;
@@ -41,15 +39,18 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
   private ExprAnnotator annotator;
 
   static class PreprocessContext {
+    Session session;
     LogicalPlan plan;
     LogicalPlan.QueryBlock currentBlock;
 
-    public PreprocessContext(LogicalPlan plan, LogicalPlan.QueryBlock currentBlock) {
+    public PreprocessContext(Session session, LogicalPlan plan, LogicalPlan.QueryBlock currentBlock) {
+      this.session = session;
       this.plan = plan;
       this.currentBlock = currentBlock;
     }
 
     public PreprocessContext(PreprocessContext context, LogicalPlan.QueryBlock currentBlock) {
+      this.session = context.session;
       this.plan = context.plan;
       this.currentBlock = currentBlock;
     }
@@ -94,21 +95,29 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     QueryBlock block = ctx.currentBlock;
     Collection<QueryBlock> queryBlocks = ctx.plan.getQueryBlocks();
     if (asteriskExpr.hasQualifier()) {
-      relationOp = block.getRelation(asteriskExpr.getQualifier());
+      String qualifier;
+
+      if (CatalogUtil.isFQTableName(asteriskExpr.getQualifier())) {
+        qualifier = asteriskExpr.getQualifier();
+      } else {
+        qualifier = CatalogUtil.buildFQName(ctx.session.getCurrentDatabase(), asteriskExpr.getQualifier());
+      }
+
+      relationOp = block.getRelation(qualifier);
 
       // if a column name is outside of this query block
       if (relationOp == null) {
         // TODO - nested query can only refer outer query block? or not?
         for (QueryBlock eachBlock : queryBlocks) {
-          if (eachBlock.existsRelation(asteriskExpr.getQualifier())) {
-            relationOp = eachBlock.getRelation(asteriskExpr.getQualifier());
+          if (eachBlock.existsRelation(qualifier)) {
+            relationOp = eachBlock.getRelation(qualifier);
           }
         }
       }
 
       // If we cannot find any relation against a qualified column name
       if (relationOp == null) {
-        throw new NoSuchColumnException(asteriskExpr.toString());
+        throw new NoSuchColumnException(CatalogUtil.buildFQName(qualifier, "*"));
       }
 
       Schema schema = relationOp.getTableSchema();
@@ -326,10 +335,16 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
   @Override
   public LogicalNode visitRelation(PreprocessContext ctx, Stack<Expr> stack, Relation expr)
       throws PlanningException {
-
     Relation relation = expr;
-    TableDesc desc = catalog.getTableDesc(relation.getName());
 
+    String actualRelationName;
+    if (CatalogUtil.isFQTableName(expr.getName())) {
+      actualRelationName = relation.getName();
+    } else {
+      actualRelationName = CatalogUtil.buildFQName(ctx.session.getCurrentDatabase(), relation.getName());
+    }
+
+    TableDesc desc = catalog.getTableDesc(actualRelationName);
     ScanNode scanNode = ctx.plan.createNode(ScanNode.class);
     if (relation.hasAlias()) {
       scanNode.init(desc, relation.getAlias());
@@ -353,7 +368,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
 
     // a table subquery should be dealt as a relation.
     TableSubQueryNode node = ctx.plan.createNode(TableSubQueryNode.class);
-    node.init(expr.getName(), child);
+    node.init(CatalogUtil.buildFQName(ctx.session.getCurrentDatabase(), expr.getName()), child);
     ctx.currentBlock.addRelation(node);
     return node;
   }
@@ -363,6 +378,20 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
   @Override
+  public LogicalNode visitCreateDatabase(PreprocessContext ctx, Stack<Expr> stack, CreateDatabase expr)
+      throws PlanningException {
+    CreateDatabaseNode createDatabaseNode = ctx.plan.createNode(CreateDatabaseNode.class);
+    return createDatabaseNode;
+  }
+
+  @Override
+  public LogicalNode visitDropDatabase(PreprocessContext ctx, Stack<Expr> stack, DropDatabase expr)
+      throws PlanningException {
+    DropDatabaseNode dropDatabaseNode = ctx.plan.createNode(DropDatabaseNode.class);
+    return dropDatabaseNode;
+  }
+
+  @Override
   public LogicalNode visitCreateTable(PreprocessContext ctx, Stack<Expr> stack, CreateTable expr)
       throws PlanningException {