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/04/18 13:44:12 UTC

[09/57] [abbrv] [partial] TAJO-752: Escalate sub modules in tajo-core into the top-level modules. (hyunsik)

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
new file mode 100644
index 0000000..49e6874
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
@@ -0,0 +1,666 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.client;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.protobuf.ServiceException;
+import com.sun.org.apache.commons.logging.Log;
+import com.sun.org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.*;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.FunctionDesc;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.ipc.ClientProtos;
+import org.apache.tajo.jdbc.TajoResultSet;
+import org.apache.tajo.storage.StorageUtil;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+@Category(IntegrationTest.class)
+public class TestTajoClient {
+  private static TajoTestingCluster cluster;
+  private static TajoConf conf;
+  private static TajoClient client;
+  private static Path testDir;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+    conf = cluster.getConfiguration();
+    client = new TajoClient(conf);
+    testDir = CommonTestingUtil.getTestDir();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    client.close();
+  }
+
+  private static Path writeTmpTable(String tableName) throws IOException {
+    Path tablePath = StorageUtil.concatPath(testDir, tableName);
+    BackendTestingUtil.writeTmpTable(conf, tablePath);
+    return tablePath;
+  }
+
+  @Test
+  public final void testCreateAndDropDatabases() throws ServiceException {
+    int currentNum = client.getAllDatabaseNames().size();
+
+    String prefix = CatalogUtil.normalizeIdentifier("testCreateDatabase_");
+    for (int i = 0; i < 10; i++) {
+      // test allDatabaseNames
+      assertEquals(currentNum + i, client.getAllDatabaseNames().size());
+
+      // test existence
+      assertFalse(client.existDatabase(prefix + i));
+      assertTrue(client.createDatabase(prefix + i));
+      assertTrue(client.existDatabase(prefix + i));
+
+      // test allDatabaseNames
+      assertEquals(currentNum + i + 1, client.getAllDatabaseNames().size());
+      assertTrue(client.getAllDatabaseNames().contains(prefix + i));
+    }
+
+    // test dropDatabase, existDatabase and getAllDatabaseNames()
+    for (int i = 0; i < 10; i++) {
+      assertTrue(client.existDatabase(prefix + i));
+      assertTrue(client.getAllDatabaseNames().contains(prefix + i));
+      assertTrue(client.dropDatabase(prefix + i));
+      assertFalse(client.existDatabase(prefix + i));
+      assertFalse(client.getAllDatabaseNames().contains(prefix + i));
+    }
+
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testCurrentDatabase() throws IOException, ServiceException, InterruptedException {
+    int currentNum = client.getAllDatabaseNames().size();
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase());
+
+    String databaseName = CatalogUtil.normalizeIdentifier("testcurrentdatabase");
+    assertTrue(client.createDatabase(databaseName));
+    assertEquals(currentNum + 1, client.getAllDatabaseNames().size());
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase());
+    assertTrue(client.selectDatabase(databaseName));
+    assertEquals(databaseName, client.getCurrentDatabase());
+    assertTrue(client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME));
+    assertTrue(client.dropDatabase(databaseName));
+
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testSelectDatabaseToInvalidOne() throws IOException, ServiceException, InterruptedException {
+    int currentNum = client.getAllDatabaseNames().size();
+    assertFalse(client.existDatabase("invaliddatabase"));
+
+    try {
+      assertTrue(client.selectDatabase("invaliddatabase"));
+      assertFalse(true);
+    } catch (Throwable t) {
+      assertFalse(false);
+    }
+
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testDropCurrentDatabase() throws IOException, ServiceException, InterruptedException {
+    int currentNum = client.getAllDatabaseNames().size();
+    String databaseName = CatalogUtil.normalizeIdentifier("testdropcurrentdatabase");
+    assertTrue(client.createDatabase(databaseName));
+    assertTrue(client.selectDatabase(databaseName));
+    assertEquals(databaseName, client.getCurrentDatabase());
+
+    try {
+      client.dropDatabase(databaseName);
+      assertFalse(true);
+    } catch (Throwable t) {
+      assertFalse(false);
+    }
+
+    assertTrue(client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME));
+    assertTrue(client.dropDatabase(databaseName));
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testSessionVariables() throws IOException, ServiceException, InterruptedException {
+    String prefixName = "key_";
+    String prefixValue = "val_";
+    for (int i = 0; i < 10; i++) {
+      String key = prefixName + i;
+      String val = prefixValue + i;
+
+      assertEquals(i, client.getAllSessionVariables().size());
+      assertFalse(client.getAllSessionVariables().containsKey(key));
+      assertFalse(client.existSessionVariable(key));
+
+      Map<String, String> map = Maps.newHashMap();
+      map.put(key, val);
+      client.updateSessionVariables(map);
+
+      assertEquals(i + 1, client.getAllSessionVariables().size());
+      assertTrue(client.getAllSessionVariables().containsKey(key));
+      assertTrue(client.existSessionVariable(key));
+    }
+
+    int totalSessionVarNum = client.getAllSessionVariables().size();
+
+    for (int i = 0; i < 10; i++) {
+      String key = prefixName + i;
+
+      assertTrue(client.getAllSessionVariables().containsKey(key));
+      assertTrue(client.existSessionVariable(key));
+
+      client.unsetSessionVariables(Lists.newArrayList(key));
+
+      assertFalse(client.getAllSessionVariables().containsKey(key));
+      assertFalse(client.existSessionVariable(key));
+    }
+
+    assertEquals(totalSessionVarNum - 10, client.getAllSessionVariables().size());
+  }
+
+  @Test
+  public final void testKillQuery() throws IOException, ServiceException, InterruptedException {
+    ClientProtos.SubmitQueryResponse res = client.executeQuery("select sleep(1) from lineitem");
+    Thread.sleep(1000);
+    QueryId queryId = new QueryId(res.getQueryId());
+    client.killQuery(queryId);
+    assertEquals(TajoProtos.QueryState.QUERY_KILLED, client.getQueryStatus(queryId).getState());
+  }
+
+  @Test
+  public final void testUpdateQuery() throws IOException, ServiceException {
+    final String tableName = CatalogUtil.normalizeIdentifier("testUpdateQuery");
+    Path tablePath = writeTmpTable(tableName);
+
+    assertFalse(client.existTable(tableName));
+    String sql =
+        "create external table " + tableName + " (deptname text, score integer) "
+            + "using csv location '" + tablePath + "'";
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+    client.dropTable(tableName);
+    assertFalse(client.existTable(tableName));
+  }
+
+  @Test
+  public final void testCreateAndDropExternalTable()
+      throws IOException, ServiceException, SQLException {
+    final String tableName = "testCreateAndDropExternalTable";
+    Path tablePath = writeTmpTable(tableName);
+    LOG.error("Full path:" + tablePath.toUri().getRawPath());
+    FileSystem fs = tablePath.getFileSystem(conf);
+    assertTrue(fs.exists(tablePath));
+
+    assertFalse(client.existTable(tableName));
+
+    client.createExternalTable(tableName, BackendTestingUtil.mockupSchema, tablePath, BackendTestingUtil.mockupMeta);
+    assertTrue(client.existTable(tableName));
+    client.dropTable(tableName);
+    assertFalse(client.existTable(tableName));
+    fs = tablePath.getFileSystem(conf);
+    assertTrue(fs.exists(tablePath));
+  }
+
+  @Test
+  public final void testCreateAndPurgeExternalTable() throws IOException, ServiceException, SQLException {
+    final String tableName = "testCreateAndPurgeExternalTable";
+    Path tablePath = writeTmpTable(tableName);
+    LOG.error("Full path:" + tablePath.toUri().getRawPath());
+    FileSystem fs = tablePath.getFileSystem(conf);
+    assertTrue(fs.exists(tablePath));
+
+    assertFalse(client.existTable(tableName));
+
+    client.createExternalTable(tableName, BackendTestingUtil.mockupSchema, tablePath, BackendTestingUtil.mockupMeta);
+    assertTrue(client.existTable(tableName));
+    client.dropTable(tableName, true);
+    assertFalse(client.existTable(tableName));
+    fs = tablePath.getFileSystem(conf);
+    assertFalse("Checking if table data exists", fs.exists(tablePath));
+  }
+
+  @Test
+  public final void testCreateAndDropExternalTableByExecuteQuery() throws IOException, ServiceException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropExternalTableByExecuteQuery");
+
+    Path tablePath = writeTmpTable(tableName);
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create external table " + tableName + " (deptname text, score int4) " + "using csv location '"
+        + tablePath + "'";
+
+    client.executeQueryAndGetResult(sql);
+    assertTrue(client.existTable(tableName));
+
+    client.updateQuery("drop table " + tableName);
+    assertFalse(client.existTable("tableName"));
+    FileSystem localFS = FileSystem.getLocal(conf);
+    assertTrue(localFS.exists(tablePath));
+  }
+
+  @Test
+  public final void testCreateAndPurgeExternalTableByExecuteQuery() throws IOException, ServiceException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndPurgeExternalTableByExecuteQuery");
+
+    Path tablePath = writeTmpTable(tableName);
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create external table " + tableName + " (deptname text, score int4) " + "using csv location '"
+        + tablePath + "'";
+
+    client.executeQueryAndGetResult(sql);
+    assertTrue(client.existTable(tableName));
+
+    client.updateQuery("drop table " + tableName + " purge");
+    assertFalse(client.existTable(tableName));
+    FileSystem localFS = FileSystem.getLocal(conf);
+    assertFalse(localFS.exists(tablePath));
+  }
+
+  @Test
+  public final void testCreateAndDropTableByExecuteQuery() throws IOException, ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropTableByExecuteQuery");
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName);
+    assertFalse(client.existTable(tableName));
+    assertTrue(hdfs.exists(tablePath));
+  }
+
+  @Test
+  public final void testCreateAndPurgeTableByExecuteQuery() throws IOException, ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndPurgeTableByExecuteQuery");
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName + " purge");
+    assertFalse(client.existTable(tableName));
+    assertFalse(hdfs.exists(tablePath));
+  }
+
+  @Test
+  public final void testDDLByExecuteQuery() throws IOException, ServiceException {
+    final String tableName = CatalogUtil.normalizeIdentifier("testDDLByExecuteQuery");
+    Path tablePath = writeTmpTable(tableName);
+
+    assertFalse(client.existTable(tableName));
+    String sql =
+        "create external table " + tableName + " (deptname text, score int4) "
+            + "using csv location '" + tablePath + "'";
+    client.executeQueryAndGetResult(sql);
+    assertTrue(client.existTable(tableName));
+  }
+
+  @Test
+  public final void testGetTableList() throws IOException, ServiceException {
+    String tableName1 = "GetTableList1".toLowerCase();
+    String tableName2 = "GetTableList2".toLowerCase();
+
+    assertFalse(client.existTable(tableName1));
+    assertFalse(client.existTable(tableName2));
+    client.updateQuery("create table GetTableList1 (age int, name text);");
+    client.updateQuery("create table GetTableList2 (age int, name text);");
+
+    assertTrue(client.existTable(tableName1));
+    assertTrue(client.existTable(tableName2));
+
+    Set<String> tables = Sets.newHashSet(client.getTableList(null));
+    assertTrue(tables.contains(tableName1));
+    assertTrue(tables.contains(tableName2));
+  }
+
+  Log LOG = LogFactory.getLog(TestTajoClient.class);
+
+  @Test
+  public final void testGetTableDesc() throws IOException, ServiceException, SQLException {
+    final String tableName1 = CatalogUtil.normalizeIdentifier("table3");
+    Path tablePath = writeTmpTable(tableName1);
+    LOG.error("Full path:" + tablePath.toUri().getRawPath());
+    FileSystem fs = tablePath.getFileSystem(conf);
+    assertTrue(fs.exists(tablePath));
+
+    assertNotNull(tablePath);
+    assertFalse(client.existTable(tableName1));
+
+    client.createExternalTable("table3", BackendTestingUtil.mockupSchema, tablePath, BackendTestingUtil.mockupMeta);
+    assertTrue(client.existTable(tableName1));
+
+    TableDesc desc = client.getTableDesc(tableName1);
+    assertNotNull(desc);
+    assertEquals(CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, tableName1), desc.getName());
+    assertTrue(desc.getStats().getNumBytes() > 0);
+  }
+
+  //@Test
+  public final void testCreateAndDropTablePartitionedHash1ByExecuteQuery() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = "testCreateAndDropTablePartitionedHash1ByExecuteQuery";
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+    sql += " PARTITION BY HASH (deptname)";
+    sql += " (PARTITION sub_part1, PARTITION sub_part2, PARTITION sub_part3)";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName);
+    assertFalse(client.existTable(tableName));
+    assertTrue(hdfs.exists(tablePath));
+  }
+
+  //@Test
+  public final void testCreateAndPurgeTablePartitionedHash1ByExecuteQuery() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = "testCreateAndPurgeTablePartitionedHash1ByExecuteQuery";
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+    sql += " PARTITION BY HASH (deptname)";
+    sql += " (PARTITION sub_part1, PARTITION sub_part2, PARTITION sub_part3)";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName + " purge");
+    assertFalse(client.existTable(tableName));
+    assertFalse(hdfs.exists(tablePath));
+  }
+
+  //@Test
+  public final void testCreateAndDropTablePartitionedHash2ByExecuteQuery() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = "testCreateAndDropTablePartitionedHash2ByExecuteQuery";
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+    sql += "PARTITION BY HASH (deptname)";
+    sql += "PARTITIONS 2";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName + " purge");
+    assertFalse(client.existTable(tableName));
+    assertFalse(hdfs.exists(tablePath));
+  }
+
+  //@Test
+  public final void testCreateAndDropTablePartitionedListByExecuteQuery() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = "testCreateAndDropTablePartitionedListByExecuteQuery";
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+    sql += "PARTITION BY LIST (deptname)";
+    sql += "( PARTITION sub_part1 VALUES('r&d', 'design'),";
+    sql += "PARTITION sub_part2 VALUES('sales', 'hr') )";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName + " purge");
+    assertFalse(client.existTable(tableName));
+    assertFalse(hdfs.exists(tablePath));
+  }
+
+  //@Test
+  public final void testCreateAndDropTablePartitionedRangeByExecuteQuery() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = "testCreateAndDropTablePartitionedRangeByExecuteQuery";
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+    sql += "PARTITION BY RANGE (score)";
+    sql += "( PARTITION sub_part1 VALUES LESS THAN (2),";
+    sql += "PARTITION sub_part2 VALUES LESS THAN (5),";
+    sql += "PARTITION sub_part2 VALUES LESS THAN (MAXVALUE) )";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName +" purge");
+    assertFalse(client.existTable(tableName));
+    assertFalse(hdfs.exists(tablePath));
+  }
+
+  @Test
+  public final void testFailCreateTablePartitionedOtherExceptColumn() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = "testFailCreateTablePartitionedOtherExceptColumn";
+
+    assertFalse(client.existTable(tableName));
+
+    String rangeSql = "create table " + tableName + " (deptname text, score int4)";
+    rangeSql += "PARTITION BY RANGE (score)";
+    rangeSql += "( PARTITION sub_part1 VALUES LESS THAN (2),";
+    rangeSql += "PARTITION sub_part2 VALUES LESS THAN (5),";
+    rangeSql += "PARTITION sub_part2 VALUES LESS THAN (MAXVALUE) )";
+
+    assertFalse(client.updateQuery(rangeSql));
+ 
+    String listSql = "create table " + tableName + " (deptname text, score int4)";
+    listSql += "PARTITION BY LIST (deptname)";
+    listSql += "( PARTITION sub_part1 VALUES('r&d', 'design'),";
+    listSql += "PARTITION sub_part2 VALUES('sales', 'hr') )";
+
+    assertFalse(client.updateQuery(listSql));
+
+    String hashSql = "create table " + tableName + " (deptname text, score int4)";
+    hashSql += "PARTITION BY HASH (deptname)";
+    hashSql += "PARTITIONS 2";
+
+    assertFalse(client.updateQuery(hashSql));
+  }
+
+  @Test
+  public final void testCreateAndDropTablePartitionedColumnByExecuteQuery() throws IOException,
+      ServiceException, SQLException {
+    TajoConf conf = cluster.getConfiguration();
+    final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropTablePartitionedColumnByExecuteQuery");
+
+    assertFalse(client.existTable(tableName));
+
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+    sql += "PARTITION BY COLUMN (key1 text)";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    Path tablePath = client.getTableDesc(tableName).getPath();
+    FileSystem hdfs = tablePath.getFileSystem(conf);
+    assertTrue(hdfs.exists(tablePath));
+
+    client.updateQuery("drop table " + tableName + " purge");
+    assertFalse(client.existTable(tableName));
+    assertFalse(hdfs.exists(tablePath));
+  }
+
+  @Test
+  public final void testGetFunctions() throws IOException,
+      ServiceException, SQLException {
+    Collection<FunctionDesc> catalogFunctions = cluster.getMaster().getCatalog().getFunctions();
+    String functionName = "sum";
+    int numFunctions = 0;
+    for(FunctionDesc eachFunction: catalogFunctions) {
+      if(functionName.equals(eachFunction.getSignature())) {
+        numFunctions++;
+      }
+    }
+
+    List<CatalogProtos.FunctionDescProto> functions = client.getFunctions(functionName);
+    assertEquals(numFunctions, functions.size());
+
+    functions = client.getFunctions("notmatched");
+    assertEquals(0, functions.size());
+
+    functions = client.getFunctions(null);
+    assertEquals(catalogFunctions.size(), functions.size());
+  }
+
+  @Test
+  public final void testGetFinishedQueryList() throws IOException,
+      ServiceException, SQLException {
+    final String tableName = CatalogUtil.normalizeIdentifier("testGetFinishedQueryList");
+    String sql = "create table " + tableName + " (deptname text, score int4)";
+
+    client.updateQuery(sql);
+    assertTrue(client.existTable(tableName));
+
+    int numFinishedQueries = client.getFinishedQueryList().size();
+    ResultSet resultSet = client.executeQueryAndGetResult("select * from " + tableName + " order by deptname");
+    assertNotNull(resultSet);
+
+    resultSet = client.executeQueryAndGetResult("select * from " + tableName + " order by deptname");
+    assertNotNull(resultSet);
+    assertEquals(numFinishedQueries + 2, client.getFinishedQueryList().size());
+
+    resultSet.close();
+  }
+
+  /**
+   * The main objective of this test is to get the status of a query which is actually finished.
+   * Statuses of queries regardless of its status should be available for a specified time duration.
+   */
+  @Test(timeout = 20 * 1000)
+  public final void testGetQueryStatusAndResultAfterFinish() throws Exception {
+    String sql = "select * from lineitem order by l_orderkey";
+    ClientProtos.SubmitQueryResponse response = client.executeQuery(sql);
+
+    assertNotNull(response);
+    QueryId queryId = new QueryId(response.getQueryId());
+
+    try {
+      long startTime = System.currentTimeMillis();
+      while (true) {
+        Thread.sleep(5 * 1000);
+
+        List<ClientProtos.BriefQueryInfo> finishedQueries = client.getFinishedQueryList();
+        boolean finished = false;
+        if (finishedQueries != null) {
+          for (ClientProtos.BriefQueryInfo eachQuery: finishedQueries) {
+            if (eachQuery.getQueryId().equals(queryId.getProto())) {
+              finished = true;
+              break;
+            }
+          }
+        }
+
+        if (finished) {
+          break;
+        }
+        if(System.currentTimeMillis() - startTime > 20 * 1000) {
+          fail("Too long time execution query");
+        }
+      }
+
+      QueryStatus queryStatus = client.getQueryStatus(queryId);
+      assertNotNull(queryStatus);
+      assertTrue(!TajoClient.isQueryRunnning(queryStatus.getState()));
+
+      TajoResultSet resultSet = (TajoResultSet) client.getQueryResult(queryId);
+      assertNotNull(resultSet);
+
+      int count = 0;
+      while(resultSet.next()) {
+        count++;
+      }
+
+      assertEquals(5, count);
+    } finally {
+      client.closeQuery(queryId);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/cluster/TestServerName.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/cluster/TestServerName.java b/tajo-core/src/test/java/org/apache/tajo/cluster/TestServerName.java
new file mode 100644
index 0000000..513187d
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/cluster/TestServerName.java
@@ -0,0 +1,102 @@
+/**
+ * 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.cluster;
+
+import org.junit.Test;
+import org.apache.tajo.master.cluster.ServerName;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestServerName {
+
+	@Test
+	public void testServerNameStringInt() {
+		ServerName server = new ServerName("ex1.com",50030);
+		assertEquals("ex1.com", server.getHostname());
+		assertEquals(50030, server.getPort());
+	}
+
+	@Test
+	public void testServerNameString() {
+		ServerName server = new ServerName("ex1.com:50030");
+		assertEquals("ex1.com", server.getHostname());
+		assertEquals(50030, server.getPort());
+	}
+
+	@Test
+	public void testParseHostname() {
+		assertEquals("ex1.com",ServerName.parseHostname("ex1.com:50030"));
+	}
+
+	@Test
+	public void testParsePort() {
+		assertEquals(50030,ServerName.parsePort("ex1.com:50030"));
+	}
+
+	@Test
+	public void testToString() {
+		ServerName server = new ServerName("ex1.com",50030);
+		assertEquals("ex1.com:50030", server.toString());
+	}
+
+	@Test
+	public void testGetServerName() {
+		ServerName server = new ServerName("ex1.com",50030);
+		assertEquals("ex1.com:50030", server.getServerName());
+	}
+
+	@Test
+	public void testGetHostname() {
+		ServerName server = new ServerName("ex1.com",50030);
+		assertEquals("ex1.com", server.getHostname());
+	}
+
+	@Test
+	public void testGetPort() {
+		ServerName server = new ServerName("ex1.com",50030);
+		assertEquals(50030, server.getPort());
+	}
+
+	@Test
+	public void testGetServerNameStringInt() {
+		assertEquals("ex2.com:50030",ServerName.getServerName("ex2.com", 50030));
+	}
+
+	@Test
+	public void testCompareTo() {
+		ServerName s1 = new ServerName("ex1.com:50030");
+		ServerName s2 = new ServerName("ex1.com:60030");
+		
+		assertTrue(s1.compareTo(s2) < 0);
+		assertTrue(s2.compareTo(s1) > 0);
+		
+		ServerName s3 = new ServerName("ex1.com:50030");
+		assertTrue(s1.compareTo(s3) == 0);
+		
+		ServerName s4 = new ServerName("ex2.com:50030");
+		assertTrue(s1.compareTo(s4) < 0);
+		assertTrue(s4.compareTo(s1) > 0);
+	}
+
+  @Test (expected = IllegalArgumentException.class)
+  public void testException() {
+    new ServerName("ex1.com");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
new file mode 100644
index 0000000..d19b4d6
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
@@ -0,0 +1,210 @@
+/**
+ * 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.engine.eval;
+
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.cli.InvalidStatementException;
+import org.apache.tajo.cli.ParsedResult;
+import org.apache.tajo.cli.SimpleParser;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.json.CoreGsonHelper;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.*;
+import org.apache.tajo.engine.utils.SchemaUtil;
+import org.apache.tajo.master.TajoMaster;
+import org.apache.tajo.master.session.Session;
+import org.apache.tajo.storage.LazyTuple;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+import org.apache.tajo.util.Bytes;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class ExprTestBase {
+  private static TajoTestingCluster util;
+  private static CatalogService cat;
+  private static SQLAnalyzer analyzer;
+  private static PreLogicalPlanVerifier preLogicalPlanVerifier;
+  private static LogicalPlanner planner;
+  private static LogicalOptimizer optimizer;
+  private static LogicalPlanVerifier annotatedPlanVerifier;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    cat = util.getMiniCatalogCluster().getCatalog();
+    cat.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
+    cat.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+      cat.createFunction(funcDesc);
+    }
+
+    analyzer = new SQLAnalyzer();
+    preLogicalPlanVerifier = new PreLogicalPlanVerifier(cat);
+    planner = new LogicalPlanner(cat);
+    optimizer = new LogicalOptimizer(util.getConfiguration());
+    annotatedPlanVerifier = new LogicalPlanVerifier(util.getConfiguration(), cat);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  private static void assertJsonSerDer(EvalNode expr) {
+    String json = CoreGsonHelper.toJson(expr, EvalNode.class);
+    EvalNode fromJson = CoreGsonHelper.fromJson(json, EvalNode.class);
+    assertEquals(expr, fromJson);
+  }
+
+  /**
+   * verify query syntax and get raw targets.
+   *
+   * @param query a query for execution
+   * @param condition this parameter means whether it is for success case or is not for failure case.
+   * @return
+   * @throws PlanningException
+   */
+  private static Target[] getRawTargets(String query, boolean condition) throws PlanningException,
+      InvalidStatementException {
+
+    Session session = LocalTajoTestingUtility.createDummySession();
+    List<ParsedResult> parsedResults = SimpleParser.parseScript(query);
+    if (parsedResults.size() > 1) {
+      throw new RuntimeException("this query includes two or more statements.");
+    }
+    Expr expr = analyzer.parse(parsedResults.get(0).getStatement());
+    VerificationState state = new VerificationState();
+    preLogicalPlanVerifier.verify(session, state, expr);
+    if (state.getErrorMessages().size() > 0) {
+      if (!condition && state.getErrorMessages().size() > 0) {
+        throw new PlanningException(state.getErrorMessages().get(0));
+      }
+      assertFalse(state.getErrorMessages().get(0), true);
+    }
+    LogicalPlan plan = planner.createPlan(session, expr, true);
+    optimizer.optimize(plan);
+    annotatedPlanVerifier.verify(session, state, plan);
+
+    if (state.getErrorMessages().size() > 0) {
+      assertFalse(state.getErrorMessages().get(0), true);
+    }
+
+    Target [] targets = plan.getRootBlock().getRawTargets();
+    if (targets == null) {
+      throw new PlanningException("Wrong query statement or query plan: " + parsedResults.get(0).getStatement());
+    }
+    for (Target t : targets) {
+      assertJsonSerDer(t.getEvalTree());
+    }
+    return targets;
+  }
+
+  public void testSimpleEval(String query, String [] expected) throws IOException {
+    testEval(null, null, null, query, expected);
+  }
+
+  public void testSimpleEval(String query, String [] expected, boolean condition) throws IOException {
+    testEval(null, null, null, query, expected, ',', condition);
+  }
+
+  public void testEval(Schema schema, String tableName, String csvTuple, String query, String [] expected)
+      throws IOException {
+    testEval(schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple, query,
+        expected, ',', true);
+  }
+
+  public void testEval(Schema schema, String tableName, String csvTuple, String query, String [] expected,
+                       char delimiter, boolean condition) throws IOException {
+    LazyTuple lazyTuple;
+    VTuple vtuple  = null;
+    String qualifiedTableName =
+        CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME,
+            tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null);
+    Schema inputSchema = null;
+    if (schema != null) {
+      inputSchema = SchemaUtil.clone(schema);
+      inputSchema.setQualifier(qualifiedTableName);
+
+      int targetIdx [] = new int[inputSchema.size()];
+      for (int i = 0; i < targetIdx.length; i++) {
+        targetIdx[i] = i;
+      }
+
+      lazyTuple =
+          new LazyTuple(inputSchema, Bytes.splitPreserveAllTokens(csvTuple.getBytes(), delimiter, targetIdx),0);
+      vtuple = new VTuple(inputSchema.size());
+      for (int i = 0; i < inputSchema.size(); i++) {
+        // If null value occurs, null datum is manually inserted to an input tuple.
+        if (lazyTuple.get(i) instanceof TextDatum && lazyTuple.get(i).asChars().equals("")) {
+          vtuple.put(i, NullDatum.get());
+        } else {
+          vtuple.put(i, lazyTuple.get(i));
+        }
+      }
+      cat.createTable(new TableDesc(qualifiedTableName, inputSchema,
+          CatalogProtos.StoreType.CSV, new Options(), CommonTestingUtil.getTestDir()));
+    }
+
+    Target [] targets;
+
+    try {
+      targets = getRawTargets(query, condition);
+
+      Tuple outTuple = new VTuple(targets.length);
+      for (int i = 0; i < targets.length; i++) {
+        EvalNode eval = targets[i].getEvalTree();
+        outTuple.put(i, eval.eval(inputSchema, vtuple));
+      }
+
+      for (int i = 0; i < expected.length; i++) {
+        assertEquals(query, expected[i], outTuple.get(i).asChars());
+      }
+    } catch (InvalidStatementException e) {
+      assertFalse(e.getMessage(), true);
+    } catch (PlanningException e) {
+      // In failure test case, an exception must occur while executing query.
+      // So, we should check an error message, and return it.
+      if (!condition) {
+        assertEquals(expected[0], e.getMessage());
+      } else {
+        assertFalse(e.getMessage(), true);
+      }
+    } finally {
+      if (schema != null) {
+        cat.dropTable(qualifiedTableName);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
new file mode 100644
index 0000000..9d7e438
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
@@ -0,0 +1,323 @@
+/**
+ * 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.engine.eval;
+
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.json.CoreGsonHelper;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+import org.junit.Test;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
+import static org.junit.Assert.*;
+
+public class TestEvalTree extends ExprTestBase{
+  @Test
+  public void testTupleEval() throws CloneNotSupportedException {
+    ConstEval e1 = new ConstEval(DatumFactory.createInt4(1));
+    assertCloneEqual(e1);
+    FieldEval e2 = new FieldEval("table1.score", CatalogUtil.newSimpleDataType(INT4)); // it indicates
+    assertCloneEqual(e2);
+
+    Schema schema1 = new Schema();
+    schema1.addColumn("table1.id", INT4);
+    schema1.addColumn("table1.score", INT4);
+    
+    BinaryEval expr = new BinaryEval(EvalType.PLUS, e1, e2);
+    assertCloneEqual(expr);
+    VTuple tuple = new VTuple(2);
+    tuple.put(0, DatumFactory.createInt4(1)); // put 0th field
+    tuple.put(1, DatumFactory.createInt4(99)); // put 0th field
+
+    // the result of evaluation must be 100.
+    assertEquals(expr.eval(schema1, tuple).asInt4(), 100);
+  }
+
+  public static class MockTrueEval extends EvalNode {
+
+    public MockTrueEval() {
+      super(EvalType.CONST);
+    }
+
+    @Override
+    public String getName() {
+      return this.getClass().getName();
+    }
+
+    @Override
+    public Datum eval(Schema schema, Tuple tuple) {
+      return DatumFactory.createBool(true);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return true;
+    }
+
+    @Override
+    public DataType getValueType() {
+      return CatalogUtil.newSimpleDataType(BOOLEAN);
+    }
+
+  }
+
+  public static class MockFalseExpr extends EvalNode {
+
+    public MockFalseExpr() {
+      super(EvalType.CONST);
+    }
+
+    @Override
+    public Datum eval(Schema schema, Tuple tuple) {
+      return DatumFactory.createBool(false);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return true;
+    }
+
+    @Override
+    public String getName() {
+      return this.getClass().getName();
+    }
+
+    @Override
+    public DataType getValueType() {
+      return CatalogUtil.newSimpleDataType(BOOLEAN);
+    }
+  }
+
+  @Test
+  public void testAndTest() {
+    MockTrueEval trueExpr = new MockTrueEval();
+    MockFalseExpr falseExpr = new MockFalseExpr();
+
+    BinaryEval andExpr = new BinaryEval(EvalType.AND, trueExpr, trueExpr);
+    assertTrue(andExpr.eval(null, null).asBool());
+
+    andExpr = new BinaryEval(EvalType.AND, falseExpr, trueExpr);
+    assertFalse(andExpr.eval(null, null).asBool());
+
+    andExpr = new BinaryEval(EvalType.AND, trueExpr, falseExpr);
+    assertFalse(andExpr.eval(null, null).asBool());
+
+    andExpr = new BinaryEval(EvalType.AND, falseExpr, falseExpr);
+    assertFalse(andExpr.eval(null, null).asBool());
+  }
+
+  @Test
+  public void testOrTest() {
+    MockTrueEval trueExpr = new MockTrueEval();
+    MockFalseExpr falseExpr = new MockFalseExpr();
+
+    BinaryEval orExpr = new BinaryEval(EvalType.OR, trueExpr, trueExpr);
+    assertTrue(orExpr.eval(null, null).asBool());
+
+    orExpr = new BinaryEval(EvalType.OR, falseExpr, trueExpr);
+    assertTrue(orExpr.eval(null, null).asBool());
+
+    orExpr = new BinaryEval(EvalType.OR, trueExpr, falseExpr);
+    assertTrue(orExpr.eval(null, null).asBool());
+
+    orExpr = new BinaryEval(EvalType.OR, falseExpr, falseExpr);
+    assertFalse(orExpr.eval(null, null).asBool());
+  }
+
+  @Test
+  public final void testCompOperator() {
+    ConstEval e1;
+    ConstEval e2;
+    BinaryEval expr;
+
+    // Constant
+    e1 = new ConstEval(DatumFactory.createInt4(9));
+    e2 = new ConstEval(DatumFactory.createInt4(34));
+    expr = new BinaryEval(EvalType.LTH, e1, e2);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, e1, e2);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.LTH, e2, e1);
+    assertFalse(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, e2, e1);
+    assertFalse(expr.eval(null, null).asBool());
+
+    expr = new BinaryEval(EvalType.GTH, e2, e1);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, e2, e1);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.GTH, e1, e2);
+    assertFalse(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, e1, e2);
+    assertFalse(expr.eval(null, null).asBool());
+
+    BinaryEval plus = new BinaryEval(EvalType.PLUS, e1, e2);
+    expr = new BinaryEval(EvalType.LTH, e1, plus);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, e1, plus);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.LTH, plus, e1);
+    assertFalse(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, plus, e1);
+    assertFalse(expr.eval(null, null).asBool());
+
+    expr = new BinaryEval(EvalType.GTH, plus, e1);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, plus, e1);
+    assertTrue(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.GTH, e1, plus);
+    assertFalse(expr.eval(null, null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, e1, plus);
+    assertFalse(expr.eval(null, null).asBool());
+  }
+
+  @Test
+  public final void testArithmaticsOperator() 
+      throws CloneNotSupportedException {
+    ConstEval e1;
+    ConstEval e2;
+
+    // PLUS
+    e1 = new ConstEval(DatumFactory.createInt4(9));
+    e2 = new ConstEval(DatumFactory.createInt4(34));
+    BinaryEval expr = new BinaryEval(EvalType.PLUS, e1, e2);
+    assertEquals(expr.eval(null, null).asInt4(), 43);
+    assertCloneEqual(expr);
+    
+    // MINUS
+    e1 = new ConstEval(DatumFactory.createInt4(5));
+    e2 = new ConstEval(DatumFactory.createInt4(2));
+    expr = new BinaryEval(EvalType.MINUS, e1, e2);
+    assertEquals(expr.eval(null, null).asInt4(), 3);
+    assertCloneEqual(expr);
+    
+    // MULTIPLY
+    e1 = new ConstEval(DatumFactory.createInt4(5));
+    e2 = new ConstEval(DatumFactory.createInt4(2));
+    expr = new BinaryEval(EvalType.MULTIPLY, e1, e2);
+    assertEquals(expr.eval(null, null).asInt4(), 10);
+    assertCloneEqual(expr);
+    
+    // DIVIDE
+    e1 = new ConstEval(DatumFactory.createInt4(10));
+    e2 = new ConstEval(DatumFactory.createInt4(5));
+    expr = new BinaryEval(EvalType.DIVIDE, e1, e2);
+    assertEquals(expr.eval(null, null).asInt4(), 2);
+    assertCloneEqual(expr);
+  }
+
+  @Test
+  public final void testGetReturnType() {
+    ConstEval e1;
+    ConstEval e2;
+
+    // PLUS
+    e1 = new ConstEval(DatumFactory.createInt4(9));
+    e2 = new ConstEval(DatumFactory.createInt4(34));
+    BinaryEval expr = new BinaryEval(EvalType.PLUS, e1, e2);
+    assertEquals(CatalogUtil.newSimpleDataType(INT4), expr.getValueType());
+
+    expr = new BinaryEval(EvalType.LTH, e1, e2);
+    assertTrue(expr.eval(null, null).asBool());
+    assertEquals(CatalogUtil.newSimpleDataType(BOOLEAN), expr.getValueType());
+
+    e1 = new ConstEval(DatumFactory.createFloat8(9.3));
+    e2 = new ConstEval(DatumFactory.createFloat8(34.2));
+    expr = new BinaryEval(EvalType.PLUS, e1, e2);
+    assertEquals(CatalogUtil.newSimpleDataType(FLOAT8), expr.getValueType());
+  }
+  
+  @Test
+  public final void testEquals() throws CloneNotSupportedException {
+    ConstEval e1;
+    ConstEval e2;
+
+    // PLUS
+    e1 = new ConstEval(DatumFactory.createInt4(34));
+    e2 = new ConstEval(DatumFactory.createInt4(34));
+    assertEquals(e1, e2);
+    
+    BinaryEval plus1 = new BinaryEval(EvalType.PLUS, e1, e2);
+    BinaryEval plus2 = new BinaryEval(EvalType.PLUS, e2, e1);
+    assertEquals(plus1, plus2);
+    
+    ConstEval e3 = new ConstEval(DatumFactory.createInt4(29));
+    BinaryEval plus3 = new BinaryEval(EvalType.PLUS, e1, e3);
+    assertFalse(plus1.equals(plus3));
+    
+    // LTH
+    ConstEval e4 = new ConstEval(DatumFactory.createInt4(9));
+    ConstEval e5 = new ConstEval(DatumFactory.createInt4(34));
+    BinaryEval compExpr1 = new BinaryEval(EvalType.LTH, e4, e5);
+    assertCloneEqual(compExpr1);
+    
+    ConstEval e6 = new ConstEval(DatumFactory.createInt4(9));
+    ConstEval e7 = new ConstEval(DatumFactory.createInt4(34));
+    BinaryEval compExpr2 = new BinaryEval(EvalType.LTH, e6, e7);
+    assertCloneEqual(compExpr2);
+    
+    assertTrue(compExpr1.equals(compExpr2));
+  }
+  
+  @Test
+  public final void testJson() throws CloneNotSupportedException {
+    ConstEval e1;
+    ConstEval e2;
+
+    // 29 > (34 + 5) + (5 + 34)
+    e1 = new ConstEval(DatumFactory.createInt4(34));
+    e2 = new ConstEval(DatumFactory.createInt4(5));
+    assertCloneEqual(e1); 
+    
+    BinaryEval plus1 = new BinaryEval(EvalType.PLUS, e1, e2);
+    assertCloneEqual(plus1);
+    BinaryEval plus2 = new BinaryEval(EvalType.PLUS, e2, e1);
+    assertCloneEqual(plus2);
+    BinaryEval plus3 = new BinaryEval(EvalType.PLUS, plus2, plus1);
+    assertCloneEqual(plus3);
+    
+    ConstEval e3 = new ConstEval(DatumFactory.createInt4(29));
+    BinaryEval gth = new BinaryEval(EvalType.GTH, e3, plus3);
+    assertCloneEqual(gth);
+    
+    String json = gth.toJson();
+    EvalNode eval = CoreGsonHelper.fromJson(json, EvalNode.class);
+    assertCloneEqual(eval);
+    
+    assertEquals(gth.getType(), eval.getType());
+    assertEquals(e3.getType(), eval.getLeftExpr().getType());
+    assertEquals(plus3.getType(), eval.getRightExpr().getType());
+    assertEquals(plus3.getLeftExpr(), eval.getRightExpr().getLeftExpr());
+    assertEquals(plus3.getRightExpr(), eval.getRightExpr().getRightExpr());
+    assertEquals(plus2.getLeftExpr(), eval.getRightExpr().getLeftExpr().getLeftExpr());
+    assertEquals(plus2.getRightExpr(), eval.getRightExpr().getLeftExpr().getRightExpr());
+    assertEquals(plus1.getLeftExpr(), eval.getRightExpr().getRightExpr().getLeftExpr());
+    assertEquals(plus1.getRightExpr(), eval.getRightExpr().getRightExpr().getRightExpr());
+  }
+  
+  private void assertCloneEqual(EvalNode eval) throws CloneNotSupportedException {
+    EvalNode copy = (EvalNode) eval.clone();
+    assertEquals(eval, copy);
+    assertFalse(eval == copy);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
new file mode 100644
index 0000000..d916bbc
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
@@ -0,0 +1,359 @@
+/**
+ * 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.engine.eval;
+
+import com.google.common.collect.Sets;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.algebra.OpType;
+import org.apache.tajo.algebra.Selection;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
+import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.LogicalPlan;
+import org.apache.tajo.engine.planner.LogicalPlanner;
+import org.apache.tajo.engine.planner.PlanningException;
+import org.apache.tajo.engine.planner.Target;
+import org.apache.tajo.engine.planner.logical.GroupbyNode;
+import org.apache.tajo.engine.planner.logical.NodeType;
+import org.apache.tajo.exception.InternalException;
+import org.apache.tajo.master.TajoMaster;
+import org.apache.tajo.master.session.Session;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.common.TajoDataTypes.Type.INT4;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestEvalTreeUtil {
+  static TajoTestingCluster util;
+  static CatalogService catalog = null;
+  static EvalNode expr1;
+  static EvalNode expr2;
+  static EvalNode expr3;
+  static SQLAnalyzer analyzer;
+  static LogicalPlanner planner;
+  static Session session = LocalTajoTestingUtility.createDummySession();
+
+  public static class TestSum extends GeneralFunction {
+    private Integer x;
+    private Integer y;
+
+    public TestSum() {
+      super(new Column[] { new Column("arg1", INT4),
+          new Column("arg2", INT4) });
+    }
+
+    @Override
+    public Datum eval(Tuple params) {
+      x =  params.get(0).asInt4();
+      y =  params.get(1).asInt4();
+      return DatumFactory.createInt4(x + y);
+    }
+  }
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+      catalog.createFunction(funcDesc);
+    }
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
+    catalog.createDatabase(TajoConstants.DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+
+    Schema schema = new Schema();
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    schema.addColumn("score", TajoDataTypes.Type.INT4);
+    schema.addColumn("age", TajoDataTypes.Type.INT4);
+
+    TableMeta meta = CatalogUtil.newTableMeta(StoreType.CSV);
+    TableDesc desc = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "people"), schema, meta,
+        CommonTestingUtil.getTestDir());
+    catalog.createTable(desc);
+
+    FunctionDesc funcMeta = new FunctionDesc("test_sum", TestSum.class,
+        FunctionType.GENERAL,
+        CatalogUtil.newSimpleDataType(TajoDataTypes.Type.INT4),
+        CatalogUtil.newSimpleDataTypeArray(TajoDataTypes.Type.INT4, TajoDataTypes.Type.INT4));
+    catalog.createFunction(funcMeta);
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog);
+
+    String[] QUERIES = {
+        "select name, score, age from people where score > 30", // 0
+        "select name, score, age from people where score * age", // 1
+        "select name, score, age from people where test_sum(score * age, 50)", // 2
+    };
+
+    expr1 = getRootSelection(QUERIES[0]);
+    expr2 = getRootSelection(QUERIES[1]);
+    expr3 = getRootSelection(QUERIES[2]);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  public static Target [] getRawTargets(String query) {
+    Expr expr = analyzer.parse(query);
+    LogicalPlan plan = null;
+    try {
+      plan = planner.createPlan(session, expr);
+    } catch (PlanningException e) {
+      e.printStackTrace();
+    }
+
+    return plan.getRootBlock().getRawTargets();
+  }
+
+  public static EvalNode getRootSelection(String query) throws PlanningException {
+    Expr block = analyzer.parse(query);
+    LogicalPlan plan = null;
+    try {
+      plan = planner.createPlan(session, block);
+    } catch (PlanningException e) {
+      e.printStackTrace();
+    }
+
+    Selection selection = plan.getRootBlock().getSingletonExpr(OpType.Filter);
+    return planner.getExprAnnotator().createEvalNode(plan, plan.getRootBlock(), selection.getQual());
+  }
+
+  @Test
+  public final void testChangeColumnRef() throws CloneNotSupportedException {
+    EvalNode copy = (EvalNode)expr1.clone();
+    EvalTreeUtil.changeColumnRef(copy, "default.people.score", "newscore");
+    Set<Column> set = EvalTreeUtil.findUniqueColumns(copy);
+    assertEquals(1, set.size());
+    assertTrue(set.contains(new Column("newscore", TajoDataTypes.Type.INT4)));
+
+    copy = (EvalNode)expr2.clone();
+    EvalTreeUtil.changeColumnRef(copy, "default.people.age", "sum_age");
+    set = EvalTreeUtil.findUniqueColumns(copy);
+    assertEquals(2, set.size());
+    assertTrue(set.contains(new Column("default.people.score", TajoDataTypes.Type.INT4)));
+    assertTrue(set.contains(new Column("sum_age", TajoDataTypes.Type.INT4)));
+
+    copy = (EvalNode)expr3.clone();
+    EvalTreeUtil.changeColumnRef(copy, "default.people.age", "sum_age");
+    set = EvalTreeUtil.findUniqueColumns(copy);
+    assertEquals(2, set.size());
+    assertTrue(set.contains(new Column("default.people.score", TajoDataTypes.Type.INT4)));
+    assertTrue(set.contains(new Column("sum_age", TajoDataTypes.Type.INT4)));
+  }
+
+  @Test
+  public final void testFindAllRefColumns() {    
+    Set<Column> set = EvalTreeUtil.findUniqueColumns(expr1);
+    assertEquals(1, set.size());
+    assertTrue(set.contains(new Column("default.people.score", TajoDataTypes.Type.INT4)));
+    
+    set = EvalTreeUtil.findUniqueColumns(expr2);
+    assertEquals(2, set.size());
+    assertTrue(set.contains(new Column("default.people.score", TajoDataTypes.Type.INT4)));
+    assertTrue(set.contains(new Column("default.people.age", TajoDataTypes.Type.INT4)));
+    
+    set = EvalTreeUtil.findUniqueColumns(expr3);
+    assertEquals(2, set.size());
+    assertTrue(set.contains(new Column("default.people.score", TajoDataTypes.Type.INT4)));
+    assertTrue(set.contains(new Column("default.people.age", TajoDataTypes.Type.INT4)));
+  }
+  
+  public static final String [] QUERIES = {
+    "select 3 + 4 as plus, (3.5 * 2) as mul", // 0
+    "select (score + 3) < 4, age > 5 from people", // 1
+    "select score from people where score > 7", // 2
+    "select score from people where (10 * 2) * (score + 2) > 20 + 30 + 10", // 3
+    "select score from people where 10 * 2 > score * 10", // 4
+    "select score from people where score < 10 and 4 < score", // 5
+    "select score from people where score < 10 and 4 < score and age > 5", // 6
+    "select score from people where (score > 1 and score < 3) or (7 < score and score < 10)", // 7
+  };
+  
+  @Test
+  public final void testGetSchemaFromTargets() throws InternalException {
+    Target [] targets = getRawTargets(QUERIES[0]);
+    Schema schema = EvalTreeUtil.getSchemaByTargets(null, targets);
+    Column col1 = schema.getColumn(0);
+    Column col2 = schema.getColumn(1);
+    assertEquals("plus", col1.getSimpleName());
+    assertEquals(TajoDataTypes.Type.INT4, col1.getDataType().getType());
+    assertEquals("mul", col2.getSimpleName());
+    assertEquals(TajoDataTypes.Type.FLOAT8, col2.getDataType().getType());
+  }
+
+  @Test
+  public final void testGetContainExprs() throws CloneNotSupportedException, PlanningException {
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalPlan plan = planner.createPlan(session, expr, true);
+    Target [] targets = plan.getRootBlock().getRawTargets();
+    Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
+    Collection<EvalNode> exprs =
+        EvalTreeUtil.getContainExpr(targets[0].getEvalTree(), col1);
+    EvalNode node = exprs.iterator().next();
+    assertEquals(EvalType.LTH, node.getType());
+    assertEquals(EvalType.PLUS, node.getLeftExpr().getType());
+    assertEquals(new ConstEval(DatumFactory.createInt4(4)), node.getRightExpr());
+
+    Column col2 = new Column("default.people.age", TajoDataTypes.Type.INT4);
+    exprs = EvalTreeUtil.getContainExpr(targets[1].getEvalTree(), col2);
+    node = exprs.iterator().next();
+    assertEquals(EvalType.GTH, node.getType());
+    assertEquals("default.people.age", node.getLeftExpr().getName());
+    assertEquals(new ConstEval(DatumFactory.createInt4(5)), node.getRightExpr());
+  }
+  
+  @Test
+  public final void testGetCNF() throws PlanningException {
+    // "select score from people where score < 10 and 4 < score "
+    EvalNode node = getRootSelection(QUERIES[5]);
+    EvalNode [] cnf = AlgebraicUtil.toConjunctiveNormalFormArray(node);
+    
+    Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
+    
+    assertEquals(2, cnf.length);
+    EvalNode first = cnf[0];
+    EvalNode second = cnf[1];
+    
+    FieldEval field = first.getLeftExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(EvalType.LTH, first.getType());
+    assertEquals(10, first.getRightExpr().eval(null,  null).asInt4());
+    
+    field = second.getRightExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(EvalType.LTH, second.getType());
+    assertEquals(4, second.getLeftExpr().eval(null,  null).asInt4());
+  }
+  
+  @Test
+  public final void testTransformCNF2Singleton() throws PlanningException {
+    // "select score from people where score < 10 and 4 < score "
+    EvalNode node = getRootSelection(QUERIES[6]);
+    EvalNode [] cnf1 = AlgebraicUtil.toConjunctiveNormalFormArray(node);
+    assertEquals(3, cnf1.length);
+    
+    EvalNode conj = AlgebraicUtil.createSingletonExprFromCNF(cnf1);
+    EvalNode [] cnf2 = AlgebraicUtil.toConjunctiveNormalFormArray(conj);
+    
+    Set<EvalNode> set1 = Sets.newHashSet(cnf1);
+    Set<EvalNode> set2 = Sets.newHashSet(cnf2);
+    assertEquals(set1, set2);
+  }
+
+  @Test
+  public final void testGetDNF() throws PlanningException {
+    // "select score from people where score > 1 and score < 3 or score > 7 and score < 10", // 7
+    EvalNode node = getRootSelection(QUERIES[7]);
+    EvalNode [] cnf = AlgebraicUtil.toDisjunctiveNormalFormArray(node);
+    assertEquals(2, cnf.length);
+
+    assertEquals("default.people.score (INT4) > 1 AND default.people.score (INT4) < 3", cnf[0].toString());
+    assertEquals("7 < default.people.score (INT4) AND default.people.score (INT4) < 10", cnf[1].toString());
+  }
+  
+  @Test
+  public final void testSimplify() throws PlanningException {
+    Target [] targets = getRawTargets(QUERIES[0]);
+    EvalNode node = AlgebraicUtil.eliminateConstantExprs(targets[0].getEvalTree());
+    assertEquals(EvalType.CONST, node.getType());
+    assertEquals(7, node.eval(null, null).asInt4());
+    node = AlgebraicUtil.eliminateConstantExprs(targets[1].getEvalTree());
+    assertEquals(EvalType.CONST, node.getType());
+    assertTrue(7.0d == node.eval(null, null).asFloat8());
+
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalPlan plan = planner.createPlan(session, expr, true);
+    targets = plan.getRootBlock().getRawTargets();
+    Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
+    Collection<EvalNode> exprs =
+        EvalTreeUtil.getContainExpr(targets[0].getEvalTree(), col1);
+    node = exprs.iterator().next();
+  }
+  
+  @Test
+  public final void testConatainSingleVar() throws PlanningException {
+    EvalNode node = getRootSelection(QUERIES[2]);
+    assertEquals(true, AlgebraicUtil.containSingleVar(node));
+    node = getRootSelection(QUERIES[3]);
+    assertEquals(true, AlgebraicUtil.containSingleVar(node));
+  }
+  
+  @Test
+  public final void testTranspose() throws PlanningException {
+    Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
+    EvalNode node = getRootSelection(QUERIES[3]);
+    // we expect that score < 3
+    EvalNode transposed = AlgebraicUtil.transpose(node, col1);
+    assertEquals(EvalType.GTH, transposed.getType());
+    FieldEval field = transposed.getLeftExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(1, transposed.getRightExpr().eval(null, null).asInt4());
+
+    node = getRootSelection(QUERIES[4]);
+    // we expect that score < 3
+    transposed = AlgebraicUtil.transpose(node, col1);
+    assertEquals(EvalType.LTH, transposed.getType());
+    field = transposed.getLeftExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(2, transposed.getRightExpr().eval(null, null).asInt4());
+  }
+
+  @Test
+  public final void testFindDistinctAggFunctions() throws PlanningException {
+    String query = "select sum(score) + max(age) from people";
+    Expr expr = analyzer.parse(query);
+    LogicalPlan plan = planner.createPlan(session, expr);
+    GroupbyNode groupByNode = plan.getRootBlock().getNode(NodeType.GROUP_BY);
+    EvalNode [] aggEvals = groupByNode.getAggFunctions();
+
+    List<AggregationFunctionCallEval> list = new ArrayList<AggregationFunctionCallEval>();
+    for (int i = 0; i < aggEvals.length; i++) {
+      list.addAll(EvalTreeUtil.findDistinctAggFunction(aggEvals[i]));
+    }
+    assertEquals(2, list.size());
+
+    Set<String> result = Sets.newHashSet("max", "sum");
+    for (AggregationFunctionCallEval eval : list) {
+      assertTrue(result.contains(eval.getName()));
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
new file mode 100644
index 0000000..7811e69
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
@@ -0,0 +1,396 @@
+/**
+ * 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.engine.eval;
+
+import org.apache.tajo.catalog.Schema;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.BOOLEAN;
+import static org.apache.tajo.common.TajoDataTypes.Type.INT4;
+import static org.apache.tajo.common.TajoDataTypes.Type.TEXT;
+
+public class TestPredicates extends ExprTestBase {
+
+  //////////////////////////////////////////////////////////////////
+  // Logical Operator
+  //////////////////////////////////////////////////////////////////
+
+  @Test
+  public void testAnd() throws IOException {
+    testSimpleEval("select true;", new String[] {"t"});
+
+    testSimpleEval("select true and true;", new String[] {"t"});
+    testSimpleEval("select true and false;", new String[] {"f"});
+    testSimpleEval("select false and true;", new String[] {"f"});
+    testSimpleEval("select false and false;", new String[] {"f"});
+  }
+
+  @Test
+  public void testOr() throws IOException {
+    testSimpleEval("select true or true;", new String[] {"t"});
+    testSimpleEval("select true or false;", new String[] {"t"});
+    testSimpleEval("select false or true;", new String[] {"t"});
+    testSimpleEval("select false or false;", new String[] {"f"});
+  }
+
+  @Test
+  public void testLogicalOperatorPrecedence() throws IOException {
+    testSimpleEval("select true or (false or false) or false;", new String[] {"t"});
+    testSimpleEval("select false or (true or false) or false;", new String[] {"t"});
+    testSimpleEval("select false or (false or true) or false;", new String[] {"t"});
+    testSimpleEval("select false or (false or false) or true;", new String[] {"t"});
+
+    testSimpleEval("select true and (false or false) or false;", new String[] {"f"});
+    testSimpleEval("select false and (true or false) or false;", new String[] {"f"});
+    testSimpleEval("select false and (false or true) or false;", new String[] {"f"});
+    testSimpleEval("select false and (false or false) or true;", new String[] {"t"});
+
+    testSimpleEval("select true or (false and false) or false;", new String[] {"t"});
+    testSimpleEval("select false or (true and false) or false;", new String[] {"f"});
+    testSimpleEval("select false or (false and true) or false;", new String[] {"f"});
+    testSimpleEval("select false or (false and true) or true;", new String[] {"t"});
+
+    testSimpleEval("select true or (false or false) and false;", new String[] {"t"});
+    testSimpleEval("select false or (true or false) and false;", new String[] {"f"});
+    testSimpleEval("select false or (false or true) and false;", new String[] {"f"});
+    testSimpleEval("select false or (false or false) and true;", new String[] {"f"});
+  }
+
+  @Test
+  public void testNot() throws IOException {
+
+    testSimpleEval("select true;", new String[] {"t"});
+    testSimpleEval("select not true;", new String[] {"f"});
+    testSimpleEval("select (true);", new String[] {"t"});
+    testSimpleEval("select not (true);", new String[] {"f"});
+    testSimpleEval("select not (not (true));", new String[] {"t"});
+
+    testSimpleEval("select (not (1 > null)) is null;", new String[] {"t"});
+
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 = col2, col1 = col3 from table1",
+        new String[]{"t", "f"});
+  }
+
+  @Test
+  public void testParenthesizedValues() throws IOException {
+    testSimpleEval("select ((true));", new String[] {"t"});
+    testSimpleEval("select ((((true))));", new String[] {"t"});
+    testSimpleEval("select not(not(not(false)));", new String[] {"t"});
+  }
+
+  //////////////////////////////////////////////////////////////////
+  // Comparison Predicate
+  //////////////////////////////////////////////////////////////////
+
+  @Test
+  public void testComparisonEqual() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+    schema1.addColumn("col4", INT4);
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 = col2, col1 = col3, col1 = col4 from table1",
+        new String[]{"t", "f", "f"});
+    testEval(schema1,
+        "table1", "123,123,,",
+        "select col1 = col2, (col1 = col3) is null, (col3 = col2) is null from table1",
+        new String[]{"t", "t", "t"});
+  }
+
+  @Test
+  public void testComparisonNotEqual() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+    schema1.addColumn("col4", INT4);
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 <> col2, col1 <> col3, col1 <> col4 from table1",
+        new String[]{"f", "t", "t"});
+    testEval(schema1,
+        "table1", "123,123,,",
+        "select col1 <> col2, (col1 <> col3) is null, (col3 <> col2) is null from table1",
+        new String[]{"f", "t", "t"});
+  }
+
+  @Test
+  public void testComparisonLessThan() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+    schema1.addColumn("col4", INT4);
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 < col2, col1 < col3, col1 < col4 from table1",
+        new String[]{"f", "t", "f"});
+    testEval(schema1,
+        "table1", "123,456,,",
+        "select col1 < col2, (col1 = col3) is null, (col4 = col1) is null from table1",
+        new String[]{"t", "t", "t"});
+  }
+
+  @Test
+  public void testComparisonLessThanEqual() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+    schema1.addColumn("col4", INT4);
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 <= col2, col1 <= col3, col1 <= col4 from table1",
+        new String[]{"t", "t", "f"});
+    testEval(schema1,
+        "table1", "123,456,,",
+        "select col1 <= col2, (col1 <= col3) is null, (col4 <= col1) is null from table1",
+        new String[]{"t", "t", "t"});
+  }
+
+  @Test
+  public void testComparisonGreaterThan() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+    schema1.addColumn("col4", INT4);
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 > col2, col3 > col2, col1 > col4 from table1",
+        new String[]{"f", "t", "t"});
+    testEval(schema1,
+        "table1", "123,456,,",
+        "select col2 > col1, col1 > col2, (col1 > col3) is null, (col4 > col1) is null from table1",
+        new String[]{"t", "f", "t", "t"});
+  }
+
+  @Test
+  public void testComparisonGreaterThanEqual() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    schema1.addColumn("col3", INT4);
+    schema1.addColumn("col4", INT4);
+    testEval(schema1,
+        "table1", "123,123,456,-123",
+        "select col1 >= col2, col3 >= col2, col1 >= col4 from table1",
+        new String[]{"t", "t", "t"});
+    testEval(schema1,
+        "table1", "123,456,,",
+        "select col2 >= col1, col1 >= col2, (col1 >= col3) is null, (col4 >= col1) is null from table1",
+        new String[]{"t", "f", "t", "t"});
+  }
+
+  //////////////////////////////////////////////////////////////////
+  // Between Predicate
+  //////////////////////////////////////////////////////////////////
+
+  @Test
+  public void testBetween() throws IOException {
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", TEXT);
+    schema2.addColumn("col2", TEXT);
+    schema2.addColumn("col3", TEXT);
+
+    // constant checker
+    testEval(schema2, "table1", "b,a,c", "select col1 between 'a' and 'c' from table1", new String[]{"t"});
+    testEval(schema2, "table1", "b,a,c", "select col1 between 'c' and 'a' from table1", new String[]{"f"});
+    testEval(schema2, "table1", "b,a,c", "select col1 between symmetric 'c' and 'a' from table1", new String[]{"t"});
+    testEval(schema2, "table1", "d,a,c", "select col1 between 'a' and 'c' from table1", new String[]{"f"});
+
+    // tests for inclusive
+    testEval(schema2, "table1", "a,a,c", "select col1 between col2 and col3 from table1", new String[]{"t"});
+    testEval(schema2, "table1", "b,a,c", "select col1 between col2 and col3 from table1", new String[]{"t"});
+    testEval(schema2, "table1", "c,a,c", "select col1 between col2 and col3 from table1", new String[]{"t"});
+    testEval(schema2, "table1", "d,a,c", "select col1 between col2 and col3 from table1", new String[]{"f"});
+
+    // tests for asymmetric and symmetric
+    testEval(schema2, "table1", "b,a,c", "select col1 between col3 and col2 from table1", new String[]{"f"});
+    testEval(schema2, "table1", "b,a,c", "select col1 between symmetric col3 and col2 from table1", new String[]{"t"});
+  }
+
+  @Test
+  public void testBetween2() throws IOException { // for TAJO-249
+    Schema schema3 = new Schema();
+    schema3.addColumn("date_a", INT4);
+    schema3.addColumn("date_b", INT4);
+    schema3.addColumn("date_c", INT4);
+    schema3.addColumn("date_d", INT4);
+
+    String query = "select " +
+        "case " +
+        "when date_a BETWEEN 20130705 AND 20130715 AND ((date_b BETWEEN 20100101 AND 20120601) OR date_b > 20130715) " +
+        "AND (date_c < 20120601 OR date_c > 20130715) AND date_d > 20130715" +
+        "then 1 else 0 end from table1";
+
+    testEval(schema3, "table1", "20130715,20100102,20120525,20130716", query, new String [] {"1"});
+    testEval(schema3, "table1", "20130716,20100102,20120525,20130716", query, new String [] {"0"});
+
+    // date_b
+    testEval(schema3, "table1", "20130715,20100102,20120525,20130716", query, new String [] {"1"});
+    testEval(schema3, "table1", "20130715,20120602,20120525,20130716", query, new String [] {"0"});
+    testEval(schema3, "table1", "20130715,20091201,20120525,20130716", query, new String [] {"0"});
+    testEval(schema3, "table1", "20130715,20130716,20120525,20130716", query, new String [] {"1"});
+
+    // date_c
+    testEval(schema3, "table1", "20130715,20100102,20120525,20130716", query, new String [] {"1"});
+    testEval(schema3, "table1", "20130715,20100102,20120602,20130716", query, new String [] {"0"});
+
+    testEval(schema3, "table1", "20130715,20100102,20130716,20130716", query, new String [] {"1"});
+    testEval(schema3, "table1", "20130715,20100102,20130714,20130716", query, new String [] {"0"});
+
+    // date_d
+    testEval(schema3, "table1", "20130715,20100102,20120525,20130716", query, new String [] {"1"});
+    testEval(schema3, "table1", "20130715,20100102,20120525,20130705", query, new String [] {"0"});
+  }
+
+  //////////////////////////////////////////////////////////////////
+  // In Predicate
+  //////////////////////////////////////////////////////////////////
+
+  @Test
+  public void testInPredicateWithConstant() throws IOException {
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", TEXT);
+    schema2.addColumn("col2", TEXT);
+    schema2.addColumn("col3", TEXT);
+
+    testEval(schema2, "table1", "a,b,c", "select col1 in ('a'), col2 in ('a', 'c') from table1", new String[]{"t","f"});
+    testEval(schema2, "table1", "a,,c", "select col1 in ('a','b','c'), (col2 in ('a', 'c')) is null from table1",
+        new String[]{"t","t"});
+
+    testEval(schema2,
+        "table1",
+        "2014-03-21,2015-04-01,2016-04-01",
+        "select substr(col1,1,4) in ('2014','2015','2016'), substr(col1,6,2)::int4 in (1,2,3) from table1",
+        new String[]{"t", "t"});
+
+    // null handling test
+    testEval(schema2,
+        "table1",
+        "2014-03-21,,2015-04-01",
+        "select (substr(col2,1,4)::int4 in (2014,2015,2016)) is null from table1",
+        new String[]{"t"});
+  }
+
+  @Test
+  public void testInPredicateWithSimpleExprs() throws IOException {
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", TEXT);
+    schema2.addColumn("col2", INT4);
+    schema2.addColumn("col3", TEXT);
+
+    testEval(schema2, "table1", "abc,2,3", "select col1 in ('a'||'b'||'c'), col2 in (1 + 1, 2 * 10, 2003) from table1",
+        new String[]{"t","t"});
+
+    testEval(schema2, "table1", "abc,2,3", "select col1 in ('a'||'b'), col2 in ('1'::int, '2'::int, 3) from table1",
+        new String[]{"f","t"});
+
+    testEval(schema2,
+        "table1",
+        "abc,,3",
+        "select col1 in (reverse('cba')), (col2 in ('1'::int, '2'::int, 3)) is null from table1",
+        new String[]{"t","t"});
+  }
+
+  //////////////////////////////////////////////////////////////////
+  // Null Predicate
+  //////////////////////////////////////////////////////////////////
+
+  @Test
+  public void testIsNullPredicate() throws IOException {
+    Schema schema1 = new Schema();
+    schema1.addColumn("col1", INT4);
+    schema1.addColumn("col2", INT4);
+    testEval(schema1, "table1", "123,", "select col1 is null, col2 is null as a from table1",
+        new String[]{"f", "t"});
+    testEval(schema1, "table1", "123,", "select col1 is not null, col2 is not null as a from table1",
+        new String[]{"t", "f"});
+  }
+
+  @Test
+  public void testIsNullPredicateWithFunction() throws IOException {
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", TEXT);
+    schema2.addColumn("col2", TEXT);
+    testEval(schema2, "table1", "_123,", "select ltrim(col1, '_') is null, upper(col2) is null as a from table1",
+        new String[]{"f", "t"});
+
+    testEval(schema2, "table1", "_123,",
+        "select ltrim(col1, '_') is not null, upper(col2) is not null as a from table1", new String[]{"t", "f"});
+  }
+
+  //////////////////////////////////////////////////////////////////
+  // Boolean Test
+  //////////////////////////////////////////////////////////////////
+
+  @Test
+  public void testBooleanTest() throws IOException {
+    testSimpleEval("select 1 < 3 is true", new String [] {"t"});
+    testSimpleEval("select 1 < 3 is not true", new String [] {"f"});
+    testSimpleEval("select 1 < 3 is false", new String [] {"f"});
+    testSimpleEval("select 1 < 3 is not false", new String [] {"t"});
+
+    testSimpleEval("select not (1 < 3 is true)", new String [] {"f"});
+    testSimpleEval("select not (1 < 3 is not true)", new String [] {"t"});
+    testSimpleEval("select not (1 < 3 is false)", new String [] {"t"});
+    testSimpleEval("select not (1 < 3 is not false)", new String [] {"f"});
+
+    testSimpleEval("select 1 > 3 is true", new String [] {"f"});
+    testSimpleEval("select 1 > 3 is not true", new String [] {"t"});
+    testSimpleEval("select 1 > 3 is false", new String [] {"t"});
+    testSimpleEval("select 1 > 3 is not false", new String [] {"f"});
+
+    testSimpleEval("select not (1 > 3 is true)", new String [] {"t"});
+    testSimpleEval("select not (1 > 3 is not true)", new String [] {"f"});
+    testSimpleEval("select not (1 > 3 is false)", new String [] {"f"});
+    testSimpleEval("select not (1 > 3 is not false)", new String [] {"t"});
+  }
+
+  @Test
+  public void testBooleanTestOnTable() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", BOOLEAN);
+    schema.addColumn("col2", BOOLEAN);
+    testEval(schema, "table1", "t,f", "select col1 is true, col2 is false from table1", new String [] {"t", "t"});
+    testEval(schema, "table1", "t,f", "select col1 is not true, col2 is not false from table1",
+        new String [] {"f", "f"});
+    testEval(schema, "table1", "t,f", "select not col1 is not true, not col2 is not false from table1",
+        new String [] {"t", "t"});
+  }
+
+  @Test
+  public void testCreateTableWithUnsupportedStoreType() throws IOException {
+    testSimpleEval("create table table1 (name text, age int) using RAW;",
+        new String[] {"Wrong query statement or query plan: create table table1 (name text, age int) using RAW"},
+        false);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
new file mode 100644
index 0000000..c9c8dd4
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
@@ -0,0 +1,53 @@
+/**
+ * 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.engine.eval;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestSQLDateTimeTypes extends ExprTestBase {
+
+  @Test
+  public void testTimestamp() throws IOException {
+    testSimpleEval("select TIMESTAMP '1970-01-17 10:09:37';", new String[]{"1970-01-17 10:09:37"});
+    testSimpleEval("select TIMESTAMP '1970-01-17 10:09:37.5';", new String[]{"1970-01-17 10:09:37.5"});
+    testSimpleEval("select TIMESTAMP '1970-01-17 10:09:37.01';", new String[]{"1970-01-17 10:09:37.01"});
+    testSimpleEval("select TIMESTAMP '1970-01-17 10:09:37.003';", new String[]{"1970-01-17 10:09:37.003"});
+  }
+
+  @Test
+  public void testToTimestamp() throws IOException {
+    testSimpleEval("select to_char(TIMESTAMP '1970-01-17 10:09:37', 'yyyy-MM-dd HH:mm:ss');",
+        new String[]{"1970-01-17 10:09:37"});
+  }
+
+  @Test
+  public void testTimeLiteral() throws IOException {
+    testSimpleEval("select TIME '10:09:37';",
+        new String[]{"10:09:37"});
+  }
+
+  @Test
+  public void testDateLiteral() throws IOException {
+    testSimpleEval("select DATE '1970-01-17';",
+        new String[]{"1970-01-17"});
+  }
+
+}