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/07/02 16:16:37 UTC

[43/51] [partial] TAJO-22: The package prefix should be org.apache.tajo. (DaeMyung Kang via hyunsik)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/DBStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/DBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/DBStore.java
deleted file mode 100644
index 6db6e49..0000000
--- a/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/DBStore.java
+++ /dev/null
@@ -1,1033 +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 tajo.catalog.store;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
-import tajo.catalog.*;
-import tajo.catalog.proto.CatalogProtos.*;
-import tajo.catalog.statistics.TableStat;
-import tajo.common.TajoDataTypes.Type;
-import tajo.conf.TajoConf;
-import tajo.exception.InternalException;
-
-import java.io.IOException;
-import java.sql.*;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-public class DBStore implements CatalogStore {
-  private final Log LOG = LogFactory.getLog(DBStore.class); 
-  private final Configuration conf;
-  private final String driver;
-  private final String jdbcUri;
-  private Connection conn;  
-
-  private static final int VERSION = 1;
-
-  private static final String TB_META = "META";
-  private static final String TB_TABLES = "TABLES";
-  private static final String TB_COLUMNS = "COLUMNS";
-  private static final String TB_OPTIONS = "OPTIONS";
-  private static final String TB_INDEXES = "INDEXES";
-  private static final String TB_STATISTICS = "STATS";
-  
-  private static final String C_TABLE_ID = "TABLE_ID";
-  
-  private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-  private Lock rlock = lock.readLock();
-  private Lock wlock = lock.writeLock();
-  
-  public DBStore(final Configuration conf)
-      throws InternalException {
-    this.conf = conf;
-    
-    this.driver =
-        this.conf.get(CatalogConstants.JDBC_DRIVER, CatalogConstants.DEFAULT_JDBC_DRIVER);
-    this.jdbcUri =
-        this.conf.get(CatalogConstants.JDBC_URI);
-
-    try {
-      Class.forName(driver).newInstance();
-      LOG.info("Loaded the JDBC driver (" + driver +")");
-    } catch (Exception e) {
-      throw new InternalException("Cannot load JDBC driver " + driver, e);
-    }
-
-    try {
-      LOG.info("Trying to connect database (" + jdbcUri + ")");
-      conn = DriverManager.getConnection(jdbcUri + ";create=true");
-      LOG.info("Connected to database (" + jdbcUri +")");
-    } catch (SQLException e) {
-      throw new InternalException("Cannot connect to database (" + jdbcUri
-          +")", e);
-    }
-
-    try {
-      if (!isInitialized()) {
-        LOG.info("The base tables of CatalogServer are created.");
-        createBaseTable();
-      } else {
-        LOG.info("The base tables of CatalogServer already is initialized.");
-      }
-    } catch (SQLException se) {
-      throw new InternalException(
-          "Cannot initialize the persistent storage of Catalog", se);
-    }
-
-    int dbVersion = 0;
-    try {
-      dbVersion = needUpgrade();
-    } catch (SQLException e) {
-      throw new InternalException(
-          "Cannot check if the DB need to be upgraded", e);
-    }
-
-//    if (dbVersion < VERSION) {
-//      LOG.info("DB Upgrade is needed");
-//      try {
-//        upgrade(dbVersion, VERSION);
-//      } catch (SQLException e) {
-//        LOG.error(e.getMessage());
-//        throw new InternalException("DB upgrade is failed.", e);
-//      }
-//    }
-  }
-
-  private int needUpgrade() throws SQLException {
-    String sql = "SELECT VERSION FROM " + TB_META;
-    Statement stmt = conn.createStatement();
-    ResultSet res = stmt.executeQuery(sql);
-
-    if (res.next() == false) { // if this db version is 0
-      insertVersion();
-      return 0;
-    } else {
-      return res.getInt(1);
-    }
-  }
-
-  private void insertVersion() throws SQLException {
-    String sql = "INSERT INTO " + TB_META + " values (0)";
-    Statement stmt = conn.createStatement();
-    stmt.executeUpdate(sql);
-    stmt.close();
-  }
-
-  private void upgrade(int from, int to) throws SQLException {
-    String sql;
-    Statement stmt;
-    if (from == 0 ) {
-      if (to == 1) {
-        sql = "DROP INDEX idx_options_key";
-        LOG.info(sql);
-
-        stmt = conn.createStatement();
-        stmt.addBatch(sql);
-
-        sql =
-            "CREATE INDEX idx_options_key on " + TB_OPTIONS + " (" + C_TABLE_ID + ")";
-        stmt.addBatch(sql);
-        LOG.info(sql);
-        stmt.executeBatch();
-        stmt.close();
-
-        LOG.info("DB Upgraded from " + from + " to " + to);
-      } else {
-        LOG.info("DB Upgraded from " + from + " to " + to);
-      }
-    }
-  }
-
-  // TODO - DDL and index statements should be renamed
-  private void createBaseTable() throws SQLException {
-    wlock.lock();
-    try {
-      // META
-      Statement stmt = conn.createStatement();
-      String meta_ddl = "CREATE TABLE " + TB_META + " (version int NOT NULL)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(meta_ddl);
-      }
-      stmt.executeUpdate(meta_ddl);
-      LOG.info("Table '" + TB_META + " is created.");
-
-      // TABLES
-      stmt = conn.createStatement();
-      String tables_ddl = "CREATE TABLE "
-          + TB_TABLES + " ("
-          + "TID int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), "
-          + C_TABLE_ID + " VARCHAR(256) NOT NULL CONSTRAINT TABLE_ID_UNIQ UNIQUE, "
-          + "path VARCHAR(1024), "
-          + "store_type CHAR(16), "
-          + "options VARCHAR(32672), "
-          + "CONSTRAINT TABLES_PK PRIMARY KEY (TID)" +
-          ")";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(tables_ddl);
-      }
-      stmt.addBatch(tables_ddl);
-      String idx_tables_tid = 
-          "CREATE UNIQUE INDEX idx_tables_tid on " + TB_TABLES + " (TID)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_tables_tid);
-      }
-      stmt.addBatch(idx_tables_tid);
-      
-      String idx_tables_name = "CREATE UNIQUE INDEX idx_tables_name on " 
-          + TB_TABLES + "(" + C_TABLE_ID + ")";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_tables_name);
-      }
-      stmt.addBatch(idx_tables_name);
-      stmt.executeBatch();
-      LOG.info("Table '" + TB_TABLES + "' is created.");
-
-      // COLUMNS
-      stmt = conn.createStatement();
-      String columns_ddl = 
-          "CREATE TABLE " + TB_COLUMNS + " ("
-          + "TID INT NOT NULL REFERENCES " + TB_TABLES + " (TID) ON DELETE CASCADE, "
-          + C_TABLE_ID + " VARCHAR(256) NOT NULL REFERENCES " + TB_TABLES + "("
-          + C_TABLE_ID + ") ON DELETE CASCADE, "
-          + "column_id INT NOT NULL,"
-          + "column_name VARCHAR(256) NOT NULL, " + "data_type CHAR(16), "
-          + "CONSTRAINT C_COLUMN_ID UNIQUE (" + C_TABLE_ID + ", column_name))";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(columns_ddl);
-      }
-      stmt.addBatch(columns_ddl);
-
-      String idx_fk_columns_table_name = 
-          "CREATE UNIQUE INDEX idx_fk_columns_table_name on "
-          + TB_COLUMNS + "(" + C_TABLE_ID + ", column_name)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_fk_columns_table_name);
-      }
-      stmt.addBatch(idx_fk_columns_table_name);
-      stmt.executeBatch();
-      LOG.info("Table '" + TB_COLUMNS + " is created.");
-
-      // OPTIONS
-      stmt = conn.createStatement();
-      String options_ddl = 
-          "CREATE TABLE " + TB_OPTIONS +" ("
-          + C_TABLE_ID + " VARCHAR(256) NOT NULL REFERENCES TABLES (" + C_TABLE_ID +") "
-          + "ON DELETE CASCADE, "
-          + "key_ VARCHAR(256) NOT NULL, value_ VARCHAR(256) NOT NULL)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(options_ddl);
-      }
-      stmt.addBatch(options_ddl);
-      
-      String idx_options_key = 
-          "CREATE INDEX idx_options_key on " + TB_OPTIONS + " (" + C_TABLE_ID + ")";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_options_key);
-      }
-      stmt.addBatch(idx_options_key);
-      String idx_options_table_name = 
-          "CREATE INDEX idx_options_table_name on " + TB_OPTIONS 
-          + "(" + C_TABLE_ID + ")";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_options_table_name);
-      }
-      stmt.addBatch(idx_options_table_name);
-      stmt.executeBatch();
-      LOG.info("Table '" + TB_OPTIONS + " is created.");
-      
-      // INDEXES
-      stmt = conn.createStatement();
-      String indexes_ddl = "CREATE TABLE " + TB_INDEXES +"("
-          + "index_name VARCHAR(256) NOT NULL PRIMARY KEY, "
-          + C_TABLE_ID + " VARCHAR(256) NOT NULL REFERENCES TABLES (" + C_TABLE_ID + ") "
-          + "ON DELETE CASCADE, "
-          + "column_name VARCHAR(256) NOT NULL, "
-          + "data_type VARCHAR(256) NOT NULL, "
-          + "index_type CHAR(32) NOT NULL, "
-          + "is_unique BOOLEAN NOT NULL, "
-          + "is_clustered BOOLEAN NOT NULL, "
-          + "is_ascending BOOLEAN NOT NULL)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(indexes_ddl);
-      }
-      stmt.addBatch(indexes_ddl);
-      
-      String idx_indexes_key = "CREATE UNIQUE INDEX idx_indexes_key ON " 
-          + TB_INDEXES + " (index_name)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_indexes_key);
-      }      
-      stmt.addBatch(idx_indexes_key);
-      
-      String idx_indexes_columns = "CREATE INDEX idx_indexes_columns ON " 
-          + TB_INDEXES + " (" + C_TABLE_ID + ", column_name)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_indexes_columns);
-      } 
-      stmt.addBatch(idx_indexes_columns);
-      stmt.executeBatch();
-      LOG.info("Table '" + TB_INDEXES + "' is created.");
-
-      String stats_ddl = "CREATE TABLE " + TB_STATISTICS + "("
-          + C_TABLE_ID + " VARCHAR(256) NOT NULL REFERENCES TABLES (" + C_TABLE_ID + ") "
-          + "ON DELETE CASCADE, "
-          + "num_rows BIGINT, "
-          + "num_bytes BIGINT)";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(stats_ddl);
-      }
-      stmt.addBatch(stats_ddl);
-
-      String idx_stats_fk_table_name = "CREATE INDEX idx_stats_table_name ON "
-          + TB_STATISTICS + " (" + C_TABLE_ID + ")";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(idx_stats_fk_table_name);
-      }
-      stmt.addBatch(idx_stats_fk_table_name);
-      stmt.executeBatch();
-      LOG.info("Table '" + TB_STATISTICS + "' is created.");
-
-    } finally {
-      wlock.unlock();
-    }
-  }
-  
-  private boolean isInitialized() throws SQLException {
-    wlock.lock();
-    try {
-      boolean found = false;
-      ResultSet res = conn.getMetaData().getTables(null, null, null, 
-          new String [] {"TABLE"});
-      
-      String resName;
-      while (res.next() && !found) {
-        resName = res.getString("TABLE_NAME");
-        if (TB_META.equals(resName)
-            || TB_TABLES.equals(resName)
-            || TB_COLUMNS.equals(resName)
-            || TB_OPTIONS.equals(resName)) {
-            return true;
-        }
-      }
-    } finally {
-      wlock.unlock();
-    }    
-    return false;
-  }
-  
-  final boolean checkInternalTable(final String tableName) throws SQLException {
-    rlock.lock();
-    try {
-      boolean found = false;
-      ResultSet res = conn.getMetaData().getTables(null, null, null, 
-              new String [] {"TABLE"});
-      while(res.next() && !found) {
-        if (tableName.equals(res.getString("TABLE_NAME")))
-          found = true;
-      }
-      
-      return found;
-    } finally {
-      rlock.unlock();
-    }
-  }
-  
-  @Override
-  public final void addTable(final TableDesc table) throws IOException {
-    Statement stmt = null;
-    ResultSet res;
-
-    String sql = 
-        "INSERT INTO " + TB_TABLES + " (" + C_TABLE_ID + ", path, store_type) "
-        + "VALUES('" + table.getId() + "', "
-        + "'" + table.getPath() + "', "
-        + "'" + table.getMeta().getStoreType() + "'"
-        + ")";
-
-    wlock.lock();
-    try {
-      stmt = conn.createStatement();
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      stmt.addBatch(sql);
-      stmt.executeBatch();
-      
-      stmt = conn.createStatement();
-      sql = "SELECT TID from " + TB_TABLES + " WHERE " + C_TABLE_ID 
-          + " = '" + table.getId() + "'";
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      res = stmt.executeQuery(sql);
-      if (!res.next()) {
-        throw new IOException("ERROR: there is no tid matched to " 
-            + table.getId());
-      }
-      int tid = res.getInt("TID");
-
-      String colSql;
-      int columnId = 0;
-      for (Column col : table.getMeta().getSchema().getColumns()) {
-        colSql = columnToSQL(tid, table, columnId, col);
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(colSql);
-        }
-        stmt.addBatch(colSql);
-        columnId++;
-      }
-      
-      Iterator<Entry<String,String>> it = table.getMeta().getOptions();
-      String optSql;
-      while (it.hasNext()) {
-        optSql = keyvalToSQL(table, it.next());
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(optSql);
-        }
-        stmt.addBatch(optSql);
-      }
-      stmt.executeBatch();
-      if (table.getMeta().getStat() != null) {
-        sql = "INSERT INTO " + TB_STATISTICS + " (" + C_TABLE_ID + ", num_rows, num_bytes) "
-            + "VALUES ('" + table.getId() + "', "
-            + table.getMeta().getStat().getNumRows() + ","
-            + table.getMeta().getStat().getNumBytes() + ")";
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(sql);
-        }
-        stmt.addBatch(sql);
-        stmt.executeBatch();
-      }
-    } catch (SQLException se) {
-      throw new IOException(se.getMessage(), se);
-    } finally {
-      wlock.unlock();
-      try {
-        stmt.close();
-      } catch (SQLException e) {
-      }      
-    }
-  }
-  
-  private String columnToSQL(final int tid, final TableDesc desc, 
-      final int columnId, final Column col) {
-    String sql =
-        "INSERT INTO " + TB_COLUMNS 
-        + " (tid, " + C_TABLE_ID + ", column_id, column_name, data_type) "
-        + "VALUES("
-        + tid + ","
-        + "'" + desc.getId() + "',"
-        + columnId + ", "
-        + "'" + col.getColumnName() + "',"
-        + "'" + col.getDataType().getType().name() + "'"
-        + ")";
-    
-    return sql;
-  }
-  
-  private String keyvalToSQL(final TableDesc desc,
-      final Entry<String,String> keyVal) {
-    String sql =
-        "INSERT INTO " + TB_OPTIONS 
-        + " (" + C_TABLE_ID + ", key_, value_) "
-        + "VALUES("
-        + "'" + desc.getId() + "',"
-        + "'" + keyVal.getKey() + "',"
-        + "'" + keyVal.getValue() + "'"
-        + ")";
-    
-    return sql;
-  }
-  
-  @Override
-  public final boolean existTable(final String name) throws IOException {
-    StringBuilder sql = new StringBuilder();
-    sql.append("SELECT " + C_TABLE_ID + " from ")
-    .append(TB_TABLES)
-    .append(" WHERE " + C_TABLE_ID + " = '")
-    .append(name)
-    .append("'");
-
-    Statement stmt = null;
-    boolean exist = false;
-    rlock.lock();
-    try {
-      stmt = conn.createStatement();
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql.toString());
-      }
-      ResultSet res = stmt.executeQuery(sql.toString());
-      exist = res.next();
-    } catch (SQLException se) {
-      throw new IOException(se);
-    } finally {
-      rlock.unlock();
-      try {
-        if (stmt != null) {
-          stmt.close();
-        }
-      } catch (SQLException e) {
-      }         
-    }
-    
-    return exist;
-  }
-
-  @Override
-  public final void deleteTable(final String name) throws IOException {
-    Statement stmt = null;
-    String sql = null;
-    try {
-      wlock.lock();
-      try {
-        stmt = conn.createStatement();
-        sql = "DELETE FROM " + TB_COLUMNS +
-            " WHERE " + C_TABLE_ID + " = '" + name + "'";
-        LOG.info(sql);
-        stmt.execute(sql);
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        try {
-          if (stmt != null) {
-            stmt.close();
-          }
-        } catch (SQLException e) {
-        }
-      }
-
-      try {
-        sql = "DELETE FROM " + TB_OPTIONS +
-            " WHERE " + C_TABLE_ID + " = '" + name + "'";
-        LOG.info(sql);
-        stmt = conn.createStatement();
-        stmt.execute(sql);
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        try {
-          if (stmt != null) {
-            stmt.close();
-          }
-        } catch (SQLException e) {
-        }
-      }
-
-      try {
-        sql = "DELETE FROM " + TB_STATISTICS +
-            " WHERE " + C_TABLE_ID + " = '" + name + "'";
-        LOG.info(sql);
-        stmt = conn.createStatement();
-        stmt.execute(sql);
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        try {
-          if (stmt != null) {
-            stmt.close();
-          }
-        } catch (SQLException e) {
-        }
-      }
-
-      try {
-        sql = "DELETE FROM " + TB_TABLES +
-            " WHERE " + C_TABLE_ID +" = '" + name + "'";
-        LOG.info(sql);
-        stmt = conn.createStatement();
-        stmt.execute(sql);
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        try {
-          if (stmt != null) {
-            stmt.close();
-          }
-        } catch (SQLException e) {
-        }
-      }
-
-    } finally {
-      wlock.unlock();
-    }
-  }
-
-  @Override
-  public final TableDesc getTable(final String name) throws IOException {
-    ResultSet res = null;
-    Statement stmt = null;
-
-    String tableName = null;
-    Path path = null;
-    StoreType storeType = null;
-    Options options;
-    TableStat stat = null;
-
-    rlock.lock();
-    try {
-      try {
-        String sql = 
-            "SELECT " + C_TABLE_ID + ", path, store_type from " + TB_TABLES
-            + " WHERE " + C_TABLE_ID + "='" + name + "'";
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(sql);
-        }
-        stmt = conn.createStatement();
-        res = stmt.executeQuery(sql);
-        if (!res.next()) { // there is no table of the given name.
-          return null;
-        }
-        tableName = res.getString(C_TABLE_ID).trim();
-        path = new Path(res.getString("path").trim());
-        storeType = CatalogUtil.getStoreType(res.getString("store_type").trim());
-      } catch (SQLException se) { 
-        throw new IOException(se);
-      } finally {
-        stmt.close();
-        res.close();
-      }
-      
-      Schema schema = null;
-      try {
-        String sql = "SELECT column_name, data_type from " + TB_COLUMNS
-            + " WHERE " + C_TABLE_ID + "='" + name + "' ORDER by column_id asc";
-
-        stmt = conn.createStatement();
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(sql);
-        }
-        res = stmt.executeQuery(sql);
-
-        schema = new Schema();
-        while (res.next()) {
-          String columnName = tableName + "." 
-              + res.getString("column_name").trim();
-          Type dataType = getDataType(res.getString("data_type")
-              .trim());
-          schema.addColumn(columnName, dataType);
-        }
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        stmt.close();
-        res.close();
-      }
-      
-      options = Options.create();
-      try {
-        String sql = "SELECT key_, value_ from " + TB_OPTIONS
-            + " WHERE " + C_TABLE_ID + "='" + name + "'";
-        stmt = conn.createStatement();
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(sql);
-        }
-        res = stmt.executeQuery(sql);        
-        
-        while (res.next()) {
-          options.put(
-              res.getString("key_"),
-              res.getString("value_"));          
-        }
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        stmt.close();
-        res.close();
-      }
-
-      try {
-        String sql = "SELECT num_rows, num_bytes from " + TB_STATISTICS
-            + " WHERE " + C_TABLE_ID + "='" + name + "'";
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(sql);
-        }
-        stmt = conn.createStatement();
-        res = stmt.executeQuery(sql);
-
-        if (res.next()) {
-          stat = new TableStat();
-          stat.setNumRows(res.getLong("num_rows"));
-          stat.setNumBytes(res.getLong("num_bytes"));
-        }
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        stmt.close();
-        res.close();
-      }
-
-      TableMeta meta = new TableMetaImpl(schema, storeType, options);
-      if (stat != null) {
-        meta.setStat(stat);
-      }
-      TableDesc table = new TableDescImpl(tableName, meta, path);
-
-      return table;
-    } catch (SQLException se) {
-      throw new IOException(se);
-    } finally {
-      rlock.unlock();
-    }
-  }
-  
-  private Type getDataType(final String typeStr) {
-    try {
-    return Enum.valueOf(Type.class, typeStr);
-    } catch (IllegalArgumentException iae) {
-      LOG.error("Cannot find a matched type aginst from '" + typeStr + "'");
-      return null;
-    }
-  }
-  
-  @Override
-  public final List<String> getAllTableNames() throws IOException {
-    String sql = "SELECT " + C_TABLE_ID + " from " + TB_TABLES;
-    
-    Statement stmt = null;
-    ResultSet res;
-    
-    List<String> tables = new ArrayList<String>();
-    rlock.lock();
-    try {
-      stmt = conn.createStatement();
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      res = stmt.executeQuery(sql);
-      while (res.next()) {
-        tables.add(res.getString(C_TABLE_ID).trim());
-      }
-    } catch (SQLException se) {
-      throw new IOException(se);
-    } finally {
-      rlock.unlock();
-      try {
-        if (stmt != null) {
-          stmt.close();
-        }
-      } catch (SQLException e) {
-      }
-    }
-    return tables;
-  }
-  
-  public final void addIndex(final IndexDescProto proto) throws IOException {
-    String sql = 
-        "INSERT INTO indexes (index_name, " + C_TABLE_ID + ", column_name, " 
-        +"data_type, index_type, is_unique, is_clustered, is_ascending) VALUES "
-        +"(?,?,?,?,?,?,?,?)";
-    
-    PreparedStatement stmt = null;
-
-    wlock.lock();
-    try {
-      stmt = conn.prepareStatement(sql);
-      stmt.setString(1, proto.getName());
-      stmt.setString(2, proto.getTableId());
-      stmt.setString(3, proto.getColumn().getColumnName());
-      stmt.setString(4, proto.getColumn().getDataType().getType().name());
-      stmt.setString(5, proto.getIndexMethod().toString());
-      stmt.setBoolean(6, proto.hasIsUnique() && proto.getIsUnique());
-      stmt.setBoolean(7, proto.hasIsClustered() && proto.getIsClustered());
-      stmt.setBoolean(8, proto.hasIsAscending() && proto.getIsAscending());
-      stmt.executeUpdate();
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(stmt.toString());
-      }
-    } catch (SQLException se) {
-      throw new IOException(se);
-    } finally {
-      wlock.unlock();
-      try {
-        if (stmt != null) {
-          stmt.close();
-        }
-      } catch (SQLException e) {     
-      }
-    }
-  }
-  
-  public final void delIndex(final String indexName) throws IOException {
-    String sql =
-        "DELETE FROM " + TB_INDEXES
-        + " WHERE index_name='" + indexName + "'";
-    if (LOG.isDebugEnabled()) {
-      LOG.debug(sql);
-    }
-      
-      Statement stmt = null;
-      wlock.lock(); 
-      try {
-        stmt = conn.createStatement();
-        if (LOG.isDebugEnabled()) {
-          LOG.debug(sql);
-        }
-        stmt.executeUpdate(sql);
-      } catch (SQLException se) {
-        throw new IOException(se);
-      } finally {
-        wlock.unlock();
-        try {
-          if (stmt != null) {
-            stmt.close();
-          }
-        } catch (SQLException e) {
-        }      
-      }
-  }
-  
-  public final IndexDescProto getIndex(final String indexName) 
-      throws IOException {
-    ResultSet res;
-    PreparedStatement stmt;
-    
-    IndexDescProto proto = null;
-    
-    rlock.lock();
-    try {
-      String sql = 
-          "SELECT index_name, " + C_TABLE_ID + ", column_name, data_type, " 
-          + "index_type, is_unique, is_clustered, is_ascending FROM indexes "
-          + "where index_name = ?";
-      stmt = conn.prepareStatement(sql);
-      stmt.setString(1, indexName);
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(stmt.toString());
-      }
-      res = stmt.executeQuery();
-      if (!res.next()) {
-        throw new IOException("ERROR: there is no index matched to " + indexName);
-      }
-      proto = resultToProto(res);
-    } catch (SQLException se) {
-    } finally {
-      rlock.unlock();
-    }
-    
-    return proto;
-  }
-  
-  public final IndexDescProto getIndex(final String tableName, 
-      final String columnName) throws IOException {
-    ResultSet res;
-    PreparedStatement stmt;
-    
-    IndexDescProto proto = null;
-    
-    rlock.lock();
-    try {
-      String sql = 
-          "SELECT index_name, " + C_TABLE_ID + ", column_name, data_type, " 
-          + "index_type, is_unique, is_clustered, is_ascending FROM indexes "
-          + "where " + C_TABLE_ID + " = ? AND column_name = ?";
-      stmt = conn.prepareStatement(sql);
-      stmt.setString(1, tableName);
-      stmt.setString(2, columnName);
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      res = stmt.executeQuery();
-      if (!res.next()) {
-        throw new IOException("ERROR: there is no index matched to " 
-            + tableName + "." + columnName);
-      }      
-      proto = resultToProto(res);
-    } catch (SQLException se) {
-      new IOException(se);
-    } finally {
-      rlock.unlock();
-    }
-    
-    return proto;
-  }
-  
-  public final boolean existIndex(final String indexName) throws IOException {
-    String sql = "SELECT index_name from " + TB_INDEXES 
-        + " WHERE index_name = ?";
-    if (LOG.isDebugEnabled()) {
-      LOG.debug(sql);
-    }
-
-    PreparedStatement stmt = null;
-    boolean exist = false;
-    rlock.lock();
-    try {
-      stmt = conn.prepareStatement(sql);
-      stmt.setString(1, indexName);
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      ResultSet res = stmt.executeQuery();
-      exist = res.next();
-    } catch (SQLException se) {
-      
-    } finally {
-      rlock.unlock();
-      try {
-        stmt.close();
-      } catch (SQLException e) {
-      }         
-    }
-    
-    return exist;
-  }
-  
-  @Override
-  public boolean existIndex(String tableName, String columnName)
-      throws IOException {
-    String sql = "SELECT index_name from " + TB_INDEXES 
-        + " WHERE " + C_TABLE_ID + " = ? AND COLUMN_NAME = ?";
-    if (LOG.isDebugEnabled()) {
-      LOG.debug(sql);
-    }
-
-    PreparedStatement stmt = null;
-    boolean exist = false;
-    rlock.lock();
-    try {
-      stmt = conn.prepareStatement(sql);
-      stmt.setString(1, tableName);
-      stmt.setString(2, columnName);
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      ResultSet res = stmt.executeQuery();
-      exist = res.next();
-    } catch (SQLException se) {
-      
-    } finally {
-      rlock.unlock();
-      try {
-        stmt.close();
-      } catch (SQLException e) {
-      }         
-    }
-    
-    return exist;
-  }
-  
-  public final IndexDescProto [] getIndexes(final String tableName) 
-      throws IOException {
-    ResultSet res;
-    PreparedStatement stmt;
-    
-    List<IndexDescProto> protos = new ArrayList<IndexDescProto>();
-    
-    rlock.lock();
-    try {
-      String sql = "SELECT index_name, " + C_TABLE_ID + ", column_name, data_type, " 
-          + "index_type, is_unique, is_clustered, is_ascending FROM indexes "
-          + "where " + C_TABLE_ID + "= ?";
-      stmt = conn.prepareStatement(sql);
-      stmt.setString(1, tableName);
-      if (LOG.isDebugEnabled()) {
-        LOG.debug(sql);
-      }
-      res = stmt.executeQuery();      
-      while (res.next()) {
-        protos.add(resultToProto(res));
-      }
-    } catch (SQLException se) {
-    } finally {
-      rlock.unlock();
-    }
-    
-    return protos.toArray(new IndexDescProto [protos.size()]);
-  }
-  
-  private IndexDescProto resultToProto(final ResultSet res) throws SQLException {
-    IndexDescProto.Builder builder = IndexDescProto.newBuilder();
-    builder.setName(res.getString("index_name"));
-    builder.setTableId(res.getString(C_TABLE_ID));
-    builder.setColumn(resultToColumnProto(res));
-    builder.setIndexMethod(getIndexMethod(res.getString("index_type").trim()));
-    builder.setIsUnique(res.getBoolean("is_unique"));
-    builder.setIsClustered(res.getBoolean("is_clustered"));
-    builder.setIsAscending(res.getBoolean("is_ascending"));
-    return builder.build();
-  }
-  
-  private ColumnProto resultToColumnProto(final ResultSet res) throws SQLException {
-    ColumnProto.Builder builder = ColumnProto.newBuilder();
-    builder.setColumnName(res.getString("column_name"));
-    builder.setDataType(CatalogUtil.newDataTypeWithoutLen(
-        getDataType(res.getString("data_type").trim())));
-    return builder.build();
-  }
-  
-  private IndexMethod getIndexMethod(final String typeStr) {
-    if (typeStr.equals(IndexMethod.TWO_LEVEL_BIN_TREE.toString())) {
-      return IndexMethod.TWO_LEVEL_BIN_TREE;
-    } else {
-      LOG.error("Cannot find a matched type aginst from '"
-          + typeStr + "'");
-      // TODO - needs exception handling
-      return null;
-    }
-  }
-  
-  @Override
-  public final void addFunction(final FunctionDesc func) throws IOException {
-    // TODO - not implemented yet    
-  }
-
-  @Override
-  public final void deleteFunction(final FunctionDesc func) throws IOException {
-    // TODO - not implemented yet    
-  }
-
-  @Override
-  public final void existFunction(final FunctionDesc func) throws IOException {
-    // TODO - not implemented yet    
-  }
-
-  @Override
-  public final List<String> getAllFunctionNames() throws IOException {
-    // TODO - not implemented yet
-    return null;
-  }
-
-  @Override
-  public final void close() {
-    try {
-      DriverManager.getConnection("jdbc:derby:;shutdown=true");
-    } catch (SQLException e) {
-      // TODO - to be fixed
-      //LOG.error(e.getMessage(), e);
-    }
-    
-    LOG.info("Shutdown database (" + jdbcUri + ")");
-  }
-  
-  
-  public static void main(final String[] args) throws IOException {
-    @SuppressWarnings("unused")
-    DBStore store = new DBStore(new TajoConf());
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/MemStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/MemStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/MemStore.java
deleted file mode 100644
index cfe68a4..0000000
--- a/tajo-catalog/tajo-catalog-server/src/main/java/tajo/catalog/store/MemStore.java
+++ /dev/null
@@ -1,207 +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 tajo.catalog.store;
-
-import com.google.common.collect.Maps;
-import org.apache.hadoop.conf.Configuration;
-import tajo.catalog.FunctionDesc;
-import tajo.catalog.TableDesc;
-import tajo.catalog.proto.CatalogProtos.IndexDescProto;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class MemStore implements CatalogStore {
-  private final Map<String,TableDesc> tables
-    = Maps.newHashMap();
-  private final Map<String, FunctionDesc> functions
-    = Maps.newHashMap();
-  private final Map<String, IndexDescProto> indexes
-    = Maps.newHashMap();
-  private final Map<String, IndexDescProto> indexesByColumn
-  = Maps.newHashMap();
-  
-  public MemStore(Configuration conf) {
-  }
-
-  /* (non-Javadoc)
-   * @see java.io.Closeable#close()
-   */
-  @Override
-  public void close() throws IOException {
-    tables.clear();
-    functions.clear();
-    indexes.clear();
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#addTable(TableDesc)
-   */
-  @Override
-  public void addTable(TableDesc desc) throws IOException {
-    synchronized(tables) {
-      tables.put(desc.getId(), desc);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#existTable(java.lang.String)
-   */
-  @Override
-  public boolean existTable(String name) throws IOException {
-    synchronized(tables) {
-      return tables.containsKey(name);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#deleteTable(java.lang.String)
-   */
-  @Override
-  public void deleteTable(String name) throws IOException {
-    synchronized(tables) {
-      tables.remove(name);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#getTable(java.lang.String)
-   */
-  @Override
-  public TableDesc getTable(String name) throws IOException {
-    return tables.get(name);
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#getAllTableNames()
-   */
-  @Override
-  public List<String> getAllTableNames() throws IOException {
-    return new ArrayList<String>(tables.keySet());
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#addIndex(nta.catalog.proto.CatalogProtos.IndexDescProto)
-   */
-  @Override
-  public void addIndex(IndexDescProto proto) throws IOException {
-    synchronized(indexes) {
-      indexes.put(proto.getName(), proto);
-      indexesByColumn.put(proto.getTableId() + "." 
-          + proto.getColumn().getColumnName(), proto);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#delIndex(java.lang.String)
-   */
-  @Override
-  public void delIndex(String indexName) throws IOException {
-    synchronized(indexes) {
-      indexes.remove(indexName);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#getIndex(java.lang.String)
-   */
-  @Override
-  public IndexDescProto getIndex(String indexName) throws IOException {
-    return indexes.get(indexName);
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#getIndex(java.lang.String, java.lang.String)
-   */
-  @Override
-  public IndexDescProto getIndex(String tableName, String columnName)
-      throws IOException {
-    return indexesByColumn.get(tableName+"."+columnName);
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#existIndex(java.lang.String)
-   */
-  @Override
-  public boolean existIndex(String indexName) throws IOException {
-    return indexes.containsKey(indexName);
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#existIndex(java.lang.String, java.lang.String)
-   */
-  @Override
-  public boolean existIndex(String tableName, String columnName)
-      throws IOException {
-    return indexesByColumn.containsKey(tableName + "." + columnName);
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#getIndexes(java.lang.String)
-   */
-  @Override
-  public IndexDescProto[] getIndexes(String tableName) throws IOException {
-    List<IndexDescProto> protos = new ArrayList<IndexDescProto>();
-    for (IndexDescProto proto : indexesByColumn.values()) {
-      if (proto.getTableId().equals(tableName)) {
-        protos.add(proto);
-      }
-    }
-    return protos.toArray(new IndexDescProto[protos.size()]);
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#addFunction(FunctionDesc)
-   */
-  @Override
-  public void addFunction(FunctionDesc func) throws IOException {
-    // to be implemented
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#deleteFunction(FunctionDesc)
-   */
-  @Override
-  public void deleteFunction(FunctionDesc func) throws IOException {
-    // to be implemented
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#existFunction(FunctionDesc)
-   */
-  @Override
-  public void existFunction(FunctionDesc func) throws IOException {
-    // to be implemented
-  }
-
-  /* (non-Javadoc)
-   * @see CatalogStore#getAllFunctionNames()
-   */
-  @Override
-  public List<String> getAllFunctionNames() throws IOException {
-    // to be implemented
-    return null;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/main/resources/catalog-default.xml
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/resources/catalog-default.xml b/tajo-catalog/tajo-catalog-server/src/main/resources/catalog-default.xml
index 218672f..d33a649 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/resources/catalog-default.xml
+++ b/tajo-catalog/tajo-catalog-server/src/main/resources/catalog-default.xml
@@ -27,7 +27,7 @@
 
   <property>
     <name>tajo.catalog.store.class</name>
-    <value>tajo.catalog.store.DBStore</value>
+    <value>org.apache.tajo.catalog.store.DBStore</value>
   </property>
 
   <property>

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
new file mode 100644
index 0000000..1ff7e61
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
@@ -0,0 +1,214 @@
+/**
+ * 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.catalog;
+
+import org.apache.hadoop.fs.Path;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.apache.tajo.catalog.function.GeneralFunction;
+import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
+import org.apache.tajo.catalog.proto.CatalogProtos.IndexMethod;
+import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.storage.Tuple;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class TestCatalog {
+	static final String FieldName1="f1";
+	static final String FieldName2="f2";
+	static final String FieldName3="f3";	
+
+	Schema schema1;
+	
+	static CatalogServer server;
+	static CatalogService catalog;
+
+	@BeforeClass
+	public static void setUp() throws Exception {
+	  server = new CatalogServer();
+    server.init(new TajoConf());
+    server.start();
+    catalog = new LocalCatalog(server);
+	}
+	
+	@AfterClass
+	public static void tearDown() throws IOException {
+	  server.stop();
+	}
+	
+	@Test
+	public void testGetTable() throws Exception {
+		schema1 = new Schema();
+		schema1.addColumn(FieldName1, Type.BLOB);
+		schema1.addColumn(FieldName2, Type.INT4);
+		schema1.addColumn(FieldName3, Type.INT8);
+		
+		TableDesc meta = CatalogUtil.newTableDesc(
+        "getTable",
+        schema1,
+        StoreType.CSV,
+        new Options(),
+        new Path("/table1"));
+		
+		assertFalse(catalog.existsTable("getTable"));
+		catalog.addTable(meta);
+		assertTrue(catalog.existsTable("getTable"));
+		
+		TableDesc meta2 = catalog.getTableDesc("getTable");
+		System.out.println(meta2);
+		
+		catalog.deleteTable("getTable");
+		assertFalse(catalog.existsTable("getTable"));
+	}
+	
+	@Test(expected = Throwable.class)
+	public void testAddTableNoName() throws Exception {
+	  schema1 = new Schema();
+    schema1.addColumn(FieldName1, Type.BLOB);
+    schema1.addColumn(FieldName2, Type.INT4);
+    schema1.addColumn(FieldName3, Type.INT8);
+    
+	  TableMeta info = CatalogUtil.newTableMeta(schema1, StoreType.CSV);
+	  TableDesc desc = new TableDescImpl();
+	  desc.setMeta(info);
+	  
+	  catalog.addTable(desc);
+	}
+
+  static IndexDesc desc1;
+  static IndexDesc desc2;
+  static IndexDesc desc3;
+
+  static {
+    desc1 = new IndexDesc(
+        "idx_test", "indexed", new Column("id", Type.INT4),
+        IndexMethod.TWO_LEVEL_BIN_TREE, true, true, true);
+
+    desc2 = new IndexDesc(
+        "idx_test2", "indexed", new Column("score", Type.FLOAT8),
+        IndexMethod.TWO_LEVEL_BIN_TREE, false, false, false);
+
+    desc3 = new IndexDesc(
+        "idx_test", "indexed", new Column("id", Type.INT4),
+        IndexMethod.TWO_LEVEL_BIN_TREE, true, true, true);
+  }
+	
+	@Test
+	public void testAddAndDelIndex() throws Exception {
+	  TableDesc desc = TestDBStore.prepareTable();
+	  catalog.addTable(desc);
+	  
+	  assertFalse(catalog.existIndex(desc1.getName()));
+	  assertFalse(catalog.existIndex("indexed", "id"));
+	  catalog.addIndex(desc1);
+	  assertTrue(catalog.existIndex(desc1.getName()));
+	  assertTrue(catalog.existIndex("indexed", "id"));
+	  
+	  assertFalse(catalog.existIndex(desc2.getName()));
+	  assertFalse(catalog.existIndex("indexed", "score"));
+	  catalog.addIndex(desc2);
+	  assertTrue(catalog.existIndex(desc2.getName()));
+	  assertTrue(catalog.existIndex("indexed", "score"));
+	  
+	  catalog.deleteIndex(desc1.getName());
+	  assertFalse(catalog.existIndex(desc1.getName()));
+	  catalog.deleteIndex(desc2.getName());
+	  assertFalse(catalog.existIndex(desc2.getName()));
+	  
+	  catalog.deleteTable(desc.getId());
+	}
+	
+	public static class TestFunc1 extends GeneralFunction {
+		public TestFunc1() {
+			super(					
+					new Column [] {
+							new Column("name", TajoDataTypes.Type.INT4)
+					}
+			);
+		}
+
+    @Override
+    public Datum eval(Tuple params) {
+      return params.get(0);
+    }
+	}
+
+  public static class TestFunc2 extends GeneralFunction {
+    private Datum param;
+    public TestFunc2() {
+      super(
+          new Column [] {
+              new Column("name", TajoDataTypes.Type.INT4),
+              new Column("bytes", TajoDataTypes.Type.BLOB)
+          }
+      );
+    }
+
+    @Override
+    public Datum eval(Tuple params) {
+      return params.get(1);
+    }
+  }
+
+	@Test
+	public final void testRegisterFunc() throws Exception { 
+		assertFalse(catalog.containFunction("test2"));
+		FunctionDesc meta = new FunctionDesc("test2", TestFunc1.class, FunctionType.GENERAL,
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4),
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4));
+
+    catalog.registerFunction(meta);
+		assertTrue(catalog.containFunction("test2", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
+		FunctionDesc retrived = catalog.getFunction("test2", CatalogUtil.newDataTypesWithoutLen(Type.INT4));
+
+		assertEquals(retrived.getSignature(),"test2");
+		assertEquals(retrived.getFuncClass(),TestFunc1.class);
+		assertEquals(retrived.getFuncType(),FunctionType.GENERAL);
+	}
+
+  @Test
+  public final void testUnregisterFunc() throws Exception {    
+    assertFalse(catalog
+        .containFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
+    FunctionDesc meta = new FunctionDesc("test3", TestFunc1.class, FunctionType.GENERAL,
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4),
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4 ));
+    catalog.registerFunction(meta);
+    assertTrue(catalog.containFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
+    catalog.unregisterFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4));
+    assertFalse(catalog
+        .containFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
+
+    assertFalse(catalog.containFunction("test3",
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4, Type.BLOB)));
+    FunctionDesc overload = new FunctionDesc("test3", TestFunc2.class, FunctionType.GENERAL,
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4),
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4, Type.BLOB));
+    catalog.registerFunction(overload);
+    assertTrue(catalog.containFunction("test3",
+        CatalogUtil.newDataTypesWithoutLen(Type.INT4, Type.BLOB)));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestDBStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestDBStore.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestDBStore.java
new file mode 100644
index 0000000..3764b34
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestDBStore.java
@@ -0,0 +1,220 @@
+/**
+ * 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.catalog;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
+import org.apache.tajo.catalog.statistics.TableStat;
+import org.apache.tajo.catalog.store.DBStore;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.util.CommonTestingUtil;
+
+import java.io.File;
+
+import static org.junit.Assert.*;
+
+public class TestDBStore {
+  private static final Log LOG = LogFactory.getLog(TestDBStore.class);  
+  private static Configuration conf;
+  private static DBStore store;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    conf = new TajoConf();
+    Path testDir = CommonTestingUtil.getTestDir("target/test-data/TestDBSTore");
+    File absolutePath = new File(testDir.toUri());
+    conf.set(CatalogConstants.JDBC_URI, "jdbc:derby:"+absolutePath.getAbsolutePath()+"/db");
+    LOG.info("derby repository is set to "+conf.get(CatalogConstants.JDBC_URI));
+    store = new DBStore(conf);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    store.close();
+  }
+
+  @Test
+  public final void testAddAndDeleteTable() throws Exception {
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4)
+    .addColumn("name", Type.TEXT)
+    .addColumn("age", Type.INT4)
+    .addColumn("score", Type.FLOAT8);
+    
+    String tableName = "addedtable";
+    Options opts = new Options();
+    opts.put("file.delimiter", ",");
+    TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV, opts);
+    TableDesc desc = new TableDescImpl(tableName, meta, new Path("/addedtable"));
+    assertFalse(store.existTable(tableName));
+    store.addTable(desc);
+    assertTrue(store.existTable(tableName));
+
+    TableDesc retrieved = store.getTable(tableName);
+    // Schema order check
+    assertSchemaOrder(desc.getMeta().getSchema(), retrieved.getMeta().getSchema());
+    store.deleteTable(tableName);
+    assertFalse(store.existTable(tableName));
+  }
+  
+  @Test
+  public final void testGetTable() throws Exception {
+    Schema schema = new Schema();
+    schema.addColumn("gettable.id", Type.INT4)
+    .addColumn("gettable.name", Type.TEXT)
+    .addColumn("gettable.age", Type.INT4)
+    .addColumn("gettable.score", Type.FLOAT8);
+    
+    String tableName = "gettable";
+    Options opts = new Options();
+    opts.put("file.delimiter", ",");
+    TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV, opts);
+
+    TableStat stat = new TableStat();
+    stat.setNumRows(957685);
+    stat.setNumBytes(1023234);
+    meta.setStat(stat);
+
+    TableDesc desc = new TableDescImpl(tableName, meta, new Path("/gettable"));
+
+    store.addTable(desc);
+    TableDesc retrieved = store.getTable(tableName);
+    assertEquals(",", retrieved.getMeta().getOption("file.delimiter"));
+    assertEquals(desc, retrieved);
+    assertTrue(957685 == desc.getMeta().getStat().getNumRows());
+    assertTrue(1023234 == desc.getMeta().getStat().getNumBytes());
+    // Schema order check
+    assertSchemaOrder(desc.getMeta().getSchema(), retrieved.getMeta().getSchema());
+    store.deleteTable(tableName);
+  }
+  
+  @Test
+  public final void testGetAllTableNames() throws Exception {
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4)
+    .addColumn("name", Type.TEXT)
+    .addColumn("age", Type.INT4)
+    .addColumn("score", Type.FLOAT8);
+    
+    int numTables = 5;
+    for (int i = 0; i < numTables; i++) {
+      String tableName = "tableA_" + i;
+      TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV);
+      TableDesc desc = new TableDescImpl(tableName, meta, 
+          new Path("/tableA_" + i));
+      store.addTable(desc);
+    }
+    
+    assertEquals(numTables, store.getAllTableNames().size());
+  }  
+  
+  @Test
+  public final void testAddAndDeleteIndex() throws Exception {
+    TableDesc table = prepareTable();
+    store.addTable(table);
+    
+    store.addIndex(TestCatalog.desc1.getProto());
+    assertTrue(store.existIndex(TestCatalog.desc1.getName()));
+    store.delIndex(TestCatalog.desc1.getName());
+    assertFalse(store.existIndex(TestCatalog.desc1.getName()));
+    
+    store.deleteTable(table.getId());
+  }
+  
+  @Test
+  public final void testGetIndex() throws Exception {
+    
+    TableDesc table = prepareTable();
+    store.addTable(table);
+    
+    store.addIndex(TestCatalog.desc2.getProto());
+    assertEquals(
+        new IndexDesc(TestCatalog.desc2.getProto()),
+        new IndexDesc(store.getIndex(TestCatalog.desc2.getName())));
+    store.delIndex(TestCatalog.desc2.getName());
+    
+    store.deleteTable(table.getId());
+  }
+  
+  @Test
+  public final void testGetIndexByTableAndColumn() throws Exception {
+    
+    TableDesc table = prepareTable();
+    store.addTable(table);
+    
+    store.addIndex(TestCatalog.desc2.getProto());
+    
+    String tableId = TestCatalog.desc2.getTableId();
+    String columnName = "score";
+    assertEquals(
+        new IndexDesc(TestCatalog.desc2.getProto()),
+        new IndexDesc(store.getIndex(tableId, columnName)));
+    store.delIndex(TestCatalog.desc2.getName());
+    
+    store.deleteTable(table.getId());
+  }
+  
+  @Test
+  public final void testGetAllIndexes() throws Exception {
+    
+    TableDesc table = prepareTable();
+    store.addTable(table);
+    
+    store.addIndex(TestCatalog.desc1.getProto());
+    store.addIndex(TestCatalog.desc2.getProto());
+        
+    assertEquals(2, 
+        store.getIndexes(TestCatalog.desc2.getTableId()).length);
+    store.delIndex(TestCatalog.desc1.getName());
+    store.delIndex(TestCatalog.desc2.getName());
+    
+    store.deleteTable(table.getId());
+  }
+  
+  public static TableDesc prepareTable() {
+    Schema schema = new Schema();
+    schema.addColumn("indexed.id", Type.INT4)
+    .addColumn("indexed.name", Type.TEXT)
+    .addColumn("indexed.age", Type.INT4)
+    .addColumn("indexed.score", Type.FLOAT8);
+    
+    String tableName = "indexed";
+    
+    TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV);
+    return new TableDescImpl(tableName, meta, new Path("/indexed"));
+  }
+
+  public static void assertSchemaOrder(Schema s1, Schema s2) {
+    // Schema order check
+    assertEquals(s1.getColumnNum(),
+        s2.getColumnNum());
+
+    for (int i = 0; i < s1.getColumnNum(); i++) {
+      assertEquals(s1.getColumn(i).getColumnName(),
+          s2.getColumn(i).getColumnName());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestColumnStat.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestColumnStat.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestColumnStat.java
new file mode 100644
index 0000000..2f09358
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestColumnStat.java
@@ -0,0 +1,68 @@
+/**
+ * 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.catalog.statistics;
+
+import org.junit.Test;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.DatumFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestColumnStat {
+
+  @Test
+  public final void testColumnStat() {
+    ColumnStat stat = new ColumnStat(new Column("test", Type.INT8));
+    stat.setNumDistVals(1000);
+    stat.setNumNulls(999);
+    
+    assertTrue(1000 == stat.getNumDistValues());
+    assertTrue(999 == stat.getNumNulls());
+    
+    ColumnStat stat2 = new ColumnStat(stat.getProto());
+    assertTrue(1000 == stat2.getNumDistValues());
+    assertTrue(999 == stat2.getNumNulls());
+  }
+
+  @Test
+  public final void testEqualsObject() {
+    ColumnStat stat = new ColumnStat(new Column("test", Type.INT8));
+    stat.setNumDistVals(1000);
+    stat.setNumNulls(999);
+    stat.setMinValue(DatumFactory.createInt8(5));
+    stat.setMaxValue(DatumFactory.createInt8(10));
+    
+    ColumnStat stat2 = new ColumnStat(stat.getProto());
+    assertEquals(stat, stat2);
+  }
+
+  @Test
+  public final void testClone() throws CloneNotSupportedException {
+    ColumnStat stat = new ColumnStat(new Column("test", Type.INT8));
+    stat.setNumDistVals(1000);
+    stat.setNumNulls(999);
+    stat.setMinValue(DatumFactory.createInt8(5));
+    stat.setMaxValue(DatumFactory.createInt8(10));
+    
+    ColumnStat stat2 = (ColumnStat) stat.clone();
+    assertEquals(stat, stat2);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatSet.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatSet.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatSet.java
new file mode 100644
index 0000000..9285c8d
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatSet.java
@@ -0,0 +1,67 @@
+/**
+ * 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.catalog.statistics;
+
+import org.junit.Test;
+import org.apache.tajo.catalog.proto.CatalogProtos.StatType;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestStatSet {
+  @Test
+  public final void testStatGroup() throws CloneNotSupportedException {
+    Stat stat = new Stat(StatType.TABLE_NUM_ROWS);
+    stat.increment();
+    stat.incrementBy(100);
+    assertEquals(101, stat.getValue());
+    
+    Stat stat2 = (Stat) stat.clone();
+    assertEquals(stat, stat2);
+    
+    Stat stat3 = new Stat(StatType.TABLE_NUM_BLOCKS);
+    stat3.increment();
+    stat3.increment();
+    stat3.increment();
+    stat3.subtract();
+    stat3.subtractBy(2);
+    stat3.increment();
+    assertEquals(1, stat3.getValue());
+    
+    StatSet group = new StatSet();
+    group.putStat(stat);
+    group.putStat(stat3);
+    
+    assertEquals(2, group.getAllStats().size());
+    assertEquals(stat, group.getStat(StatType.TABLE_NUM_ROWS));
+    assertEquals(101, group.getStat(StatType.TABLE_NUM_ROWS).getValue());
+    assertEquals(1, group.getStat(StatType.TABLE_NUM_BLOCKS).getValue());
+    
+    StatSet group2 = new StatSet(group.getProto());
+    assertEquals(2, group2.getAllStats().size());
+    assertEquals(stat, group2.getStat(StatType.TABLE_NUM_ROWS));
+    assertEquals(101, group2.getStat(StatType.TABLE_NUM_ROWS).getValue());
+    assertEquals(1, group2.getStat(StatType.TABLE_NUM_BLOCKS).getValue());
+    
+    StatSet group3 = (StatSet) group.clone();
+    assertEquals(2, group3.getAllStats().size());
+    assertEquals(stat, group3.getStat(StatType.TABLE_NUM_ROWS));
+    assertEquals(101, group3.getStat(StatType.TABLE_NUM_ROWS).getValue());
+    assertEquals(1, group3.getStat(StatType.TABLE_NUM_BLOCKS).getValue());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatisticsUtil.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatisticsUtil.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatisticsUtil.java
new file mode 100644
index 0000000..8019fec
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestStatisticsUtil.java
@@ -0,0 +1,68 @@
+/**
+ * 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.catalog.statistics;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.apache.tajo.catalog.proto.CatalogProtos.StatType;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestStatisticsUtil {
+  @Test
+  public void testAggregate() throws CloneNotSupportedException {
+    Stat stat = new Stat(StatType.TABLE_NUM_ROWS);
+    stat.incrementBy(100); // 100
+    assertEquals(100, stat.getValue());
+    
+    Stat stat2 = (Stat) stat.clone();
+    stat2.incrementBy(100); // 200
+    assertEquals(200, stat2.getValue());
+    
+    Stat stat3 = new Stat(StatType.TABLE_NUM_BLOCKS);
+    stat3.incrementBy(50); // 50
+    assertEquals(50, stat3.getValue());
+    
+    StatSet group = new StatSet();
+    group.putStat(stat); // num of rows - 100 
+    group.putStat(stat2); // num of rows - 200
+    group.putStat(stat3); // num of blocks - 50
+    
+    // One group has 300 rows and 50 blocks, and it is cloned.
+    StatSet group2 = (StatSet) group.clone();
+    group2.getStat(StatType.TABLE_NUM_ROWS).incrementBy(100); // plus 100
+    
+    // expected that num of rows = 200 * 2 + 100, num of blocks = 50 * 2 
+    StatSet agg = StatisticsUtil.aggregateStatSet(
+        Lists.newArrayList(group, group2));
+    assertEquals(500, agg.getStat(StatType.TABLE_NUM_ROWS).getValue());
+    assertEquals(100, agg.getStat(StatType.TABLE_NUM_BLOCKS).getValue());
+  }
+
+  @Test
+  public void testEmptyAggregate() {
+    TableStat stat1 = new TableStat();
+    TableStat stat2 = new TableStat();
+    TableStat stat3 = new TableStat();
+
+    assertNotNull(StatisticsUtil.aggregateTableStat(
+        Lists.newArrayList(stat1, stat2, stat3)));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestTableStat.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestTableStat.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestTableStat.java
new file mode 100644
index 0000000..6fdd7e2
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/statistics/TestTableStat.java
@@ -0,0 +1,74 @@
+/**
+ * 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.catalog.statistics;
+
+import org.junit.Test;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes.Type;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestTableStat {
+  @Test
+  public final void testTableStat() throws CloneNotSupportedException {
+    TableStat stat = new TableStat();
+    stat.setNumRows(957685);
+    stat.setNumBytes(1023234);
+    stat.setNumBlocks(3123);
+    stat.setNumPartitions(5);
+    stat.setAvgRows(80000);
+        
+    int numCols = 3;
+    ColumnStat[] cols = new ColumnStat[numCols];
+    for (int i = 0; i < numCols; i++) {
+      cols[i] = new ColumnStat(new Column("col_" + i, Type.INT8));
+      cols[i].setNumDistVals(1024 * i);
+      cols[i].setNumNulls(100 * i);
+      stat.addColumnStat(cols[i]);
+    }
+    
+    assertTrue(957685 == stat.getNumRows());
+    assertTrue(1023234 == stat.getNumBytes());
+    assertTrue(3123 == stat.getNumBlocks());
+    assertTrue(5 == stat.getNumPartitions());
+    assertTrue(80000 == stat.getAvgRows());
+    assertEquals(3, stat.getColumnStats().size());
+    for (int i = 0; i < numCols; i++) {
+      assertEquals(cols[i], stat.getColumnStats().get(i));
+    }
+    
+    TableStat stat2 = new TableStat(stat.getProto());
+    tableStatEquals(stat, stat2);
+    
+    TableStat stat3 = (TableStat) stat.clone();
+    tableStatEquals(stat, stat3);    
+  }
+  
+  public void tableStatEquals(TableStat s1, TableStat s2) {
+    assertEquals(s1.getNumRows(), s2.getNumRows());
+    assertEquals(s1.getNumBlocks(), s2.getNumBlocks());
+    assertEquals(s1.getNumPartitions(), s2.getNumPartitions());
+    assertEquals(s1.getAvgRows(), s2.getAvgRows());
+    assertEquals(s1.getColumnStats().size(), s2.getColumnStats().size());
+    for (int i = 0; i < s1.getColumnStats().size(); i++) {
+      assertEquals(s1.getColumnStats().get(i), s2.getColumnStats().get(i));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestCatalog.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestCatalog.java b/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestCatalog.java
deleted file mode 100644
index 9e61d83..0000000
--- a/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestCatalog.java
+++ /dev/null
@@ -1,214 +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 tajo.catalog;
-
-import org.apache.hadoop.fs.Path;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import tajo.catalog.function.GeneralFunction;
-import tajo.catalog.proto.CatalogProtos.FunctionType;
-import tajo.catalog.proto.CatalogProtos.IndexMethod;
-import tajo.catalog.proto.CatalogProtos.StoreType;
-import tajo.common.TajoDataTypes;
-import tajo.common.TajoDataTypes.Type;
-import tajo.conf.TajoConf;
-import tajo.datum.Datum;
-import tajo.storage.Tuple;
-
-import java.io.IOException;
-
-import static org.junit.Assert.*;
-
-public class TestCatalog {
-	static final String FieldName1="f1";
-	static final String FieldName2="f2";
-	static final String FieldName3="f3";	
-
-	Schema schema1;
-	
-	static CatalogServer server;
-	static CatalogService catalog;
-
-	@BeforeClass
-	public static void setUp() throws Exception {
-	  server = new CatalogServer();
-    server.init(new TajoConf());
-    server.start();
-    catalog = new LocalCatalog(server);
-	}
-	
-	@AfterClass
-	public static void tearDown() throws IOException {
-	  server.stop();
-	}
-	
-	@Test
-	public void testGetTable() throws Exception {
-		schema1 = new Schema();
-		schema1.addColumn(FieldName1, Type.BLOB);
-		schema1.addColumn(FieldName2, Type.INT4);
-		schema1.addColumn(FieldName3, Type.INT8);
-		
-		TableDesc meta = CatalogUtil.newTableDesc(
-        "getTable",
-        schema1,
-        StoreType.CSV,
-        new Options(),
-        new Path("/table1"));
-		
-		assertFalse(catalog.existsTable("getTable"));
-		catalog.addTable(meta);
-		assertTrue(catalog.existsTable("getTable"));
-		
-		TableDesc meta2 = catalog.getTableDesc("getTable");
-		System.out.println(meta2);
-		
-		catalog.deleteTable("getTable");
-		assertFalse(catalog.existsTable("getTable"));
-	}
-	
-	@Test(expected = Throwable.class)
-	public void testAddTableNoName() throws Exception {
-	  schema1 = new Schema();
-    schema1.addColumn(FieldName1, Type.BLOB);
-    schema1.addColumn(FieldName2, Type.INT4);
-    schema1.addColumn(FieldName3, Type.INT8);
-    
-	  TableMeta info = CatalogUtil.newTableMeta(schema1, StoreType.CSV);
-	  TableDesc desc = new TableDescImpl();
-	  desc.setMeta(info);
-	  
-	  catalog.addTable(desc);
-	}
-
-  static IndexDesc desc1;
-  static IndexDesc desc2;
-  static IndexDesc desc3;
-
-  static {
-    desc1 = new IndexDesc(
-        "idx_test", "indexed", new Column("id", Type.INT4),
-        IndexMethod.TWO_LEVEL_BIN_TREE, true, true, true);
-
-    desc2 = new IndexDesc(
-        "idx_test2", "indexed", new Column("score", Type.FLOAT8),
-        IndexMethod.TWO_LEVEL_BIN_TREE, false, false, false);
-
-    desc3 = new IndexDesc(
-        "idx_test", "indexed", new Column("id", Type.INT4),
-        IndexMethod.TWO_LEVEL_BIN_TREE, true, true, true);
-  }
-	
-	@Test
-	public void testAddAndDelIndex() throws Exception {
-	  TableDesc desc = TestDBStore.prepareTable();
-	  catalog.addTable(desc);
-	  
-	  assertFalse(catalog.existIndex(desc1.getName()));
-	  assertFalse(catalog.existIndex("indexed", "id"));
-	  catalog.addIndex(desc1);
-	  assertTrue(catalog.existIndex(desc1.getName()));
-	  assertTrue(catalog.existIndex("indexed", "id"));
-	  
-	  assertFalse(catalog.existIndex(desc2.getName()));
-	  assertFalse(catalog.existIndex("indexed", "score"));
-	  catalog.addIndex(desc2);
-	  assertTrue(catalog.existIndex(desc2.getName()));
-	  assertTrue(catalog.existIndex("indexed", "score"));
-	  
-	  catalog.deleteIndex(desc1.getName());
-	  assertFalse(catalog.existIndex(desc1.getName()));
-	  catalog.deleteIndex(desc2.getName());
-	  assertFalse(catalog.existIndex(desc2.getName()));
-	  
-	  catalog.deleteTable(desc.getId());
-	}
-	
-	public static class TestFunc1 extends GeneralFunction {
-		public TestFunc1() {
-			super(					
-					new Column [] {
-							new Column("name", TajoDataTypes.Type.INT4)
-					}
-			);
-		}
-
-    @Override
-    public Datum eval(Tuple params) {
-      return params.get(0);
-    }
-	}
-
-  public static class TestFunc2 extends GeneralFunction {
-    private Datum param;
-    public TestFunc2() {
-      super(
-          new Column [] {
-              new Column("name", TajoDataTypes.Type.INT4),
-              new Column("bytes", TajoDataTypes.Type.BLOB)
-          }
-      );
-    }
-
-    @Override
-    public Datum eval(Tuple params) {
-      return params.get(1);
-    }
-  }
-
-	@Test
-	public final void testRegisterFunc() throws Exception { 
-		assertFalse(catalog.containFunction("test2"));
-		FunctionDesc meta = new FunctionDesc("test2", TestFunc1.class, FunctionType.GENERAL,
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4),
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4));
-
-    catalog.registerFunction(meta);
-		assertTrue(catalog.containFunction("test2", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
-		FunctionDesc retrived = catalog.getFunction("test2", CatalogUtil.newDataTypesWithoutLen(Type.INT4));
-
-		assertEquals(retrived.getSignature(),"test2");
-		assertEquals(retrived.getFuncClass(),TestFunc1.class);
-		assertEquals(retrived.getFuncType(),FunctionType.GENERAL);
-	}
-
-  @Test
-  public final void testUnregisterFunc() throws Exception {    
-    assertFalse(catalog
-        .containFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
-    FunctionDesc meta = new FunctionDesc("test3", TestFunc1.class, FunctionType.GENERAL,
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4),
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4 ));
-    catalog.registerFunction(meta);
-    assertTrue(catalog.containFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
-    catalog.unregisterFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4));
-    assertFalse(catalog
-        .containFunction("test3", CatalogUtil.newDataTypesWithoutLen(Type.INT4)));
-
-    assertFalse(catalog.containFunction("test3",
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4, Type.BLOB)));
-    FunctionDesc overload = new FunctionDesc("test3", TestFunc2.class, FunctionType.GENERAL,
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4),
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4, Type.BLOB));
-    catalog.registerFunction(overload);
-    assertTrue(catalog.containFunction("test3",
-        CatalogUtil.newDataTypesWithoutLen(Type.INT4, Type.BLOB)));
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestDBStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestDBStore.java b/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestDBStore.java
deleted file mode 100644
index 8ed8fb3..0000000
--- a/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/TestDBStore.java
+++ /dev/null
@@ -1,220 +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 tajo.catalog;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import tajo.catalog.proto.CatalogProtos.StoreType;
-import tajo.catalog.statistics.TableStat;
-import tajo.catalog.store.DBStore;
-import tajo.common.TajoDataTypes.Type;
-import tajo.conf.TajoConf;
-import tajo.util.CommonTestingUtil;
-
-import java.io.File;
-
-import static org.junit.Assert.*;
-
-public class TestDBStore {
-  private static final Log LOG = LogFactory.getLog(TestDBStore.class);  
-  private static Configuration conf;
-  private static DBStore store;
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    conf = new TajoConf();
-    Path testDir = CommonTestingUtil.getTestDir("target/test-data/TestDBSTore");
-    File absolutePath = new File(testDir.toUri());
-    conf.set(CatalogConstants.JDBC_URI, "jdbc:derby:"+absolutePath.getAbsolutePath()+"/db");
-    LOG.info("derby repository is set to "+conf.get(CatalogConstants.JDBC_URI));
-    store = new DBStore(conf);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    store.close();
-  }
-
-  @Test
-  public final void testAddAndDeleteTable() throws Exception {
-    Schema schema = new Schema();
-    schema.addColumn("id", Type.INT4)
-    .addColumn("name", Type.TEXT)
-    .addColumn("age", Type.INT4)
-    .addColumn("score", Type.FLOAT8);
-    
-    String tableName = "addedtable";
-    Options opts = new Options();
-    opts.put("file.delimiter", ",");
-    TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV, opts);
-    TableDesc desc = new TableDescImpl(tableName, meta, new Path("/addedtable"));
-    assertFalse(store.existTable(tableName));
-    store.addTable(desc);
-    assertTrue(store.existTable(tableName));
-
-    TableDesc retrieved = store.getTable(tableName);
-    // Schema order check
-    assertSchemaOrder(desc.getMeta().getSchema(), retrieved.getMeta().getSchema());
-    store.deleteTable(tableName);
-    assertFalse(store.existTable(tableName));
-  }
-  
-  @Test
-  public final void testGetTable() throws Exception {
-    Schema schema = new Schema();
-    schema.addColumn("gettable.id", Type.INT4)
-    .addColumn("gettable.name", Type.TEXT)
-    .addColumn("gettable.age", Type.INT4)
-    .addColumn("gettable.score", Type.FLOAT8);
-    
-    String tableName = "gettable";
-    Options opts = new Options();
-    opts.put("file.delimiter", ",");
-    TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV, opts);
-
-    TableStat stat = new TableStat();
-    stat.setNumRows(957685);
-    stat.setNumBytes(1023234);
-    meta.setStat(stat);
-
-    TableDesc desc = new TableDescImpl(tableName, meta, new Path("/gettable"));
-
-    store.addTable(desc);
-    TableDesc retrieved = store.getTable(tableName);
-    assertEquals(",", retrieved.getMeta().getOption("file.delimiter"));
-    assertEquals(desc, retrieved);
-    assertTrue(957685 == desc.getMeta().getStat().getNumRows());
-    assertTrue(1023234 == desc.getMeta().getStat().getNumBytes());
-    // Schema order check
-    assertSchemaOrder(desc.getMeta().getSchema(), retrieved.getMeta().getSchema());
-    store.deleteTable(tableName);
-  }
-  
-  @Test
-  public final void testGetAllTableNames() throws Exception {
-    Schema schema = new Schema();
-    schema.addColumn("id", Type.INT4)
-    .addColumn("name", Type.TEXT)
-    .addColumn("age", Type.INT4)
-    .addColumn("score", Type.FLOAT8);
-    
-    int numTables = 5;
-    for (int i = 0; i < numTables; i++) {
-      String tableName = "tableA_" + i;
-      TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV);
-      TableDesc desc = new TableDescImpl(tableName, meta, 
-          new Path("/tableA_" + i));
-      store.addTable(desc);
-    }
-    
-    assertEquals(numTables, store.getAllTableNames().size());
-  }  
-  
-  @Test
-  public final void testAddAndDeleteIndex() throws Exception {
-    TableDesc table = prepareTable();
-    store.addTable(table);
-    
-    store.addIndex(TestCatalog.desc1.getProto());
-    assertTrue(store.existIndex(TestCatalog.desc1.getName()));
-    store.delIndex(TestCatalog.desc1.getName());
-    assertFalse(store.existIndex(TestCatalog.desc1.getName()));
-    
-    store.deleteTable(table.getId());
-  }
-  
-  @Test
-  public final void testGetIndex() throws Exception {
-    
-    TableDesc table = prepareTable();
-    store.addTable(table);
-    
-    store.addIndex(TestCatalog.desc2.getProto());
-    assertEquals(
-        new IndexDesc(TestCatalog.desc2.getProto()),
-        new IndexDesc(store.getIndex(TestCatalog.desc2.getName())));
-    store.delIndex(TestCatalog.desc2.getName());
-    
-    store.deleteTable(table.getId());
-  }
-  
-  @Test
-  public final void testGetIndexByTableAndColumn() throws Exception {
-    
-    TableDesc table = prepareTable();
-    store.addTable(table);
-    
-    store.addIndex(TestCatalog.desc2.getProto());
-    
-    String tableId = TestCatalog.desc2.getTableId();
-    String columnName = "score";
-    assertEquals(
-        new IndexDesc(TestCatalog.desc2.getProto()),
-        new IndexDesc(store.getIndex(tableId, columnName)));
-    store.delIndex(TestCatalog.desc2.getName());
-    
-    store.deleteTable(table.getId());
-  }
-  
-  @Test
-  public final void testGetAllIndexes() throws Exception {
-    
-    TableDesc table = prepareTable();
-    store.addTable(table);
-    
-    store.addIndex(TestCatalog.desc1.getProto());
-    store.addIndex(TestCatalog.desc2.getProto());
-        
-    assertEquals(2, 
-        store.getIndexes(TestCatalog.desc2.getTableId()).length);
-    store.delIndex(TestCatalog.desc1.getName());
-    store.delIndex(TestCatalog.desc2.getName());
-    
-    store.deleteTable(table.getId());
-  }
-  
-  public static TableDesc prepareTable() {
-    Schema schema = new Schema();
-    schema.addColumn("indexed.id", Type.INT4)
-    .addColumn("indexed.name", Type.TEXT)
-    .addColumn("indexed.age", Type.INT4)
-    .addColumn("indexed.score", Type.FLOAT8);
-    
-    String tableName = "indexed";
-    
-    TableMeta meta = CatalogUtil.newTableMeta(schema, StoreType.CSV);
-    return new TableDescImpl(tableName, meta, new Path("/indexed"));
-  }
-
-  public static void assertSchemaOrder(Schema s1, Schema s2) {
-    // Schema order check
-    assertEquals(s1.getColumnNum(),
-        s2.getColumnNum());
-
-    for (int i = 0; i < s1.getColumnNum(); i++) {
-      assertEquals(s1.getColumn(i).getColumnName(),
-          s2.getColumn(i).getColumnName());
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/statistics/TestColumnStat.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/statistics/TestColumnStat.java b/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/statistics/TestColumnStat.java
deleted file mode 100644
index cffd42f..0000000
--- a/tajo-catalog/tajo-catalog-server/src/test/java/tajo/catalog/statistics/TestColumnStat.java
+++ /dev/null
@@ -1,68 +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 tajo.catalog.statistics;
-
-import org.junit.Test;
-import tajo.catalog.Column;
-import tajo.common.TajoDataTypes.Type;
-import tajo.datum.DatumFactory;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class TestColumnStat {
-
-  @Test
-  public final void testColumnStat() {
-    ColumnStat stat = new ColumnStat(new Column("test", Type.INT8));
-    stat.setNumDistVals(1000);
-    stat.setNumNulls(999);
-    
-    assertTrue(1000 == stat.getNumDistValues());
-    assertTrue(999 == stat.getNumNulls());
-    
-    ColumnStat stat2 = new ColumnStat(stat.getProto());
-    assertTrue(1000 == stat2.getNumDistValues());
-    assertTrue(999 == stat2.getNumNulls());
-  }
-
-  @Test
-  public final void testEqualsObject() {
-    ColumnStat stat = new ColumnStat(new Column("test", Type.INT8));
-    stat.setNumDistVals(1000);
-    stat.setNumNulls(999);
-    stat.setMinValue(DatumFactory.createInt8(5));
-    stat.setMaxValue(DatumFactory.createInt8(10));
-    
-    ColumnStat stat2 = new ColumnStat(stat.getProto());
-    assertEquals(stat, stat2);
-  }
-
-  @Test
-  public final void testClone() throws CloneNotSupportedException {
-    ColumnStat stat = new ColumnStat(new Column("test", Type.INT8));
-    stat.setNumDistVals(1000);
-    stat.setNumNulls(999);
-    stat.setMinValue(DatumFactory.createInt8(5));
-    stat.setMaxValue(DatumFactory.createInt8(10));
-    
-    ColumnStat stat2 = (ColumnStat) stat.clone();
-    assertEquals(stat, stat2);
-  }
-}