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 2015/08/14 16:29:40 UTC

[01/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Repository: tajo
Updated Branches:
  refs/heads/master ab60d02e1 -> a4106883d


http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..7d89fa2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash_NoBroadcast.plan
@@ -0,0 +1,190 @@
+explain
+-------------------------------
+JOIN(14)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)
+  => out schema: {(6) default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+  => in schema: {(7) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => filter: default.n.n_name (TEXT) IN (ARGENTINA, ETHIOPIA, MOROCCO)
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+   JOIN(13)(INNER)
+     => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+     => target list: default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+     => out schema: {(3) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+     => in schema: {(4) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+      SCAN(5) on default.supplier as s
+        => target list: default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+        => out schema: {(2) default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+        => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+      SCAN(7) on default.partsupp as ps
+        => target list: default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)
+        => out schema: {(2) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)}
+        => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000008)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000008
+   |-eb_0000000000000_0000_000007
+      |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+         |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000004
+4: eb_0000000000000_0000_000005
+5: eb_0000000000000_0000_000003
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+8: eb_0000000000000_0000_000008
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), num=32)
+
+SCAN(7) on default.partsupp as ps
+  => target list: default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)
+  => out schema: {(2) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)}
+  => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.s.s_suppkey (INT4), num=32)
+
+SCAN(5) on default.supplier as s
+  => target list: default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+  => out schema: {(2) default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+  => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 6 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n
+  => filter: default.n.n_name (TEXT) IN (ARGENTINA, ETHIOPIA, MOROCCO)
+  => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+  => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as r
+  => target list: default.r.r_regionkey (INT4)
+  => out schema: {(1) default.r.r_regionkey (INT4)}
+  => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.s.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 7 (type=HASH_SHUFFLE, key=default.s.s_nationkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+  => target list: default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+  => out schema: {(3) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+  => in schema: {(4) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+   SCAN(17) on eb_0000000000000_0000_000002
+     => out schema: {(2) default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+     => in schema: {(2) default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+   SCAN(16) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)}
+     => in schema: {(2) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 4 => 6 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 5 => 6 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 7 (type=HASH_SHUFFLE, key=default.t.n_nationkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.t
+  => Targets: default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+  => out schema: {(4) default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+  => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+   PROJECTION(3)
+     => Targets: default.n.n_nationkey (INT4), default.n.n_name (TEXT), default.n.n_regionkey (INT4), default.n.n_comment (TEXT)
+     => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+     => in  schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(19) on eb_0000000000000_0000_000005
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(1) default.r.r_regionkey (INT4)}
+         SCAN(18) on eb_0000000000000_0000_000004
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 7 (type=HASH_SHUFFLE, key=default.s.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 6 => 7 (type=HASH_SHUFFLE, key=default.t.n_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)
+  => out schema: {(6) default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+  => in schema: {(7) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+   SCAN(21) on eb_0000000000000_0000_000006
+     => out schema: {(4) default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+     => in schema: {(4) default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+     => in schema: {(3) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [TERMINAL]
+=======================================================


[36/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
new file mode 100644
index 0000000..f34cbce
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
@@ -0,0 +1,643 @@
+/**
+ * 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.query;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.partition.PartitionMethodDesc;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.storage.StorageUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestCreateTable extends QueryTestCaseBase {
+
+  @Test
+  public final void testVariousTypes() throws Exception {
+    List<String> createdNames;
+    if (testingCluster.isHiveCatalogStoreRunning()) {
+      createdNames = executeDDL("create_table_various_types_for_hive_catalog.sql", null);
+    } else {
+      createdNames = executeDDL("create_table_various_types.sql", null);
+    }
+    assertTableExists(createdNames.get(0));
+  }
+
+  @Test
+  public final void testCreateTable1() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1", "table1");
+    assertTableExists(createdNames.get(0));
+    executeString("DROP TABLE table1");
+  }
+
+  @Test
+  public final void testCreateTable2() throws Exception {
+    executeString("CREATE DATABASE D1;").close();
+    executeString("CREATE DATABASE D2;").close();
+
+    executeString("CREATE TABLE D1.table1 (age int);").close();
+    executeString("CREATE TABLE D1.table2 (age int);").close();
+    executeString("CREATE TABLE d2.table3 (age int);").close();
+    executeString("CREATE TABLE d2.table4 (age int);").close();
+
+    assertTableExists("d1.table1");
+    assertTableExists("d1.table2");
+    assertTableNotExists("d2.table1");
+    assertTableNotExists("d2.table2");
+
+    assertTableExists("d2.table3");
+    assertTableExists("d2.table4");
+    assertTableNotExists("d1.table3");
+    assertTableNotExists("d1.table4");
+
+    executeString("DROP TABLE D1.table1");
+    executeString("DROP TABLE D1.table2");
+    executeString("DROP TABLE D2.table3");
+    executeString("DROP TABLE D2.table4");
+
+    assertDatabaseExists("d1");
+    assertDatabaseExists("d2");
+    executeString("DROP DATABASE D1").close();
+    executeString("DROP DATABASE D2").close();
+    assertDatabaseNotExists("d1");
+    assertDatabaseNotExists("d2");
+  }
+
+  private final void assertPathOfCreatedTable(final String databaseName,
+                                              final String originalTableName,
+                                              final String newTableName,
+                                              String createTableStmt) throws Exception {
+    // create one table
+    executeString("CREATE DATABASE " + CatalogUtil.denormalizeIdentifier(databaseName)).close();
+    getClient().existDatabase(CatalogUtil.denormalizeIdentifier(databaseName));
+    final String oldFQTableName = CatalogUtil.buildFQName(databaseName, originalTableName);
+
+    ResultSet res = executeString(createTableStmt);
+    res.close();
+    assertTableExists(oldFQTableName);
+    TableDesc oldTableDesc = client.getTableDesc(oldFQTableName);
+
+
+    // checking the existence of the table directory and validating the path
+    Path warehouseDir = TajoConf.getWarehouseDir(testingCluster.getConfiguration());
+    FileSystem fs = warehouseDir.getFileSystem(testingCluster.getConfiguration());
+    assertTrue(fs.exists(new Path(oldTableDesc.getUri())));
+    assertEquals(StorageUtil.concatPath(warehouseDir, databaseName, originalTableName),
+        new Path(oldTableDesc.getUri()));
+
+    // Rename
+    client.executeQuery("ALTER TABLE " + CatalogUtil.denormalizeIdentifier(oldFQTableName)
+        + " RENAME to " + CatalogUtil.denormalizeIdentifier(newTableName));
+
+    // checking the existence of the new table directory and validating the path
+    final String newFQTableName = CatalogUtil.buildFQName(databaseName, newTableName);
+    TableDesc newTableDesc = client.getTableDesc(newFQTableName);
+    assertTrue(fs.exists(new Path(newTableDesc.getUri())));
+    assertEquals(StorageUtil.concatPath(warehouseDir, databaseName, newTableName), new Path(newTableDesc.getUri()));
+  }
+
+  @Test
+  public final void testCreatedTableViaCTASAndVerifyPath() throws Exception {
+    assertPathOfCreatedTable("d4", "old_table", "new_mgmt_table",
+        "CREATE TABLE d4.old_table AS SELECT * FROM default.lineitem;");
+  }
+
+  @Test
+  public final void testCreatedTableJustCreatedAndVerifyPath() throws Exception {
+    assertPathOfCreatedTable("d5", "old_table", "new_mgmt_table", "CREATE TABLE d5.old_table (age integer);");
+  }
+
+  @Test
+  public final void testCreatedTableWithQuotedIdentifierAndVerifyPath() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertPathOfCreatedTable("D6", "OldTable", "NewMgmtTable", "CREATE TABLE \"D6\".\"OldTable\" (age integer);");
+    }
+  }
+
+  @Test
+  public final void testCreateTableIfNotExists() throws Exception {
+    executeString("CREATE DATABASE D3;").close();
+
+    assertTableNotExists("d3.table1");
+    executeString("CREATE TABLE D3.table1 (age int);").close();
+    assertTableExists("d3.table1");
+
+    executeString("CREATE TABLE IF NOT EXISTS D3.table1 (age int);").close();
+    assertTableExists("d3.table1");
+
+    executeString("DROP TABLE D3.table1");
+  }
+
+  @Test
+  public final void testDropTableIfExists() throws Exception {
+    executeString("CREATE DATABASE D7;").close();
+
+    assertTableNotExists("d7.table1");
+    executeString("CREATE TABLE d7.table1 (age int);").close();
+    assertTableExists("d7.table1");
+
+    executeString("DROP TABLE d7.table1;").close();
+    assertTableNotExists("d7.table1");
+
+    executeString("DROP TABLE IF EXISTS d7.table1");
+    assertTableNotExists("d7.table1");
+
+    executeString("DROP DATABASE D7;").close();
+  }
+
+  @Test
+  public final void testDelimitedIdentifierWithNonAsciiCharacters() throws Exception {
+
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      ResultSet res = null;
+      try {
+        List<String> tableNames = executeDDL("quoted_identifier_non_ascii_ddl.sql", "table1", "\"테이블1\"");
+        assertTableExists(tableNames.get(0));
+
+        // SELECT "아이디", "텍스트", "숫자" FROM "테이블1";
+        res = executeFile("quoted_identifier_non_ascii_1.sql");
+        assertResultSet(res, "quoted_identifier_non_ascii_1.result");
+      } finally {
+        cleanupQuery(res);
+      }
+
+      // SELECT "아이디" as "진짜아이디", "텍스트" as text, "숫자" FROM "테이블1" as "테이블 별명"
+      try {
+        res = executeFile("quoted_identifier_non_ascii_2.sql");
+        assertResultSet(res, "quoted_identifier_non_ascii_2.result");
+      } finally {
+        cleanupQuery(res);
+      }
+
+      // SELECT "아이디" "진짜아이디", char_length("텍스트") as "길이", "숫자" * 2 FROM "테이블1" "테이블 별명"
+      try {
+        res = executeFile("quoted_identifier_non_ascii_3.sql");
+        assertResultSet(res, "quoted_identifier_non_ascii_3.result");
+      } finally {
+        cleanupQuery(res);
+      }
+    }
+  }
+
+  @Test
+  public final void testDelimitedIdentifierWithMixedCharacters() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      ResultSet res = null;
+
+      try {
+        List<String> tableNames = executeDDL("quoted_identifier_mixed_chars_ddl_1.sql", "table1", "\"TABLE1\"");
+        assertTableExists(tableNames.get(0));
+
+        tableNames = executeDDL("quoted_identifier_mixed_chars_ddl_1.sql", "table2", "\"tablE1\"");
+        assertTableExists(tableNames.get(0));
+
+        // SELECT "aGe", "tExt", "Number" FROM "TABLE1";
+        res = executeFile("quoted_identifier_mixed_chars_1.sql");
+        assertResultSet(res, "quoted_identifier_mixed_chars_1.result");
+      } finally {
+        cleanupQuery(res);
+      }
+
+      try {
+        res = executeFile("quoted_identifier_mixed_chars_2.sql");
+        assertResultSet(res, "quoted_identifier_mixed_chars_2.result");
+      } finally {
+        cleanupQuery(res);
+      }
+
+      try {
+        res = executeFile("quoted_identifier_mixed_chars_3.sql");
+        assertResultSet(res, "quoted_identifier_mixed_chars_3.result");
+      } finally {
+        cleanupQuery(res);
+      }
+    }
+  }
+
+  @Test
+  public final void testNonreservedKeywordTableNames() throws Exception {
+    List<String> createdNames = null;
+    createdNames = executeDDL("table1_ddl.sql", "table1", "filter");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "first");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "format");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "grouping");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "hash");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "index");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "insert");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "last");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "location");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "max");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "min");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "national");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "nullif");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "overwrite");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "precision");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "range");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "regexp");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "rlike");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "set");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "unknown");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "var_pop");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "var_samp");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "varying");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "zone");
+    assertTableExists(createdNames.get(0));
+
+    createdNames = executeDDL("table1_ddl.sql", "table1", "bigint");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "bit");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "blob");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "bool");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "boolean");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "bytea");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "char");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "date");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "decimal");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "double");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "float");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "float4");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "float8");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "inet4");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "int");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "int1");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "int2");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "int4");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "int8");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "integer");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "nchar");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "numeric");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "nvarchar");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "real");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "smallint");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "text");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "time");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "timestamp");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "timestamptz");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "timetz");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "tinyint");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "varbinary");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "varbit");
+    assertTableExists(createdNames.get(0));
+    createdNames = executeDDL("table1_ddl.sql", "table1", "varchar");
+    assertTableExists(createdNames.get(0));
+  }
+
+  private boolean isClonedSchema(Schema origSchema, Schema newSchema)  {
+    // Check schema of tables
+    boolean schemaEqual =
+      (origSchema.size() == newSchema.size());
+    if(schemaEqual == false)  {
+      fail("Number of columns in schema not equal");
+      return false;
+    }
+
+    for(int col = 0; col < origSchema.size(); col++)  {
+      Column colA = origSchema.getColumn(col);
+      Column colB = newSchema.getColumn(col);
+      if(colA.getSimpleName().equals(colB.getSimpleName()) == false)  {
+        fail("Column names at index " + col + " do not match");
+        return false;
+      }
+      if(colA.getDataType().equals(colB.getDataType()) == false) {
+        fail("Column datatypes at index " + col + " do not match");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean isClonedTable(String orignalTable, String newTable) throws Exception  {
+    assertTableExists(newTable);
+    TableDesc origTableDesc = client.getTableDesc(orignalTable);
+    TableDesc newTableDesc = client.getTableDesc(newTable);
+
+    if(isClonedSchema(origTableDesc.getSchema(), newTableDesc.getSchema()) == false) {
+      fail("Schema of input tables do not match");
+      return false;
+    }
+
+    // Check partition information
+    PartitionMethodDesc origPartMethod = origTableDesc.getPartitionMethod();
+    PartitionMethodDesc newPartMethod = newTableDesc.getPartitionMethod();
+    if(origPartMethod != null) {
+      if(newPartMethod == null)  {
+        fail("New table does not have partition info");
+        return false;
+      }
+      if(isClonedSchema(origPartMethod.getExpressionSchema(),
+                        newPartMethod.getExpressionSchema()) == false) {
+	fail("Partition columns of input tables do not match");
+        return false;
+      }
+
+      if(origPartMethod.getPartitionType().equals(newPartMethod.getPartitionType()) == false)  {
+        fail("Partition type of input tables do not match");
+        return false;
+      }
+    }
+
+    // Check external flag
+    if(origTableDesc.isExternal() != newTableDesc.isExternal()) {
+      fail("External table flag on input tables not equal");
+      return false;
+    }
+
+    if(origTableDesc.getMeta() != null) {
+      TableMeta origMeta = origTableDesc.getMeta();
+      TableMeta newMeta = newTableDesc.getMeta();
+      if(origMeta.getStoreType().equals(newMeta.getStoreType()) == false) {
+        fail("Store type of input tables not equal");
+        return false;
+      }
+
+      KeyValueSet origOptions = origMeta.getOptions();
+      KeyValueSet newOptions = newMeta.getOptions();
+      if(origOptions.equals(newOptions) == false)  {
+        fail("Meta options of input tables not equal");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Test
+  public final void testCreateExternalTable1FromOnlyPath() throws Exception {
+    // This test verifies CREATE EXTERNAL TABLE from just a path instead of a full qualified URI.
+    ResultSet res = null;
+    try {
+      res = executeString(
+          "INSERT INTO LOCATION '/testCreateExternalTable1FromOnlyPath' SELECT * FROM default.lineitem");
+      res = executeString(
+          "CREATE EXTERNAL TABLE table1 (col1 INTEGER) USING TEXT LOCATION '/testCreateExternalTable1FromOnlyPath';");
+    } catch (Throwable t) {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  @Test
+  public final void testCreateTableLike1() throws Exception {
+    // //HiveCatalogStore does not support varchar type in hive-0.12.0
+    if (testingCluster.isHiveCatalogStoreRunning()) {
+      // Basic create table with default database
+      executeString("CREATE TABLE table1 (c1 int, c2 text);").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      String testMsg = "testCreateTableLike1: Basic create table with default db";
+      assertTrue(testMsg,isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+      // Basic create table with database
+      executeString("CREATE DATABASE d1").close();
+      executeString("CREATE TABLE d1.table1 (c1 int, c2 text);").close();
+      executeString("CREATE TABLE d1.table2 LIKE d1.table1");
+      testMsg = "testCreateTableLike1: Basic create table with db test failed";
+      assertTrue(testMsg, isClonedTable("d1.table1","d1.table2"));
+      executeString("DROP TABLE d1.table1");
+      executeString("DROP TABLE d1.table2");
+
+      // Table with non-default store type
+      executeString("CREATE TABLE table1 (c1 int, c2 text) USING rcfile;").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      testMsg = "testCreateTableLike1: Table with non-default store type test failed";
+      assertTrue(testMsg, isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+      // Table with non-default meta options
+      executeString("CREATE TABLE table1 (c1 int, c2 text) USING text WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec');").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      testMsg = "testCreateTableLike1: Table with non-default meta options test failed";
+      assertTrue(testMsg, isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+
+      // Table with partitions (default partition type)
+      executeString("CREATE TABLE table1 (c1 int, c2 text) PARTITION BY COLUMN (c3 int, c4 float, c5 text);").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      testMsg = "testCreateTableLike1: Table with partitions test failed";
+      assertTrue(testMsg, isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+
+      // Table with external flag
+      // Use existing file as input for creating external table
+      String className = getClass().getSimpleName();
+      Path currentDatasetPath = new Path(datasetBasePath, className);
+      Path filePath = StorageUtil.concatPath(currentDatasetPath, "table1");
+      executeString("CREATE EXTERNAL TABLE table3 (c1 int, c2 text) USING rcfile LOCATION '" + filePath.toUri() + "'").close();
+      executeString("CREATE TABLE table2 LIKE table3");
+      testMsg = "testCreateTableLike1: Table with external table flag test failed";
+      assertTrue(testMsg, isClonedTable("table3","table2"));
+      executeString("DROP TABLE table3");
+      executeString("DROP TABLE table2");
+
+
+      // Table created using CTAS
+      executeString("CREATE TABLE table3 (c1 int, c2 text) PARTITION BY COLUMN (c3 int);").close();
+      executeString("CREATE TABLE table4 AS SELECT c1 * c1 as m_c1, c2, c2 as c2_a,c3 from table3;").close();
+      executeString("CREATE TABLE table2 LIKE table4");
+      testMsg = "testCreateTableLike1: Table using CTAS test failed";
+      assertTrue(testMsg, isClonedTable("table4","table2"));
+      executeString("DROP TABLE table3");
+      executeString("DROP TABLE table4");
+      executeString("DROP TABLE table2");
+    } else {
+      // Basic create table with default database
+      executeString("CREATE TABLE table1 (c1 int, c2 varchar);").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      String testMsg = "testCreateTableLike1: Basic create table with default db";
+      assertTrue(testMsg,isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+      // Basic create table with database
+      executeString("CREATE DATABASE d1").close();
+      executeString("CREATE TABLE d1.table1 (c1 int, c2 varchar);").close();
+      executeString("CREATE TABLE d1.table2 LIKE d1.table1");
+      testMsg = "testCreateTableLike1: Basic create table with db test failed";
+      assertTrue(testMsg, isClonedTable("d1.table1","d1.table2"));
+      executeString("DROP TABLE d1.table1");
+      executeString("DROP TABLE d1.table2");
+
+      // Table with non-default store type
+      executeString("CREATE TABLE table1 (c1 int, c2 varchar) USING rcfile;").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      testMsg = "testCreateTableLike1: Table with non-default store type test failed";
+      assertTrue(testMsg, isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+      // Table with non-default meta options
+      executeString("CREATE TABLE table1 (c1 int, c2 varchar) USING text WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec');").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      testMsg = "testCreateTableLike1: Table with non-default meta options test failed";
+      assertTrue(testMsg, isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+
+      // Table with partitions (default partition type)
+      executeString("CREATE TABLE table1 (c1 int, c2 varchar) PARTITION BY COLUMN (c3 int, c4 float, c5 text);").close();
+      executeString("CREATE TABLE table2 LIKE table1");
+      testMsg = "testCreateTableLike1: Table with partitions test failed";
+      assertTrue(testMsg, isClonedTable("table1","table2"));
+      executeString("DROP TABLE table1");
+      executeString("DROP TABLE table2");
+
+
+      // Table with external flag
+      // Use existing file as input for creating external table
+      String className = getClass().getSimpleName();
+      Path currentDatasetPath = new Path(datasetBasePath, className);
+      Path filePath = StorageUtil.concatPath(currentDatasetPath, "table1");
+      executeString("CREATE EXTERNAL TABLE table3 (c1 int, c2 varchar) USING rcfile LOCATION '" + filePath.toUri() + "'").close();
+      executeString("CREATE TABLE table2 LIKE table3");
+      testMsg = "testCreateTableLike1: Table with external table flag test failed";
+      assertTrue(testMsg, isClonedTable("table3","table2"));
+      executeString("DROP TABLE table3");
+      executeString("DROP TABLE table2");
+
+
+      // Table created using CTAS
+      executeString("CREATE TABLE table3 (c1 int, c2 varchar) PARTITION BY COLUMN (c3 int);").close();
+      executeString("CREATE TABLE table4 AS SELECT c1*c1, c2, c2 as c2_a,c3 from table3;").close();
+      executeString("CREATE TABLE table2 LIKE table4");
+      testMsg = "testCreateTableLike1: Table using CTAS test failed";
+      assertTrue(testMsg, isClonedTable("table4","table2"));
+      executeString("DROP TABLE table3");
+      executeString("DROP TABLE table4");
+      executeString("DROP TABLE table2");
+
+
+    /* Enable when view is supported
+    // View
+    executeString("CREATE TABLE table3 (c1 int, c2 varchar) PARTITION BY COLUMN (c3 int);").close();
+    executeString("CREATE VIEW table4(c1,c2,c3) AS SELECT c1*c1, c2, c2,c3 from table3;").close();
+    executeString("CREATE TABLE table2 LIKE table4");
+    testMsg = "testCreateTableLike1: Table using VIEW test failed";
+    assertTrue(testMsg, isClonedTable("table4","table2"));
+    executeString("DROP TABLE table3");
+    executeString("DROP TABLE table4");
+    executeString("DROP TABLE table2");
+    */
+
+    /*  Enable when partition type other than column is supported
+    // Table with partitions (range partition)
+    executeString("CREATE TABLE table1 (c1 int, c2 varchar) PARTITION BY RANGE (c1) (  PARTITION c1 VALUES LESS THAN (2),  PARTITION c1 VALUES LESS THAN (5),  PARTITION c1 VALUES LESS THAN (MAXVALUE) );").close();
+    executeString("CREATE TABLE table2 LIKE table1");
+    testMsg = "testCreateTableLike1: Table using non-default partition type failed";
+    assertTrue(testMsg, isClonedTable("table1","table2"));
+    executeString("DROP TABLE table1");
+    executeString("DROP TABLE table2");
+    */
+    }
+  }
+
+  @Test
+  public final void testNestedRecord1() throws Exception {
+    executeString("CREATE DATABASE D9;").close();
+
+    assertTableNotExists("d9.nested_table");
+    executeQuery().close();
+    assertTableExists("d9.nested_table");
+
+    executeString("DROP TABLE D9.nested_table");
+    executeString("DROP DATABASE D9").close();
+  }
+
+  @Test
+  public final void testNestedRecord2() throws Exception {
+    executeString("CREATE DATABASE D9;").close();
+
+    assertTableNotExists("d9.nested_table2");
+    executeQuery();
+    assertTableExists("d9.nested_table2");
+
+    executeString("DROP TABLE D9.nested_table2");
+    executeString("DROP DATABASE D9").close();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestDropTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
new file mode 100644
index 0000000..0020156
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
@@ -0,0 +1,38 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.List;
+
+@Category(IntegrationTest.class)
+public class TestDropTable extends QueryTestCaseBase {
+
+  @Test
+  public final void testDropManagedTable() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "abc");
+    assertTableExists(createdNames.get(0));
+    executeDDL("drop_table_ddl.sql", null);
+    assertTableNotExists("abc");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
new file mode 100644
index 0000000..a5caf38
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
@@ -0,0 +1,870 @@
+/**
+ * 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.query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.*;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.querymaster.Query;
+import org.apache.tajo.querymaster.QueryMasterTask;
+import org.apache.tajo.querymaster.Stage;
+import org.apache.tajo.querymaster.Task;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TajoWorker;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.sql.ResultSet;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+public class TestGroupByQuery extends QueryTestCaseBase {
+  private static final Log LOG = LogFactory.getLog(TestGroupByQuery.class);
+
+  public TestGroupByQuery(String groupByOption) throws Exception {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+
+    Map<String, String> variables = new HashMap<String, String>();
+    if (groupByOption.equals("MultiLevel")) {
+      variables.put(SessionVars.GROUPBY_MULTI_LEVEL_ENABLED.keyname(), "true");
+    } else {
+      variables.put(SessionVars.GROUPBY_MULTI_LEVEL_ENABLED.keyname(), "false");
+    }
+    client.updateSessionVariables(variables);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    client.unsetSessionVariables(TUtil.newList(SessionVars.GROUPBY_MULTI_LEVEL_ENABLED.keyname()));
+  }
+
+  @Parameters
+  public static Collection<Object[]> generateParameters() {
+    return Arrays.asList(new Object[][]{
+        {"MultiLevel"},
+        {"No-MultiLevel"},
+    });
+  }
+
+  @Test
+  public final void testGroupBy() throws Exception {
+    // select count(1) as unique_key from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupBy2() throws Exception {
+    // select count(1) as unique_key from lineitem group by l_linenumber;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupBy3() throws Exception {
+    // select l_orderkey as gkey from lineitem group by gkey order by gkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupBy4() throws Exception {
+    // select l_orderkey as gkey, count(1) as unique_key from lineitem group by lineitem.l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupBy5() throws Exception {
+    // select l_orderkey as gkey, '00' as num from lineitem group by lineitem.l_orderkey order by gkey
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByNested1() throws Exception {
+    // select l_orderkey + l_partkey as unique_key from lineitem group by l_orderkey + l_partkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByNested2() throws Exception {
+    // select sum(l_orderkey) + sum(l_partkey) as total from lineitem group by l_orderkey + l_partkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithSameExprs1() throws Exception {
+    // select sum(l_orderkey) + sum(l_orderkey) as total from lineitem group by l_orderkey + l_partkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithSameExprs2() throws Exception {
+    // select sum(l_orderkey) as total1, sum(l_orderkey) as total2 from lineitem group by l_orderkey + l_partkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithExpressionKeys1() throws Exception {
+    // select upper(lower(l_orderkey::text)) as key, count(1) as total from lineitem
+    // group by key order by upper(lower(l_orderkey::text)), total;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithExpressionKeys2() throws Exception {
+    // select upper(lower(l_orderkey::text)) as key, count(1) as total from lineitem
+    // group by upper(lower(l_orderkey::text)) order by upper(l_orderkey::text), total;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithSameConstantKeys1() throws Exception {
+    // select l_partkey as a, '##' as b, '##' as c, count(*) d from lineitem group by a, b, c order by a;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithConstantKeys1() throws Exception {
+    // select 123 as key, count(1) as total from lineitem group by key order by key, total;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithConstantKeys2() throws Exception {
+    // select l_partkey as a, timestamp '2014-07-07 04:28:31.561' as b, '##' as c, count(*) d from lineitem
+    // group by a, b, c order by l_partkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithConstantKeys3() throws Exception {
+    // select
+    //   l_partkey as a,
+    //   timestamp '2014-07-07 04:28:31.561' as b,
+    //   '##' as c,
+    //   count(*) d
+    // from
+    //   lineitem
+    // group by
+    //  b, c;         <- b and c all are constant values.
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithConstantKeys4() throws Exception {
+    //    select
+    //    'day',
+    //        l_orderkey,
+    //        count(*) as sum
+    //    from
+    //        lineitem
+    //    group by
+    //    'day',
+    //        l_orderkey
+    //    order by
+    //    'day',
+    //        l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithConstantKeys5() throws Exception {
+    //    select
+    //    'day',
+    //        l_orderkey,
+    //        count(*) as sum
+    //    from
+    //        lineitem
+    //    group by
+    //    'day',
+    //        l_orderkey
+    //    order by
+    //    'day',
+    //        l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation1() throws Exception {
+    // select l_orderkey, max(l_orderkey) as maximum, count(distinct l_linenumber) as unique_key from lineitem
+    // group by l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * This is an unit test for a combination of aggregation and distinct aggregation functions.
+   */
+  public final void testDistinctAggregation2() throws Exception {
+    // select l_orderkey, count(*) as cnt, count(distinct l_linenumber) as unique_key from lineitem group by l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation3() throws Exception {
+    // select count(*), count(distinct l_orderkey), sum(distinct l_orderkey) from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation4() throws Exception {
+    // select l_linenumber, count(*), count(distinct l_orderkey), sum(distinct l_orderkey)
+    // from lineitem group by l_linenumber;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation5() throws Exception {
+    // select sum(distinct l_orderkey), l_linenumber, count(distinct l_orderkey), count(*) as total
+    // from lineitem group by l_linenumber;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation6() throws Exception {
+    // select count(distinct l_orderkey) v0, sum(l_orderkey) v1, sum(l_linenumber) v2, count(*) as v4 from lineitem
+    // group by l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation7() throws Exception {
+    // select count(*), count(distinct c_nationkey), count(distinct c_mktsegment) from customer
+    // tpch scale 1000: 15000000	25	5
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregation8() throws Exception {
+    /*
+    select
+    sum(distinct l_orderkey),
+        l_linenumber, l_returnflag, l_linestatus, l_shipdate,
+        count(distinct l_partkey),
+        sum(l_orderkey)
+    from
+        lineitem
+    group by
+    l_linenumber, l_returnflag, l_linestatus, l_shipdate;
+    */
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregationWithHaving1() throws Exception {
+    // select l_linenumber, count(*), count(distinct l_orderkey), sum(distinct l_orderkey) from lineitem
+    // group by l_linenumber having sum(distinct l_orderkey) >= 6;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregationWithUnion1() throws Exception {
+    // select sum(distinct l_orderkey), l_linenumber, count(distinct l_orderkey), count(*) as total
+    // from (select * from lineitem union select * from lineitem) group by l_linenumber;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase1() throws Exception {
+    // one groupby, distinct, aggregation
+    ResultSet res = executeFile("testDistinctAggregation_case1.sql");
+    assertResultSet(res, "testDistinctAggregation_case1.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase2() throws Exception {
+    // one groupby, two distinct, one aggregation
+    ResultSet res = executeFile("testDistinctAggregation_case2.sql");
+    assertResultSet(res, "testDistinctAggregation_case2.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase3() throws Exception {
+    // one groupby, two distinct, two aggregation(no alias)
+    ResultSet res = executeFile("testDistinctAggregation_case3.sql");
+    assertResultSet(res, "testDistinctAggregation_case3.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase4() throws Exception {
+    // two groupby, two distinct, two aggregation
+    ResultSet res = executeFile("testDistinctAggregation_case4.sql");
+    assertResultSet(res, "testDistinctAggregation_case4.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase5() throws Exception {
+    // two groupby, two distinct, two aggregation with stage
+    ResultSet res = executeFile("testDistinctAggregation_case5.sql");
+    assertResultSet(res, "testDistinctAggregation_case5.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase6() throws Exception {
+    ResultSet res = executeFile("testDistinctAggregation_case6.sql");
+    assertResultSet(res, "testDistinctAggregation_case6.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase7() throws Exception {
+    ResultSet res = executeFile("testDistinctAggregation_case7.sql");
+    assertResultSet(res, "testDistinctAggregation_case7.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase8() throws Exception {
+    ResultSet res = executeFile("testDistinctAggregation_case8.sql");
+    assertResultSet(res, "testDistinctAggregation_case8.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase9() throws Exception {
+    ResultSet res = executeFile("testDistinctAggregation_case9.sql");
+    assertResultSet(res, "testDistinctAggregation_case9.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase10() throws Exception {
+    ResultSet res = executeFile("testDistinctAggregation_case10.sql");
+    assertResultSet(res, "testDistinctAggregation_case10.result");
+    res.close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCasebyCase11() throws Exception {
+    ResultSet res;
+
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.TEXT);
+    schema.addColumn("code", Type.TEXT);
+    schema.addColumn("qty", Type.INT4);
+    schema.addColumn("qty2", Type.FLOAT8);
+    String[] data = new String[]{"1|a|3|3.0", "1|a|4|4.0", "1|b|5|5.0", "2|a|1|6.0", "2|c|2|7.0", "2|d|3|8.0"};
+    TajoTestingCluster.createTable("table10", schema, tableOptions, data);
+
+    res = executeString("select id, count(distinct code), " +
+        "avg(qty), min(qty), max(qty), sum(qty), " +
+        "cast(avg(qty2) as INT8), cast(min(qty2) as INT8), cast(max(qty2) as INT8), cast(sum(qty2) as INT8) " +
+        "from table10 group by id");
+
+    String expected = "id,?count_4,?avg_5,?min_6,?max_7,?sum_8,?cast_9,?cast_10,?cast_11,?cast_12\n" +
+        "-------------------------------\n" +
+        "1,2,4.0,3,5,12,4,3,5,12\n" +
+        "2,3,2.0,1,3,6,7,6,8,21\n";
+
+    assertEquals(expected, resultSetToString(res));
+
+    // multiple distinct with expression
+    res = executeString(
+        "select count(distinct code) + count(distinct qty) from table10"
+    );
+
+    expected = "?plus_2\n" +
+        "-------------------------------\n" +
+        "9\n";
+
+    assertEquals(expected, resultSetToString(res));
+    res.close();
+
+    res = executeString(
+        "select id, count(distinct code) + count(distinct qty) from table10 group by id"
+    );
+
+    expected = "id,?plus_2\n" +
+        "-------------------------------\n" +
+        "1,5\n" +
+        "2,6\n";
+
+    assertEquals(expected, resultSetToString(res));
+    res.close();
+
+    executeString("DROP TABLE table10 PURGE").close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCaseByCase3() throws Exception {
+    // first distinct is smaller than second distinct.
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.TEXT);
+    schema.addColumn("col2", Type.TEXT);
+    schema.addColumn("col3", Type.TEXT);
+
+    String[] data = new String[]{
+        "a|b-1|\\N",
+        "a|b-2|\\N",
+        "a|b-2|\\N",
+        "a|b-3|\\N",
+        "a|b-3|\\N",
+        "a|b-3|\\N"
+    };
+
+    TajoTestingCluster.createTable("table10", schema, tableOptions, data);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE table10 PURGE").close();
+  }
+
+  @Test
+  public final void testDistinctAggregationCaseByCase4() throws Exception {
+    // Reproduction case for TAJO-994
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.TEXT);
+    schema.addColumn("col2", Type.TEXT);
+
+    String[] data = new String[]{
+        "a|\\N",
+        "a|\\N|",
+        "a|\\N|",
+        "a|\\N|",
+        "a|\\N|",
+        "a|\\N|"
+    };
+
+    TajoTestingCluster.createTable("testDistinctAggregationCaseByCase4".toLowerCase(), schema, tableOptions, data);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE testDistinctAggregationCaseByCase4 PURGE").close();
+  }
+
+  @Test
+  public final void testComplexParameter() throws Exception {
+    // select sum(l_extendedprice*l_discount) as revenue from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testComplexParameterWithSubQuery() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testComplexParameter2() throws Exception {
+    // select count(*) + max(l_orderkey) as merged from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testHavingWithNamedTarget() throws Exception {
+    // select l_orderkey, avg(l_partkey) total, sum(l_linenumber) as num from lineitem group by l_orderkey
+    // having total >= 2 or num = 3 order by l_orderkey, total;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  @Option(sort = true)
+  @SimpleTest
+  public final void testHavingWithAggFunction() throws Exception {
+    // select l_orderkey, avg(l_partkey) total, sum(l_linenumber) as num from lineitem group by l_orderkey
+    // having avg(l_partkey) = 2.5 or num = 1;
+    runSimpleTests();
+  }
+
+  @Test
+  public final void testGroupbyWithJson() throws Exception {
+    // select l_orderkey, avg(l_partkey) total, sum(l_linenumber) as num from lineitem group by l_orderkey
+    // having total >= 2 or num = 3;
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData5() throws Exception {
+    executeString("CREATE TABLE testGroupByWithNullData5 (age INT4, point FLOAT4);").close();
+    assertTableExists("testGroupByWithNullData5".toLowerCase());
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE testGroupByWithNullData5");
+  }
+
+  @Test
+  public final void testGroupByWithNullData6() throws Exception {
+    executeString("CREATE TABLE testGroupByWithNullData6 (age INT4, point FLOAT4);").close();
+    assertTableExists("testGroupByWithNullData6".toLowerCase());
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE testGroupByWithNullData6");
+  }
+
+  @Test
+  public final void testGroupByWithNullData7() throws Exception {
+    executeString("CREATE TABLE testGroupByWithNullData7 (age INT4, point FLOAT4);").close();
+    assertTableExists("testGroupByWithNullData7".toLowerCase());
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE testGroupByWithNullData7");
+  }
+
+  @Test
+  public final void testGroupByWithNullData8() throws Exception {
+    executeString("CREATE TABLE testGroupByWithNullData8 (age INT4, point FLOAT4);").close();
+    assertTableExists("testGroupByWithNullData8".toLowerCase());
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE testGroupByWithNullData8");
+  }
+
+  @Test
+  public final void testGroupByWithNullData9() throws Exception {
+    executeString("CREATE TABLE testGroupByWithNullData9 (age INT4, point FLOAT4);").close();
+    assertTableExists("testGroupByWithNullData9".toLowerCase());
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE testGroupByWithNullData9");
+  }
+
+  @Test
+  public final void testGroupByWithNullData10() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData11() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupByWithNullData12() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNumShufflePartition() throws Exception {
+
+    Thread.sleep(5000);
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.TEXT);
+    schema.addColumn("col2", Type.TEXT);
+
+    List<String> data = new ArrayList<String>();
+    int totalBytes = 0;
+    Random rand = new Random(System.currentTimeMillis());
+    String col1Prefix = "Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1" +
+        "Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1" +
+        "Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1Column-1";
+
+    Set<Integer> uniqKeys = new HashSet<Integer>();
+    while(true) {
+      int col1RandomValue = rand.nextInt(1000000);
+      uniqKeys.add(col1RandomValue);
+      String str = (col1Prefix + "-" + col1RandomValue) + "|col2-" + rand.nextInt(1000000);
+      data.add(str);
+
+      totalBytes += str.getBytes().length;
+
+      if (totalBytes > 3 * 1024 * 1024) {
+        break;
+      }
+    }
+    TajoTestingCluster.createTable("testnumshufflepartition", schema, tableOptions, data.toArray(new String[]{}), 3);
+
+    try {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$DIST_QUERY_GROUPBY_PARTITION_VOLUME.varname, "2");
+      ResultSet res = executeString(
+          "select col1 \n" +
+              ",count(distinct col2) as cnt1\n" +
+              "from testnumshufflepartition \n" +
+              "group by col1"
+      );
+
+      int numRows = 0;
+      while (res.next()) {
+        numRows++;
+      }
+      assertEquals(uniqKeys.size(), numRows);
+
+      // find last QueryMasterTask
+      List<QueryMasterTask> qmTasks = new ArrayList<QueryMasterTask>();
+
+      for(TajoWorker worker: testingCluster.getTajoWorkers()) {
+        qmTasks.addAll(worker.getWorkerContext().getQueryMaster().getFinishedQueryMasterTasks());
+      }
+
+      assertTrue(!qmTasks.isEmpty());
+
+      Collections.sort(qmTasks, new Comparator<QueryMasterTask>() {
+        @Override
+        public int compare(QueryMasterTask o1, QueryMasterTask o2) {
+          long l1 = o1.getQuerySubmitTime();
+          long l2 = o2.getQuerySubmitTime();
+          return l1 < l2 ? - 1 : (l1 > l2 ? 1 : 0);
+        }
+      });
+
+      // Getting the number of partitions. It should be 2.
+      Set<Integer> partitionIds = new HashSet<Integer>();
+
+      Query query = qmTasks.get(qmTasks.size() - 1).getQuery();
+      Collection<Stage> stages = query.getStages();
+      assertNotNull(stages);
+      assertTrue(!stages.isEmpty());
+      for (Stage stage : stages) {
+        if (stage.getId().toStringNoPrefix().endsWith("_000001")) {
+          for (Task.IntermediateEntry eachInterm: stage.getHashShuffleIntermediateEntries()) {
+            partitionIds.add(eachInterm.getPartId());
+          }
+        }
+      }
+
+      assertEquals(2, partitionIds.size());
+      executeString("DROP TABLE testnumshufflepartition PURGE").close();
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$DIST_QUERY_GROUPBY_PARTITION_VOLUME.varname,
+          ConfVars.$DIST_QUERY_GROUPBY_PARTITION_VOLUME.defaultVal);
+    }
+  }
+
+  @Test
+  public final void testGroupbyWithLimit1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupbyWithLimit2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupbyWithLimit3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  @Option(sort = true)
+  @SimpleTest
+  public final void testGroupbyWithPythonFunc() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(sort = true)
+  @SimpleTest
+  public final void testGroupbyWithPythonFunc2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  public final void testPythonUdaf() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testPythonUdaf2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  @Option(sort = true)
+  @SimpleTest
+  public final void testPythonUdaf3() throws Exception {
+    runSimpleTests();
+  }
+
+  // TODO: this test cannot be executed due to the bug of logical planner (TAJO-1588)
+//  @Test
+  public final void testPythonUdafWithHaving() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testPythonUdafWithNullData() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  // TODO: this test cannot be executed due to the bug of logical planner (TAJO-1588)
+//  @Test
+  public final void testComplexTargetWithPythonUdaf() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  // TODO: this test cannot be executed due to the bug of logical planner (TAJO-1588)
+//  @Test
+  public final void testDistinctPythonUdafWithUnion1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+}


[31/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestWindowQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestWindowQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestWindowQuery.java
new file mode 100644
index 0000000..9993992
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestWindowQuery.java
@@ -0,0 +1,465 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+
+import static org.junit.Assert.assertEquals;
+
+@Category(IntegrationTest.class)
+public class TestWindowQuery extends QueryTestCaseBase {
+
+  public TestWindowQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testWindow1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow5() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow6() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow7() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindow8() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithOrderBy1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithOrderBy2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithOrderBy3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithOrderBy4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithOrderBy5() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowBeforeLimit() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithSubQuery() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithSubQuery2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithSubQuery3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithSubQuery4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithSubQuery5() throws Exception {
+    // filter push down test
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithSubQuery6() throws Exception {
+    // filter push down test
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithAggregation1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithAggregation2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithAggregation3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithAggregation4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithAggregation5() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWindowWithAggregation6() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testComplexOrderBy1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testRowNumber1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testRowNumber2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testRowNumber3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testFirstValue1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testFirstValueTime() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("time", TajoDataTypes.Type.TIME);
+    String[] data = new String[]{ "1|12:11:12", "2|10:11:13", "2|05:42:41" };
+    TajoTestingCluster.createTable("firstvaluetime", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString(
+          "select id, first_value(time) over ( partition by id order by time ) as time_first from firstvaluetime");
+      String ascExpected = "id,time_first\n" +
+          "-------------------------------\n" +
+          "1,12:11:12\n" +
+          "2,05:42:41\n" +
+          "2,05:42:41\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE firstvaluetime PURGE");
+    }
+  }
+
+  @Test
+  public final void testLastValue1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLastValueTime() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("time", TajoDataTypes.Type.TIME);
+    String[] data = new String[]{ "1|12:11:12", "2|10:11:13", "2|05:42:41" };
+    TajoTestingCluster.createTable("lastvaluetime", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString(
+          "select id, last_value(time) over ( partition by id order by time ) as time_last from lastvaluetime");
+      String ascExpected = "id,time_last\n" +
+          "-------------------------------\n" +
+          "1,12:11:12\n" +
+          "2,10:11:13\n" +
+          "2,10:11:13\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE lastvaluetime PURGE");
+    }
+  }
+
+  @Test
+  public final void testLag1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLagTime() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("time", TajoDataTypes.Type.TIME);
+    String[] data = new String[]{ "1|12:11:12", "2|10:11:13", "2|05:42:41" };
+    TajoTestingCluster.createTable("lagtime", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString(
+          "select id, lag(time, 1) over ( partition by id order by time ) as time_lag from lagtime");
+      String ascExpected = "id,time_lag\n" +
+          "-------------------------------\n" +
+          "1,null\n" +
+          "2,null\n" +
+          "2,05:42:41\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE lagtime PURGE");
+    }
+  }
+
+  @Test
+  public final void testLagWithNoArgs() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLagWithDefault() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLead1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLeadTime() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("time", TajoDataTypes.Type.TIME);
+    String[] data = new String[]{ "1|12:11:12", "2|10:11:13", "2|05:42:41" };
+    TajoTestingCluster.createTable("leadtime", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString(
+          "select id, lead(time, 1) over ( partition by id order by time ) as time_lead from leadtime");
+      String ascExpected = "id,time_lead\n" +
+          "-------------------------------\n" +
+          "1,null\n" +
+          "2,10:11:13\n" +
+          "2,null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE leadtime PURGE");
+    }
+  }
+
+  @Test
+  public final void testLeadWithNoArgs() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLeadWithDefault() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testStdDevSamp1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testStdDevPop1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testMultipleWindow() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("time", TajoDataTypes.Type.TIME);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    String[] data = new String[]{ "1|12:11:12|abc", "2|10:11:13|def", "2|05:42:41|ghi" };
+    TajoTestingCluster.createTable("multiwindow", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString(
+          "select id, last_value(time) over ( partition by id order by time ) as time_last, last_value(name) over ( partition by id order by time ) as name_last from multiwindow");
+      String ascExpected = "id,time_last,name_last\n" +
+          "-------------------------------\n" +
+          "1,12:11:12,abc\n" +
+          "2,10:11:13,def\n" +
+          "2,10:11:13,def\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE multiwindow PURGE");
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTableCache.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTableCache.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTableCache.java
new file mode 100644
index 0000000..f10f2a1
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTableCache.java
@@ -0,0 +1,109 @@
+/**
+ * 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.util;
+
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.engine.utils.CacheHolder;
+import org.apache.tajo.engine.utils.TableCache;
+import org.apache.tajo.engine.utils.TableCacheKey;
+import org.apache.tajo.worker.ExecutionBlockSharedResource;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class TestTableCache {
+
+  @Test
+  public void testBroadcastTableCache() throws Exception {
+
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(
+        QueryIdFactory.newQueryId(System.currentTimeMillis(), 0));
+
+    final TableCacheKey key = new TableCacheKey(ebId.toString(), "testBroadcastTableCache", "path");
+    final ExecutionBlockSharedResource resource = new ExecutionBlockSharedResource();
+
+    final int parallelCount = 30;
+    ExecutorService executor = Executors.newFixedThreadPool(parallelCount);
+    List<Future<CacheHolder<Long>>> tasks = new ArrayList<Future<CacheHolder<Long>>>();
+    for (int i = 0; i < parallelCount; i++) {
+      tasks.add(executor.submit(createTask(key, resource)));
+    }
+
+    long expected = tasks.get(0).get().getData().longValue();
+
+    for (Future<CacheHolder<Long>> future : tasks) {
+      assertEquals(expected, future.get().getData().longValue());
+    }
+
+    resource.releaseBroadcastCache(ebId);
+    assertFalse(resource.hasBroadcastCache(key));
+    executor.shutdown();
+  }
+
+  private Callable<CacheHolder<Long>> createTask(final TableCacheKey key, final ExecutionBlockSharedResource resource) {
+    return new Callable<CacheHolder<Long>>() {
+      @Override
+      public CacheHolder<Long> call() throws Exception {
+        CacheHolder<Long> result;
+        synchronized (resource.getLock()) {
+          if (!TableCache.getInstance().hasCache(key)) {
+            final long nanoTime = System.nanoTime();
+            final TableStats tableStats = new TableStats();
+            tableStats.setNumRows(100);
+            tableStats.setNumBytes(1000);
+
+            final CacheHolder<Long> cacheHolder = new CacheHolder<Long>() {
+
+              @Override
+              public Long getData() {
+                return nanoTime;
+              }
+
+              @Override
+              public TableStats getTableStats() {
+                return tableStats;
+              }
+
+              @Override
+              public void release() {
+
+              }
+            };
+
+            resource.addBroadcastCache(key, cacheHolder);
+          }
+        }
+
+        CacheHolder<?> holder = resource.getBroadcastCache(key);
+        result = (CacheHolder<Long>) holder;
+        return result;
+      }
+    };
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTupleUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTupleUtil.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTupleUtil.java
new file mode 100644
index 0000000..4a3565e
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/util/TestTupleUtil.java
@@ -0,0 +1,188 @@
+/**
+ * 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.util;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.SortSpec;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.engine.planner.RangePartitionAlgorithm;
+import org.apache.tajo.engine.planner.UniformRangePartition;
+import org.apache.tajo.plan.rewrite.rules.PartitionedTableRewriter;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.RowStoreUtil.RowStoreDecoder;
+import org.apache.tajo.storage.RowStoreUtil.RowStoreEncoder;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestTupleUtil {
+  @Test
+  public final void testFixedSizeChar() {
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.CHAR, 5);
+
+    Tuple tuple = new VTuple(1);
+    tuple.put(new Datum[] {
+      DatumFactory.createChar("abc\0\0")
+    });
+
+    RowStoreEncoder encoder = RowStoreUtil.createEncoder(schema);
+    RowStoreDecoder decoder = RowStoreUtil.createDecoder(schema);
+    byte [] bytes = encoder.toBytes(tuple);
+    Tuple tuple2 = decoder.toTuple(bytes);
+
+    assertEquals(tuple, tuple2);
+  }
+
+  @Test
+  public final void testToBytesAndToTuple() {
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.BOOLEAN);
+    schema.addColumn("col2", Type.BIT);
+    schema.addColumn("col3", Type.CHAR);
+    schema.addColumn("col4", Type.INT2);
+    schema.addColumn("col5", Type.INT4);
+    schema.addColumn("col6", Type.INT8);
+    schema.addColumn("col7", Type.FLOAT4);
+    schema.addColumn("col8", Type.FLOAT8);
+    schema.addColumn("col9", Type.TEXT);
+    schema.addColumn("col10", Type.BLOB);
+    schema.addColumn("col11", Type.INET4);
+    //schema.addColumn("col11", DataType.IPv6);
+    
+    Tuple tuple = new VTuple(new Datum[] {
+        DatumFactory.createBool(true),
+        DatumFactory.createBit((byte) 0x99),
+        DatumFactory.createChar('7'),
+        DatumFactory.createInt2((short) 17),
+        DatumFactory.createInt4(59),
+        DatumFactory.createInt8(23l),
+        DatumFactory.createFloat4(77.9f),
+        DatumFactory.createFloat8(271.9f),
+        DatumFactory.createText("hyunsik"),
+        DatumFactory.createBlob("hyunsik".getBytes()),
+        DatumFactory.createInet4("192.168.0.1")
+    });
+
+    RowStoreEncoder encoder = RowStoreUtil.createEncoder(schema);
+    RowStoreDecoder decoder = RowStoreUtil.createDecoder(schema);
+    byte [] bytes = encoder.toBytes(tuple);
+    Tuple tuple2 = decoder.toTuple(bytes);
+    
+    assertEquals(tuple, tuple2);
+  }
+
+  @Test
+  public final void testGetPartitions() {
+    VTuple sTuple = new VTuple(7);
+    VTuple eTuple = new VTuple(7);
+
+    Schema schema = new Schema();
+
+    schema.addColumn("numByte", Type.BIT);
+    schema.addColumn("numChar", Type.CHAR);
+    schema.addColumn("numShort", Type.INT2);
+    schema.addColumn("numInt", Type.INT4);
+    schema.addColumn("numLong", Type.INT8);
+    schema.addColumn("numFloat", Type.FLOAT4);
+    schema.addColumn("numDouble", Type.FLOAT4);
+
+    SortSpec[] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    sTuple.put(0, DatumFactory.createBit((byte) 44));
+    sTuple.put(1, DatumFactory.createChar('a'));
+    sTuple.put(2, DatumFactory.createInt2((short) 10));
+    sTuple.put(3, DatumFactory.createInt4(5));
+    sTuple.put(4, DatumFactory.createInt8(100));
+    sTuple.put(5, DatumFactory.createFloat4(100));
+    sTuple.put(6, DatumFactory.createFloat8(100));
+
+    eTuple.put(0, DatumFactory.createBit((byte) 99));
+    eTuple.put(1, DatumFactory.createChar('p'));
+    eTuple.put(2, DatumFactory.createInt2((short) 70));
+    eTuple.put(3, DatumFactory.createInt4(70));
+    eTuple.put(4, DatumFactory.createInt8(10000));
+    eTuple.put(5, DatumFactory.createFloat4(150));
+    eTuple.put(6, DatumFactory.createFloat8(170));
+
+    RangePartitionAlgorithm partitioner = new UniformRangePartition(new TupleRange(sortSpecs, sTuple, eTuple),
+        sortSpecs);
+    TupleRange [] ranges = partitioner.partition(5);
+    assertTrue(5 <= ranges.length);
+    BaseTupleComparator comp = new BaseTupleComparator(schema, PlannerUtil.schemaToSortSpecs(schema));
+    TupleRange prev = ranges[0];
+    for (int i = 1; i < ranges.length; i++) {
+      assertTrue(comp.compare(prev.getStart(), ranges[i].getStart()) < 0);
+      assertTrue(comp.compare(prev.getEnd(), ranges[i].getEnd()) < 0);
+      prev = ranges[i];
+    }
+  }
+
+  @Test
+  public void testBuildTupleFromPartitionPath() {
+
+    Schema schema = new Schema();
+    schema.addColumn("key1", Type.INT8);
+    schema.addColumn("key2", Type.TEXT);
+
+    Path path = new Path("hdfs://tajo/warehouse/partition_test/");
+    Tuple tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, true);
+    assertNull(tuple);
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, false);
+    assertNull(tuple);
+
+    path = new Path("hdfs://tajo/warehouse/partition_test/key1=123");
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, true);
+    assertNotNull(tuple);
+    assertEquals(DatumFactory.createInt8(123), tuple.asDatum(0));
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, false);
+    assertNotNull(tuple);
+    assertEquals(DatumFactory.createInt8(123), tuple.asDatum(0));
+
+    path = new Path("hdfs://tajo/warehouse/partition_test/key1=123/part-0000"); // wrong cases;
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, true);
+    assertNull(tuple);
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, false);
+    assertNull(tuple);
+
+    path = new Path("hdfs://tajo/warehouse/partition_test/key1=123/key2=abc");
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, true);
+    assertNotNull(tuple);
+    assertEquals(DatumFactory.createInt8(123), tuple.asDatum(0));
+    assertEquals(DatumFactory.createText("abc"), tuple.asDatum(1));
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, false);
+    assertNotNull(tuple);
+    assertEquals(DatumFactory.createInt8(123), tuple.asDatum(0));
+    assertEquals(DatumFactory.createText("abc"), tuple.asDatum(1));
+
+
+    path = new Path("hdfs://tajo/warehouse/partition_test/key1=123/key2=abc/part-0001");
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, true);
+    assertNull(tuple);
+
+    tuple = PartitionedTableRewriter.buildTupleFromPartitionPath(schema, path, false);
+    assertNotNull(tuple);
+    assertEquals(DatumFactory.createInt8(123), tuple.asDatum(0));
+    assertEquals(DatumFactory.createText("abc"), tuple.asDatum(1));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ha/TestHAServiceHDFSImpl.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ha/TestHAServiceHDFSImpl.java b/tajo-core-tests/src/test/java/org/apache/tajo/ha/TestHAServiceHDFSImpl.java
new file mode 100644
index 0000000..265f075
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ha/TestHAServiceHDFSImpl.java
@@ -0,0 +1,160 @@
+/**
+ * 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.ha;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.IOUtils;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.TajoMaster;
+import org.apache.tajo.service.ServiceTracker;
+import org.apache.tajo.service.ServiceTrackerFactory;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class TestHAServiceHDFSImpl  {
+  private TajoTestingCluster cluster;
+
+  private TajoMaster primaryMaster;
+  private TajoMaster backupMaster;
+
+  private Path haPath, activePath, backupPath;
+
+  @Test
+  public final void testAutoFailOver() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+
+    try {
+      FileSystem fs = cluster.getDefaultFileSystem();
+
+      TajoConf primaryConf = setConfigForHAMaster();
+      primaryMaster = new TajoMaster();
+      primaryMaster.init(primaryConf);
+      primaryMaster.start();
+
+      TajoConf backupConf = setConfigForHAMaster();
+      backupMaster = new TajoMaster();
+      backupMaster.init(backupConf);
+      backupMaster.start();
+
+      ServiceTracker tracker = ServiceTrackerFactory.get(primaryConf);
+
+      assertNotEquals(primaryMaster.getMasterName(), backupMaster.getMasterName());
+      verifySystemDirectories(fs);
+
+      assertEquals(2, fs.listStatus(activePath).length);
+      assertEquals(1, fs.listStatus(backupPath).length);
+
+      assertTrue(fs.exists(new Path(activePath, HAConstants.ACTIVE_LOCK_FILE)));
+      assertTrue(fs.exists(new Path(activePath, primaryMaster.getMasterName().replaceAll(":", "_"))));
+      assertTrue(fs.exists(new Path(backupPath, backupMaster.getMasterName().replaceAll(":", "_"))));
+
+      createDatabaseAndTable(tracker);
+      verifyDataBaseAndTable(tracker);
+
+      primaryMaster.stop();
+
+      verifyDataBaseAndTable(tracker);
+
+      assertEquals(2, fs.listStatus(activePath).length);
+      assertEquals(0, fs.listStatus(backupPath).length);
+
+      assertTrue(fs.exists(new Path(activePath, HAConstants.ACTIVE_LOCK_FILE)));
+      assertTrue(fs.exists(new Path(activePath, backupMaster.getMasterName().replaceAll(":", "_"))));
+    } finally {
+      backupMaster.stop();
+    }
+  }
+
+  private TajoConf setConfigForHAMaster() {
+    TajoConf conf = new TajoConf(cluster.getConfiguration());
+
+    conf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS,
+        "localhost:" + NetUtils.getFreeSocketPort());
+    conf.setVar(TajoConf.ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS,
+        "localhost:" + NetUtils.getFreeSocketPort());
+    conf.setVar(TajoConf.ConfVars.RESOURCE_TRACKER_RPC_ADDRESS,
+        "localhost:" + NetUtils.getFreeSocketPort());
+    conf.setVar(TajoConf.ConfVars.CATALOG_ADDRESS,
+        "localhost:" + NetUtils.getFreeSocketPort());
+    conf.setVar(TajoConf.ConfVars.TAJO_MASTER_INFO_ADDRESS,
+        "localhost:" + NetUtils.getFreeSocketPort());
+    conf.setIntVar(TajoConf.ConfVars.REST_SERVICE_PORT,
+        NetUtils.getFreeSocketPort());
+
+    conf.setBoolVar(TajoConf.ConfVars.TAJO_MASTER_HA_ENABLE, true);
+    conf.setIntVar(TajoConf.ConfVars.TAJO_MASTER_HA_MONITOR_INTERVAL, 1000);
+
+    //Client API service RPC Server
+    conf.setIntVar(TajoConf.ConfVars.MASTER_SERVICE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_SERVICE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+
+    // Internal RPC Server
+    conf.setIntVar(TajoConf.ConfVars.MASTER_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(TajoConf.ConfVars.QUERY_MASTER_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(TajoConf.ConfVars.CATALOG_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+
+    return conf;
+  }
+
+  private void verifySystemDirectories(FileSystem fs) throws Exception {
+    haPath = TajoConf.getSystemHADir(cluster.getConfiguration());
+    assertTrue(fs.exists(haPath));
+
+    activePath = new Path(haPath, TajoConstants.SYSTEM_HA_ACTIVE_DIR_NAME);
+    assertTrue(fs.exists(activePath));
+
+    backupPath = new Path(haPath, TajoConstants.SYSTEM_HA_BACKUP_DIR_NAME);
+    assertTrue(fs.exists(backupPath));
+  }
+
+  private void createDatabaseAndTable(ServiceTracker tracker) throws Exception {
+    TajoClient client = null;
+    try {
+      client = new TajoClientImpl(tracker);
+      client.executeQuery("CREATE TABLE default.ha_test1 (age int);");
+      client.executeQuery("CREATE TABLE default.ha_test2 (age int);");
+    } finally {
+      IOUtils.cleanup(null, client);
+    }
+  }
+
+  private void verifyDataBaseAndTable(ServiceTracker tracker) throws Exception {
+    TajoClient client = null;
+    try {
+      client = new TajoClientImpl(tracker);
+      client.existDatabase("default");
+      client.existTable("default.ha_test1");
+      client.existTable("default.ha_test2");
+    } finally {
+      IOUtils.cleanup(null, client);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestResultSet.java b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
new file mode 100644
index 0000000..0c83fd0
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
@@ -0,0 +1,224 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 
+ */
+package org.apache.tajo.jdbc;
+
+import com.google.common.collect.Lists;
+import com.google.protobuf.ByteString;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.util.KeyValueSet;
+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.*;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestResultSet {
+  private static TajoTestingCluster util;
+  private static TajoConf conf;
+  private static TableDesc desc;
+  private static FileTablespace sm;
+  private static TableMeta scoreMeta;
+  private static Schema scoreSchema;
+  private static List<ByteString> serializedData;
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    util = TpchTestBase.getInstance().getTestingCluster();
+    conf = util.getConfiguration();
+    sm = TablespaceManager.getDefault();
+
+    scoreSchema = new Schema();
+    scoreSchema.addColumn("deptname", Type.TEXT);
+    scoreSchema.addColumn("score", Type.INT4);
+    scoreMeta = CatalogUtil.newTableMeta("TEXT");
+    TableStats stats = new TableStats();
+
+    Path p = new Path(sm.getTableUri("default", "score"));
+    sm.getFileSystem().mkdirs(p);
+    Appender appender = sm.getAppender(scoreMeta, scoreSchema, new Path(p, "score"));
+    RowStoreUtil.RowStoreEncoder encoder = RowStoreUtil.createEncoder(scoreSchema);
+    serializedData = Lists.newArrayList();
+    appender.init();
+
+    int deptSize = 100;
+    int tupleNum = 10000;
+    Tuple tuple;
+    long written = 0;
+    for (int i = 0; i < tupleNum; i++) {
+      tuple = new VTuple(2);
+      String key = "test" + (i % deptSize);
+      tuple.put(0, DatumFactory.createText(key));
+      tuple.put(1, DatumFactory.createInt4(i + 1));
+      written += key.length() + Integer.SIZE;
+      appender.addTuple(tuple);
+      serializedData.add(ByteString.copyFrom(encoder.toBytes(tuple)));
+    }
+    appender.close();
+    stats.setNumRows(tupleNum);
+    stats.setNumBytes(written);
+    stats.setAvgRows(tupleNum);
+    stats.setNumBlocks(1000);
+    stats.setNumShuffleOutputs(100);
+    desc = new TableDesc(CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "score"),
+        scoreSchema, scoreMeta, p.toUri());
+    desc.setStats(stats);
+  }
+
+  @AfterClass
+  public static void terminate() throws IOException {
+
+  }
+
+  @Test
+  public void testMemoryResultSet() throws Exception {
+    TajoMemoryResultSet rs = new TajoMemoryResultSet(null, desc.getSchema(),
+        serializedData, desc.getStats().getNumRows().intValue(), null);
+
+    ResultSetMetaData meta = rs.getMetaData();
+    assertNotNull(meta);
+    Schema schema = scoreSchema;
+    assertEquals(schema.size(), meta.getColumnCount());
+    for (int i = 0; i < meta.getColumnCount(); i++) {
+      assertEquals(schema.getColumn(i).getSimpleName(), meta.getColumnName(i + 1));
+      assertEquals(schema.getColumn(i).getQualifier(), meta.getTableName(i + 1));
+    }
+
+    int i = 0;
+    assertTrue(rs.isBeforeFirst());
+    for (; rs.next(); i++) {
+      assertEquals("test"+i%100, rs.getString(1));
+      assertEquals("test"+i%100, rs.getString("deptname"));
+      assertEquals(i+1, rs.getInt(2));
+      assertEquals(i+1, rs.getInt("score"));
+    }
+    assertEquals(10000, i);
+    assertTrue(rs.isAfterLast());
+  }
+
+  @Test
+  public void testDateTimeType() throws Exception {
+    // HiveCatalog does not support date type, time type in hive-0.12.0
+    if(util.isHiveCatalogStoreRunning()) return;
+
+    ResultSet res = null;
+    TajoClient client = util.newTajoClient();
+    try {
+      String tableName = "datetimetable";
+      String query = "select col1, col2, col3 from " + tableName;
+
+      String [] table = new String[] {tableName};
+      Schema schema = new Schema();
+      schema.addColumn("col1", Type.DATE);
+      schema.addColumn("col2", Type.TIME);
+      schema.addColumn("col3", Type.TIMESTAMP);
+      Schema [] schemas = new Schema[] {schema};
+      String [] data = {
+          "2014-01-01|01:00:00|2014-01-01 01:00:00"
+      };
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+
+      res = TajoTestingCluster
+          .run(table, schemas, tableOptions, new String[][]{data}, query, client);
+
+      assertTrue(res.next());
+
+      Date date = res.getDate(1);
+      assertNotNull(date);
+      assertEquals(Date.valueOf("2014-01-01"), date);
+
+      date = res.getDate("col1");
+      assertNotNull(date);
+      assertEquals(Date.valueOf("2014-01-01"), date);
+
+      Time time = res.getTime(2);
+      assertNotNull(time);
+      assertEquals(Time.valueOf("01:00:00"), time);
+
+      time = res.getTime("col2");
+      assertNotNull(time);
+      assertEquals(Time.valueOf("01:00:00"), time);
+
+      Timestamp timestamp = res.getTimestamp(3);
+      assertNotNull(timestamp);
+      assertEquals(Timestamp.valueOf("2014-01-01 01:00:00"), timestamp);
+
+      timestamp = res.getTimestamp("col3");
+      assertNotNull(timestamp);
+      assertEquals(Timestamp.valueOf("2014-01-01 01:00:00"), timestamp);
+
+      // assert with timezone
+      Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+9"));
+      date = res.getDate(1, cal);
+      assertNotNull(date);
+      assertEquals("2014-01-01", date.toString());
+
+      date = res.getDate("col1", cal);
+      assertNotNull(date);
+      assertEquals("2014-01-01", date.toString());
+
+      time = res.getTime(2, cal);
+      assertNotNull(time);
+      assertEquals("10:00:00", time.toString());
+
+      time = res.getTime("col2", cal);
+      assertNotNull(time);
+      assertEquals("10:00:00", time.toString());
+
+      timestamp = res.getTimestamp(3, cal);
+      assertNotNull(timestamp);
+      assertEquals("2014-01-01 10:00:00.0", timestamp.toString());
+
+      timestamp = res.getTimestamp("col3", cal);
+      assertNotNull(timestamp);
+      assertEquals("2014-01-01 10:00:00.0", timestamp.toString());
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+
+      client.close();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestSQLState.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestSQLState.java b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestSQLState.java
new file mode 100644
index 0000000..e711524
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestSQLState.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import com.google.common.collect.Maps;
+import org.apache.hadoop.io.IOUtils;
+import org.apache.tajo.*;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.QueryClient;
+import org.apache.tajo.client.QueryStatus;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.net.InetSocketAddress;
+import java.sql.*;
+import java.util.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestSQLState extends QueryTestCaseBase {
+  private static InetSocketAddress tajoMasterAddress;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    tajoMasterAddress = testingCluster.getMaster().getTajoMasterClientService().getBindAddress();
+    Class.forName("org.apache.tajo.jdbc.TajoDriver").newInstance();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+  }
+
+  static String buildConnectionUri(String hostName, int port, String databaseName) {
+    return "jdbc:tajo://" + hostName + ":" + port + "/" + databaseName;
+  }
+
+  private Connection makeConnection() throws SQLException {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+    assertTrue(conn.isValid(100));
+
+    return conn;
+  }
+
+  public void assertSQLState(String sql, String sqlState) throws SQLException {
+    Connection conn = null;
+    Statement stmt = null;
+    ResultSet res = null;
+
+    try {
+      conn = makeConnection();
+      stmt = conn.createStatement();
+      res = stmt.executeQuery(sql);
+    } catch (SQLException se) {
+      assertEquals(sqlState, se.getSQLState());
+    } catch (Throwable t) {
+      fail(t.getMessage());
+    } finally {
+      CatalogUtil.closeQuietly(stmt, res);
+      CatalogUtil.closeQuietly(conn);
+    }
+  }
+
+  @Test
+  public void testSyntaxError() throws Exception {
+    assertSQLState("selec x,y,x from lineitem", "42601");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
new file mode 100644
index 0000000..8ee6755
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
@@ -0,0 +1,504 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import com.google.common.collect.Sets;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.common.type.TajoTypeUtil;
+import org.apache.tajo.util.TUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.net.InetSocketAddress;
+import java.sql.*;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+public class TestTajoDatabaseMetaData extends QueryTestCaseBase {
+  private static InetSocketAddress tajoMasterAddress;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    tajoMasterAddress = testingCluster.getMaster().getTajoMasterClientService().getBindAddress();
+    Class.forName("org.apache.tajo.jdbc.TajoDriver").newInstance();
+  }
+
+  public static List<String> getListFromResultSet(ResultSet resultSet, String columnName) throws SQLException {
+    List<String> list = new ArrayList<String>();
+    while(resultSet.next()) {
+      list.add(resultSet.getString(columnName));
+    }
+    return list;
+  }
+
+  @Test
+  public void testSetAndGetCatalogAndSchema() throws Exception {
+    String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        TajoConstants.DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+
+    assertDatabaseNotExists("jdbc_test1");
+    PreparedStatement pstmt = conn.prepareStatement("CREATE DATABASE jdbc_test1");
+    pstmt.executeUpdate();
+    assertDatabaseExists("jdbc_test1");
+    pstmt.close();
+
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertDatabaseNotExists("Jdbc_Test2");
+      pstmt = conn.prepareStatement("CREATE DATABASE \"Jdbc_Test2\"");
+      pstmt.executeUpdate();
+      assertDatabaseExists("Jdbc_Test2");
+      pstmt.close();
+    }
+
+    conn.setCatalog("jdbc_test1");
+    assertEquals("jdbc_test1", conn.getCatalog());
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      conn.setCatalog("Jdbc_Test2");
+      assertEquals("Jdbc_Test2", conn.getCatalog());
+    }
+    conn.setCatalog("jdbc_test1");
+    assertEquals("jdbc_test1", conn.getCatalog());
+
+    ResultSet resultSet = conn.getMetaData().getSchemas();
+    assertResultSet(resultSet, "getSchemas1.result");
+    resultSet.close();
+
+    resultSet = conn.getMetaData().getSchemas("jdbc_test1", "%");
+    assertResultSet(resultSet, "getSchemas2.result");
+    resultSet.close();
+
+    resultSet = conn.getMetaData().getTableTypes();
+    assertResultSet(resultSet, "getTableTypes.result");
+    resultSet.close();
+
+    conn.setCatalog(TajoConstants.DEFAULT_DATABASE_NAME);
+    pstmt = conn.prepareStatement("DROP DATABASE jdbc_test1");
+    pstmt.executeUpdate();
+    pstmt.close();
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      pstmt = conn.prepareStatement("DROP DATABASE \"Jdbc_Test2\"");
+      pstmt.executeUpdate();
+      pstmt.close();
+    }
+
+    conn.close();
+  }
+
+  @Test
+  public void testGetCatalogsAndTables() throws Exception {
+    String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        TajoConstants.DEFAULT_DATABASE_NAME);
+    Connection defaultConnect = DriverManager.getConnection(connUri);
+
+    DatabaseMetaData dbmd = defaultConnect.getMetaData();
+    List<String> existingDatabases = getListFromResultSet(dbmd.getCatalogs(), "TABLE_CAT");
+
+    // create database "jdbc_test1" and its tables
+    assertDatabaseNotExists("jdbc_test3");
+    PreparedStatement pstmt = defaultConnect.prepareStatement("CREATE DATABASE jdbc_test3");
+    pstmt.executeUpdate();
+    assertDatabaseExists("jdbc_test3");
+    pstmt.close();
+    pstmt = defaultConnect.prepareStatement("CREATE TABLE jdbc_test3.table1 (age int)");
+    pstmt.executeUpdate();
+    pstmt.close();
+    pstmt = defaultConnect.prepareStatement("CREATE TABLE jdbc_test3.table2 (age int)");
+    pstmt.executeUpdate();
+    pstmt.close();
+
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // create database "jdbc_test2" and its tables
+      assertDatabaseNotExists("Jdbc_Test4");
+      pstmt = defaultConnect.prepareStatement("CREATE DATABASE \"Jdbc_Test4\"");
+      pstmt.executeUpdate();
+      assertDatabaseExists("Jdbc_Test4");
+      pstmt.close();
+
+      pstmt = defaultConnect.prepareStatement("CREATE TABLE \"Jdbc_Test4\".table3 (age int)");
+      pstmt.executeUpdate();
+      pstmt.close();
+      pstmt = defaultConnect.prepareStatement("CREATE TABLE \"Jdbc_Test4\".table4 (age int)");
+      pstmt.executeUpdate();
+      pstmt.close();
+    }
+
+    // verify getCatalogs()
+    dbmd = defaultConnect.getMetaData();
+    List<String> newDatabases = getListFromResultSet(dbmd.getCatalogs(), "TABLE_CAT");
+
+    newDatabases.removeAll(existingDatabases);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(2, newDatabases.size());
+    } else {
+      assertEquals(1, newDatabases.size());
+    }
+    assertTrue(newDatabases.contains("jdbc_test3"));
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertTrue(newDatabases.contains("Jdbc_Test4"));
+    }
+
+    // verify getTables()
+    ResultSet res = defaultConnect.getMetaData().getTables("jdbc_test3", null, null, null);
+    assertResultSet(res, "getTables1.result");
+    res.close();
+
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      res = defaultConnect.getMetaData().getTables("Jdbc_Test4", null, null, null);
+      assertResultSet(res, "getTables2.result");
+      res.close();
+    }
+
+    defaultConnect.close();
+
+    // jdbc1_test database connection test
+    String jdbcTest1ConnUri =
+        TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(), "jdbc_test3");
+    Connection jdbcTest1Conn = DriverManager.getConnection(jdbcTest1ConnUri);
+    assertEquals("jdbc_test3", jdbcTest1Conn.getCatalog());
+    jdbcTest1Conn.close();
+
+    client.selectDatabase("default");
+    executeString("DROP TABLE jdbc_test3.table1");
+    executeString("DROP TABLE jdbc_test3.table2");
+    executeString("DROP DATABASE jdbc_test3");
+
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      String jdbcTest2ConnUri =
+          TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(), "Jdbc_Test4");
+      Connection jdbcTest2Conn = DriverManager.getConnection(jdbcTest2ConnUri);
+      assertEquals("Jdbc_Test4", jdbcTest2Conn.getCatalog());
+      jdbcTest2Conn.close();
+
+      client.selectDatabase("default");
+      executeString("DROP TABLE \"Jdbc_Test4\".table3");
+      executeString("DROP TABLE \"Jdbc_Test4\".table4");
+      executeString("DROP DATABASE \"Jdbc_Test4\"");
+    }
+  }
+
+  @Test
+  public void testGetTablesWithPattern() throws Exception {
+    String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        TajoConstants.DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+
+    Map<String,List<String>> tables = new HashMap<String,List<String>>();
+    assertDatabaseNotExists("db_1");
+    executeString("CREATE DATABASE db_1");
+    assertDatabaseExists("db_1");
+    for (int i = 0; i < 3; i++) {
+      String tableName = "tb_" + i;
+      TUtil.putToNestedList(tables, "db_1", tableName);
+      executeString("CREATE TABLE db_1." + tableName + " (age int)");
+    }
+    for (int i = 0; i < 3; i++) {
+      String tableName = "table_" + i + "_ptn";
+      TUtil.putToNestedList(tables, "db_1", tableName);
+      executeString("CREATE TABLE db_1." + tableName + " (age int)");
+    }
+
+    assertDatabaseNotExists("db_2");
+    executeString("CREATE DATABASE db_2");
+    assertDatabaseExists("db_2");
+    for (int i = 0; i < 3; i++) {
+      String tableName = "tb_" + i;
+      TUtil.putToNestedList(tables, "db_2", tableName);
+      executeString("CREATE TABLE db_2." + tableName + " (age int)");
+    }
+    for (int i = 0; i < 3; i++) {
+      String tableName = "table_" + i + "_ptn";
+      TUtil.putToNestedList(tables, "db_2", tableName);
+      executeString("CREATE TABLE db_2." + tableName + " (age int)");
+    }
+
+    // all wildcard test
+    Set<String> tableList =
+        Sets.newHashSet(getListFromResultSet(conn.getMetaData().getTables("db_2", null, "%", null), "TABLE_NAME"));
+    assertEquals(Sets.newHashSet(tables.get("db_2")), tableList);
+
+    // leading wildcard test
+    tableList =
+        Sets.newHashSet(getListFromResultSet(conn.getMetaData().getTables("db_2", null, "%_ptn", null), "TABLE_NAME"));
+    assertEquals(Sets.newHashSet("table_0_ptn", "table_1_ptn", "table_2_ptn"), tableList);
+
+    // tailing wildcard test
+    tableList =
+        Sets.newHashSet(getListFromResultSet(conn.getMetaData().getTables("db_2", null, "tb_%", null), "TABLE_NAME"));
+    assertEquals(Sets.newHashSet("tb_0", "tb_1", "tb_2"), tableList);
+
+    ResultSet resultSet = conn.getMetaData().getTables(null, null, "tb\\_%", null);
+    int i = 0;
+    while(resultSet.next()) {
+      tables.get(resultSet.getString("TABLE_CAT")).contains(resultSet.getString("TABLE_NAME"));
+      i++;
+    }
+    assertEquals(6, i);
+
+    executeString("DROP DATABASE db_1");
+    executeString("DROP DATABASE db_2");
+  }
+
+  private static String getTestColName(String dbName, String tableName, int i) {
+    if (i % 2 == 1) {
+      return CatalogUtil.denormalizeIdentifier(dbName + "_" + tableName + "_col") + " int";
+    } else {
+      return CatalogUtil.denormalizeIdentifier(dbName + "_" + tableName + "_COL") + " int";
+    }
+  }
+
+  @Test
+  public void testGetColumnsWithPattern() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+          TajoConstants.DEFAULT_DATABASE_NAME);
+      Connection conn = DriverManager.getConnection(connUri);
+
+      // Below creates the following 12 tables
+      // db<i>.tb<j>, i = {1,2}, 0 <= j < 2
+      // db<i>.table_<j>, i = {1,2}, 0 <= j < 2
+
+      Map<String,List<String>> tables = new HashMap<String,List<String>>();
+      for (int j = 1; j <= 2; j++) {
+        String dbName = "db" + j;
+        assertDatabaseNotExists(dbName);
+        executeString("CREATE DATABASE " + dbName).close();
+        assertDatabaseExists(dbName);
+        for (int i = 3; i < 6; i++) {
+          String tableName = "tb" + i;
+
+
+          if (i % 2 == 0) {
+            tableName = tableName.toUpperCase();
+          }
+
+          TUtil.putToNestedList(tables, dbName, tableName);
+
+          executeString("CREATE TABLE " + dbName + "." + CatalogUtil.denormalizeIdentifier(tableName) +
+              " (" + getTestColName(dbName, tableName, 1) +
+              ") PARTITION BY COLUMN (" + getTestColName(dbName, tableName, 2) + ")").close();
+          assertTableExists(dbName + "." + tableName);
+        }
+        for (int i = 3; i < 6; i++) {
+          String tableName = "table" + i;
+
+
+          if (i % 2 == 0) {
+            tableName = tableName.toUpperCase();
+          }
+
+          TUtil.putToNestedList(tables, dbName, tableName);
+
+          executeString("CREATE TABLE " + dbName + "." + CatalogUtil.denormalizeIdentifier(tableName) +
+              " (" + getTestColName(dbName, tableName, 1) +
+              ") PARTITION BY COLUMN (" + getTestColName(dbName, tableName, 2) + ")").close();
+          assertTableExists(dbName + "." + tableName);
+        }
+      }
+
+      // all wildcard test on columns
+      Set<String> columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "tb3", "%"),
+              "COLUMN_NAME"));
+      assertEquals(Sets.newHashSet("db2_tb3_col", "db2_tb3_COL"), columnList);
+
+      // tailing wildcard + case sensitive test on columns
+      columnList = Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "tb3", "%col"),
+          "COLUMN_NAME"));
+      assertEquals(Sets.newHashSet("db2_tb3_col"), columnList);
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "tb3", "%COL"),
+              "COLUMN_NAME"));
+      assertEquals(Sets.newHashSet("db2_tb3_COL"), columnList);
+
+      // tailing wildcard test on columns
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "tb3", "db2\\_tb3\\_%"),
+              "COLUMN_NAME"));
+      assertEquals(Sets.newHashSet("db2_tb3_col", "db2_tb3_COL"), columnList);
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "%", "db2\\_tb3\\_%"),
+              "COLUMN_NAME"));
+      assertEquals(Sets.newHashSet("db2_tb3_col", "db2_tb3_COL"), columnList);
+
+      // leading wildcard test on tables
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db1", null, "%3", "%"),
+              "COLUMN_NAME"));
+      assertEquals(
+          Sets.newHashSet(
+              "db1_tb3_col", "db1_tb3_COL",
+              "db1_table3_col", "db1_table3_COL"),
+          columnList);
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "%3", "%"),
+              "COLUMN_NAME"));
+      assertEquals(
+          Sets.newHashSet(
+              "db2_tb3_col", "db2_tb3_COL",
+              "db2_table3_col", "db2_table3_COL"),
+          columnList);
+
+      // tailing wildcard + case sensitive test on tables
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "TABLE%", "%"),
+              "COLUMN_NAME"));
+      assertEquals(
+          Sets.newHashSet(
+              "db2_TABLE4_col", "db2_TABLE4_COL"), columnList);
+
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "TABLE4", "%"),
+              "COLUMN_NAME"));
+      assertEquals(
+          Sets.newHashSet(
+              "db2_TABLE4_col", "db2_TABLE4_COL"),
+          columnList);
+
+      // tailing wildcard test on tables
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns("db2", null, "table%", "%"),
+              "COLUMN_NAME"));
+      assertEquals(
+          Sets.newHashSet(
+              "db2_table3_col", "db2_table3_COL",
+              "db2_table5_col", "db2_table5_COL"),
+          columnList);
+
+      // wildcard test on database
+      columnList =
+          Sets.newHashSet(getListFromResultSet(conn.getMetaData().getColumns(null, null, "%3", "db1_tb3%"),
+              "COLUMN_NAME"));
+      assertEquals(Sets.newHashSet("db1_tb3_col", "db1_tb3_COL"), columnList);
+
+      executeString("DROP DATABASE db1");
+      executeString("DROP DATABASE db2");
+    }
+  }
+
+  @Test
+  public void testEmptyMetaInfo() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+          TajoConstants.DEFAULT_DATABASE_NAME);
+      Connection conn = DriverManager.getConnection(connUri);
+
+      try {
+        DatabaseMetaData meta = conn.getMetaData();
+
+        ResultSet res = meta.getProcedures(null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getProcedureColumns(null, null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getUDTs(null, null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getColumnPrivileges(null, null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getTablePrivileges(null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getBestRowIdentifier(null, null, null, 0, false);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getVersionColumns(null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getPrimaryKeys(null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getImportedKeys(null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getExportedKeys(null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getCrossReference(null, null, null, null, null, null);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getIndexInfo(null, null, null, false, false);
+        assertNotNull(res);
+        assertFalse(res.next());
+
+        res = meta.getClientInfoProperties();
+        assertNotNull(res);
+        assertFalse(res.next());
+      } finally {
+        conn.close();
+      }
+    }
+  }
+
+  @Test
+  public void testGetTypeInfo() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+          TajoConstants.DEFAULT_DATABASE_NAME);
+      Connection conn = DriverManager.getConnection(connUri);
+
+      try {
+        DatabaseMetaData meta = conn.getMetaData();
+
+        ResultSet res = meta.getTypeInfo();
+
+        assertNotNull(res);
+
+        int numTypes = 0;
+
+        String[] columnNames = {"TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", "LITERAL_SUFFIX",
+            "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE",
+            "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE",
+            "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"};
+
+        while (res.next()) {
+          for (int i = 0; i < columnNames.length; i++) {
+            Object value = res.getObject(columnNames[i]);
+            if (i == 15 || i == 16) {
+              assertNull(value);
+            } else {
+              assertNotNull(value);
+            }
+          }
+          numTypes++;
+        }
+
+        assertEquals(numTypes, TajoTypeUtil.getTypeInfos().size());
+      } finally {
+        conn.close();
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
new file mode 100644
index 0000000..acbc1a8
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
@@ -0,0 +1,608 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.jdbc;
+
+import com.google.common.collect.Maps;
+import org.apache.tajo.*;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.QueryClient;
+import org.apache.tajo.client.QueryStatus;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.net.InetSocketAddress;
+import java.sql.*;
+import java.util.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestTajoJdbc extends QueryTestCaseBase {
+  private static InetSocketAddress tajoMasterAddress;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    tajoMasterAddress = testingCluster.getMaster().getTajoMasterClientService().getBindAddress();
+    Class.forName("org.apache.tajo.jdbc.TajoDriver").newInstance();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+  }
+
+  public static String buildConnectionUri(String hostName, int port, String databaseName) {
+    return "jdbc:tajo://" + hostName + ":" + port + "/" + databaseName;
+  }
+
+  @Test
+  public void testAcceptURL() throws SQLException {
+    TajoDriver driver = new TajoDriver();
+    assertTrue(driver.acceptsURL("jdbc:tajo:"));
+    assertFalse(driver.acceptsURL("jdbc:taju:"));
+  }
+
+  @Test(expected = SQLException.class)
+  public void testGetConnection() throws SQLException {
+    DriverManager.getConnection("jdbc:taju://" + tajoMasterAddress.getHostName() + ":" + tajoMasterAddress.getPort()
+      + "/default");
+  }
+
+  @Test
+  public void testStatement() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+    assertTrue(conn.isValid(100));
+
+    Statement stmt = null;
+    ResultSet res = null;
+    try {
+      stmt = conn.createStatement();
+
+      res = stmt.executeQuery("select l_returnflag, l_linestatus, count(*) as count_order from lineitem " +
+        "group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus");
+
+      try {
+        Map<String, Integer> result = Maps.newHashMap();
+        result.put("NO", 3);
+        result.put("RF", 2);
+
+        assertNotNull(res);
+        assertTrue(res.next());
+        assertTrue(result.get(res.getString(1) + res.getString(2)) == res.getInt(3));
+        assertTrue(res.next());
+        assertTrue(result.get(res.getString(1) + res.getString(2)) == res.getInt(3));
+        assertFalse(res.next());
+
+        ResultSetMetaData rsmd = res.getMetaData();
+        assertEquals(3, rsmd.getColumnCount());
+        assertEquals("l_returnflag", rsmd.getColumnName(1));
+        assertEquals("l_linestatus", rsmd.getColumnName(2));
+        assertEquals("count_order", rsmd.getColumnName(3));
+      } finally {
+        res.close();
+      }
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+      if (stmt != null) {
+        stmt.close();
+      }
+      if (conn != null) {
+        conn.close();
+      }
+    }
+  }
+
+  @Test
+  public void testPreparedStatement() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      TajoConstants.DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+    assertTrue(conn.isValid(100));
+
+    PreparedStatement stmt = null;
+    ResultSet res = null;
+    try {
+      /*
+      test data set
+      1,17.0,N
+      1,36.0,N
+      2,38.0,N
+      3,45.0,R
+      3,49.0,R
+      */
+
+      String sql =
+        "select l_orderkey, l_quantity, l_returnflag from lineitem where l_quantity > ? and l_returnflag = ?";
+
+      stmt = conn.prepareStatement(sql);
+
+      stmt.setInt(1, 20);
+      stmt.setString(2, "N");
+
+      res = stmt.executeQuery();
+
+      ResultSetMetaData rsmd = res.getMetaData();
+      assertEquals(3, rsmd.getColumnCount());
+      assertEquals("l_orderkey", rsmd.getColumnName(1));
+      assertEquals("l_quantity", rsmd.getColumnName(2));
+      assertEquals("l_returnflag", rsmd.getColumnName(3));
+
+      try {
+        int numRows = 0;
+        String[] resultData = {"136.0N", "238.0N"};
+        while (res.next()) {
+          assertEquals(resultData[numRows],
+            ("" + res.getObject(1).toString() + res.getObject(2).toString() + res.getObject(3).toString()));
+          numRows++;
+        }
+        assertEquals(2, numRows);
+      } finally {
+        res.close();
+      }
+
+      stmt.setInt(1, 20);
+      stmt.setString(2, "R");
+
+      res = stmt.executeQuery();
+
+      rsmd = res.getMetaData();
+      assertEquals(3, rsmd.getColumnCount());
+      assertEquals("l_orderkey", rsmd.getColumnName(1));
+      assertEquals("l_quantity", rsmd.getColumnName(2));
+      assertEquals("l_returnflag", rsmd.getColumnName(3));
+
+      try {
+        int numRows = 0;
+        String[] resultData = {"345.0R", "349.0R"};
+        while (res.next()) {
+          assertEquals(resultData[numRows],
+            ("" + res.getObject(1).toString() + res.getObject(2).toString() + res.getObject(3).toString()));
+          numRows++;
+        }
+        assertEquals(2, numRows);
+      } finally {
+        res.close();
+      }
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+      if (stmt != null) {
+        stmt.close();
+      }
+      if (conn != null) {
+        conn.close();
+      }
+    }
+  }
+
+  @Test
+  public void testDatabaseMetaDataGetTable() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      TajoConstants.DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+    assertTrue(conn.isValid(100));
+
+    DatabaseMetaData dbmd = conn.getMetaData();
+
+    ResultSet rs = null;
+
+    try {
+      rs = dbmd.getTables("default", null, null, null);
+
+      ResultSetMetaData rsmd = rs.getMetaData();
+      int numCols = rsmd.getColumnCount();
+      assertEquals(5, numCols);
+
+      Set<String> retrivedViaJavaAPI = new HashSet<String>(client.getTableList("default"));
+
+      Set<String> retrievedViaJDBC = new HashSet<String>();
+      while (rs.next()) {
+        retrievedViaJDBC.add(rs.getString("TABLE_NAME"));
+      }
+      assertEquals(retrievedViaJDBC, retrivedViaJavaAPI);
+    } finally {
+      if (rs != null) {
+        rs.close();
+      }
+    }
+
+    assertTrue(conn.isValid(100));
+    conn.close();
+  }
+
+  @Test
+  public void testDatabaseMetaDataGetColumns() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      TajoConstants.DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+    assertTrue(conn.isValid(100));
+
+    DatabaseMetaData dbmd = conn.getMetaData();
+    ResultSet rs = null;
+
+    try {
+      String tableName = "lineitem";
+      rs = dbmd.getColumns(null, null, tableName, null);
+
+      ResultSetMetaData rsmd = rs.getMetaData();
+      int numCols = rsmd.getColumnCount();
+
+      assertEquals(22, numCols);
+      int numColumns = 0;
+
+      TableDesc tableDesc = client.getTableDesc(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, tableName));
+      assertNotNull(tableDesc);
+
+      List<Column> columns = tableDesc.getSchema().getRootColumns();
+
+      while (rs.next()) {
+        assertEquals(tableName, rs.getString("TABLE_NAME"));
+        assertEquals(columns.get(numColumns).getSimpleName(), rs.getString("COLUMN_NAME"));
+        // TODO assert type
+        numColumns++;
+      }
+
+      assertEquals(16, numColumns);
+    } finally {
+      if (rs != null) {
+        rs.close();
+      }
+    }
+
+    assertTrue(conn.isValid(100));
+    conn.close();
+    assertFalse(conn.isValid(100));
+  }
+
+  @Test
+  public void testMultipleConnections() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      TajoConstants.DEFAULT_DATABASE_NAME);
+
+    Connection[] conns = new Connection[2];
+    conns[0] = DriverManager.getConnection(connUri);
+    conns[1] = DriverManager.getConnection(connUri);
+
+    try {
+      for (int i = 0; i < conns.length; i++) {
+        Statement stmt = null;
+        ResultSet res = null;
+        try {
+          stmt = conns[i].createStatement();
+
+          res = stmt.executeQuery("select l_returnflag, l_linestatus, count(*) as count_order from lineitem " +
+            "group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus");
+
+          try {
+            Map<String, Integer> result = Maps.newHashMap();
+            result.put("NO", 3);
+            result.put("RF", 2);
+
+            assertNotNull(res);
+            assertTrue(res.next());
+            assertTrue(result.get(res.getString(1) + res.getString(2)) == res.getInt(3));
+            assertTrue(res.next());
+            assertTrue(result.get(res.getString(1) + res.getString(2)) == res.getInt(3));
+            assertFalse(res.next());
+
+            ResultSetMetaData rsmd = res.getMetaData();
+            assertEquals(3, rsmd.getColumnCount());
+            assertEquals("l_returnflag", rsmd.getColumnName(1));
+            assertEquals("l_linestatus", rsmd.getColumnName(2));
+            assertEquals("count_order", rsmd.getColumnName(3));
+          } finally {
+            res.close();
+          }
+        } finally {
+          if (res != null) {
+            res.close();
+          }
+          if (stmt != null) {
+            stmt.close();
+          }
+        }
+      }
+    } finally {
+      assertTrue(conns[0].isValid(100));
+      conns[0].close();
+      assertFalse(conns[0].isValid(100));
+      assertTrue(conns[1].isValid(100));
+      conns[1].close();
+      assertFalse(conns[1].isValid(100));
+    }
+  }
+
+  @Test
+  public void testMultipleConnectionsSequentialClose() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      DEFAULT_DATABASE_NAME);
+
+    Connection[] conns = new Connection[2];
+    conns[0] = DriverManager.getConnection(connUri);
+    conns[1] = DriverManager.getConnection(connUri);
+
+    try {
+      for (int i = 0; i < conns.length; i++) {
+        Statement stmt = null;
+        ResultSet res = null;
+        try {
+          stmt = conns[i].createStatement();
+
+          res = stmt.executeQuery("select l_returnflag, l_linestatus, count(*) as count_order from lineitem " +
+            "group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus");
+
+          try {
+            Map<String, Integer> result = Maps.newHashMap();
+            result.put("NO", 3);
+            result.put("RF", 2);
+
+            assertNotNull(res);
+            assertTrue(res.next());
+            assertTrue(result.get(res.getString(1) + res.getString(2)) == res.getInt(3));
+            assertTrue(res.next());
+            assertTrue(result.get(res.getString(1) + res.getString(2)) == res.getInt(3));
+            assertFalse(res.next());
+
+            ResultSetMetaData rsmd = res.getMetaData();
+            assertEquals(3, rsmd.getColumnCount());
+            assertEquals("l_returnflag", rsmd.getColumnName(1));
+            assertEquals("l_linestatus", rsmd.getColumnName(2));
+            assertEquals("count_order", rsmd.getColumnName(3));
+          } finally {
+            res.close();
+          }
+        } finally {
+          if (res != null) {
+            res.close();
+          }
+          if (stmt != null) {
+            stmt.close();
+          }
+          conns[i].close();
+        }
+      }
+    } finally {
+      if (!conns[0].isClosed()) {
+        assertTrue(conns[0].isValid(100));
+        conns[0].close();
+        assertFalse(conns[0].isValid(100));
+      }
+      if (!conns[1].isClosed()) {
+        assertTrue(conns[1].isValid(100));
+        conns[1].close();
+        assertFalse(conns[1].isValid(100));
+      }
+    }
+  }
+
+  @Test
+  public void testCreateTableWithDateAndTimestamp() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("testCreateTableWithDateAndTimestamp");
+
+    int result;
+    Statement stmt = null;
+    ResultSet res = null;
+    Connection conn = null;
+    try {
+      String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        DEFAULT_DATABASE_NAME);
+      conn = DriverManager.getConnection(connUri);
+      assertTrue(conn.isValid(100));
+
+      stmt = conn.createStatement();
+      result = stmt.executeUpdate("create table " + tableName + " (id int, name text, score double"
+        + ", register_date timestamp, update_date date, send_date time)");
+      assertEquals(result, 1);
+
+      res = stmt.executeQuery("select * from " + tableName);
+      assertFalse(res.next());
+
+      ResultSetMetaData rsmd = res.getMetaData();
+      assertNotNull(rsmd);
+      assertEquals(6, rsmd.getColumnCount());
+
+      assertEquals("id", rsmd.getColumnName(1));
+      assertEquals("name", rsmd.getColumnName(2));
+      assertEquals("score", rsmd.getColumnName(3));
+      assertEquals("register_date", rsmd.getColumnName(4));
+      assertEquals("update_date", rsmd.getColumnName(5));
+      assertEquals("send_date", rsmd.getColumnName(6));
+
+      assertEquals("integer", rsmd.getColumnTypeName(1));
+      assertEquals("varchar", rsmd.getColumnTypeName(2));
+      assertEquals("float8", rsmd.getColumnTypeName(3));
+      assertEquals("timestamp", rsmd.getColumnTypeName(4));
+      assertEquals("date", rsmd.getColumnTypeName(5));
+      assertEquals("time", rsmd.getColumnTypeName(6));
+
+    } finally {
+      cleanupQuery(res);
+      if (stmt != null) {
+        stmt.close();
+      }
+
+      if(conn != null) {
+        conn.close();
+      }
+    }
+  }
+
+  @Test
+  public void testSortWithDateTime() throws Exception {
+    Statement stmt = null;
+    ResultSet res = null;
+    Connection conn = null;
+    int result;
+
+    // skip this test if catalog uses HiveCatalogStore.
+    // It is because HiveCatalogStore does not support Time data type.
+    try {
+      if (!testingCluster.isHiveCatalogStoreRunning()) {
+        executeDDL("create_table_with_date_ddl.sql", "table1");
+
+        String connUri = buildConnectionUri(tajoMasterAddress.getHostName(),
+          tajoMasterAddress.getPort(), "TestTajoJdbc");
+
+        conn = DriverManager.getConnection(connUri);
+        assertTrue(conn.isValid(100));
+
+        stmt = conn.createStatement();
+        res = stmt.executeQuery("select col1, col2, col3 from table1 order by col1, col2, col3");
+
+        ResultSetMetaData rsmd = res.getMetaData();
+        assertNotNull(rsmd);
+        assertEquals(3, rsmd.getColumnCount());
+
+        assertEquals("timestamp", rsmd.getColumnTypeName(1));
+        assertEquals("date", rsmd.getColumnTypeName(2));
+        assertEquals("time", rsmd.getColumnTypeName(3));
+
+        assertResultSet(res);
+
+        result = stmt.executeUpdate("drop table table1");
+        assertEquals(result, 1);
+
+      }
+    } finally {
+      cleanupQuery(res);
+      if (stmt != null) {
+        stmt.close();
+      }
+
+      if(conn != null) {
+        conn.close();
+      }
+    }
+  }
+
+
+  @Test
+  public void testAlterTableAddPartition() throws Exception {
+    Statement stmt = null;
+    ResultSet resultSet = null;
+    int retCode = 0;
+    Connection conn = null;
+    int result;
+    String errorMessage = null;
+
+    // skip this test if catalog uses HiveCatalogStore.
+    // It is because HiveCatalogStore does not support Time data type.
+    try {
+      if (!testingCluster.isHiveCatalogStoreRunning()) {
+        String connUri = buildConnectionUri(tajoMasterAddress.getHostName(),
+          tajoMasterAddress.getPort(), "TestTajoJdbc");
+
+        conn = DriverManager.getConnection(connUri);
+        assertTrue(conn.isValid(100));
+
+        String tableName = CatalogUtil.normalizeIdentifier("testAlterTablePartition");
+        resultSet = executeString(
+          "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) ");
+        resultSet.close();
+
+        stmt = conn.createStatement();
+        result  = stmt.executeUpdate("alter table " + tableName + " add partition (key = 0.1)");
+        assertEquals(result, 1);
+     }
+    } finally {      
+      cleanupQuery(resultSet);
+      if (stmt != null) {
+        stmt.close();
+      }
+
+      if(conn != null) {
+        conn.close();
+      }
+    }
+  }
+
+  @Test
+  public void testMaxRows() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+      DEFAULT_DATABASE_NAME);
+    Connection conn = DriverManager.getConnection(connUri);
+    assertTrue(conn.isValid(100));
+    Statement stmt = null;
+    ResultSet res = null;
+    //Parameter value setting for test.
+    final int maxRowsNum = 3;
+    int resultRowsNum = 0, returnMaxRows = 0;
+    try {
+      stmt = conn.createStatement();
+      //set maxRows(3)
+      stmt.setMaxRows(maxRowsNum);
+      //get MaxRows
+      returnMaxRows = stmt.getMaxRows();
+      res = stmt.executeQuery("select * from lineitem");
+      assertNotNull(res);
+      while (res.next()) {
+        //Actuality result Rows.
+        resultRowsNum++;	
+      }
+      //The test success, if maxRowsNum and resultRowsNum and returnMaxRows is same.
+      assertTrue(maxRowsNum == resultRowsNum && maxRowsNum == returnMaxRows);
+    } finally {
+      if (res != null) {
+        cleanupQuery(res);
+      }
+      if (stmt != null) {
+        stmt.close();
+      }
+      if (conn != null) {
+        conn.close();
+      }
+    }
+  }
+
+  @Test
+  public final void testCancel() throws Exception {
+    String connUri = buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(),
+        DEFAULT_DATABASE_NAME);
+    Properties props = new Properties();
+    props.setProperty(SessionVars.BLOCK_ON_RESULT.keyname(), "false");
+
+    Connection conn = new JdbcConnection(connUri, props);
+    PreparedStatement statement = conn.prepareStatement("select sleep(1) from lineitem");
+    try {
+      assertTrue("should have result set", statement.execute());
+      TajoResultSetBase result = (TajoResultSetBase) statement.getResultSet();
+      Thread.sleep(1000);   // todo query master is not killed properly if it's compiling the query (use 100, if you want see)
+      statement.cancel();
+
+      QueryStatus status = client.getQueryStatus(result.getQueryId());
+      assertEquals(TajoProtos.QueryState.QUERY_KILLED, status.getState());
+    } finally {
+      if (statement != null) {
+        statement.close();
+      }
+      if (conn != null) {
+        conn.close();
+      }
+    }
+  }
+}


[21/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/set_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/set_4.sql b/tajo-core-tests/src/test/resources/queries/default/set_4.sql
new file mode 100644
index 0000000..a8f0814
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/set_4.sql
@@ -0,0 +1,36 @@
+SELECT *
+FROM
+(
+  SELECT
+          a.reg_date,
+          a.user_id
+  FROM
+          (SELECT buy_date AS bdate
+          FROM buy_history
+          WHERE host='a0') as a JOIN (SELECT * FROM category_info WHERE category_id ='A1') as  b ON a.id=b.id
+  UNION ALL
+  SELECT
+          a.reg_date,
+          a.user_id
+  FROM
+          (SELECT buy_date AS bdate
+          FROM buy_history
+          WHERE host='b0') as a JOIN (SELECT * FROM category_info WHERE category_id ='B1') as b ON a.id=b.id
+  UNION ALL
+  SELECT
+          a.reg_date,
+          a.user_id
+  FROM
+          (SELECT buy_date AS bdate
+          FROM buy_history
+          WHERE host='c0') as a JOIN (SELECT * FROM category_info WHERE category_id ='C1') as  b ON a.id=b.id
+  UNION ALL
+  SELECT
+          a.reg_date,
+          a.user_id
+  FROM
+          (SELECT buy_date AS bdate
+          FROM buy_history
+          WHERE host='d0') as  a JOIN (SELECT * FROM category_info WHERE category_id ='D1') as  b ON a.id=b.id
+
+)  as T
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/table_subquery1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/table_subquery1.sql b/tajo-core-tests/src/test/resources/queries/default/table_subquery1.sql
new file mode 100644
index 0000000..3181e43
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/table_subquery1.sql
@@ -0,0 +1,19 @@
+SELECT unioninput.*
+FROM (
+  select
+    table1.key,
+    table1.value
+  FROM
+    table1
+  WHERE
+    table1.key < 100
+
+  UNION ALL
+
+  SELECT
+    table2.*
+  FROM
+    table2
+  WHERE
+    table2.key > 100
+) unioninput
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/table_subquery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/table_subquery2.sql b/tajo-core-tests/src/test/resources/queries/default/table_subquery2.sql
new file mode 100644
index 0000000..206b76f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/table_subquery2.sql
@@ -0,0 +1,21 @@
+SELECT
+  t1.fk,
+  t2.name
+FROM
+ (
+    SELECT
+      table1.fk
+    FROM
+      table1
+ ) t1
+
+ inner join
+
+ (
+    SELECT
+      table2.name
+    FROM
+      table2
+ ) t2
+
+ ON t1.fk = t2.fk;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/union_1.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/union_1.hiveql b/tajo-core-tests/src/test/resources/queries/default/union_1.hiveql
new file mode 100644
index 0000000..d5cda15
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/union_1.hiveql
@@ -0,0 +1,14 @@
+SELECT unioninput.*
+FROM (
+  select table1.key, table1.value
+  FROM table1
+  WHERE table1.key < 100
+  UNION ALL
+  SELECT table2.*
+  FROM table2
+  WHERE table2.key > 100
+  UNION ALL
+  select table3.key, table3.value
+  FROM table3
+  WHERE table3.key < 100
+) unioninput
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestAlterTable/after_set_property_delimiter.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestAlterTable/after_set_property_delimiter.result b/tajo-core-tests/src/test/resources/results/TestAlterTable/after_set_property_delimiter.result
new file mode 100644
index 0000000..6729298
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestAlterTable/after_set_property_delimiter.result
@@ -0,0 +1,3 @@
+xx,yy,zz
+-------------------------------
+aaa+AAA,bbb+BBB,ccc

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestAlterTable/before_set_property_delimiter.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestAlterTable/before_set_property_delimiter.result b/tajo-core-tests/src/test/resources/results/TestAlterTable/before_set_property_delimiter.result
new file mode 100644
index 0000000..af74e40
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestAlterTable/before_set_property_delimiter.result
@@ -0,0 +1,3 @@
+xx,yy,zz
+-------------------------------
+aaa,AAA|bbb,BBB|ccc

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgDouble.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgDouble.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgDouble.result
new file mode 100644
index 0000000..bd2a69f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgDouble.result
@@ -0,0 +1,5 @@
+l_orderkey,revenue
+-------------------------------
+1,0.065
+2,0.0
+3,0.08
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgInt.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgInt.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgInt.result
new file mode 100644
index 0000000..aef1b53
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgInt.result
@@ -0,0 +1,3 @@
+total_avg
+-------------------------------
+1.8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLong.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLong.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLong.result
new file mode 100644
index 0000000..9c12da0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLong.result
@@ -0,0 +1,3 @@
+total_avg
+-------------------------------
+2.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLongOverflow.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLongOverflow.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLongOverflow.result
new file mode 100644
index 0000000..5e1c937
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testAvgLongOverflow.result
@@ -0,0 +1,3 @@
+avg
+-------------------------------
+9.34786981E8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testCount.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testCount.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testCount.result
new file mode 100644
index 0000000..381cded
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testCount.result
@@ -0,0 +1,3 @@
+rownum
+-------------------------------
+5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxLong.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxLong.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxLong.result
new file mode 100644
index 0000000..6a87409
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxLong.result
@@ -0,0 +1,3 @@
+total_max
+-------------------------------
+3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxString.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxString.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxString.result
new file mode 100644
index 0000000..6a87409
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMaxString.result
@@ -0,0 +1,3 @@
+total_max
+-------------------------------
+3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinLong.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinLong.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinLong.result
new file mode 100644
index 0000000..216e683
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinLong.result
@@ -0,0 +1,3 @@
+total_min
+-------------------------------
+1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinString.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinString.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinString.result
new file mode 100644
index 0000000..216e683
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testMinString.result
@@ -0,0 +1,3 @@
+total_min
+-------------------------------
+1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPart.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPart.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPart.result
new file mode 100644
index 0000000..d22cd68
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPart.result
@@ -0,0 +1,7 @@
+?split_part
+-------------------------------
+DELIVER
+TAKE
+TAKE
+NONE
+TAKE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartByString.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartByString.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartByString.result
new file mode 100644
index 0000000..ac8119d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartByString.result
@@ -0,0 +1,7 @@
+?split_part
+-------------------------------
+DELIVER IN PERSON
+TA
+TA
+NONE
+TA
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartNested.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartNested.result b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartNested.result
new file mode 100644
index 0000000..ec0f07b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestBuiltinFunctions/testSplitPartNested.result
@@ -0,0 +1,7 @@
+?split_part
+-------------------------------
+null
+KE
+KE
+null
+KE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result
new file mode 100644
index 0000000..048902f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result
@@ -0,0 +1,7 @@
+col1,col2,key
+-------------------------------
+1.0,1.0,17.0
+1.0,1.0,36.0
+2.0,2.0,38.0
+3.0,2.0,45.0
+3.0,3.0,49.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithLimit.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithLimit.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithLimit.result
new file mode 100644
index 0000000..ea78854
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithLimit.result
@@ -0,0 +1,5 @@
+col1,col2,key
+-------------------------------
+1.0,1.0,17.0
+1.0,1.0,36.0
+2.0,2.0,38.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOptions.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOptions.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOptions.result
new file mode 100644
index 0000000..ea78854
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOptions.result
@@ -0,0 +1,5 @@
+col1,col2,key
+-------------------------------
+1.0,1.0,17.0
+1.0,1.0,36.0
+2.0,2.0,38.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result
new file mode 100644
index 0000000..048902f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result
@@ -0,0 +1,7 @@
+col1,col2,key
+-------------------------------
+1.0,1.0,17.0
+1.0,1.0,36.0
+2.0,2.0,38.0
+3.0,2.0,45.0
+3.0,3.0,49.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithStoreType.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithStoreType.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithStoreType.result
new file mode 100644
index 0000000..ea78854
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithStoreType.result
@@ -0,0 +1,5 @@
+col1,col2,key
+-------------------------------
+1.0,1.0,17.0
+1.0,1.0,36.0
+2.0,2.0,38.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithTextFile.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithTextFile.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithTextFile.result
new file mode 100644
index 0000000..ea78854
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithTextFile.result
@@ -0,0 +1,5 @@
+col1,col2,key
+-------------------------------
+1.0,1.0,17.0
+1.0,1.0,36.0
+2.0,2.0,38.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result
new file mode 100644
index 0000000..a6f9853
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result
@@ -0,0 +1,8 @@
+col1,col2,key
+-------------------------------
+1,0,17.0
+1,0,17.0
+1,0,36.0
+1,0,36.0
+2,0,38.0
+2,0,38.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO1224Case1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO1224Case1.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO1224Case1.result
new file mode 100644
index 0000000..19336a7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO1224Case1.result
@@ -0,0 +1,3 @@
+?count
+-------------------------------
+5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO415Case.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO415Case.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO415Case.result
new file mode 100644
index 0000000..6c527af
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO415Case.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey,cnt
+-------------------------------
+1,1,1
+2,2,1
+3,3,1
+4,null,1
+5,null,1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO418Case.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO418Case.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO418Case.result
new file mode 100644
index 0000000..d78067e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO418Case.result
@@ -0,0 +1,4 @@
+l_returnflag,l_linestatus
+-------------------------------
+N,O
+R,F
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO619Case.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO619Case.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO619Case.result
new file mode 100644
index 0000000..86249b0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO619Case.result
@@ -0,0 +1,3 @@
+?count
+-------------------------------
+13

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO718Case.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO718Case.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO718Case.result
new file mode 100644
index 0000000..86c4d57
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO718Case.result
@@ -0,0 +1,5 @@
+l_orderkey,l_orderkey1,t57801e5322bc50
+-------------------------------
+1,1,2
+2,2,1
+3,3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO739Case.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO739Case.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO739Case.result
new file mode 100644
index 0000000..83ae904
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO739Case.result
@@ -0,0 +1,7 @@
+n_nationkey,n_name
+-------------------------------
+1,ARGENTINA
+3,CANADA
+4,EGYPT
+13,JORDAN
+15,MOROCCO
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case1.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case1.result
new file mode 100644
index 0000000..01e467c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case1.result
@@ -0,0 +1,5 @@
+l_orderkey,col1
+-------------------------------
+1,##
+2,##
+3,##
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case2.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case2.result
new file mode 100644
index 0000000..01e467c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case2.result
@@ -0,0 +1,5 @@
+l_orderkey,col1
+-------------------------------
+1,##
+2,##
+3,##
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case3.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case3.result
new file mode 100644
index 0000000..01e467c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case3.result
@@ -0,0 +1,5 @@
+l_orderkey,col1
+-------------------------------
+1,##
+2,##
+3,##
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case4.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case4.result
new file mode 100644
index 0000000..d3b79d1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO914Case4.result
@@ -0,0 +1,5 @@
+l_orderkey,col1,s1
+-------------------------------
+1,##,2
+2,##,2
+3,##,6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO917Case1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO917Case1.result b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO917Case1.result
new file mode 100644
index 0000000..5dbe646
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCaseByCases/testTAJO917Case1.result
@@ -0,0 +1,7 @@
+r_regionkey
+-------------------------------
+0
+1
+2
+3
+4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_1.result b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_1.result
new file mode 100644
index 0000000..e31bc89
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_1.result
@@ -0,0 +1,5 @@
+aGe,teXt,Number
+-------------------------------
+1,abc,2
+2,def,5
+3,ghi,8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_2.result b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_2.result
new file mode 100644
index 0000000..d0c2732
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_2.result
@@ -0,0 +1,5 @@
+AgE,TEXT,NUMBER
+-------------------------------
+1,abc,2
+2,def,5
+3,ghi,8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_3.result b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_3.result
new file mode 100644
index 0000000..b04e5c1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_mixed_chars_3.result
@@ -0,0 +1,8 @@
+aGe,teXt,Number
+-------------------------------
+1,abc,2
+2,def,5
+3,ghi,8
+4,jkl,7
+5,opq,8
+6,stu,9
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_1.result b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_1.result
new file mode 100644
index 0000000..4656661
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_1.result
@@ -0,0 +1,5 @@
+아이디,텍스트,숫자
+-------------------------------
+1,abc,2
+2,def,5
+3,ghi,8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_2.result b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_2.result
new file mode 100644
index 0000000..7917cb4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_2.result
@@ -0,0 +1,5 @@
+진짜아이디,text,숫자
+-------------------------------
+1,abc,2
+2,def,5
+3,ghi,8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_3.result b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_3.result
new file mode 100644
index 0000000..3b51f2c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestCreateTable/quoted_identifier_non_ascii_3.result
@@ -0,0 +1,5 @@
+진짜아이디,길이,?multiply
+-------------------------------
+1,3,4
+2,3,10
+3,3,16
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result b/tajo-core-tests/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
new file mode 100644
index 0000000..ac2408d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
@@ -0,0 +1,2 @@
+float8 pi()
+float8 pow(float8,float8)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter.result
new file mode 100644
index 0000000..628924b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter.result
@@ -0,0 +1,3 @@
+revenue
+-------------------------------
+12908.3436
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter2.result
new file mode 100644
index 0000000..6ee9cb5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameter2.result
@@ -0,0 +1,3 @@
+merged
+-------------------------------
+8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameterWithSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameterWithSubQuery.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameterWithSubQuery.result
new file mode 100644
index 0000000..59e09fe
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexParameterWithSubQuery.result
@@ -0,0 +1,3 @@
+total
+-------------------------------
+10
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexTargetWithPythonUdaf.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexTargetWithPythonUdaf.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexTargetWithPythonUdaf.result
new file mode 100644
index 0000000..6ee9cb5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testComplexTargetWithPythonUdaf.result
@@ -0,0 +1,3 @@
+merged
+-------------------------------
+8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation1.result
new file mode 100644
index 0000000..f2ad32a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation1.result
@@ -0,0 +1,5 @@
+l_orderkey,maximum,unique_key
+-------------------------------
+1,1,2
+2,2,1
+3,3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation2.result
new file mode 100644
index 0000000..9164120
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation2.result
@@ -0,0 +1,5 @@
+l_orderkey,cnt,unique_key
+-------------------------------
+1,2,2
+2,1,1
+3,2,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation3.result
new file mode 100644
index 0000000..5600470
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation3.result
@@ -0,0 +1,3 @@
+?count,?count_1,?sum_2
+-------------------------------
+5,3,6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation4.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation4.result
new file mode 100644
index 0000000..72b4e8e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation4.result
@@ -0,0 +1,4 @@
+l_linenumber,?count,?count_1,?sum_2
+-------------------------------
+1,3,3,6
+2,2,2,4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation5.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation5.result
new file mode 100644
index 0000000..229a279
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation5.result
@@ -0,0 +1,4 @@
+?sum,l_linenumber,?count_1,?count_2
+-------------------------------
+6,1,3,3
+4,2,2,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation6.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation6.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation6.result
new file mode 100644
index 0000000..cd59b8f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation6.result
@@ -0,0 +1,5 @@
+v0,v1,v2,v4
+-------------------------------
+1,2,3,2
+1,2,1,1
+1,6,3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation7.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation7.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation7.result
new file mode 100644
index 0000000..4173b04
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation7.result
@@ -0,0 +1,3 @@
+?count,?count_1,?count_2
+-------------------------------
+5,5,4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation8.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation8.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation8.result
new file mode 100644
index 0000000..519390d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation8.result
@@ -0,0 +1,7 @@
+?sum,l_linenumber,l_returnflag,l_linestatus,l_shipdate,?count_1,?sum_2
+-------------------------------
+1,1,N,O,1996-03-13,1,1
+2,1,N,O,1997-01-28,1,2
+3,1,R,F,1994-02-02,1,3
+1,2,N,O,1996-04-12,1,1
+3,2,R,F,1993-11-09,1,3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase3.result
new file mode 100644
index 0000000..320ab29
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase3.result
@@ -0,0 +1,3 @@
+col1,cnt1,cnt2
+-------------------------------
+a,3,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase4.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase4.result
new file mode 100644
index 0000000..a65e71f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationCaseByCase4.result
@@ -0,0 +1,3 @@
+col1,cnt
+-------------------------------
+a,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithHaving1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithHaving1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithHaving1.result
new file mode 100644
index 0000000..5560a23
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithHaving1.result
@@ -0,0 +1,3 @@
+l_linenumber,?count,?count_1,?sum_2
+-------------------------------
+1,3,3,6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithUnion1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithUnion1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithUnion1.result
new file mode 100644
index 0000000..16c5524
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregationWithUnion1.result
@@ -0,0 +1,4 @@
+?sum,l_linenumber,?count_1,total
+-------------------------------
+6,1,3,6
+4,2,2,4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case1.result
new file mode 100644
index 0000000..9296346
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case1.result
@@ -0,0 +1,4 @@
+quantity,suppkey,l_returnflag
+-------------------------------
+91.0,3,N
+94.0,2,R
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case10.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case10.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case10.result
new file mode 100644
index 0000000..2035d9f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case10.result
@@ -0,0 +1,3 @@
+?sum,?sum_1
+-------------------------------
+3,414440.9
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case2.result
new file mode 100644
index 0000000..7af127f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case2.result
@@ -0,0 +1,4 @@
+quantity,partkey,suppkey,l_returnflag
+-------------------------------
+91.0,2,3,N
+94.0,2,2,R
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case3.result
new file mode 100644
index 0000000..31905fa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case3.result
@@ -0,0 +1,4 @@
+quantity,partkey,?count,?max_1,l_returnflag
+-------------------------------
+91.0,2,3,38.0,N
+94.0,2,2,49.0,R
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case4.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case4.result
new file mode 100644
index 0000000..8afda65
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case4.result
@@ -0,0 +1,5 @@
+l_orderkey,quantity,partkey,?count,?max_1,l_returnflag
+-------------------------------
+1,53.0,1,2,36.0,N
+2,38.0,1,1,38.0,N
+3,94.0,2,2,49.0,R
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case5.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case5.result
new file mode 100644
index 0000000..8afda65
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case5.result
@@ -0,0 +1,5 @@
+l_orderkey,quantity,partkey,?count,?max_1,l_returnflag
+-------------------------------
+1,53.0,1,2,36.0,N
+2,38.0,1,1,38.0,N
+3,94.0,2,2,49.0,R
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case6.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case6.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case6.result
new file mode 100644
index 0000000..8afda65
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case6.result
@@ -0,0 +1,5 @@
+l_orderkey,quantity,partkey,?count,?max_1,l_returnflag
+-------------------------------
+1,53.0,1,2,36.0,N
+2,38.0,1,1,38.0,N
+3,94.0,2,2,49.0,R
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case7.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case7.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case7.result
new file mode 100644
index 0000000..03cdf1e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case7.result
@@ -0,0 +1,5 @@
+?count,quantity,partkey,?count_1,?max_2
+-------------------------------
+1,53.0,1,2,36.0
+1,38.0,1,1,38.0
+1,94.0,2,2,49.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case8.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case8.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case8.result
new file mode 100644
index 0000000..e234896
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case8.result
@@ -0,0 +1,6 @@
+l_orderkey,l_partkey,cnt1,cnt2,sum1
+-------------------------------
+1,1,1,2,53.0
+2,2,1,1,38.0
+3,2,1,1,45.0
+3,3,1,1,49.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case9.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case9.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case9.result
new file mode 100644
index 0000000..506eea0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctAggregation_case9.result
@@ -0,0 +1,6 @@
+l_orderkey,cnt1,value2,l_partkey,avg1,cnt2
+-------------------------------
+1,1,28.0,1,26.5,2
+2,1,39.0,2,38.0,1
+3,1,46.0,2,45.0,1
+3,1,51.0,3,49.0,1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctPythonUdafWithUnion1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctPythonUdafWithUnion1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctPythonUdafWithUnion1.result
new file mode 100644
index 0000000..16c5524
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testDistinctPythonUdafWithUnion1.result
@@ -0,0 +1,4 @@
+?sum,l_linenumber,?count_1,total
+-------------------------------
+6,1,3,6
+4,2,2,4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy.result
new file mode 100644
index 0000000..385d0de
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy.result
@@ -0,0 +1,3 @@
+unique_key
+-------------------------------
+5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy2.result
new file mode 100644
index 0000000..6afdd23
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy2.result
@@ -0,0 +1,4 @@
+unique_key
+-------------------------------
+2
+3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy3.result
new file mode 100644
index 0000000..c956d65
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy3.result
@@ -0,0 +1,5 @@
+gkey
+-------------------------------
+1
+2
+3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy4.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy4.result
new file mode 100644
index 0000000..22c6664
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy4.result
@@ -0,0 +1,5 @@
+gkey,unique_key
+-------------------------------
+1,2
+2,1
+3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy5.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy5.result
new file mode 100644
index 0000000..abf0e45
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupBy5.result
@@ -0,0 +1,5 @@
+gkey,const_val
+-------------------------------
+1,00
+2,00
+3,00
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested1.result
new file mode 100644
index 0000000..788a084
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested1.result
@@ -0,0 +1,6 @@
+unique_key
+-------------------------------
+2
+4
+5
+6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested2.result
new file mode 100644
index 0000000..8656add
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByNested2.result
@@ -0,0 +1,6 @@
+total
+-------------------------------
+4
+4
+5
+6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys1.result
new file mode 100644
index 0000000..2c04315
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys1.result
@@ -0,0 +1,3 @@
+key,total
+-------------------------------
+123,5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys2.result
new file mode 100644
index 0000000..776db3c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys2.result
@@ -0,0 +1,5 @@
+a,b,c,d
+-------------------------------
+1,2014-07-07 04:28:31.561,##,2
+2,2014-07-07 04:28:31.561,##,2
+3,2014-07-07 04:28:31.561,##,1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys3.result
new file mode 100644
index 0000000..3285621
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys3.result
@@ -0,0 +1,3 @@
+b,c,d
+-------------------------------
+2014-07-07 04:28:31.561,##,5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys4.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys4.result
new file mode 100644
index 0000000..69560d5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys4.result
@@ -0,0 +1,5 @@
+?text,l_orderkey,sum
+-------------------------------
+day,1,2
+day,2,1
+day,3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys5.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys5.result
new file mode 100644
index 0000000..30ba1de
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithConstantKeys5.result
@@ -0,0 +1,5 @@
+?text,key,l_orderkey,sum
+-------------------------------
+day,day,1,2
+day,day,2,1
+day,day,3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys1.result
new file mode 100644
index 0000000..d1f1282
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys1.result
@@ -0,0 +1,5 @@
+key,total
+-------------------------------
+1,2
+2,1
+3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys2.result
new file mode 100644
index 0000000..d1f1282
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithExpressionKeys2.result
@@ -0,0 +1,5 @@
+key,total
+-------------------------------
+1,2
+2,1
+3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData1.result
new file mode 100644
index 0000000..13335cb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData1.result
@@ -0,0 +1,3 @@
+unique_key
+-------------------------------
+0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData10.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData10.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData10.result
new file mode 100644
index 0000000..c865378
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData10.result
@@ -0,0 +1,3 @@
+unique_key,flag
+-------------------------------
+0,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData11.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData11.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData11.result
new file mode 100644
index 0000000..bd69ff2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData11.result
@@ -0,0 +1,2 @@
+l_orderkey,unique_key,flag
+-------------------------------
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData12.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData12.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData12.result
new file mode 100644
index 0000000..2b8b687
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData12.result
@@ -0,0 +1,2 @@
+s_acctbal,s_name,t_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData2.result
new file mode 100644
index 0000000..8746e36
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData2.result
@@ -0,0 +1,3 @@
+unique_key,max_key
+-------------------------------
+0,null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData3.result
new file mode 100644
index 0000000..c2cc22e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData3.result
@@ -0,0 +1,3 @@
+maximum,unique_key
+-------------------------------
+null,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData4.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData4.result
new file mode 100644
index 0000000..c2cc22e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData4.result
@@ -0,0 +1,3 @@
+maximum,unique_key
+-------------------------------
+null,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData5.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData5.result
new file mode 100644
index 0000000..13335cb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData5.result
@@ -0,0 +1,3 @@
+unique_key
+-------------------------------
+0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData6.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData6.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData6.result
new file mode 100644
index 0000000..4014f6d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData6.result
@@ -0,0 +1,3 @@
+unique_key,maximum
+-------------------------------
+0,null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData7.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData7.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData7.result
new file mode 100644
index 0000000..c2cc22e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData7.result
@@ -0,0 +1,3 @@
+maximum,unique_key
+-------------------------------
+null,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData8.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData8.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData8.result
new file mode 100644
index 0000000..c2cc22e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData8.result
@@ -0,0 +1,3 @@
+maximum,unique_key
+-------------------------------
+null,0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData9.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData9.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData9.result
new file mode 100644
index 0000000..1f6d988
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithNullData9.result
@@ -0,0 +1,2 @@
+l_orderkey,unique_key
+-------------------------------
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameConstantKeys1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameConstantKeys1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameConstantKeys1.result
new file mode 100644
index 0000000..a8fbe00
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameConstantKeys1.result
@@ -0,0 +1,5 @@
+a,b,c,d
+-------------------------------
+1,##,##,2
+2,##,##,2
+3,##,##,1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs1.result
new file mode 100644
index 0000000..c7db60e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs1.result
@@ -0,0 +1,6 @@
+total
+-------------------------------
+4
+4
+6
+6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs2.result
new file mode 100644
index 0000000..c2b2851
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupByWithSameExprs2.result
@@ -0,0 +1,6 @@
+total1,total2
+-------------------------------
+2,2
+2,2
+3,3
+3,3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithJson.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithJson.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithJson.result
new file mode 100644
index 0000000..81f1bfd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithJson.result
@@ -0,0 +1,5 @@
+l_orderkey,total,num
+-------------------------------
+1,1.0,3
+2,2.0,1
+3,2.5,3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit1.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit1.result
new file mode 100644
index 0000000..23bbaea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit1.result
@@ -0,0 +1,3 @@
+?sum
+-------------------------------
+7
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit2.result
new file mode 100644
index 0000000..23bbaea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit2.result
@@ -0,0 +1,3 @@
+?sum
+-------------------------------
+7
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit3.result
new file mode 100644
index 0000000..e882158
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithLimit3.result
@@ -0,0 +1,3 @@
+l_orderkey,?sum
+-------------------------------
+1,3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc.result
new file mode 100644
index 0000000..1e8821c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc.result
@@ -0,0 +1,7 @@
+?count
+-------------------------------
+4
+4
+5
+5
+5

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc2.result
new file mode 100644
index 0000000..1413e41
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testGroupbyWithPythonFunc2.result
@@ -0,0 +1,7 @@
+n_regionkey,cnt
+-------------------------------
+0,5
+1,5
+2,5
+3,5
+4,5

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithAggFunction.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithAggFunction.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithAggFunction.result
new file mode 100644
index 0000000..fcd604e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithAggFunction.result
@@ -0,0 +1,4 @@
+l_orderkey,total,num
+-------------------------------
+2,2.0,1
+3,2.5,3

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithNamedTarget.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithNamedTarget.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithNamedTarget.result
new file mode 100644
index 0000000..81f1bfd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testHavingWithNamedTarget.result
@@ -0,0 +1,5 @@
+l_orderkey,total,num
+-------------------------------
+1,1.0,3
+2,2.0,1
+3,2.5,3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf.result
new file mode 100644
index 0000000..e1ba22d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf.result
@@ -0,0 +1,3 @@
+?avgpy,?avg_1,?countpy_2
+-------------------------------
+12.0,12.0,25
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf2.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf2.result
new file mode 100644
index 0000000..2852167
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf2.result
@@ -0,0 +1,4 @@
+?countpy,?count_1
+-------------------------------
+2,2
+3,3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf3.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf3.result
new file mode 100644
index 0000000..7338988
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdaf3.result
@@ -0,0 +1,5 @@
+?avgpy,?countpy_1,?avg_2,?count_3
+-------------------------------
+173665.47,1,173665.47,1
+193846.25,1,193846.25,1
+46929.18,1,46929.18,1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithHaving.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithHaving.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithHaving.result
new file mode 100644
index 0000000..b8369d2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithHaving.result
@@ -0,0 +1,4 @@
+l_orderkey,total,num
+-------------------------------
+3,2.5,3
+2,2.0,1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithNullData.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithNullData.result b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithNullData.result
new file mode 100644
index 0000000..1f6d988
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestGroupByQuery/testPythonUdafWithNullData.result
@@ -0,0 +1,2 @@
+l_orderkey,unique_key
+-------------------------------
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testBinaryMappedQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testBinaryMappedQuery.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testBinaryMappedQuery.result
new file mode 100644
index 0000000..8d50bf1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testBinaryMappedQuery.result
@@ -0,0 +1,81 @@
+rk,col1,col2,col3
+-------------------------------
+21,a-21,{"k1":"k1-21", "k2":"k2-21"},21
+22,a-22,{"k1":"k1-22", "k2":"k2-22"},22
+23,a-23,{"k1":"k1-23", "k2":"k2-23"},23
+24,a-24,{"k1":"k1-24", "k2":"k2-24"},24
+25,a-25,{"k1":"k1-25", "k2":"k2-25"},25
+26,a-26,{"k1":"k1-26", "k2":"k2-26"},26
+27,a-27,{"k1":"k1-27", "k2":"k2-27"},27
+28,a-28,{"k1":"k1-28", "k2":"k2-28"},28
+29,a-29,{"k1":"k1-29", "k2":"k2-29"},29
+30,a-30,{"k1":"k1-30", "k2":"k2-30"},30
+31,a-31,{"k1":"k1-31", "k2":"k2-31"},31
+32,a-32,{"k1":"k1-32", "k2":"k2-32"},32
+33,a-33,{"k1":"k1-33", "k2":"k2-33"},33
+34,a-34,{"k1":"k1-34", "k2":"k2-34"},34
+35,a-35,{"k1":"k1-35", "k2":"k2-35"},35
+36,a-36,{"k1":"k1-36", "k2":"k2-36"},36
+37,a-37,{"k1":"k1-37", "k2":"k2-37"},37
+38,a-38,{"k1":"k1-38", "k2":"k2-38"},38
+39,a-39,{"k1":"k1-39", "k2":"k2-39"},39
+40,a-40,{"k1":"k1-40", "k2":"k2-40"},40
+41,a-41,{"k1":"k1-41", "k2":"k2-41"},41
+42,a-42,{"k1":"k1-42", "k2":"k2-42"},42
+43,a-43,{"k1":"k1-43", "k2":"k2-43"},43
+44,a-44,{"k1":"k1-44", "k2":"k2-44"},44
+45,a-45,{"k1":"k1-45", "k2":"k2-45"},45
+46,a-46,{"k1":"k1-46", "k2":"k2-46"},46
+47,a-47,{"k1":"k1-47", "k2":"k2-47"},47
+48,a-48,{"k1":"k1-48", "k2":"k2-48"},48
+49,a-49,{"k1":"k1-49", "k2":"k2-49"},49
+50,a-50,{"k1":"k1-50", "k2":"k2-50"},50
+51,a-51,{"k1":"k1-51", "k2":"k2-51"},51
+52,a-52,{"k1":"k1-52", "k2":"k2-52"},52
+53,a-53,{"k1":"k1-53", "k2":"k2-53"},53
+54,a-54,{"k1":"k1-54", "k2":"k2-54"},54
+55,a-55,{"k1":"k1-55", "k2":"k2-55"},55
+56,a-56,{"k1":"k1-56", "k2":"k2-56"},56
+57,a-57,{"k1":"k1-57", "k2":"k2-57"},57
+58,a-58,{"k1":"k1-58", "k2":"k2-58"},58
+59,a-59,{"k1":"k1-59", "k2":"k2-59"},59
+60,a-60,{"k1":"k1-60", "k2":"k2-60"},60
+61,a-61,{"k1":"k1-61", "k2":"k2-61"},61
+62,a-62,{"k1":"k1-62", "k2":"k2-62"},62
+63,a-63,{"k1":"k1-63", "k2":"k2-63"},63
+64,a-64,{"k1":"k1-64", "k2":"k2-64"},64
+65,a-65,{"k1":"k1-65", "k2":"k2-65"},65
+66,a-66,{"k1":"k1-66", "k2":"k2-66"},66
+67,a-67,{"k1":"k1-67", "k2":"k2-67"},67
+68,a-68,{"k1":"k1-68", "k2":"k2-68"},68
+69,a-69,{"k1":"k1-69", "k2":"k2-69"},69
+70,a-70,{"k1":"k1-70", "k2":"k2-70"},70
+71,a-71,{"k1":"k1-71", "k2":"k2-71"},71
+72,a-72,{"k1":"k1-72", "k2":"k2-72"},72
+73,a-73,{"k1":"k1-73", "k2":"k2-73"},73
+74,a-74,{"k1":"k1-74", "k2":"k2-74"},74
+75,a-75,{"k1":"k1-75", "k2":"k2-75"},75
+76,a-76,{"k1":"k1-76", "k2":"k2-76"},76
+77,a-77,{"k1":"k1-77", "k2":"k2-77"},77
+78,a-78,{"k1":"k1-78", "k2":"k2-78"},78
+79,a-79,{"k1":"k1-79", "k2":"k2-79"},79
+80,a-80,{"k1":"k1-80", "k2":"k2-80"},80
+81,a-81,{"k1":"k1-81", "k2":"k2-81"},81
+82,a-82,{"k1":"k1-82", "k2":"k2-82"},82
+83,a-83,{"k1":"k1-83", "k2":"k2-83"},83
+84,a-84,{"k1":"k1-84", "k2":"k2-84"},84
+85,a-85,{"k1":"k1-85", "k2":"k2-85"},85
+86,a-86,{"k1":"k1-86", "k2":"k2-86"},86
+87,a-87,{"k1":"k1-87", "k2":"k2-87"},87
+88,a-88,{"k1":"k1-88", "k2":"k2-88"},88
+89,a-89,{"k1":"k1-89", "k2":"k2-89"},89
+90,a-90,{"k1":"k1-90", "k2":"k2-90"},90
+91,a-91,{"k1":"k1-91", "k2":"k2-91"},91
+92,a-92,{"k1":"k1-92", "k2":"k2-92"},92
+93,a-93,{"k1":"k1-93", "k2":"k2-93"},93
+94,a-94,{"k1":"k1-94", "k2":"k2-94"},94
+95,a-95,{"k1":"k1-95", "k2":"k2-95"},95
+96,a-96,{"k1":"k1-96", "k2":"k2-96"},96
+97,a-97,{"k1":"k1-97", "k2":"k2-97"},97
+98,a-98,{"k1":"k1-98", "k2":"k2-98"},98
+99,a-99,{"k1":"k1-99", "k2":"k2-99"},99
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testCTAS.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testCTAS.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testCTAS.result
new file mode 100644
index 0000000..72013f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testCTAS.result
@@ -0,0 +1,100 @@
+000, value0
+001, value1
+002, value2
+003, value3
+004, value4
+005, value5
+006, value6
+007, value7
+008, value8
+009, value9
+010, value10
+011, value11
+012, value12
+013, value13
+014, value14
+015, value15
+016, value16
+017, value17
+018, value18
+019, value19
+020, value20
+021, value21
+022, value22
+023, value23
+024, value24
+025, value25
+026, value26
+027, value27
+028, value28
+029, value29
+030, value30
+031, value31
+032, value32
+033, value33
+034, value34
+035, value35
+036, value36
+037, value37
+038, value38
+039, value39
+040, value40
+041, value41
+042, value42
+043, value43
+044, value44
+045, value45
+046, value46
+047, value47
+048, value48
+049, value49
+050, value50
+051, value51
+052, value52
+053, value53
+054, value54
+055, value55
+056, value56
+057, value57
+058, value58
+059, value59
+060, value60
+061, value61
+062, value62
+063, value63
+064, value64
+065, value65
+066, value66
+067, value67
+068, value68
+069, value69
+070, value70
+071, value71
+072, value72
+073, value73
+074, value74
+075, value75
+076, value76
+077, value77
+078, value78
+079, value79
+080, value80
+081, value81
+082, value82
+083, value83
+084, value84
+085, value85
+086, value86
+087, value87
+088, value88
+089, value89
+090, value90
+091, value91
+092, value92
+093, value93
+094, value94
+095, value95
+096, value96
+097, value97
+098, value98
+099, value99

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testColumnKeyValueSelectQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testColumnKeyValueSelectQuery.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testColumnKeyValueSelectQuery.result
new file mode 100644
index 0000000..82d4fd2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testColumnKeyValueSelectQuery.result
@@ -0,0 +1,12 @@
+rk1,col2_key,col2_value,col3
+-------------------------------
+rk-0,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-0
+rk-1,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-1
+rk-2,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-2
+rk-3,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-3
+rk-4,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-4
+rk-5,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-5
+rk-6,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-6
+rk-7,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-7
+rk-8,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-8
+rk-9,["key-0", "key-1", "key-2", "key-3", "key-4"],["value-0", "value-1", "value-2", "value-3", "value-4"],col3-value-9
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testIndexPredication.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testIndexPredication.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testIndexPredication.result
new file mode 100644
index 0000000..f38d238
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testIndexPredication.result
@@ -0,0 +1,38 @@
+rk,col1,col2,col3
+-------------------------------
+020,a-20,{"k1":"k1-20", "k2":"k2-20"},b-20
+021,a-21,{"k1":"k1-21", "k2":"k2-21"},b-21
+022,a-22,{"k1":"k1-22", "k2":"k2-22"},b-22
+023,a-23,{"k1":"k1-23", "k2":"k2-23"},b-23
+024,a-24,{"k1":"k1-24", "k2":"k2-24"},b-24
+025,a-25,{"k1":"k1-25", "k2":"k2-25"},b-25
+026,a-26,{"k1":"k1-26", "k2":"k2-26"},b-26
+027,a-27,{"k1":"k1-27", "k2":"k2-27"},b-27
+028,a-28,{"k1":"k1-28", "k2":"k2-28"},b-28
+029,a-29,{"k1":"k1-29", "k2":"k2-29"},b-29
+030,a-30,{"k1":"k1-30", "k2":"k2-30"},b-30
+031,a-31,{"k1":"k1-31", "k2":"k2-31"},b-31
+032,a-32,{"k1":"k1-32", "k2":"k2-32"},b-32
+033,a-33,{"k1":"k1-33", "k2":"k2-33"},b-33
+034,a-34,{"k1":"k1-34", "k2":"k2-34"},b-34
+035,a-35,{"k1":"k1-35", "k2":"k2-35"},b-35
+036,a-36,{"k1":"k1-36", "k2":"k2-36"},b-36
+037,a-37,{"k1":"k1-37", "k2":"k2-37"},b-37
+038,a-38,{"k1":"k1-38", "k2":"k2-38"},b-38
+039,a-39,{"k1":"k1-39", "k2":"k2-39"},b-39
+040,a-40,{"k1":"k1-40", "k2":"k2-40"},b-40
+041,a-41,{"k1":"k1-41", "k2":"k2-41"},b-41
+042,a-42,{"k1":"k1-42", "k2":"k2-42"},b-42
+043,a-43,{"k1":"k1-43", "k2":"k2-43"},b-43
+044,a-44,{"k1":"k1-44", "k2":"k2-44"},b-44
+045,a-45,{"k1":"k1-45", "k2":"k2-45"},b-45
+046,a-46,{"k1":"k1-46", "k2":"k2-46"},b-46
+047,a-47,{"k1":"k1-47", "k2":"k2-47"},b-47
+048,a-48,{"k1":"k1-48", "k2":"k2-48"},b-48
+049,a-49,{"k1":"k1-49", "k2":"k2-49"},b-49
+050,a-50,{"k1":"k1-50", "k2":"k2-50"},b-50
+051,a-51,{"k1":"k1-51", "k2":"k2-51"},b-51
+052,a-52,{"k1":"k1-52", "k2":"k2-52"},b-52
+053,a-53,{"k1":"k1-53", "k2":"k2-53"},b-53
+054,a-54,{"k1":"k1-54", "k2":"k2-54"},b-54
+055,a-55,{"k1":"k1-55", "k2":"k2-55"},b-55
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertInto.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertInto.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertInto.result
new file mode 100644
index 0000000..e0c97ef
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertInto.result
@@ -0,0 +1,3 @@
+1, 1996-03-13, {"": "N"}, 7706
+2, 1997-01-28, {"": "N"}, 1191
+3, 1994-02-02, {"": "R"}, 1798


[43/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
new file mode 100644
index 0000000..4b0303f
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
@@ -0,0 +1,470 @@
+/**
+ * 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.function;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
+
+public class TestMathFunctions extends ExprTestBase {
+  @Test
+  public void testRound() throws TajoException {
+    testSimpleEval("select round(5.1) as col1 ", new String[]{"5"});
+    testSimpleEval("select round(5.5) as col1 ", new String[]{"6"});
+    testSimpleEval("select round(5.6) as col1 ", new String[]{"6"});
+
+    testSimpleEval("select round(-5.1) as col1 ", new String[]{"-5"});
+    testSimpleEval("select round(-5.5) as col1 ", new String[]{"-6"});
+    testSimpleEval("select round(-5.6) as col1 ", new String[]{"-6"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.4", "select round(col1 + col2 + col3) from table1",
+        new String[]{"2"});
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", INT4);
+    schema2.addColumn("col2", INT8);
+    schema2.addColumn("col3", FLOAT4);
+    schema2.addColumn("col4", FLOAT8);
+
+    testEval(schema2, "table1", "9,9,9.5,9.5",
+        "select round(col1), round (col2), round(col3), round(col4) from table1",
+        new String [] {"9", "9", "10", "10"});
+  }
+
+  @Test
+  public void testFloor() throws TajoException {
+    testSimpleEval("select floor(5.1) as col1 ", new String[]{"5"});
+    testSimpleEval("select floor(5.5) as col1 ", new String[]{"5"});
+    testSimpleEval("select floor(5.6) as col1 ", new String[]{"5"});
+
+    testSimpleEval("select floor(-5.1) as col1 ", new String[]{"-6"});
+    testSimpleEval("select floor(-5.6) as col1 ", new String[]{"-6"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.4", "select floor(col1 + col2 + col3) from table1",
+        new String[]{"1"});
+  }
+
+  @Test
+  public void testCeil() throws TajoException {
+    testSimpleEval("select ceil(5.0) as col1 ", new String[]{"5"});
+    testSimpleEval("select ceil(5.1) as col1 ", new String[]{"6"});
+    testSimpleEval("select ceil(5.5) as col1 ", new String[]{"6"});
+    testSimpleEval("select ceil(5.6) as col1 ", new String[]{"6"});
+
+    testSimpleEval("select ceil(-5.1) as col1 ", new String[]{"-5"});
+    testSimpleEval("select ceil(-5.6) as col1 ", new String[]{"-5"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select ceil(col1 + col2 + col3) from table1",
+        new String[]{"2"});
+  }
+
+  @Test
+  public void testCeiling() throws TajoException {
+    testSimpleEval("select ceiling(5.0) as col1 ", new String[]{"5"});
+    testSimpleEval("select ceiling(5.1) as col1 ", new String[]{"6"});
+    testSimpleEval("select ceiling(5.5) as col1 ", new String[]{"6"});
+    testSimpleEval("select ceiling(5.6) as col1 ", new String[]{"6"});
+
+    testSimpleEval("select ceiling(-5.1) as col1 ", new String[]{"-5"});
+    testSimpleEval("select ceiling(-5.6) as col1 ", new String[]{"-5"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select ceiling(col1 + col2 + col3) from table1",
+        new String[]{"2"});
+  }
+
+  @Test
+  public void testSin() throws TajoException {
+    testSimpleEval("select sin(0.0) as col1 ", new String[]{"0.0"});
+    testSimpleEval("select sin(0.7) as col1 ", new String[]{"0.644217687237691"});
+    testSimpleEval("select sin(1.2) as col1 ", new String[]{"0.9320390859672263"});
+    testSimpleEval("select sin(-0.5) as col1 ", new String[]{"-0.479425538604203"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select sin(col1 + col2 + col3) from table1",
+        new String[]{"0.963558185417193"});
+  }
+
+
+  @Test
+  public void testCos() throws TajoException {
+    testSimpleEval("select cos(0.0) as col1 ", new String[]{"1.0"});
+    testSimpleEval("select cos(0.7) as col1 ", new String[]{"0.7648421872844885"});
+    testSimpleEval("select cos(1.2) as col1 ", new String[]{"0.3623577544766736"});
+    testSimpleEval("select cos(-0.5) as col1 ", new String[]{"0.8775825618903728"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select cos(col1 + col2 + col3) from table1",
+        new String[]{"0.26749882862458735"});
+  }
+
+  @Test
+  public void testTan() throws TajoException {
+    testSimpleEval("select tan(0.0) as col1 ", new String[]{"0.0"});
+    testSimpleEval("select tan(0.3) as col1 ", new String[]{"0.30933624960962325"});
+    testSimpleEval("select tan(0.8) as col1 ", new String[]{"1.0296385570503641"});
+    testSimpleEval("select tan(-0.5) as col1 ", new String[]{"-0.5463024898437905"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select tan(col1 - col2 - col3) from table1",
+        new String[]{"0.8422883804630795"});
+  }
+
+  @Test
+  public void testAsin() throws TajoException {
+    testSimpleEval("select asin(0.0) as col1 ", new String[]{"0.0"});
+    testSimpleEval("select asin(0.3) as col1 ", new String[]{"0.3046926540153975"});
+    testSimpleEval("select asin(0.8) as col1 ", new String[]{"0.9272952180016123"});
+    testSimpleEval("select asin(-0.5) as col1 ", new String[]{"-0.5235987755982989"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select asin(col1 - col2 - col3) from table1",
+        new String[]{"0.7753974966107532"});
+  }
+
+  @Test
+  public void testAcos() throws TajoException {
+    testSimpleEval("select acos(0.0) as col1 ", new String[]{"1.5707963267948966"});
+    testSimpleEval("select acos(0.3) as col1 ", new String[]{"1.2661036727794992"});
+    testSimpleEval("select acos(0.8) as col1 ", new String[]{"0.6435011087932843"});
+    testSimpleEval("select acos(-0.5) as col1 ", new String[]{"2.0943951023931957"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select acos(col1 - col2 - col3) from table1",
+        new String[]{"0.7953988301841435"});
+  }
+
+  @Test
+  public void testAtan() throws TajoException {
+    testSimpleEval("select atan(0.0) as col1 ", new String[]{"0.0"});
+    testSimpleEval("select atan(0.8) as col1 ", new String[]{"0.6747409422235527"});
+    testSimpleEval("select atan(1.2) as col1 ", new String[]{"0.8760580505981934"});
+    testSimpleEval("select atan(-0.5) as col1 ", new String[]{"-0.4636476090008061"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select atan(col1 + col2 + col3) from table1",
+        new String[]{"0.9151007005533605"});
+  }
+
+  @Test
+  public void testAtan2() throws TajoException {
+    testSimpleEval("select atan2(0.8, 0.0) as col1 ", new String[]{"1.5707963267948966"});
+    testSimpleEval("select atan2(0.8, 1.1) as col1 ", new String[]{"0.628796286415433"});
+    testSimpleEval("select atan2(2.7, 0.3) as col1 ", new String[]{"1.460139105621001"});
+    testSimpleEval("select atan2(-0.5, 0.3) as col1 ", new String[]{"-1.0303768265243125"});
+    testSimpleEval("select atan2(-0.2, -1.3) as col1 ", new String[]{"-2.988943325194528"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select atan2(col1 + col2, col3) from table1",
+        new String[]{"1.4876550949064553"});
+  }
+
+  @Test
+  public void testMod() throws TajoException {
+    testSimpleEval("select mod(9,4) as col1 ", new String[]{"1"});
+    testSimpleEval("select mod(200000000001,200000000000) as col1 ", new String[]{"1"});
+    testSimpleEval("select mod(200000000000,2) as col1 ", new String[]{"0"});
+    testSimpleEval("select mod(2,200000000000) as col1 ", new String[]{"2"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", INT8);
+    schema.addColumn("col2", INT8);
+    schema.addColumn("col3", INT8);
+
+    testEval(schema, "table1", "9,2,3", "select mod(col1 + col2, col3) from table1", 
+        new String[]{"2"});
+  }
+
+  @Test
+  public void testDiv() throws TajoException {
+    testSimpleEval("select div(9,4) as col1 ", new String[]{"2"});
+    testSimpleEval("select div(200000000001,200000000000) as col1 ", new String[]{"1"});
+    testSimpleEval("select div(200000000000,2) as col1 ", new String[]{"100000000000"});
+    testSimpleEval("select div(2,200000000000) as col1 ", new String[]{"0"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", INT8);
+    schema.addColumn("col2", INT8);
+    schema.addColumn("col3", INT8);
+
+    testEval(schema, "table1", "9,2,3", "select div(col1 + col2, col3) from table1", 
+        new String[]{"3"});
+  }
+
+  @Test
+  public void testSign() throws TajoException {
+    testSimpleEval("select sign(2) as col1 ", new String[]{"1.0"});
+    testSimpleEval("select sign(2.345) as col1 ", new String[]{"1.0"});
+    testSimpleEval("select sign(0.3) as col1 ", new String[]{"1.0"});
+
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT4);
+    schema.addColumn("col3", FLOAT4);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select sign(col1 + col2 + col3) from table1",
+        new String[]{"1.0"});
+
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", FLOAT8);
+    schema2.addColumn("col2", FLOAT8);
+    schema2.addColumn("col3", FLOAT8);
+
+    testEval(schema2, "table1", "1.0, 0.2, 0.1", "select sign(col1 + col2 + col3) from table1",
+        new String[]{"1.0"});
+  }
+
+  @Test
+  public void testSqrt() throws TajoException {
+    testSimpleEval("select sqrt(27.0) as col1 ", new String[]{"5.196152422706632"});
+    testSimpleEval("select sqrt(64.0) as col1 ", new String[]{"8.0"});
+    testSimpleEval("select sqrt(8.0) as col1 ", new String[]{"2.8284271247461903"});
+
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT4);
+    schema.addColumn("col3", FLOAT4);
+
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select sqrt(col1 + col2 + col3) from table1",
+        new String[]{"1.1401754564651765"});
+
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", FLOAT8);
+    schema2.addColumn("col2", FLOAT8);
+    schema2.addColumn("col3", FLOAT8);
+
+    testEval(schema2, "table1", "1.0, 0.2, 0.1", "select sqrt(col1 + col2 + col3) from table1",
+        new String[]{"1.140175425099138"});
+  }
+
+  @Test
+  public void testExp() throws TajoException {
+    testSimpleEval("select exp(1.0) as col1 ", new String[]{String.valueOf(Math.exp(1.0d))});
+    testSimpleEval("select exp(1.1) as col1 ", new String[]{String.valueOf(Math.exp(1.1d))});
+    testSimpleEval("select exp(1.2) as col1 ", new String[]{String.valueOf(Math.exp(1.2d))});
+
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+
+    testEval(schema, "table1", "1.123", "select exp(col1) from table1",
+        new String[]{String.valueOf(Math.exp(1.123f))});
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", FLOAT8);
+
+    testEval(schema2, "table1", "1.123", "select exp(col1) from table1",
+        new String[]{String.valueOf(Math.exp(1.123d))});
+  }
+
+
+  @Test
+  public void testAbs() throws TajoException {
+    testSimpleEval("select abs(9) as col1 ", new String[]{"9"});
+    testSimpleEval("select abs(-9) as col1 ", new String[]{"9"});
+    testSimpleEval("select abs(200000000000) as col1 ", new String[]{"200000000000"});
+    testSimpleEval("select abs(-200000000000) as col1 ", new String[]{"200000000000"});
+    testSimpleEval("select abs(2.0) as col1 ", new String[]{"2.0"});
+    testSimpleEval("select abs(-2.0) as col1 ", new String[]{"2.0"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT4);
+    testEval(schema, "table1", "0.39,-0.39", "select abs(col1), abs(col2) from table1", new String[]{"0.39", "0.39"});
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", FLOAT8);
+    schema2.addColumn("col2", FLOAT8);
+    testEval(schema2, "table1", "0.033312347,-0.033312347", "select abs(col1), abs(col2) from table1",
+        new String[]{"0.033312347", "0.033312347"});
+  }
+
+  @Test
+  public void testCbrt() throws TajoException {
+    testSimpleEval("select cbrt(27.0) as col1 ", new String[]{"3.0"});
+    testSimpleEval("select cbrt(64.0) as col1 ", new String[]{"4.0"});
+    testSimpleEval("select cbrt(8.0) as col1 ", new String[]{"2.0"});
+
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT4);
+    schema.addColumn("col3", FLOAT4);
+    testEval(schema, "table1", "1.0, 0.2, 0.1", "select cbrt(col1 + col2 + col3) from table1",
+        new String[]{"1.0913929030771317"});
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", FLOAT8);
+    schema2.addColumn("col2", FLOAT8);
+    schema2.addColumn("col3", FLOAT8);
+    testEval(schema2, "table1", "1.0, 0.2, 0.1", "select cbrt(col1 + col2 + col3) from table1",
+        new String[]{"1.091392883061106"});
+  }
+
+  @Test
+  public void testDegrees() throws TajoException {
+    testSimpleEval("select degrees(0.0) as col1 ", new String[]{String.valueOf(Math.toDegrees(0.0))});
+    testSimpleEval("select degrees(0.8) as col1 ", new String[]{String.valueOf(Math.toDegrees(0.8))});
+    testSimpleEval("select degrees(2.7) as col1 ", new String[]{String.valueOf(Math.toDegrees(2.7))});
+    testSimpleEval("select degrees(-0.8) as col1 ", new String[]{String.valueOf(Math.toDegrees(-0.8))});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "0.8,2.7,-0.8", "select degrees(col1), degrees(col2), degrees(col3) from table1",
+        new String[]{
+            String.valueOf(Math.toDegrees((float)0.8)),
+            String.valueOf(Math.toDegrees(2.7)),
+            String.valueOf(Math.toDegrees(-0.8))
+        });
+  }
+
+  @Test
+  public void testPow() throws TajoException {
+    testSimpleEval("select pow(9,3) as col1 ", new String[]{String.valueOf(Math.pow(9, 3))});
+    testSimpleEval("select pow(1.0,3) as col1 ", new String[]{String.valueOf(Math.pow(1.0, 3))});
+    testSimpleEval("select pow(20.1,3.1) as col1 ", new String[]{String.valueOf(Math.pow(20.1, 3.1))});
+    testSimpleEval("select pow(null,3.1) as col1 ", new String[]{""});
+    testSimpleEval("select pow(20.1,null) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", INT4);
+    schema.addColumn("col4", INT8);
+
+    testEval(schema, "table1", "0.4,2.7,3,2", "select pow(col1, col2), pow(col3, col4) from table1",
+        new String[]{
+            String.valueOf(Math.pow((float) 0.4, 2.7)),
+            String.valueOf(Math.pow(3, 2))
+        });
+  }
+
+  @Test
+  public void testRadians() throws TajoException {
+    testSimpleEval("select radians(0.0) as col1 ", new String[]{String.valueOf(Math.toRadians(0.0))});
+    testSimpleEval("select radians(0.8) as col1 ", new String[]{String.valueOf(Math.toRadians(0.8))});
+    testSimpleEval("select radians(2.7) as col1 ", new String[]{String.valueOf(Math.toRadians(2.7))});
+    testSimpleEval("select radians(-0.8) as col1 ", new String[]{String.valueOf(Math.toRadians(-0.8))});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT4);
+    schema.addColumn("col2", FLOAT8);
+    schema.addColumn("col3", FLOAT8);
+
+    testEval(schema, "table1", "0.8,2.7,-0.8", "select radians(col1), radians(col2), radians(col3) from table1",
+        new String[]{
+            String.valueOf(Math.toRadians((float)0.8)),
+            String.valueOf(Math.toRadians(2.7)),
+            String.valueOf(Math.toRadians(-0.8))
+        });
+  }
+
+  @Test
+  public void testPi() throws TajoException {
+    testSimpleEval("select pi() as col1 ", new String[]{String.valueOf(Math.PI)});
+  }
+
+  @Test
+  public void testRoundWithSpecifiedPrecision() throws TajoException {
+    // TODO - in order to make this test possible, testSimpleEval should take session variables. Now, we disable it.
+    // divide zero
+//    try {
+//      testSimpleEval("select round(10.0/0.0,2) ", new String[]{""});
+//      fail("10.0/0 should throw InvalidOperationException");
+//    } catch (InvalidOperationException e) {
+//      //success
+//    }
+
+    testSimpleEval("select round(42.4382,2) ", new String[]{"42.44"});
+    testSimpleEval("select round(-42.4382,2) ", new String[]{"-42.44"});
+    testSimpleEval("select round(-425,2) ", new String[]{"-425.0"});
+    testSimpleEval("select round(425,2) ", new String[]{"425.0"});
+
+    testSimpleEval("select round(1234567890,0) ", new String[]{"1.23456789E9"});
+    testSimpleEval("select round(1234567890,1) ", new String[]{"1.23456789E9"});
+    testSimpleEval("select round(1234567890,2) ", new String[]{"1.23456789E9"});
+
+    testSimpleEval("select round(1.2345678901234567,13) ", new String[]{"1.2345678901235"});
+    testSimpleEval("select round(1234567890.1234567,3) ", new String[]{"1.234567890123E9"});
+    testSimpleEval("select round(1234567890.1234567,5) ", new String[]{"1.23456789012346E9"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", FLOAT8);
+    schema.addColumn("col2", INT4);
+
+    testEval(schema, "table1", ",", "select round(col1, col2) from table1", new String[]{""});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
new file mode 100644
index 0000000..50a8f35
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
@@ -0,0 +1,139 @@
+/**
+ * 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.function;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.TEXT;
+
+public class TestPatternMatchingPredicates extends ExprTestBase {
+
+  @Test
+  public void testLike() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+
+    // test for null values
+    testEval(schema, "table1", ",", "select col1 like 'a%' from table1", new String[]{""});
+    testSimpleEval("select null like 'a%'", new String[]{""});
+
+    testEval(schema, "table1", "abc", "select col1 like '%c' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 like 'a%' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 like '_bc' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 like 'ab_' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 like '_b_' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 like '%b%' from table1", new String[]{"t"});
+
+    // test for escaping regular expressions
+    testEval(schema, "table1", "abc", "select col1 not like '.bc' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 not like '.*bc' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 not like '.bc' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 not like '*bc' from table1", new String[]{"t"});
+
+    // test for case sensitive
+    testEval(schema, "table1", "abc", "select col1 not like '%C' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 not like 'A%' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 not like '_BC' from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc", "select col1 not like '_C_' from table1", new String[]{"t"});
+  }
+
+  @Test
+  public void testILike() throws TajoException {
+    testSimpleEval("select 'abc' ilike '%c'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike 'a%'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike '_bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike 'ab_'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike '_b_'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike '%b%'", new String[]{"t"});
+
+    // test for escaping regular expressions
+    testSimpleEval("select 'abc' not like '.bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' not like '.*bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' not like '.bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' not like '*bc'", new String[]{"t"});
+
+    // test for case insensitive
+    testSimpleEval("select 'abc' ilike '%C'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike 'A%'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike '_BC'", new String[]{"t"});
+    testSimpleEval("select 'abc' ilike '_B_'", new String[]{"t"});
+  }
+
+  @Test
+  public void testSimilarToLike() throws TajoException {
+    testSimpleEval("select 'abc' similar to '%c'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to 'a%'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to '_bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to 'ab_'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to '_b_'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to '%b%'", new String[]{"t"});
+
+    // test for now allowed
+    testSimpleEval("select 'abc' not similar to '.bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' not similar to 'ab.'", new String[]{"t"});
+
+    // test for escaping regular expressions
+    testSimpleEval("select 'abc' similar to '(a|f)b%'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to '[a-z]b%'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to '_+bc'", new String[]{"t"});
+    testSimpleEval("select 'abc' similar to 'abc'", new String[]{"t"});
+
+    // test for case sensitive
+    testSimpleEval("select 'abc' not similar to '%C'", new String[]{"t"});
+    testSimpleEval("select 'abc' not similar to '_Bc'", new String[]{"t"});
+  }
+
+  @Test
+  public void testRegexWithSimilarOperator() throws TajoException {
+    testSimpleEval("select 'abc' ~ '.*c'", new String[]{"t"});
+    testSimpleEval("select 'abc' ~ '.*c$'", new String[]{"t"});
+    testSimpleEval("select 'aaabc' ~ '([a-z]){3}bc'", new String[]{"t"});
+
+    // for negative condition
+    testSimpleEval("select 'abc' !~ '.*c$'", new String[]{"f"});
+
+    // for case sensitivity
+    testSimpleEval("select 'abc' ~ '.*C'", new String[]{"f"});
+
+    // for case insensitivity
+    testSimpleEval("select 'abc' ~* '.*C'", new String[]{"t"});
+    testSimpleEval("select 'abc' !~* '.*C'", new String[]{"f"});
+  }
+
+  @Test
+  public void testRegexp() throws TajoException {
+    testSimpleEval("select 'abc' regexp '.*c'", new String[]{"t"});
+    testSimpleEval("select 'abc' regexp '.*c$'", new String[]{"t"});
+
+    // for negative condition
+    testSimpleEval("select 'abc' not regexp '.*c$'", new String[]{"f"});
+  }
+
+  @Test
+  public void testRLike() throws TajoException {
+    testSimpleEval("select 'abc' rlike '.*c'", new String[]{"t"});
+    testSimpleEval("select 'abc' rlike '.*c$'", new String[]{"t"});
+
+    // for negative condition
+    testSimpleEval("select 'abc' not rlike '.*c$'", new String[]{"f"});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPythonFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPythonFunctions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPythonFunctions.java
new file mode 100644
index 0000000..1b29743
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestPythonFunctions.java
@@ -0,0 +1,43 @@
+/*
+ * 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.function;
+
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+public class TestPythonFunctions extends ExprTestBase {
+
+  @Test
+  public void testFunctions() throws TajoException {
+    testSimpleEval("select return_one()", new String[]{"1"});
+    testSimpleEval("select helloworld()", new String[]{"Hello, World"});
+    testSimpleEval("select concat_py('1')", new String[]{"11"});
+    testSimpleEval("select comma_format(12345)", new String[]{"12,345"});
+    testSimpleEval("select add_py(1,2)", new String[]{"3"});
+    testSimpleEval("select percent(386, 1000)", new String[]{"38.6"});
+    testSimpleEval("select concat4('Tajo', 'is', 'awesome', '!')", new String[]{"Tajo is awesome !"});
+  }
+
+  @Test
+  public void testNestedFunctions() throws TajoException {
+    testSimpleEval("select add_py(3, return_one())", new String[]{"4"});
+    testSimpleEval("select concat_py(helloworld())", new String[]{"Hello, WorldHello, World"});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
new file mode 100644
index 0000000..366d8ed
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
@@ -0,0 +1,615 @@
+/**
+ * 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.function;
+
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
+
+public class TestStringOperatorsAndFunctions extends ExprTestBase {
+
+  @Test
+  public void testConcatenateOnLiteral() throws TajoException {
+    testSimpleEval("select ('abc' || 'def') col1 ", new String[]{"abcdef"});
+    testSimpleEval("select 'abc' || 'def' as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select 1 || 'def' as col1 ", new String[]{"1def"});
+    testSimpleEval("select 'abc' || 2 as col1 ", new String[]{"abc2"});
+  }
+
+  @Test
+  public void testConcatenateOnExpressions() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", FLOAT8);
+
+    testSimpleEval("select (1+3) || 2 as col1 ", new String[]{"42"});
+
+    testEval(schema, "table1", "abc,2,3.14", "select col1 || col2 || col3 from table1", new String[]{"abc23.14"});
+    testEval(schema, "table1", "abc,2,3.14", "select col1 || '---' || col3 from table1", new String[]{"abc---3.14"});
+  }
+
+  @Test
+  public void testFunctionCallIngoreCases() throws TajoException {
+    testSimpleEval("select ltrim(' trim') ", new String[]{"trim"});
+    testSimpleEval("select LTRIM(' trim') ", new String[]{"trim"});
+    testSimpleEval("select lTRim(' trim') ", new String[]{"trim"});
+    testSimpleEval("select ltrIM(' trim') ", new String[]{"trim"});
+  }
+
+  @Test
+  public void testLTrim() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+
+    testSimpleEval("select ltrim(' trim') ", new String[]{"trim"});
+    testSimpleEval("select ltrim('xxtrim', 'xx') ", new String[]{"trim"});
+
+    testSimpleEval("select trim(leading 'xx' from 'xxtrim') ", new String[]{"trim"});
+    testSimpleEval("select trim(leading from '  trim') ", new String[]{"trim"});
+    testSimpleEval("select trim('  trim') ", new String[]{"trim"});
+
+    testEval(schema, "table1", "  trim,abc", "select ltrim(col1) from table1", new String[]{"trim"});
+    testEval(schema, "table1", "xxtrim,abc", "select ltrim(col1, 'xx') from table1", new String[]{"trim"});
+    testEval(schema, "table1", "xxtrim,abc", "select trim(leading 'xx' from col1) from table1", new String[]{"trim"});
+
+    testEval(schema, "table1", "  trim,  abc", "select ltrim(col1) || ltrim(col2) from table1",
+        new String[]{"trimabc"});
+  }
+
+  @Test
+  public void testRTrim() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+
+    testSimpleEval("select rtrim('trim ') ", new String[]{"trim"});
+    testSimpleEval("select rtrim('trimxx', 'xx') ", new String[]{"trim"});
+
+    testSimpleEval("select trim(trailing 'xx' from 'trimxx') ", new String[]{"trim"});
+    testSimpleEval("select trim(trailing from 'trim  ') ", new String[]{"trim"});
+    testSimpleEval("select trim('trim  ') ", new String[]{"trim"});
+
+    testEval(schema, "table1", "trim  ,abc", "select rtrim(col1) from table1", new String[]{"trim"});
+    testEval(schema, "table1", "trimxx,abc", "select rtrim(col1, 'xx') from table1", new String[]{"trim"});
+    testEval(schema, "table1", "trimxx,abc", "select trim(trailing 'xx' from col1) from table1", new String[]{"trim"});
+
+    testEval(schema, "table1", "trim  ,abc  ", "select rtrim(col1) || rtrim(col2) from table1",
+        new String[]{"trimabc"});
+  }
+
+  @Test
+  public void testTrim() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+
+    testSimpleEval("select trim(' trim ') ", new String[]{"trim"});
+    testSimpleEval("select btrim('xxtrimxx', 'xx') ", new String[]{"trim"});
+
+    testSimpleEval("select trim(both 'xx' from 'xxtrimxx') ", new String[]{"trim"});
+    testSimpleEval("select trim(both from '  trim  ') ", new String[]{"trim"});
+    testSimpleEval("select trim('  trim  ') ", new String[]{"trim"});
+
+    testEval(schema, "table1", "  trim  ,abc", "select trim(col1) from table1", new String[]{"trim"});
+    testEval(schema, "table1", "xxtrimxx,abc", "select trim(col1, 'xx') from table1", new String[]{"trim"});
+    testEval(schema, "table1", "xxtrimxx,abc", "select trim(both 'xx' from col1) from table1", new String[]{"trim"});
+
+    testEval(schema, "table1", "  trim  ,xxabcxx", "select trim(col1) || trim(col2,'xx') from table1",
+        new String[]{"trimabc"});
+  }
+
+  @Test
+  public void testRegexReplace() throws TajoException {
+    testSimpleEval("select regexp_replace('abcdef','bc','--') as col1 ", new String[]{"a--def"});
+
+    // null test
+    testSimpleEval("select regexp_replace(null, 'bc', '--') as col1 ", new String[]{""});
+    testSimpleEval("select regexp_replace('abcdef', null, '--') as col1 ", new String[]{""});
+    testSimpleEval("select regexp_replace('abcdef','bc', null) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+
+    // find matches and replace from column values
+    testEval(schema, "table1", "------,(^--|--$),ab", "select regexp_replace(col1, col2, col3) as str from table1",
+        new String[]{"ab--ab"});
+
+    // null test from a table
+    testEval(schema, "table1", ",(^--|--$),ab", "select regexp_replace(col1, col2, col3) as str from table1",
+        new String[]{""});
+    testEval(schema, "table1", "------,(^--|--$),", "select regexp_replace(col1, col2, col3) as str from table1",
+        new String[]{""});
+  }
+
+  @Test
+  public void testLeft() throws TajoException {
+    testSimpleEval("select left('abcdef',1) as col1 ", new String[]{"a"});
+    testSimpleEval("select left('abcdef',2) as col1 ", new String[]{"ab"});
+    testSimpleEval("select left('abcdef',3) as col1 ", new String[]{"abc"});
+    testSimpleEval("select left('abcdef',4) as col1 ", new String[]{"abcd"});
+    testSimpleEval("select left('abcdef',5) as col1 ", new String[]{"abcde"});
+    testSimpleEval("select left('abcdef',6) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select left('abcdef',7) as col1 ", new String[]{"abcdef"});
+
+    testSimpleEval("select left('abcdef',-1) as col1 ", new String[]{"abcde"});
+    testSimpleEval("select left('abcdef',-2) as col1 ", new String[]{"abcd"});
+    testSimpleEval("select left('abcdef',-3) as col1 ", new String[]{"abc"});
+    testSimpleEval("select left('abcdef',-4) as col1 ", new String[]{"ab"});
+    testSimpleEval("select left('abcdef',-5) as col1 ", new String[]{"a"});
+    testSimpleEval("select left('abcdef',-6) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", TEXT);
+
+    // for null tests
+    testEval(schema, "table1", ",1,ghi", "select left(col1,1) is null from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc,,ghi", "select left(col1,col2) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "abc,1,ghi", "select left(col1,1) || left(col3,3) from table1", new String[]{"aghi"});
+  }
+
+  @Test
+  public void testRight() throws TajoException {
+    testSimpleEval("select right('abcdef',1) as col1 ", new String[]{"f"});
+    testSimpleEval("select right('abcdef',2) as col1 ", new String[]{"ef"});
+    testSimpleEval("select right('abcdef',3) as col1 ", new String[]{"def"});
+    testSimpleEval("select right('abcdef',4) as col1 ", new String[]{"cdef"});
+    testSimpleEval("select right('abcdef',5) as col1 ", new String[]{"bcdef"});
+    testSimpleEval("select right('abcdef',6) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select right('abcdef',7) as col1 ", new String[]{"abcdef"});
+
+    testSimpleEval("select right('abcdef',-1) as col1 ", new String[]{"bcdef"});
+    testSimpleEval("select right('abcdef',-2) as col1 ", new String[]{"cdef"});
+    testSimpleEval("select right('abcdef',-3) as col1 ", new String[]{"def"});
+    testSimpleEval("select right('abcdef',-4) as col1 ", new String[]{"ef"});
+    testSimpleEval("select right('abcdef',-5) as col1 ", new String[]{"f"});
+    testSimpleEval("select right('abcdef',-6) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", TEXT);
+
+    // for null tests
+    testEval(schema, "table1", ",1,ghi", "select right(col1,1) is null from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc,,ghi", "select right(col1,col2) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "abc,1,ghi", "select right(col1,1) || right(col3,3) from table1", new String[]{"cghi"});
+  }
+
+  @Test
+  public void testReverse() throws TajoException {
+    testSimpleEval("select reverse('abcdef') as col1 ", new String[]{"fedcba"});
+    testSimpleEval("select reverse('가') as col1 ", new String[]{"가"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "abc,efg,3.14", "select reverse(col1) || reverse(col2) from table1",
+        new String[]{"cbagfe"});
+  }
+
+  @Test
+  public void testRepeat() throws TajoException {
+    testSimpleEval("select repeat('ab',4) as col1 ", new String[]{"abababab"});
+    testSimpleEval("select repeat('가',3) as col1 ", new String[]{"가가가"});
+    testSimpleEval("select repeat('a',2) as col1 ", new String[]{"aa"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "abc,efg,3.14", "select repeat(col1,2) from table1", new String[]{"abcabc"});
+  }
+
+
+  @Test
+  public void testUpper() throws TajoException {
+    testSimpleEval("select upper('abcdef') as col1 ", new String[]{"ABCDEF"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "abc,efg,3.14", "select upper(col1), upper(col2) from table1",
+        new String[]{"ABC", "EFG"});
+    testEval(schema, "table1", "abc,efg,3.14", "select upper(col1) || upper(col2) from table1", new String[]{"ABCEFG"});
+  }
+
+  @Test
+  public void testLower() throws TajoException {
+    testSimpleEval("select lower('ABCdEF') as col1 ", new String[]{"abcdef"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABC,DEF,3.14", "select lower(col1), lower(col2) from table1",
+        new String[]{"abc", "def"});
+    testEval(schema, "table1", "ABC,DEF,3.14", "select lower(col1) || lower(col2) from table1", new String[]{"abcdef"});
+  }
+
+  @Test
+  public void testCharLength() throws TajoException {
+    testSimpleEval("select char_length('123456') as col1 ", new String[]{"6"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABC,DEF,3.14", "select character_length(lower(col1) || lower(col2)) from table1",
+        new String[]{"6"});
+  }
+
+  @Test
+  public void testLength() throws TajoException {
+    testSimpleEval("select length('123456') as col1 ", new String[]{"6"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABC,DEF,3.14", "select length(lower(col1) || lower(col2)) from table1",
+        new String[]{"6"});
+  }
+
+  @Test
+  public void testMd5() throws TajoException {
+    testSimpleEval("select md5('1') as col1 ", new String[]{"c4ca4238a0b923820dcc509a6f75849b"});
+    testSimpleEval("select md5('tajo') as col1 ", new String[]{"742721b3a79f71a9491681b8e8a7ce85"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "abc,efg,3.14", "select md5(col1) from table1",
+        new String[]{"900150983cd24fb0d6963f7d28e17f72"});
+  }
+
+  @Test
+  public void testDigest() throws TajoException {
+    testSimpleEval("select digest('tajo', 'md2') as col1 ", new String[]{"bf523bce8241982f6bea9af0f7fd37ff"});
+    testSimpleEval("select digest('tajo', 'md5') as col1 ", new String[]{"742721b3a79f71a9491681b8e8a7ce85"});
+    testSimpleEval("select digest('tajo', 'sha1') as col1 ", new String[]{"02b0e20540b89f0b735092bbac8093eb2e3804cf"});
+    testSimpleEval("select digest('tajo', 'sha256') as col1 ", 
+      new String[]{"6440083be076869a9f9d0271a4bf298d98c8aa3ecb49df841895fbcddbb04a70"});
+    testSimpleEval("select digest('tajo', 'sha384') as col1 ", 
+      new String[]{"59ff99b0e274eb3d8e10f221b6b949bfc1244d2a1226c5c720062fb03d82272be633e4a0f2babccffbfdff7cc1cb06fb"});
+    testSimpleEval("select digest('tajo', 'sha512') as col1 ", 
+      new String[]{"ee8ba254d331ddfb1bca9aaf0c4b8c58aea5331928cbd20168c87828afb853b0c096af71ec69a23b669217a1dddd2934edaac33b1296fe526b22abd28a15c4b3"});
+    testSimpleEval("select digest('tajo', 'not') as col1 ", new String[]{""});
+  }
+
+  @Test
+  public void testHex() throws TajoException {
+    testSimpleEval("select to_hex(1) as col1 ", new String[]{"1"});
+    testSimpleEval("select to_hex(10) as col1 ", new String[]{"a"});
+    testSimpleEval("select to_hex(1234) as col1 ", new String[]{"4d2"});
+    testSimpleEval("select to_hex(1023456788888888) as col1 ", new String[]{"3a2d41a583d38"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", ",abcdef,3.14", "select to_hex(10) from table1",
+        new String[]{"a"});
+  }
+
+  @Test
+  public void testBin() throws TajoException {
+    testSimpleEval("select to_bin(1) as col1 ", new String[]{"1"});
+    testSimpleEval("select to_bin(10) as col1 ", new String[]{"1010"});
+    testSimpleEval("select to_bin(1234) as col1 ", new String[]{"10011010010"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", ",abcdef,3.14", "select to_bin(20) from table1",
+        new String[]{"10100"});
+  }
+
+  @Test
+  public void testOctetLength() throws TajoException {
+    testSimpleEval("select octet_length('123456') as col1 ", new String[]{"6"});
+    testSimpleEval("select octet_length('1') as col1 ", new String[]{"1"});
+    testSimpleEval("select octet_length('가') as col1 ", new String[]{"3"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABC,DEF,3.14", "select octet_length(lower(col1) || lower(col2)) from table1",
+        new String[]{"6"});
+  }
+
+  @Test
+  public void testSplitPart() throws TajoException {
+    testSimpleEval("select split_part('1386577650.123', '.', 1) as col1 ", new String[]{"1386577650"});
+    testSimpleEval("select split_part('1386577650.123', '.', 2) as col1 ", new String[]{"123"});
+    // If part is larger than the number of string portions, it will returns NULL.
+    testSimpleEval("select split_part('1386577650.123', '.', 3) is null", new String[]{"t"});
+
+    // null handling tests
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "t1", ",.,1", "select split_part(col1, col2, col3::int) is null from t1", new String[]{"t"});
+    testEval(schema, "t1", "1386577650.123,,1", "select split_part(col1, col2, col3::int) from t1",
+        new String[]{"1386577650.123"});
+    testEval(schema, "t1", "1386577650.123,.,", "select split_part(col1, col2, col3::int) is null from t1",
+        new String[]{"t"});
+  }
+
+  @Test
+  public void testSubstr() throws TajoException {
+    testSimpleEval("select substr('abcdef', 3, 2) as col1 ", new String[]{"cd"});
+    testSimpleEval("select substr('abcdef', 3) as col1 ", new String[]{"cdef"});
+    testSimpleEval("select substr('abcdef', 1, 1) as col1 ", new String[]{"a"});
+    testSimpleEval("select substr('abcdef', 0, 1) as col1 ", new String[]{""});
+    testSimpleEval("select substr('abcdef', 0, 2) as col1 ", new String[]{"a"});
+    testSimpleEval("select substr('abcdef', 0) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select substr('abcdef', 1, 100) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select substr('abcdef', 0, 100) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select substr('일이삼사오', 2, 2) as col1 ", new String[]{"이삼"});
+    testSimpleEval("select substr('일이삼사오', 3) as col1 ", new String[]{"삼사오"});
+
+    testSimpleEval("select substr('abcdef', -1) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select substr('abcdef', -1, 100) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select substr('abcdef', -1, 3) as col1 ", new String[]{"a"});
+    testSimpleEval("select substr('abcdef', -1, 1) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", ",abcdef,3.14", "select substr(lower(col2), 2, 3) from table1",
+        new String[]{"bcd"});
+  }
+  
+  @Test
+  public void testLocate() throws TajoException {
+    // normal case
+    testSimpleEval("select locate('abcdef', 'a') as col1 ", new String[]{"1"});
+    testSimpleEval("select locate('abcdef', 'a', 0) as col1 ", new String[]{"1"});
+    testSimpleEval("select locate('abcdef', 'a', 1) as col1 ", new String[]{"1"});
+    testSimpleEval("select locate('abcdef', 'z') as col1 ", new String[]{"0"});
+    testSimpleEval("select locate('abcdef', 'z', 1) as col1 ", new String[]{"0"});
+    testSimpleEval("select locate('foobarbar', 'bar') as col1 ", new String[]{"4"});
+    testSimpleEval("select locate('foobarbar', 'bar', 0) as col1 ", new String[]{"4"});
+    testSimpleEval("select locate('foobarbar', 'bar', 1) as col1 ", new String[]{"4"});
+    testSimpleEval("select locate('foobarbar', 'bar', 5) as col1 ", new String[]{"7"});
+    testSimpleEval("select locate('foobarbar', 'bar', 9) as col1 ", new String[]{"0"});
+    testSimpleEval("select locate('가나다라마라마', '라마') as col1 ", new String[]{"4"});
+    testSimpleEval("select locate('가나다라마라마', '라마', 5) as col1 ", new String[]{"6"});
+    // empty string
+    testSimpleEval("select locate('abcdef', '') as col1 ", new String[]{"1"});
+    testSimpleEval("select locate('abcdef', '', 2) as col1 ", new String[]{"2"});
+    // pos = last index of string (expected value(6) is tested on mysql)
+    testSimpleEval("select locate('abcdef', '', 6) as col1 ", new String[]{"6"});
+    // pos = last index + 1 (expected value(7) is tested on mysql)
+    testSimpleEval("select locate('abcdef', '', 7) as col1 ", new String[]{"7"});
+    // pos = greater then last index + 1 (expected value(0) is tested on mysql)
+    testSimpleEval("select locate('abcdef', '', 8) as col1 ", new String[]{"0"});
+    // pos = greater then last index + 1 (expected value(0) is tested on mysql)
+    testSimpleEval("select locate('abcdef', '', 9) as col1 ", new String[]{"0"});
+    testSimpleEval("select locate('가나다라', '', 2) as col1 ", new String[]{"2"});
+    testSimpleEval("select locate('가나다라', '', 4) as col1 ", new String[]{"4"});
+    testSimpleEval("select locate('가나다라', '', 5) as col1 ", new String[]{"5"});
+    testSimpleEval("select locate('가나다라', '', 6) as col1 ", new String[]{"0"});
+    
+    // negative pos    
+    testSimpleEval("select locate('abcdef', 'a', -1) as col1 ", new String[]{"0"});
+    testSimpleEval("select locate('abcdef', 'a', -5) as col1 ", new String[]{"0"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", ",abcdef,3.14", "select locate(col2, 'cd') from table1", new String[]{"3"});
+    testEval(schema, "table1", ",abcdef,3.14", "select locate(col2, 'cd', 1) from table1", new String[]{"3"});
+    testEval(schema, "table1", ",abcdef,3.14", "select locate(col2, 'cd', 4) from table1", new String[]{"0"});
+    testEval(schema, "table1", ",abcdef,3.14", "select locate(col2, 'xy') from table1", new String[]{"0"});
+    // null string
+    testEval(schema, "table1", ",abcdef,3.14", "select locate(col1, 'cd') is null from table1", new String[]{"t"});
+    // nul substring
+    testEval(schema, "table1", ",abcdef,3.14", "select locate('cd', col1) is null from table1", new String[]{"t"});
+  }
+
+  @Test
+  public void testBitLength() throws TajoException {
+    testSimpleEval("select bit_length('123456') as col1 ", new String[]{"48"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABC,DEF,3.14", "select bit_length(lower(col1) || lower(col2)) from table1",
+        new String[]{"48"});
+  }
+
+  @Test
+  public void testStrpos() throws TajoException {
+    testSimpleEval("select strpos('tajo','jo') as col1 ", new String[]{"3"});
+    testSimpleEval("select strpos('tajo','') as col1 ", new String[]{"1"});
+    testSimpleEval("select strpos('tajo','abcdef') as col1 ", new String[]{"0"});
+    testSimpleEval("select strpos('일이삼사오육','삼사') as col1 ", new String[]{"3"});
+    testSimpleEval("select strpos('일이삼사오육','일이삼') as col1 ", new String[]{"1"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABCDEF,HIJKLMN,3.14", "select strpos(lower(col1) || lower(col2), 'fh') from table1",
+        new String[]{"6"});
+  }
+
+  @Test
+  public void testStrposb() throws TajoException {
+    testSimpleEval("select strposb('tajo','jo') as col1 ", new String[]{"3"});
+    testSimpleEval("select strposb('tajo','') as col1 ", new String[]{"1"});
+    testSimpleEval("select strposb('tajo','abcdef') as col1 ", new String[]{"0"});
+    testSimpleEval("select strposb('일이삼사오육','삼사') as col1 ", new String[]{"7"});    //utf8 1 korean word = 3 chars
+    testSimpleEval("select strposb('일이삼사오육','삼사일') as col1 ", new String[]{"0"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    schema.addColumn("col3", TEXT);
+    testEval(schema, "table1", "ABCDEF,HIJKLMN,3.14", "select strposb(lower(col1) || lower(col2), 'fh') from table1",
+        new String[]{"6"});
+  }
+
+  @Test
+  public void testInitcap() throws TajoException {
+    testSimpleEval("select initcap('hi bro') ", new String[]{"Hi Bro"});
+    testSimpleEval("select initcap('HI BRO') ", new String[]{"Hi Bro"});
+  }
+
+  @Test
+  public void testAscii() throws TajoException {
+    testSimpleEval("select ascii('abc') as col1 ", new String[]{"97"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    testEval(schema, "table1", "abc", "select ascii(col1) from table1",
+            new String[]{"97"});
+    testEval(schema, "table1", "12", "select ascii(col1) from table1",
+            new String[]{"49"});
+
+  }
+
+  @Test
+  public void testChr() throws TajoException {
+    testSimpleEval("select chr(48) as col1 ", new String[]{"0"});
+    testSimpleEval("select chr(49) as col1 ", new String[]{"1"});
+    testSimpleEval("select chr(50) as col1 ", new String[]{"2"});
+    testSimpleEval("select chr(64) as col1 ", new String[]{"@"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", INT4);
+    testEval(schema, "table1", "65", "select chr(col1) from table1", new String[]{"A"});
+    testEval(schema, "table1", "66", "select chr(col1) from table1", new String[]{"B"});
+    testEval(schema, "table1", "52512", "select chr(col1) from table1", new String[]{"촠"});
+  }
+
+  @Test
+  public void testLpad() throws TajoException {
+    testSimpleEval("select lpad('hi', 5, 'xy') ", new String[]{"xyxhi"});
+    testSimpleEval("select LPAD('hello', 7, 'xy') ", new String[]{"xyhello"});
+    testSimpleEval("select LPAD('hello', 3, 'xy') ", new String[]{"hel"});
+    testSimpleEval("select lPAD('hello', 7) ", new String[]{"  hello"});
+    testSimpleEval("select lPAD('가나다라', 3) ", new String[]{"가나다"});
+
+  }
+
+  @Test
+  public void testRpad() throws TajoException {
+    testSimpleEval("select rpad('hi', 5, 'xy') ", new String[]{"hixyx"});
+    testSimpleEval("select RPAD('hello', 7, 'xy') ", new String[]{"helloxy"});
+    testSimpleEval("select RPAD('hello', 3, 'xy') ", new String[]{"hel"});
+    testSimpleEval("select rPAD('hello', 7) ", new String[]{"hello  "});
+    testSimpleEval("select rPAD('가나다라', 3) ", new String[]{"가나다"});
+
+  }
+
+  @Test
+  public void testQuote_ident() throws TajoException {
+    testSimpleEval("select quote_ident('Foo bar') ", new String[]{"\"Foo bar\""});
+    testSimpleEval("select QUOTE_IDENT('Tajo Function') ", new String[]{"\"Tajo Function\""});
+  }
+
+  @Test
+  public void testEncode() throws TajoException {
+    testSimpleEval("select encode('Hello\nworld', 'base64') ", new String[]{"SGVsbG8Kd29ybGQ="});
+    testSimpleEval("select encode('Hello\nworld', 'hex') ",
+        new String[]{"0x480x650x6c0x6c0x6f0x0a0x770x6f0x720x6c0x64"});
+    testSimpleEval("select encode('한글', 'base64') ", new String[]{"7ZWc6riA"});
+    testSimpleEval("select encode('한글', 'hex') ", new String[]{"0xd55c0xae00"});
+    testSimpleEval("select encode('한글\n테스트\t입니다.', 'hex') ",
+        new String[]{"0xd55c0xae000x0a0xd14c0xc2a40xd2b80x090xc7850xb2c80xb2e40x2e"});
+  }
+
+
+  @Test
+  public void testDecode() throws TajoException {
+    testSimpleEval("select decode('SGVsbG8Kd29ybGQ=', 'base64') ",
+        new String[]{StringEscapeUtils.escapeJava("Hello\nworld")});
+    testSimpleEval("select decode('0x480x650x6c0x6c0x6f0x0a0x770x6f0x720x6c0x64', 'hex') ",
+        new String[]{StringEscapeUtils.escapeJava("Hello\nworld")});
+    testSimpleEval("select decode('7ZWc6riA', 'base64') ", new String[]{StringEscapeUtils.escapeJava("한글")});
+    testSimpleEval("select decode('0xd55c0xae00', 'hex') ", new String[]{StringEscapeUtils.escapeJava("한글")});
+    testSimpleEval("select decode('0xd55c0xae000x0a0xd14c0xc2a40xd2b80x090xc7850xb2c80xb2e40x2e', 'hex') ",
+        new String[]{StringEscapeUtils.escapeJava("한글\n" + "테스트\t입니다.")});
+  }
+
+  @Test
+  public void testFindInSet() throws TajoException {
+    // abnormal cases
+    testSimpleEval("select find_in_set('cr','crt') as col1 ", new String[]{"0"}); // there is no matched string
+    testSimpleEval("select find_in_set('c,r','crt,c,cr,c,def') as col1 ", new String[]{"0"}); // abnormal parameter
+
+    // normal cases
+    testSimpleEval("select find_in_set('crt','crt,c,cr,d,def') as col1 ", new String[]{"1"});
+    testSimpleEval("select find_in_set('c','crt,c,cr,d,def') as col1 ", new String[]{"2"});
+    testSimpleEval("select find_in_set('def','crt,c,cr,d,def') as col1 ", new String[]{"5"});
+    // unicode test
+    testSimpleEval("select find_in_set('딸기','사과,배,옥수수,감자,딸기,수박') as col1 ", new String[]{"5"});
+
+    // null test
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    testEval(schema, "table1", "|crt,c,cr,c,def", "select find_in_set(col1, col2) is null from table1",
+        new String[]{"t"}, '|', true);
+    testEval(schema, "table1", "cr|", "select find_in_set(col1, col2) is null from table1",
+        new String[]{"t"}, '|', true);
+  }
+
+  @Test
+  public void testConcat() throws TajoException {
+    testSimpleEval("select concat('333', '22') ", new String[]{"33322"});
+    testSimpleEval("select concat('한글', '22') ", new String[]{"한글22"});
+    testSimpleEval("select concat(null, '22') ", new String[]{"22"});
+    testSimpleEval("select concat('22',null) ", new String[]{"22"});
+    testSimpleEval("select concat('22',null, '33', null, '44') ", new String[]{"223344"});
+  }
+
+  @Test
+  public void testConcat_ws() throws TajoException {
+    testSimpleEval("select concat_ws(',', '333', '22') ", new String[]{"333,22"});
+    testSimpleEval("select concat_ws(',', '한글', '22') ", new String[]{"한글,22"});
+    testSimpleEval("select concat_ws(',', '22', null) ", new String[]{"22"});
+    testSimpleEval("select concat_ws(',', '22', '33', '33') ", new String[]{"22,33,33"});
+    testSimpleEval("select concat_ws(',', null, '22') ", new String[]{"22"});
+  }
+}


[28/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java
new file mode 100644
index 0000000..7cb7e71
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java
@@ -0,0 +1,315 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.*;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.rpc.CallFuture;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.event.NodeResourceAllocateEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.tajo.ResourceProtos.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestTaskExecutor {
+
+  private NodeResourceManager resourceManager;
+  private NodeStatusUpdater statusUpdater;
+  private TaskManager taskManager;
+  private MyTaskExecutor taskExecutor;
+  private AsyncDispatcher dispatcher;
+  private AsyncDispatcher taskDispatcher;
+  private TajoWorker.WorkerContext workerContext;
+
+  private CompositeService service;
+  private TajoConf conf;
+  private Semaphore barrier;
+  private Semaphore resourceManagerBarrier;
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES, 2);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM, 2);
+    dispatcher = new AsyncDispatcher();
+    taskDispatcher = new AsyncDispatcher();
+
+    workerContext = new MockWorkerContext() {
+      WorkerConnectionInfo workerConnectionInfo;
+
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return taskManager;
+      }
+
+      @Override
+      public org.apache.tajo.worker.TaskExecutor getTaskExecuor() {
+        return taskExecutor;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return resourceManager;
+      }
+
+      @Override
+      public WorkerConnectionInfo getConnectionInfo() {
+        if (workerConnectionInfo == null) {
+          workerConnectionInfo = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+        }
+        return workerConnectionInfo;
+      }
+    };
+
+    barrier = new Semaphore(0);
+    resourceManagerBarrier = new Semaphore(0);
+    taskManager = new MockTaskManager(new Semaphore(0), taskDispatcher, workerContext);
+    taskExecutor = new MyTaskExecutor(barrier, workerContext);
+    resourceManager = new MockNodeResourceManager(resourceManagerBarrier, dispatcher, workerContext);
+    statusUpdater = new MockNodeStatusUpdater(new CountDownLatch(0), workerContext);
+
+    service = new CompositeService("MockService") {
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        addIfService(dispatcher);
+        addIfService(taskDispatcher);
+        addIfService(taskManager);
+        addIfService(taskExecutor);
+        addIfService(resourceManager);
+        addIfService(statusUpdater);
+        super.serviceInit(conf);
+      }
+
+
+      @Override
+      protected void serviceStop() throws Exception {
+        workerContext.getMetrics().stop();
+        super.serviceStop();
+      }
+    };
+
+    service.init(conf);
+    service.start();
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test
+  public void testTaskRequest() throws Exception {
+    int requestSize = 1;
+
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, 10, requestSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    //verify running task
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(1, taskExecutor.getRunningTasks());
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(0, taskExecutor.getRunningTasks());
+    assertEquals(1, taskExecutor.completeTasks);
+
+    //verify the released resources
+    Thread.sleep(100);
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+  }
+
+  @Test
+  public void testTaskException() throws Exception {
+    int requestSize = 1;
+
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, 10, requestSize));
+
+    taskExecutor.throwException.set(true);
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    //verify running task
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(1, taskExecutor.getRunningTasks());
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(0, taskExecutor.getRunningTasks());
+    assertEquals(0, taskExecutor.completeTasks);
+
+    //verify the released resources
+    Thread.sleep(100);
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+  }
+
+  class MyTaskExecutor extends MockTaskExecutor {
+    int completeTasks;
+    AtomicBoolean throwException = new AtomicBoolean();
+
+    public MyTaskExecutor(Semaphore barrier, TajoWorker.WorkerContext workerContext) {
+      super(barrier, workerContext);
+    }
+
+    @Override
+    protected void stopTask(TaskAttemptId taskId) {
+      super.stopTask(taskId);
+      super.barrier.release();
+    }
+
+    @Override
+    protected Task createTask(final ExecutionBlockContext context, TaskRequestProto taskRequest) {
+      final TaskAttemptId taskAttemptId = new TaskAttemptId(taskRequest.getId());
+      final TaskAttemptContext taskAttemptContext = new TaskAttemptContext(null, context, taskAttemptId, null, null);
+
+      return new Task() {
+        @Override
+        public void init() throws IOException {
+
+          try {
+            Thread.sleep(50);
+          } catch (InterruptedException e) {
+            e.printStackTrace();
+          }
+        }
+
+        @Override
+        public void fetch(ExecutorService fetchExecutor) {
+          try {
+            Thread.sleep(50);
+          } catch (InterruptedException e) {
+            e.printStackTrace();
+          }
+        }
+
+        @Override
+        public void run() throws Exception {
+          Thread.sleep(50);
+
+          if(throwException.get()) throw new RuntimeException();
+
+          taskAttemptContext.stop();
+          taskAttemptContext.setProgress(1.0f);
+          taskAttemptContext.setState(TajoProtos.TaskAttemptState.TA_SUCCEEDED);
+          completeTasks++;
+        }
+
+        @Override
+        public void kill() {
+
+        }
+
+        @Override
+        public void abort() {
+
+        }
+
+        @Override
+        public void cleanup() {
+        }
+
+        @Override
+        public boolean hasFetchPhase() {
+          return false;
+        }
+
+        @Override
+        public boolean isProgressChanged() {
+          return false;
+        }
+
+        @Override
+        public boolean isStopped() {
+          return taskAttemptContext.isStopped();
+        }
+
+        @Override
+        public void updateProgress() {
+
+        }
+
+        @Override
+        public TaskAttemptContext getTaskContext() {
+          return taskAttemptContext;
+        }
+
+        @Override
+        public ExecutionBlockContext getExecutionBlockContext() {
+          return context;
+        }
+
+        @Override
+        public TaskStatusProto getReport() {
+          TaskStatusProto.Builder builder = TaskStatusProto.newBuilder();
+          builder.setWorkerName("localhost:0");
+          builder.setId(taskAttemptContext.getTaskId().getProto())
+              .setProgress(taskAttemptContext.getProgress())
+              .setState(taskAttemptContext.getState());
+
+          builder.setInputStats(new TableStats().getProto());
+          return builder.build();
+        }
+
+        @Override
+        public TaskHistory createTaskHistory() {
+          return null;
+        }
+
+        @Override
+        public List<Fetcher> getFetchers() {
+          return null;
+        }
+      };
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java
new file mode 100644
index 0000000..1d84afe
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java
@@ -0,0 +1,184 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.resource.NodeResource;
+import org.apache.tajo.rpc.CallFuture;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.event.ExecutionBlockStopEvent;
+import org.apache.tajo.worker.event.NodeResourceAllocateEvent;
+import org.apache.tajo.worker.event.TaskStartEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.tajo.ResourceProtos.*;
+import static org.junit.Assert.*;
+
+public class TestTaskManager {
+
+  private NodeResourceManager resourceManager;
+  private NodeStatusUpdater statusUpdater;
+  private TaskManager taskManager;
+  private TaskExecutor taskExecutor;
+  private AsyncDispatcher dispatcher;
+  private AsyncDispatcher taskDispatcher;
+  private TajoWorker.WorkerContext workerContext;
+
+  private CompositeService service;
+  private int taskMemory;
+  private TajoConf conf;
+  private Semaphore barrier;
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+
+    taskMemory = 512;
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES, 4);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_MEMORY_MB,
+        taskMemory * conf.getIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES));
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_DISKS, 4);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_DISK_PARALLEL_NUM, 1);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM, 2);
+
+    dispatcher = new AsyncDispatcher();
+    taskDispatcher = new AsyncDispatcher();
+
+    workerContext = new MockWorkerContext() {
+      WorkerConnectionInfo workerConnectionInfo;
+
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return taskManager;
+      }
+
+      @Override
+      public TaskExecutor getTaskExecuor() {
+        return taskExecutor;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return resourceManager;
+      }
+
+      @Override
+      public WorkerConnectionInfo getConnectionInfo() {
+        if (workerConnectionInfo == null) {
+          workerConnectionInfo = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+        }
+        return workerConnectionInfo;
+      }
+    };
+    barrier = new Semaphore(0);
+    taskManager = new MockTaskManager(barrier, taskDispatcher, workerContext);
+    taskExecutor = new MockTaskExecutor(new Semaphore(0), workerContext);
+    resourceManager = new NodeResourceManager(dispatcher, workerContext);
+    statusUpdater = new MockNodeStatusUpdater(new CountDownLatch(0), workerContext);
+
+    service = new CompositeService("MockService") {
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        addIfService(dispatcher);
+        addIfService(taskDispatcher);
+        addIfService(taskManager);
+        addIfService(taskExecutor);
+        addIfService(resourceManager);
+        addIfService(statusUpdater);
+        super.serviceInit(conf);
+      }
+
+
+      @Override
+      protected void serviceStop() throws Exception {
+        workerContext.getMetrics().stop();
+        super.serviceStop();
+      }
+    };
+
+    service.init(conf);
+    service.start();
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test(timeout = 10000)
+  public void testExecutionBlockStart() throws Exception {
+    int requestSize = 1;
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, taskMemory, requestSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertNotNull(taskManager.getExecutionBlockContext(ebId));
+    assertEquals(ebId, taskManager.getExecutionBlockContext(ebId).getExecutionBlockId());
+  }
+
+  @Test(timeout = 10000)
+  public void testExecutionBlockStop() throws Exception {
+
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+    TaskAllocationProto requestProto =
+        MockNodeResourceManager.createTaskRequests(ebId, taskMemory, 1).poll();
+
+    taskDispatcher.getEventHandler().handle(new TaskStartEvent(requestProto.getTaskRequest(),
+        new NodeResource(requestProto.getResource())));
+
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertNotNull(taskManager.getExecutionBlockContext(ebId));
+    assertEquals(ebId, taskManager.getExecutionBlockContext(ebId).getExecutionBlockId());
+
+    ExecutionBlockListProto.Builder ebList = ExecutionBlockListProto.newBuilder();
+    taskDispatcher.getEventHandler().handle(new ExecutionBlockStopEvent(ebId.getProto(), ebList.build()));
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertNull(taskManager.getExecutionBlockContext(ebId));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java
new file mode 100644
index 0000000..e0d9db3
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java
@@ -0,0 +1,64 @@
+/**
+ * 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.ws.rs.resources;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.json.FunctionAdapter;
+import org.apache.tajo.catalog.json.TableMetaAdapter;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.function.Function;
+import org.apache.tajo.json.ClassNameSerializer;
+import org.apache.tajo.json.DataTypeAdapter;
+import org.apache.tajo.json.DatumAdapter;
+import org.apache.tajo.json.GsonSerDerAdapter;
+import org.apache.tajo.json.PathSerializer;
+import org.apache.tajo.json.TimeZoneGsonSerdeAdapter;
+import org.apache.tajo.plan.expr.EvalNode;
+import org.apache.tajo.plan.function.AggFunction;
+import org.apache.tajo.plan.function.GeneralFunction;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.serder.EvalNodeAdapter;
+import org.apache.tajo.plan.serder.LogicalNodeAdapter;
+import org.apache.tajo.util.TUtil;
+
+public class RestTestUtils {
+  
+  public static Map<Type, GsonSerDerAdapter<?>> registerTypeAdapterMap() {
+    Map<Type, GsonSerDerAdapter<?>> adapters = TUtil.newHashMap();
+    adapters.put(Path.class, new PathSerializer());
+    adapters.put(Class.class, new ClassNameSerializer());
+    adapters.put(LogicalNode.class, new LogicalNodeAdapter());
+    adapters.put(EvalNode.class, new EvalNodeAdapter());
+    adapters.put(TableMeta.class, new TableMetaAdapter());
+    adapters.put(Function.class, new FunctionAdapter());
+    adapters.put(GeneralFunction.class, new FunctionAdapter());
+    adapters.put(AggFunction.class, new FunctionAdapter());
+    adapters.put(Datum.class, new DatumAdapter());
+    adapters.put(DataType.class, new DataTypeAdapter());
+    adapters.put(TimeZone.class, new TimeZoneGsonSerdeAdapter());
+
+    return adapters;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java
new file mode 100644
index 0000000..7e18c1d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java
@@ -0,0 +1,83 @@
+/**
+ * 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.ws.rs.resources;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.GenericType;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestClusterResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI clusterURI;
+  private Client restClient;
+
+  public TestClusterResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    clusterURI = new URI(restServiceURI + "/cluster");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  @Test
+  public void testGetCluster() throws Exception {
+    Map<String, List<Object>> workerMap =
+        restClient.target(clusterURI)
+        .request().get(new GenericType<Map<String, List<Object>>>(Map.class));
+    
+    assertNotNull(workerMap);
+    assertFalse(workerMap.isEmpty());
+    assertNotNull(workerMap.get("workers"));
+    
+    List<Object> workerList = workerMap.get("workers");
+    
+    assertTrue(workerList.size() > 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java
new file mode 100644
index 0000000..59c53f1
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java
@@ -0,0 +1,189 @@
+/**
+ * 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.ws.rs.resources;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewDatabaseRequest;
+import org.apache.tajo.ws.rs.responses.DatabaseInfoResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestDatabasesResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI databasesURI;
+  private Client restClient;
+  
+  public TestDatabasesResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    databasesURI = new URI(restServiceURI + "/databases");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  @Test
+  public void testGetAllDatabases() throws Exception {
+    Map<String, Collection<String>> databaseNames = restClient.target(databasesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+    
+    assertNotNull(databaseNames);
+    assertFalse(databaseNames.isEmpty());
+    assertNotNull(databaseNames.get("databases"));
+    
+    Collection<String> databaseNamesCollection = databaseNames.get("databases");
+    
+    assertTrue(databaseNamesCollection.contains(TajoConstants.DEFAULT_DATABASE_NAME));
+  }
+  
+  @Test
+  public void testCreateDatabase() throws Exception {
+    String databaseName = "TestDatabasesResource";
+    NewDatabaseRequest request = new NewDatabaseRequest();
+    
+    request.setDatabaseName(databaseName);
+    
+    Response response = restClient.target(databasesURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+    
+    Map<String, Collection<String>> databaseNames = restClient.target(databasesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+    
+    assertNotNull(databaseNames);
+    assertFalse(databaseNames.isEmpty());
+    assertNotNull(databaseNames.get("databases"));
+    
+    Collection<String> databaseNamesCollection = databaseNames.get("databases");
+    
+    assertTrue(databaseNamesCollection.contains(databaseName));
+  }
+  
+  @Test
+  public void testCreateDatabaseBadRequest() throws Exception {
+    NewDatabaseRequest request = new NewDatabaseRequest();
+    
+    Response response = restClient.target(databasesURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testGetDatabase() throws Exception {
+    DatabaseInfoResponse response =
+        restClient.target(databasesURI).path("/{databaseName}")
+        .resolveTemplate("databaseName", TajoConstants.DEFAULT_DATABASE_NAME)
+        .request().get(new GenericType<DatabaseInfoResponse>(DatabaseInfoResponse.class));
+    
+    assertNotNull(response);
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, response.getName());
+    assertTrue(response.getTablespace() != null && !response.getTablespace().isEmpty());
+  }
+  
+  @Test
+  public void testGetDatabaseNotFound() throws Exception {
+    Response response =
+        restClient.target(databasesURI).path("/{databaseName}")
+        .resolveTemplate("databaseName", "testGetDatabaseNotFound")
+        .request().get();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropDatabase() throws Exception {
+    String databaseName = "TestDropDatabase";
+    NewDatabaseRequest request = new NewDatabaseRequest();
+    
+    request.setDatabaseName(databaseName);
+    
+    Response response = restClient.target(databasesURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+    
+    Map<String, Collection<String>> databaseNames = restClient.target(databasesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+    
+    assertNotNull(databaseNames);
+    assertFalse(databaseNames.isEmpty());
+    assertNotNull(databaseNames.get("databases"));
+    
+    Collection<String> databaseNamesCollection = databaseNames.get("databases");
+    
+    assertTrue(databaseNamesCollection.contains(databaseName));
+    
+    response = restClient.target(databasesURI)
+        .path("/{databaseName}").resolveTemplate("databaseName", databaseName)
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.OK.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropDatabaseNotFound() throws Exception {
+    Response response = restClient.target(databasesURI)
+        .path("/{databaseName}").resolveTemplate("databaseName", "TestDropDatabaseNotFound")
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
new file mode 100644
index 0000000..7c7aeae
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
@@ -0,0 +1,78 @@
+/**
+ * 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.ws.rs.resources;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.function.FunctionSignature;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.GenericType;
+import java.net.URI;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestFunctionsResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI functionsURI;
+  private Client restClient;
+  
+  public TestFunctionsResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    functionsURI = new URI(restServiceURI + "/functions");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  @Test
+  public void testGetAllFunctions() throws Exception {
+    List<FunctionSignature> functionSignatures =
+        restClient.target(functionsURI)
+        .request().get(new GenericType<List<FunctionSignature>>(List.class));
+    
+    assertNotNull(functionSignatures);
+    assertTrue(functionSignatures.size() > 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java
new file mode 100644
index 0000000..210d38d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java
@@ -0,0 +1,199 @@
+/**
+ * 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.ws.rs.resources;
+
+import com.google.gson.internal.StringMap;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.ErrorUtil;
+import org.apache.tajo.master.QueryInfo;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.requests.SubmitQueryRequest;
+import org.apache.tajo.ws.rs.responses.GetSubmitQueryResponse;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class TestQueryResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI sessionsURI;
+  private URI queriesURI;
+  private Client restClient;
+  
+  private static final String tajoSessionIdHeaderName = "X-Tajo-Session";
+  
+  public TestQueryResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    sessionsURI = new URI(restServiceURI + "/sessions");
+    queriesURI = new URI(restServiceURI + "/queries");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  private SubmitQueryRequest createNewQueryRequest(String query) throws Exception {
+    SubmitQueryRequest request = new SubmitQueryRequest();
+    request.setQuery(query);
+    return request;
+  }
+  
+  private String generateNewSessionAndGetId() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+    request.setDatabaseName(TajoConstants.DEFAULT_DATABASE_NAME);
+    
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+    
+    assertNotNull(response);
+    assertTrue(ErrorUtil.isOk(response.getResultCode()));
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+    
+    return response.getId();
+  }
+  
+  @Test
+  public void testGetAllQueries() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    SubmitQueryRequest queryRequest = createNewQueryRequest("select * from lineitem");
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+            new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+    
+    String queryId = location.lastIndexOf('/') >= 0?
+			location.substring(location.lastIndexOf('/')+1):null;
+        
+    assertTrue(queryId != null && !queryId.isEmpty());
+    
+    Map<String, List<StringMap>> queriesMap = restClient.target(queriesURI)
+        .request().get(new GenericType<Map<String, List<StringMap>>>(Map.class));
+    
+    assertNotNull(queriesMap);
+    
+    List<StringMap> queryInfoList = queriesMap.get("queries");
+    assertNotNull(queryInfoList);
+    
+    boolean assertQueryIdFound = false;
+    for (StringMap queryInfo: queryInfoList) {
+      if (queryId.equals(queryInfo.get("queryIdStr"))) {
+        assertQueryIdFound = true;
+      }
+    }
+    
+    assertTrue(assertQueryIdFound);
+  }
+  
+  @Test
+  public void testSubmitQuery() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    SubmitQueryRequest queryRequest = createNewQueryRequest("select * from lineitem");
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+            new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+    
+    String queryId = location.lastIndexOf('/') >= 0?
+			location.substring(location.lastIndexOf('/')+1):null;
+        
+    assertTrue(queryId != null && !queryId.isEmpty());
+    
+    QueryInfo queryInfo = restClient.target(queriesURI)
+        .path("/{queryId}")
+        .resolveTemplate("queryId", queryId)
+        .queryParam("print", "BRIEF")
+        .request().get(new GenericType<QueryInfo>(QueryInfo.class));
+    
+    assertNotNull(queryInfo);
+    assertEquals(queryId, queryInfo.getQueryIdStr());
+  }
+
+  @Test
+  public void testGetQueryInfoWithDefault() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    SubmitQueryRequest queryRequest = createNewQueryRequest("select * from lineitem");
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+      .request().header(tajoSessionIdHeaderName, sessionId)
+      .post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+          new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+
+    String queryId = location.lastIndexOf('/') >= 0?
+			location.substring(location.lastIndexOf('/')+1):null;
+
+    assertTrue(queryId != null && !queryId.isEmpty());
+
+    QueryInfo queryInfo = restClient.target(queriesURI)
+      .path("/{queryId}")
+      .resolveTemplate("queryId", queryId)
+      .request().get(new GenericType<QueryInfo>(QueryInfo.class));
+
+    assertNotNull(queryInfo);
+    assertEquals(queryId, queryInfo.getQueryIdStr());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java
new file mode 100644
index 0000000..7762b05
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java
@@ -0,0 +1,296 @@
+/**
+ * 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.ws.rs.resources;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.ErrorUtil;
+import org.apache.tajo.storage.RowStoreUtil;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.requests.SubmitQueryRequest;
+import org.apache.tajo.ws.rs.responses.GetQueryResultDataResponse;
+import org.apache.tajo.ws.rs.responses.GetSubmitQueryResponse;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.net.URI;
+import java.security.MessageDigest;
+import java.util.List;
+
+import static org.apache.tajo.exception.ErrorUtil.isOk;
+import static org.junit.Assert.*;
+
+public class TestQueryResultResource extends QueryTestCaseBase {
+
+  private URI restServiceURI;
+  private URI sessionsURI;
+  private URI queriesURI;
+  private Client restClient;
+
+  private static final String tajoSessionIdHeaderName = "X-Tajo-Session";
+  private static final String tajoDigestHeaderName = "X-Tajo-Digest";
+	private static final String tajoOffsetHeaderName = "X-Tajo-Offset";
+	private static final String tajoCountHeaderName = "X-Tajo-Count";
+	private static final String tajoEOSHeaderName = "X-Tajo-EOS";
+
+  public TestQueryResultResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    sessionsURI = new URI(restServiceURI + "/sessions");
+    queriesURI = new URI(restServiceURI + "/queries");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+
+  private String generateNewSessionAndGetId() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+    request.setDatabaseName(TajoConstants.DEFAULT_DATABASE_NAME);
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(isOk(response.getResultCode()));
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    return response.getId();
+  }
+
+  private URI sendNewQueryResquest(String sessionId, String query) throws Exception {
+
+    SubmitQueryRequest request = new SubmitQueryRequest();
+    request.setQuery(query);
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .post(Entity.entity(request, MediaType.APPLICATION_JSON),
+					new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+
+    URI queryIdURI = new URI(location);
+
+    assertNotNull(queryIdURI);
+
+    return queryIdURI;
+  }
+
+  @Test
+  public void testGetQueryResult() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    GetQueryResultDataResponse response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get(new GenericType<GetQueryResultDataResponse>(GetQueryResultDataResponse.class));
+
+    assertNotNull(response);
+    assertNotNull(response.getResultCode());
+    assertTrue(isOk(response.getResultCode()));
+    assertNotNull(response.getSchema());
+    assertEquals(16, response.getSchema().getRootColumns().size());
+    assertNotNull(response.getResultset());
+    assertTrue(response.getResultset().getId() != 0);
+    assertNotNull(response.getResultset().getLink());
+  }
+
+  @Test
+  public void testGetQueryResultNotFound() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = new URI(queriesURI + "/q_11111_0001");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    Response response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get();
+
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testGetQueryResultSet() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    GetQueryResultDataResponse response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get(new GenericType<GetQueryResultDataResponse>(GetQueryResultDataResponse.class));
+
+    assertNotNull(response);
+    assertNotNull(response.getResultCode());
+    assertTrue(ErrorUtil.isOk(response.getResultCode()));
+    assertNotNull(response.getSchema());
+    assertEquals(16, response.getSchema().getRootColumns().size());
+    assertNotNull(response.getResultset());
+    assertTrue(response.getResultset().getId() != 0);
+    assertNotNull(response.getResultset().getLink());
+
+    URI queryResultSetURI = response.getResultset().getLink();
+
+    Response queryResultSetResponse = restClient.target(queryResultSetURI)
+        .queryParam("count", 100)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get();
+
+    assertNotNull(queryResultSetResponse);
+    String tajoDigest = queryResultSetResponse.getHeaderString(tajoDigestHeaderName);
+    assertTrue(tajoDigest != null && !tajoDigest.isEmpty());
+
+    DataInputStream queryResultSetInputStream =
+        new DataInputStream(new BufferedInputStream(queryResultSetResponse.readEntity(InputStream.class)));
+
+    assertNotNull(queryResultSetInputStream);
+
+    boolean isFinished = false;
+    List<Tuple> tupleList = TUtil.newList();
+    RowStoreUtil.RowStoreDecoder decoder = RowStoreUtil.createDecoder(response.getSchema());
+    MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+    while (!isFinished) {
+      try {
+        int length = queryResultSetInputStream.readInt();
+        byte[] dataByteArray = new byte[length];
+        int readBytes = queryResultSetInputStream.read(dataByteArray);
+
+        assertEquals(length, readBytes);
+
+        tupleList.add(decoder.toTuple(dataByteArray));
+        messageDigest.update(dataByteArray);
+      } catch (EOFException eof) {
+        isFinished = true;
+      }
+    }
+
+    assertEquals(5, tupleList.size());
+    assertEquals(tajoDigest, Base64.encodeBase64String(messageDigest.digest()));
+
+    for (Tuple aTuple: tupleList) {
+      assertTrue(aTuple.getInt4(response.getSchema().getColumnId("l_orderkey")) > 0);
+    }
+  }
+
+  @Test
+  public void testGetQueryResultSetWithDefaultCount() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    GetQueryResultDataResponse response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get(new GenericType<GetQueryResultDataResponse>(GetQueryResultDataResponse.class));
+
+    assertNotNull(response);
+    assertNotNull(response.getResultCode());
+    assertTrue(isOk(response.getResultCode()));
+    assertNotNull(response.getSchema());
+    assertEquals(16, response.getSchema().getRootColumns().size());
+    assertNotNull(response.getResultset());
+    assertTrue(response.getResultset().getId() != 0);
+    assertNotNull(response.getResultset().getLink());
+
+    URI queryResultSetURI = response.getResultset().getLink();
+
+    Response queryResultSetResponse = restClient.target(queryResultSetURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get();
+
+    assertNotNull(queryResultSetResponse);
+    String tajoDigest = queryResultSetResponse.getHeaderString(tajoDigestHeaderName);
+    int offset = Integer.valueOf(queryResultSetResponse.getHeaderString(tajoOffsetHeaderName));
+    int count = Integer.valueOf(queryResultSetResponse.getHeaderString(tajoCountHeaderName));
+    boolean eos = Boolean.valueOf(queryResultSetResponse.getHeaderString(tajoEOSHeaderName));
+
+    assertTrue(tajoDigest != null && !tajoDigest.isEmpty());
+    assertTrue(eos);
+    assertEquals(0, offset);
+    assertEquals(5, count);
+
+    DataInputStream queryResultSetInputStream =
+        new DataInputStream(new BufferedInputStream(queryResultSetResponse.readEntity(InputStream.class)));
+
+    assertNotNull(queryResultSetInputStream);
+
+    boolean isFinished = false;
+    List<Tuple> tupleList = TUtil.newList();
+    RowStoreUtil.RowStoreDecoder decoder = RowStoreUtil.createDecoder(response.getSchema());
+    MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+    while (!isFinished) {
+      try {
+        int length = queryResultSetInputStream.readInt();
+        byte[] dataByteArray = new byte[length];
+        int readBytes = queryResultSetInputStream.read(dataByteArray);
+
+        assertEquals(length, readBytes);
+
+        tupleList.add(decoder.toTuple(dataByteArray));
+        messageDigest.update(dataByteArray);
+      } catch (EOFException eof) {
+        isFinished = true;
+      }
+    }
+
+    assertEquals(5, tupleList.size());
+    assertEquals(tajoDigest, Base64.encodeBase64String(messageDigest.digest()));
+
+    for (Tuple aTuple: tupleList) {
+      assertTrue(aTuple.getInt4(response.getSchema().getColumnId("l_orderkey")) > 0);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java
new file mode 100644
index 0000000..7b293d8
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java
@@ -0,0 +1,263 @@
+/**
+ * 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.ws.rs.resources;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestSessionsResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI sessionsURI;
+  private Client restClient;
+
+  public TestSessionsResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    sessionsURI = new URI(restServiceURI + "/sessions");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  private NewSessionRequest createNewSessionRequest() {
+    NewSessionRequest request = new NewSessionRequest();
+    
+    request.setUserName("tajo-user1");
+    request.setDatabaseName("default");
+    
+    return request;
+  }
+  
+  @Test
+  public void testNewSession() throws Exception {    
+    NewSessionRequest request = createNewSessionRequest();
+    
+    assertNotNull(request);
+    
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+    
+    assertNotNull(response);
+    assertNotNull(response.getId());
+    assertTrue(response.getMessage() == null || response.getMessage().isEmpty());
+    assertFalse(response.getId().isEmpty());
+  }
+  
+  @Test
+  public void testNewSessionWithoutDBName() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+    
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+    
+    assertNotNull(response);
+    assertNotNull(response.getId());
+    assertTrue(response.getMessage() == null || response.getMessage().isEmpty());
+    assertFalse(response.getId().isEmpty());
+  }
+  
+  @Test
+  public void testNewSessionWithBadRequest() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setDatabaseName("default");
+    
+    Response response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testRemoveSession() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Response restResponse = restClient.target(sessionsURI)
+        .path("/{session-id}").resolveTemplate("session-id", response.getId())
+        .request().delete();
+
+    assertNotNull(restResponse);
+    assertEquals(Status.OK.getStatusCode(), restResponse.getStatus());
+  }
+
+  @Test
+  public void testRemoveSessionNotFound() throws Exception {
+    String invalidSessionId = "invalid";
+
+    Response response = restClient.target(sessionsURI)
+        .path("/{session-id}").resolveTemplate("session-id", invalidSessionId)
+        .request().delete();
+
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testGetAllSessionVariables() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Map<String, Map<String, String>> variablesMap = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().get(new GenericType<Map<String, Map<String, String>>>(Map.class));
+
+    assertNotNull(variablesMap);
+    assertTrue(variablesMap.containsKey("variables"));
+  }
+
+  @Test
+  public void testGetAllSessionVariablesNotFound() throws Exception {
+    String invalidSessionId = "invalid";
+
+    Response response = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", invalidSessionId)
+        .request().get();
+
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testUpdateSessionVariables() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Map<String, String> variablesMap = new HashMap<String, String>();
+    variablesMap.put("variableA", "valueA");
+    variablesMap.put("variableB", "valueB");
+    Map<String, Map<String, String>> variables = new HashMap<String, Map<String, String>>();
+    variables.put("variables", variablesMap);
+    Response restResponse = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().put(Entity.entity(variables, MediaType.APPLICATION_JSON));
+
+    assertNotNull(restResponse);
+    assertEquals(Status.OK.getStatusCode(), restResponse.getStatus());
+    
+    Map<String, Map<String, String>> retrievedVariables = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().get(new GenericType<Map<String, Map<String, String>>>(Map.class));
+    
+    assertNotNull(retrievedVariables);
+    assertFalse(retrievedVariables.isEmpty());
+    
+    Map<String, String> retrievedVariablesMap = retrievedVariables.get("variables");
+    
+    assertNotNull(retrievedVariablesMap);
+    assertFalse(retrievedVariablesMap.isEmpty());
+    
+    assertTrue(retrievedVariablesMap.containsKey("variableA"));
+    assertTrue(retrievedVariablesMap.containsKey("variableB"));
+    assertTrue("valueA".equals(retrievedVariablesMap.get("variableA")));
+    assertTrue("valueB".equals(retrievedVariablesMap.get("variableB")));
+  }
+  
+  @Test
+  public void testUpdateSessionVariable() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Map<String, String> variablesMap = new HashMap<String, String>();
+    variablesMap.put("variableA", "valueA");
+    Response restResponse = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().put(Entity.entity(variablesMap, MediaType.APPLICATION_JSON));
+
+    assertNotNull(restResponse);
+    assertEquals(Status.OK.getStatusCode(), restResponse.getStatus());
+    
+    Map<String, Map<String, String>> retrievedVariables = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().get(new GenericType<Map<String, Map<String, String>>>(Map.class));
+    
+    assertNotNull(retrievedVariables);
+    assertFalse(retrievedVariables.isEmpty());
+    
+    Map<String, String> retrievedVariablesMap = retrievedVariables.get("variables");
+    
+    assertNotNull(retrievedVariablesMap);
+    assertFalse(retrievedVariablesMap.isEmpty());
+    
+    assertTrue(retrievedVariablesMap.containsKey("variableA"));
+    assertTrue("valueA".equals(retrievedVariablesMap.get("variableA")));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java
new file mode 100644
index 0000000..aa8a696
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java
@@ -0,0 +1,202 @@
+/**
+ * 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.ws.rs.resources;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.requests.SubmitQueryRequest;
+import org.apache.tajo.ws.rs.responses.GetSubmitQueryResponse;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import java.net.URI;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class TestTablesResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI tablesURI;
+	private URI queriesURI;
+	private URI sessionsURI;
+
+	private Client restClient;
+  
+  private static final String defaultDatabaseName = "testtablesdb";
+	private static final String tajoSessionIdHeaderName = "X-Tajo-Session";
+
+	public TestTablesResource() {
+    super(defaultDatabaseName);
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    tablesURI = new URI(restServiceURI + "/databases/" + defaultDatabaseName + "/tables");
+		queriesURI = new URI(restServiceURI + "/queries");
+		sessionsURI = new URI(restServiceURI + "/sessions");
+		restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+
+	private SubmitQueryRequest createNewQueryRequest(String query) throws Exception {
+		SubmitQueryRequest request = new SubmitQueryRequest();
+		request.setQuery(query);
+		return request;
+	}
+
+	private String generateNewSessionAndGetId() throws Exception {
+		NewSessionRequest request = new NewSessionRequest();
+		request.setUserName("tajo-user");
+		request.setDatabaseName(defaultDatabaseName);
+
+		NewSessionResponse response = restClient.target(sessionsURI)
+			.request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+		assertNotNull(response);
+		assertTrue(ResultCode.OK.equals(response.getResultCode()));
+		assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+		return response.getId();
+	}
+
+	private void createNewTableForTestCreateTable(String tableName, String sessionId) throws Exception {
+		String query = "create table " + tableName + " (column1 text)";
+		SubmitQueryRequest queryRequest = createNewQueryRequest(query);
+
+		GetSubmitQueryResponse response = restClient.target(queriesURI)
+			.request().header(tajoSessionIdHeaderName, sessionId)
+			.post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+				new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+		assertNotNull(response);
+		assertEquals(ResultCode.OK, response.getResultCode());
+	}
+
+  @Test
+  public void testGetAllTable() throws Exception {
+    String tableName = "testgetalltable";
+		String sessionId = generateNewSessionAndGetId();
+
+		createNewTableForTestCreateTable(tableName, sessionId);
+
+    Map<String, Collection<String>> tables = restClient.target(tablesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+
+    List<String> tableNames = (List<String>)tables.get("tables");
+    assertNotNull(tableNames);
+    assertTrue(!tableNames.isEmpty());
+
+    boolean tableFound = false;
+    for (String table: tableNames) {
+      if (StringUtils.equalsIgnoreCase(tableName, CatalogUtil.extractSimpleName(table))) {
+        tableFound = true;
+        break;
+      }
+    }
+    
+    assertTrue(tableFound);
+  }
+  
+  @Test
+  public void testGetTable() throws Exception {
+    String tableName = "testgettable";
+		String sessionId = generateNewSessionAndGetId();
+
+		createNewTableForTestCreateTable(tableName, sessionId);
+    
+    TableDesc selectedTable = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", tableName)
+        .request().get(new GenericType<TableDesc>(TableDesc.class));
+    
+    assertNotNull(selectedTable);
+    assertTrue(StringUtils.equalsIgnoreCase(tableName, CatalogUtil.extractSimpleName(selectedTable.getName())));
+  }
+  
+  @Test
+  public void testGetTableNotFound() throws Exception {
+    Response response = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", "TestGetTableNotFound")
+        .request().get();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropTable() throws Exception {
+    String tableName = "testdroptable";
+		String sessionId = generateNewSessionAndGetId();
+
+		createNewTableForTestCreateTable(tableName, sessionId);
+    
+    TableDesc selectedTable = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", tableName)
+        .request().get(new GenericType<TableDesc>(TableDesc.class));
+    
+    assertNotNull(selectedTable);
+    assertTrue(StringUtils.equalsIgnoreCase(tableName, CatalogUtil.extractSimpleName(selectedTable.getName())));
+    
+    Response response = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", tableName)
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.OK.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropTableNotFound() throws Exception {
+    Response response = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", "TestDropTableNotFound")
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl
new file mode 100644
index 0000000..59f652e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl
@@ -0,0 +1 @@
+aaa+AAA|bbb+BBB|ccc

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl
new file mode 100644
index 0000000..8095c0b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl
new file mode 100644
index 0000000..953ee3d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl
@@ -0,0 +1,3 @@
+4|jkl|7
+5|opq|8
+6|stu|9
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data b/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data
new file mode 100644
index 0000000..417d480
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data
@@ -0,0 +1,4 @@
+010
+040
+060
+080
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl
new file mode 100644
index 0000000..6405b31
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl
@@ -0,0 +1,5 @@
+1|ooo|1.1|a
+2|ppp|2.3|b
+3|qqq|3.4|c
+4|rrr|4.5|d
+5|xxx|5.6|e
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl
new file mode 100644
index 0000000..68340bf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl
@@ -0,0 +1,4 @@
+1|NULL|NULL|a
+2|NULL|NULL|b
+NULL|NULL|10.0|c
+NULL|NULL|20.0|d
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl
new file mode 100644
index 0000000..63db89d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl
@@ -0,0 +1,5 @@
+1|ooo|1.1|a|127.0.0.1
+2|ppp|2.3|b|127.0.1.1
+3|qqq|3.4|c|127.0.0.8
+4|rrr|4.5|d|127.0.0.1
+5|xxx|5.6|e|127.0.1.1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl
new file mode 100644
index 0000000..9d46bc0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl
@@ -0,0 +1,5 @@
+1|NULL|NULL|a|127.0.0.8
+2|NULL|NULL|b|127.0.0.8
+NULL|NULL|10.0|c|NULL
+NULL|NULL|20.0|d|127.0.0.1
+NULL|NULL|20.0|d|255.255.255.255
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json
new file mode 100644
index 0000000..db3ad6c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json
@@ -0,0 +1,3 @@
+{ "title" : "Hand of the King", "name" : { "first_name": "Eddard", "last_name": "Stark"}}
+{ "title" : "Assassin", "name" : { "first_name": "Arya", "last_name": "Stark"}}
+{ "title" : "Dancing Master", "name" : { "first_name": "Syrio", "last_name": "Forel"}}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json
new file mode 100644
index 0000000..20bab62
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json
@@ -0,0 +1 @@
+{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }
\ No newline at end of file


[14/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..5a0c312
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort.plan
new file mode 100644
index 0000000..d1c32a0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..5a0c312
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Sort_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.result
new file mode 100644
index 0000000..a7dd7b5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.result
@@ -0,0 +1,27 @@
+c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment
+-------------------------------
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash.plan
new file mode 100644
index 0000000..4997c1d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..f0e930f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Hash_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+  => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+  => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort.plan
new file mode 100644
index 0000000..4997c1d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..f0e930f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.Sort_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+  => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+  => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.result
new file mode 100644
index 0000000..8e08403
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk4.result
@@ -0,0 +1,27 @@
+len,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment,?multiply
+-------------------------------
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s,50
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca,50
+45,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse,10
+45,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse,20
+45,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse,30
+45,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse,40
+45,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse,50
+108,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,10
+108,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,20
+108,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,30
+108,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,40
+108,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,50
+115,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,10
+115,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,20
+115,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,30
+115,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,40
+115,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,50

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash.plan
new file mode 100644
index 0000000..988980c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.empty_orders
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================


[30/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java b/tajo-core-tests/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
new file mode 100644
index 0000000..b139645
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
@@ -0,0 +1,135 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     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.master;
+
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.benchmark.TPCH;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.global.ExecutionBlock;
+import org.apache.tajo.engine.planner.global.ExecutionBlockCursor;
+import org.apache.tajo.engine.planner.global.GlobalPlanner;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.assertEquals;
+
+public class TestExecutionBlockCursor {
+  private static TajoTestingCluster util;
+  private static TajoConf conf;
+  private static CatalogService catalog;
+  private static GlobalPlanner planner;
+  private static SQLAnalyzer analyzer;
+  private static LogicalPlanner logicalPlanner;
+  private static LogicalOptimizer optimizer;
+  private static AsyncDispatcher dispatcher;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+
+    conf = util.getConfiguration();
+    conf.set(TajoConf.ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname, "false");
+
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:!234/warehouse");
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    TPCH tpch = new TPCH();
+    tpch.loadSchemas();
+    tpch.loadOutSchema();
+    for (String table : tpch.getTableNames()) {
+      TableMeta m = CatalogUtil.newTableMeta("TEXT");
+      TableDesc d = CatalogUtil.newTableDesc(
+          CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, table), tpch.getSchema(table), m, CommonTestingUtil.getTestDir());
+      TableStats stats = new TableStats();
+      stats.setNumBytes(TPCH.tableVolumes.get(table));
+      d.setStats(stats);
+      catalog.createTable(d);
+    }
+
+    analyzer = new SQLAnalyzer();
+    logicalPlanner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(conf, catalog);
+
+    dispatcher = new AsyncDispatcher();
+    dispatcher.init(conf);
+    dispatcher.start();
+    planner = new GlobalPlanner(conf, catalog);
+  }
+
+  @AfterClass
+  public static void tearDown() {
+    util.shutdownCatalogCluster();
+    if (dispatcher != null) {
+      dispatcher.stop();
+    }
+  }
+
+  @Test
+  public void testNextBlock() throws Exception {
+    Expr context = analyzer.parse(
+        "select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment, ps_supplycost, " +
+            "r_name, p_type, p_size " +
+            "from region join nation on n_regionkey = r_regionkey and r_name = 'AMERICA' " +
+            "join supplier on s_nationkey = n_nationkey " +
+            "join partsupp on s_suppkey = ps_suppkey " +
+            "join part on p_partkey = ps_partkey and p_type like '%BRASS' and p_size = 15");
+    LogicalPlan logicalPlan = logicalPlanner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), context);
+    optimizer.optimize(logicalPlan);
+    QueryContext queryContext = new QueryContext(conf);
+    MasterPlan plan = new MasterPlan(LocalTajoTestingUtility.newQueryId(), queryContext, logicalPlan);
+    planner.build(queryContext, plan);
+
+    ExecutionBlockCursor cursor = new ExecutionBlockCursor(plan);
+
+    int count = 0;
+    for (ExecutionBlock eb : cursor) {
+      count++;
+    }
+
+    /*
+     |-eb_0000000000000_0001_000010
+       |-eb_0000000000000_0001_000009
+          |-eb_0000000000000_0001_000008
+          |-eb_0000000000000_0001_000007
+             |-eb_0000000000000_0001_000006
+                |-eb_0000000000000_0001_000005
+                |-eb_0000000000000_0001_000004
+             |-eb_0000000000000_0001_000003
+                |-eb_0000000000000_0001_000002
+                |-eb_0000000000000_0001_000001
+     */
+    assertEquals(10, count);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/master/TestNonForwardQueryResultSystemScanner.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/master/TestNonForwardQueryResultSystemScanner.java b/tajo-core-tests/src/test/java/org/apache/tajo/master/TestNonForwardQueryResultSystemScanner.java
new file mode 100644
index 0000000..207f64d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/master/TestNonForwardQueryResultSystemScanner.java
@@ -0,0 +1,41 @@
+/**
+ * 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.master;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+
+public class TestNonForwardQueryResultSystemScanner extends QueryTestCaseBase {
+  @Test
+  public void testGetNextRowsForAggregateFunction() throws Exception {
+    assertQueryStr("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
+        "WHERE TABLE_NAME = 'lineitem' OR TABLE_NAME = 'nation' OR TABLE_NAME = 'customer'");
+  }
+
+  @Test
+  public void testGetNextRowsForTable() throws Exception {
+    assertQueryStr("SELECT TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES " +
+        "WHERE TABLE_NAME = 'lineitem' OR TABLE_NAME = 'nation' OR TABLE_NAME = 'customer'");
+  }
+
+  @Test
+  public void testGetClusterDetails() throws Exception {
+    assertQueryStr("SELECT TYPE FROM INFORMATION_SCHEMA.CLUSTER");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/master/TestRepartitioner.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/master/TestRepartitioner.java b/tajo-core-tests/src/test/java/org/apache/tajo/master/TestRepartitioner.java
new file mode 100644
index 0000000..36942a4
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/master/TestRepartitioner.java
@@ -0,0 +1,511 @@
+/**
+ * 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.master;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import io.netty.handler.codec.http.QueryStringDecoder;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.ResourceProtos.FetchProto;
+import org.apache.tajo.TestTajoIds;
+import org.apache.tajo.querymaster.Repartitioner;
+import org.apache.tajo.querymaster.Task;
+import org.apache.tajo.querymaster.Task.IntermediateEntry;
+import org.apache.tajo.util.Pair;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.FetchImpl;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.*;
+
+import static junit.framework.Assert.assertEquals;
+import static org.apache.tajo.plan.serder.PlanProto.ShuffleType;
+import static org.apache.tajo.plan.serder.PlanProto.ShuffleType.HASH_SHUFFLE;
+import static org.apache.tajo.plan.serder.PlanProto.ShuffleType.SCATTERED_HASH_SHUFFLE;
+import static org.apache.tajo.querymaster.Repartitioner.FetchGroupMeta;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestRepartitioner {
+  @Test
+  public void testCreateHashFetchURL() throws Exception {
+    QueryId q1 = TestTajoIds.createQueryId(1315890136000l, 2);
+    String hostName = "tajo1";
+    int port = 1234;
+    ExecutionBlockId sid = new ExecutionBlockId(q1, 2);
+    int numPartition = 10;
+
+    Map<Integer, List<IntermediateEntry>> intermediateEntries = new HashMap<Integer, List<IntermediateEntry>>();
+    for (int i = 0; i < numPartition; i++) {
+      intermediateEntries.put(i, new ArrayList<IntermediateEntry>());
+    }
+    for (int i = 0; i < 1000; i++) {
+      int partitionId = i % numPartition;
+      IntermediateEntry entry = new IntermediateEntry(i, 0, partitionId, new Task.PullHost(hostName, port));
+      entry.setEbId(sid);
+      entry.setVolume(10);
+      intermediateEntries.get(partitionId).add(entry);
+    }
+
+    Map<Integer, Map<ExecutionBlockId, List<IntermediateEntry>>> hashEntries =
+        new HashMap<Integer, Map<ExecutionBlockId, List<IntermediateEntry>>>();
+
+    for (Map.Entry<Integer, List<IntermediateEntry>> eachEntry: intermediateEntries.entrySet()) {
+      FetchImpl fetch = new FetchImpl(new Task.PullHost(hostName, port), ShuffleType.HASH_SHUFFLE,
+          sid, eachEntry.getKey(), eachEntry.getValue());
+
+      fetch.setName(sid.toString());
+
+      FetchProto proto = fetch.getProto();
+      fetch = new FetchImpl(proto);
+      assertEquals(proto, fetch.getProto());
+
+      Map<ExecutionBlockId, List<IntermediateEntry>> ebEntries = new HashMap<ExecutionBlockId, List<IntermediateEntry>>();
+      ebEntries.put(sid, eachEntry.getValue());
+
+      hashEntries.put(eachEntry.getKey(), ebEntries);
+
+      List<URI> uris = fetch.getURIs();
+      assertEquals(1, uris.size());   //In Hash Suffle, Fetcher return only one URI per partition.
+
+      URI uri = uris.get(0);
+      final Map<String, List<String>> params =
+          new QueryStringDecoder(uri).parameters();
+
+      assertEquals(eachEntry.getKey().toString(), params.get("p").get(0));
+      assertEquals("h", params.get("type").get(0));
+      assertEquals("" + sid.getId(), params.get("sid").get(0));
+    }
+
+    Map<Integer, Map<ExecutionBlockId, List<IntermediateEntry>>> mergedHashEntries =
+        Repartitioner.mergeIntermediateByPullHost(hashEntries);
+
+    assertEquals(numPartition, mergedHashEntries.size());
+    for (int i = 0; i < numPartition; i++) {
+      Map<ExecutionBlockId, List<IntermediateEntry>> eachEntry = mergedHashEntries.get(0);
+      assertEquals(1, eachEntry.size());
+      List<IntermediateEntry> interEntry = eachEntry.get(sid);
+      assertEquals(1, interEntry.size());
+
+      assertEquals(1000, interEntry.get(0).getVolume());
+    }
+  }
+
+  @Test
+  public void testScheduleFetchesByEvenDistributedVolumes() {
+    Map<Integer, FetchGroupMeta> fetchGroups = Maps.newHashMap();
+    String tableName = "test1";
+
+
+    ExecutionBlockId ebId = new ExecutionBlockId(LocalTajoTestingUtility.newQueryId(), 0);
+    FetchImpl [] fetches = new FetchImpl[12];
+    for (int i = 0; i < 12; i++) {
+      fetches[i] = new FetchImpl(new Task.PullHost("localhost", 10000 + i), HASH_SHUFFLE, ebId, i / 2);
+    }
+
+    int [] VOLUMES = {100, 80, 70, 30, 10, 5};
+
+    for (int i = 0; i < 12; i += 2) {
+      fetchGroups.put(i, new FetchGroupMeta(VOLUMES[i / 2], fetches[i]).addFetche(fetches[i + 1]));
+    }
+
+    Pair<Long [], Map<String, List<FetchImpl>>[]> results;
+
+    results = Repartitioner.makeEvenDistributedFetchImpl(fetchGroups, tableName, 1);
+    long expected [] = {100 + 80 + 70 + 30 + 10 + 5};
+    assertFetchVolumes(expected, results.getFirst());
+    assertFetchImpl(fetches, results.getSecond());
+
+    results = Repartitioner.makeEvenDistributedFetchImpl(fetchGroups, tableName, 2);
+    long expected0 [] = {140, 155};
+    assertFetchVolumes(expected0, results.getFirst());
+    assertFetchImpl(fetches, results.getSecond());
+
+    results = Repartitioner.makeEvenDistributedFetchImpl(fetchGroups, tableName, 3);
+    long expected1 [] = {100, 95, 100};
+    assertFetchVolumes(expected1, results.getFirst());
+    assertFetchImpl(fetches, results.getSecond());
+
+    results = Repartitioner.makeEvenDistributedFetchImpl(fetchGroups, tableName, 4);
+    long expected2 [] = {100, 80, 70, 45};
+    assertFetchVolumes(expected2, results.getFirst());
+    assertFetchImpl(fetches, results.getSecond());
+
+    results = Repartitioner.makeEvenDistributedFetchImpl(fetchGroups, tableName, 5);
+    long expected3 [] = {100, 80, 70, 30, 15};
+    assertFetchVolumes(expected3, results.getFirst());
+    assertFetchImpl(fetches, results.getSecond());
+
+    results = Repartitioner.makeEvenDistributedFetchImpl(fetchGroups, tableName, 6);
+    long expected4 [] = {100, 80, 70, 30, 10, 5};
+    assertFetchVolumes(expected4, results.getFirst());
+    assertFetchImpl(fetches, results.getSecond());
+  }
+
+  private static void assertFetchVolumes(long [] expected, Long [] results) {
+    assertEquals("the lengths of volumes are mismatch", expected.length, results.length);
+
+    for (int i = 0; i < expected.length; i++) {
+      assertTrue(expected[i] + " is expected, but " + results[i], expected[i] == results[i]);
+    }
+  }
+
+  @Test
+  public void testMergeIntermediates() {
+    //Test Merge
+    List<IntermediateEntry> intermediateEntries = new ArrayList<IntermediateEntry>();
+
+    int[] pageLengths = {10 * 1024 * 1024, 10 * 1024 * 1024, 10 * 1024 * 1024, 5 * 1024 * 1024};   //35 MB
+    long expectedTotalLength = 0;
+    for (int i = 0; i < 20; i++) {
+      List<Pair<Long, Integer>> pages = new ArrayList<Pair<Long, Integer>>();
+      long offset = 0;
+      for (int j = 0; j < pageLengths.length; j++) {
+        pages.add(new Pair(offset, pageLengths[j]));
+        offset += pageLengths[j];
+        expectedTotalLength += pageLengths[j];
+      }
+      IntermediateEntry interm = new IntermediateEntry(i, -1, -1, new Task.PullHost("" + i, i));
+      interm.setPages(pages);
+      interm.setVolume(offset);
+      intermediateEntries.add(interm);
+    }
+
+    long splitVolume = 128 * 1024 * 1024;
+    List<List<FetchImpl>> fetches = Repartitioner.splitOrMergeIntermediates(null, intermediateEntries,
+        splitVolume, 10 * 1024 * 1024);
+    assertEquals(6, fetches.size());
+
+    int totalInterms = 0;
+    int index = 0;
+    int numZeroPosFetcher = 0;
+    long totalLength = 0;
+    for (List<FetchImpl> eachFetchList: fetches) {
+      totalInterms += eachFetchList.size();
+      long eachFetchVolume = 0;
+      for (FetchImpl eachFetch: eachFetchList) {
+        eachFetchVolume += eachFetch.getLength();
+        if (eachFetch.getOffset() == 0) {
+          numZeroPosFetcher++;
+        }
+        totalLength += eachFetch.getLength();
+      }
+      assertTrue(eachFetchVolume + " should be smaller than splitVolume", eachFetchVolume < splitVolume);
+      if (index < fetches.size() - 1) {
+        assertTrue(eachFetchVolume + " should be great than 100MB", eachFetchVolume >= 100 * 1024 * 1024);
+      }
+      index++;
+    }
+    assertEquals(23, totalInterms);
+    assertEquals(20, numZeroPosFetcher);
+    assertEquals(expectedTotalLength, totalLength);
+  }
+
+  @Test
+  public void testSplitIntermediates() {
+    List<IntermediateEntry> intermediateEntries = new ArrayList<IntermediateEntry>();
+
+    int[] pageLengths = new int[20];  //195MB
+    for (int i = 0 ; i < pageLengths.length; i++) {
+      if (i < pageLengths.length - 1) {
+        pageLengths[i] =  10 * 1024 * 1024;
+      } else {
+        pageLengths[i] =  5 * 1024 * 1024;
+      }
+    }
+
+    long expectedTotalLength = 0;
+    for (int i = 0; i < 20; i++) {
+      List<Pair<Long, Integer>> pages = new ArrayList<Pair<Long, Integer>>();
+      long offset = 0;
+      for (int j = 0; j < pageLengths.length; j++) {
+        pages.add(new Pair(offset, pageLengths[j]));
+        offset += pageLengths[j];
+        expectedTotalLength += pageLengths[j];
+      }
+      IntermediateEntry interm = new IntermediateEntry(i, -1, 0, new Task.PullHost("" + i, i));
+      interm.setPages(pages);
+      interm.setVolume(offset);
+      intermediateEntries.add(interm);
+    }
+
+    long splitVolume = 128 * 1024 * 1024;
+    List<List<FetchImpl>> fetches = Repartitioner.splitOrMergeIntermediates(null, intermediateEntries,
+        splitVolume, 10 * 1024 * 1024);
+    assertEquals(32, fetches.size());
+
+    int index = 0;
+    int numZeroPosFetcher = 0;
+    long totalLength = 0;
+    Set<String> uniqPullHost = new HashSet<String>();
+
+    for (List<FetchImpl> eachFetchList: fetches) {
+      long length = 0;
+      for (FetchImpl eachFetch: eachFetchList) {
+        if (eachFetch.getOffset() == 0) {
+          numZeroPosFetcher++;
+        }
+        totalLength += eachFetch.getLength();
+        length += eachFetch.getLength();
+        uniqPullHost.add(eachFetch.getPullHost().toString());
+      }
+      assertTrue(length + " should be smaller than splitVolume", length < splitVolume);
+      if (index < fetches.size() - 1) {
+        assertTrue(length + " should be great than 100MB" + fetches.size() + "," + index, length >= 100 * 1024 * 1024);
+      }
+      index++;
+    }
+    assertEquals(20, numZeroPosFetcher);
+    assertEquals(20, uniqPullHost.size());
+    assertEquals(expectedTotalLength, totalLength);
+  }
+
+  @Test
+  public void testSplitIntermediates2() {
+    long[][] pageDatas = {
+        {0, 10538717},
+        {10538717, 10515884},
+        {21054601, 10514343},
+        {31568944, 10493988},
+        {42062932, 10560639},
+        {52623571, 10548486},
+        {63172057, 10537811},
+        {73709868, 10571060},
+        {84280928, 10515062},
+        {94795990, 10502964},
+        {105298954, 10514011},
+        {115812965, 10532154},
+        {126345119, 10534133},
+        {136879252, 10549749},
+        {147429001, 10566547},
+        {157995548, 10543700},
+        {168539248, 10490324},
+        {179029572, 10500720},
+        {189530292, 10505425},
+        {200035717, 10548418},
+        {210584135, 10562887},
+        {221147022, 10554967},
+        {231701989, 10507297},
+        {242209286, 10515612},
+        {252724898, 10491274},
+        {263216172, 10512956},
+        {273729128, 10490736},
+        {284219864, 10501878},
+        {294721742, 10564568},
+        {305286310, 10488896},
+        {315775206, 10516308},
+        {326291514, 10517965},
+        {336809479, 10487038},
+        {347296517, 10603472},
+        {357899989, 10507330},
+        {368407319, 10549429},
+        {378956748, 10533443},
+        {389490191, 10530852},
+        {400021043, 11036431},
+        {411057474, 10541007},
+        {421598481, 10600477},
+        {432198958, 10519805},
+        {442718763, 10500769},
+        {453219532, 10507192},
+        {463726724, 10540424},
+        {474267148, 10509129},
+        {484776277, 10527100},
+        {495303377, 10720789},
+        {506024166, 10568542},
+        {516592708, 11046886},
+        {527639594, 10580358},
+        {538219952, 10508940},
+        {548728892, 10523968},
+        {559252860, 10580626},
+        {569833486, 10539361},
+        {580372847, 10496662},
+        {590869509, 10505280},
+        {601374789, 10564655},
+        {611939444, 10505842},
+        {622445286, 10523889},
+        {632969175, 10553186},
+        {643522361, 10535866},
+        {654058227, 10501796},
+        {664560023, 10530358},
+        {675090381, 10585340},
+        {685675721, 10602017},
+        {696277738, 10546614},
+        {706824352, 10511511},
+        {717335863, 11019221},
+        {728355084, 10558143},
+        {738913227, 10516245},
+        {749429472, 10502613},
+        {759932085, 10522145},
+        {770454230, 10489373},
+        {780943603, 10520973},
+        {791464576, 11021218},
+        {802485794, 10496362},
+        {812982156, 10502354},
+        {823484510, 10515932},
+        {834000442, 10591044},
+        {844591486, 5523957}
+    };
+
+    List<IntermediateEntry> entries = new ArrayList<IntermediateEntry>();
+    for (int i = 0; i < 2; i++) {
+      List<Pair<Long, Integer>> pages = new ArrayList<Pair<Long, Integer>>();
+      for (int j = 0; j < pageDatas.length; j++) {
+        pages.add(new Pair(pageDatas[j][0], (int) (pageDatas[j][1])));
+      }
+      IntermediateEntry entry = new IntermediateEntry(-1, -1, 1, new Task.PullHost("host" + i , 9000));
+      entry.setPages(pages);
+
+      entries.add(entry);
+    }
+
+    long splitVolume = 256 * 1024 * 1024;
+    List<List<FetchImpl>> fetches = Repartitioner.splitOrMergeIntermediates(null, entries, splitVolume,
+        10 * 1024 * 1024);
+
+
+    long[][] expected = {
+        {0,263216172},
+        {263216172,264423422},
+        {527639594,263824982},
+        {791464576,58650867},
+        {0,200035717},
+        {200035717,263691007},
+        {463726724,264628360},
+        {728355084,121760359},
+    };
+    int index = 0;
+    for (List<FetchImpl> eachFetchList: fetches) {
+      if (index == 3) {
+        assertEquals(2, eachFetchList.size());
+      } else {
+        assertEquals(1, eachFetchList.size());
+      }
+      for (FetchImpl eachFetch: eachFetchList) {
+        assertEquals(expected[index][0], eachFetch.getOffset());
+        assertEquals(expected[index][1], eachFetch.getLength());
+        index++;
+      }
+    }
+  }
+
+  @Test
+  public void testSplitIntermediatesWithUniqueHost() {
+    List<IntermediateEntry> intermediateEntries = new ArrayList<IntermediateEntry>();
+
+    int[] pageLengths = new int[20];  //195MB
+    for (int i = 0 ; i < pageLengths.length; i++) {
+      if (i < pageLengths.length - 1) {
+        pageLengths[i] =  10 * 1024 * 1024;
+      } else {
+        pageLengths[i] =  5 * 1024 * 1024;
+      }
+    }
+
+    long expectedTotalLength = 0;
+    Task.PullHost pullHost = new Task.PullHost("host", 0);
+
+    for (int i = 0; i < 20; i++) {
+      List<Pair<Long, Integer>> pages = new ArrayList<Pair<Long, Integer>>();
+      long offset = 0;
+      for (int j = 0; j < pageLengths.length; j++) {
+        pages.add(new Pair(offset, pageLengths[j]));
+        offset += pageLengths[j];
+        expectedTotalLength += pageLengths[j];
+      }
+      IntermediateEntry interm = new IntermediateEntry(i, -1, 0, pullHost);
+      interm.setPages(pages);
+      interm.setVolume(offset);
+      intermediateEntries.add(interm);
+    }
+
+    long splitVolume = 128 * 1024 * 1024;
+    List<List<FetchImpl>> fetches = Repartitioner.splitOrMergeIntermediates(null, intermediateEntries,
+        splitVolume, 10 * 1024 * 1024);
+    assertEquals(32, fetches.size());
+
+    int expectedSize = 0;
+    Set<FetchImpl> fetchSet = TUtil.newHashSet();
+    for(List<FetchImpl> list : fetches){
+      expectedSize += list.size();
+      fetchSet.addAll(list);
+    }
+    assertEquals(expectedSize, fetchSet.size());
+
+
+    int index = 0;
+    int numZeroPosFetcher = 0;
+    long totalLength = 0;
+    Set<String> uniqPullHost = new HashSet<String>();
+
+    for (List<FetchImpl> eachFetchList: fetches) {
+      long length = 0;
+      for (FetchImpl eachFetch: eachFetchList) {
+        if (eachFetch.getOffset() == 0) {
+          numZeroPosFetcher++;
+        }
+        totalLength += eachFetch.getLength();
+        length += eachFetch.getLength();
+        uniqPullHost.add(eachFetch.getPullHost().toString());
+      }
+      assertTrue(length + " should be smaller than splitVolume", length < splitVolume);
+      if (index < fetches.size() - 1) {
+        assertTrue(length + " should be great than 100MB" + fetches.size() + "," + index, length >= 100 * 1024 * 1024);
+      }
+      index++;
+    }
+    assertEquals(20, numZeroPosFetcher);
+    assertEquals(1, uniqPullHost.size());
+    assertEquals(expectedTotalLength, totalLength);
+  }
+
+  @Test
+  public void testFetchImpl() {
+    ExecutionBlockId ebId = new ExecutionBlockId(LocalTajoTestingUtility.newQueryId(), 0);
+    Task.PullHost pullHost = new Task.PullHost("localhost", 0);
+
+    FetchImpl expected = new FetchImpl(pullHost, SCATTERED_HASH_SHUFFLE, ebId, 1);
+    FetchImpl fetch2 = new FetchImpl(pullHost, SCATTERED_HASH_SHUFFLE, ebId, 1);
+    assertEquals(expected, fetch2);
+    fetch2.setOffset(5);
+    fetch2.setLength(10);
+    assertNotEquals(expected, fetch2);
+  }
+
+  private static void assertFetchImpl(FetchImpl [] expected, Map<String, List<FetchImpl>>[] result) {
+    Set<FetchImpl> expectedURLs = Sets.newHashSet();
+
+    for (FetchImpl f : expected) {
+      expectedURLs.add(f);
+    }
+
+    Set<FetchImpl> resultURLs = Sets.newHashSet();
+
+    for (Map<String, List<FetchImpl>> e : result) {
+      for (List<FetchImpl> list : e.values()) {
+        resultURLs.addAll(list);
+      }
+    }
+
+    assertEquals(expectedURLs.size(), resultURLs.size());
+    assertEquals(expectedURLs, resultURLs);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/master/rule/TestMasterRules.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/master/rule/TestMasterRules.java b/tajo-core-tests/src/test/java/org/apache/tajo/master/rule/TestMasterRules.java
new file mode 100644
index 0000000..dc34620
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/master/rule/TestMasterRules.java
@@ -0,0 +1,156 @@
+/**
+ * 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.master.rule;
+
+import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.rule.EvaluationContext;
+import org.apache.tajo.rule.EvaluationFailedException;
+import org.apache.tajo.rule.EvaluationResult;
+import org.apache.tajo.rule.EvaluationResult.EvaluationResultCode;
+import org.apache.tajo.rule.SelfDiagnosisRuleEngine;
+import org.apache.tajo.rule.SelfDiagnosisRuleSession;
+import org.apache.tajo.rule.base.TajoConfValidationRule;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestMasterRules {
+  
+  private static Path rootFilePath;
+  
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    rootFilePath = CommonTestingUtil.getTestDir();
+  }
+  
+  @AfterClass
+  public static void tearDownClass() throws Exception {
+    CommonTestingUtil.cleanupTestDir(rootFilePath.toUri().getPath());
+  }
+
+  @Test
+  public void testTajoConfValidationRule() throws Exception {
+    TajoConf tajoConf = new TajoConf(new YarnConfiguration());
+    
+    EvaluationContext context = new EvaluationContext();
+    context.addParameter(TajoConf.class.getName(), tajoConf);
+    
+    TajoConfValidationRule validationRule = new TajoConfValidationRule();
+    EvaluationResult result = validationRule.evaluate(context);
+    
+    assertThat(result, is(notNullValue()));
+    assertThat(result.getReturnCode(), is(EvaluationResultCode.OK));
+  }
+  
+  @Test(expected=EvaluationFailedException.class)
+  public void testTajoConfValidationRuleWithException() throws Exception {
+    TajoConf tajoConf = new TajoConf(new YarnConfiguration());
+    SelfDiagnosisRuleEngine ruleEngine = SelfDiagnosisRuleEngine.getInstance();
+    SelfDiagnosisRuleSession ruleSession = ruleEngine.newRuleSession();
+    
+    tajoConf.setVar(TajoConf.ConfVars.ROOT_DIR, "invalid path.");
+    
+    EvaluationContext context = new EvaluationContext();
+    context.addParameter(TajoConf.class.getName(), tajoConf);
+    
+    ruleSession.withRuleNames("TajoConfValidationRule").fireRules(context);
+    
+    fail("EvaluationFailedException exception is expected, but it does not happen.");
+  }
+  
+  protected void createTajoDirectories(TajoConf tajoConf) throws Exception {
+    Path tajoRootDir = new Path(rootFilePath, "tajo-root");
+    FileSystem rootFs = tajoRootDir.getFileSystem(tajoConf);
+    FsPermission defaultPermission = FsPermission.createImmutable((short)0700);
+    
+    if (!rootFs.exists(tajoRootDir)) {
+      rootFs.mkdirs(tajoRootDir, new FsPermission(defaultPermission));
+    }
+    
+    tajoConf.setVar(ConfVars.ROOT_DIR, tajoRootDir.toUri().toString());
+    
+    Path tajoSystemDir = new Path(tajoRootDir, TajoConstants.SYSTEM_DIR_NAME);
+    if (!rootFs.exists(tajoSystemDir)) {
+      rootFs.mkdirs(tajoSystemDir, new FsPermission(defaultPermission));
+    }
+    
+    Path tajoSystemResourceDir = new Path(tajoSystemDir, TajoConstants.SYSTEM_RESOURCE_DIR_NAME);
+    if (!rootFs.exists(tajoSystemResourceDir)) {
+      rootFs.mkdirs(tajoSystemResourceDir, new FsPermission(defaultPermission));
+    }
+    
+    Path tajoWarehouseDir = new Path(tajoRootDir, TajoConstants.WAREHOUSE_DIR_NAME);
+    if (!rootFs.exists(tajoWarehouseDir)) {
+      rootFs.mkdirs(tajoWarehouseDir, new FsPermission(defaultPermission));
+    }
+    
+    Path tajoStagingDir = new Path(tajoRootDir, "staging");
+    if (!rootFs.exists(tajoStagingDir)) {
+      rootFs.mkdirs(tajoStagingDir, new FsPermission(defaultPermission));
+    }
+    tajoConf.setVar(ConfVars.STAGING_ROOT_DIR, tajoStagingDir.toUri().toString());
+  }
+  
+  @Test
+  public void testFileSystemRule() throws Exception {
+    TajoConf tajoConf = new TajoConf(new YarnConfiguration());
+    
+    createTajoDirectories(tajoConf);
+    
+    EvaluationContext context = new EvaluationContext();
+    context.addParameter(TajoConf.class.getName(), tajoConf);
+    
+    FileSystemRule fsRule = new FileSystemRule();
+    EvaluationResult result = fsRule.evaluate(context);
+    
+    assertThat(result, is(notNullValue()));
+    assertThat(result.getReturnCode(), is(EvaluationResultCode.OK));
+  }
+  
+  @Test
+  public void testFileSystemRuleWithError() throws Exception {
+    TajoConf tajoConf = new TajoConf(new YarnConfiguration());
+    
+    createTajoDirectories(tajoConf);
+    Path systemResourceDir = TajoConf.getSystemResourceDir(tajoConf);
+    FileSystem defaultFs = systemResourceDir.getFileSystem(tajoConf);
+    if (defaultFs.exists(systemResourceDir)) {
+      defaultFs.delete(systemResourceDir, true);
+    }
+    
+    EvaluationContext context = new EvaluationContext();
+    context.addParameter(TajoConf.class.getName(), tajoConf);
+    
+    FileSystemRule fsRule = new FileSystemRule();
+    EvaluationResult result = fsRule.evaluate(context);
+    
+    assertThat(result, is(notNullValue()));
+    assertThat(result.getReturnCode(), is(EvaluationResultCode.ERROR));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/master/scheduler/TestSimpleScheduler.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/master/scheduler/TestSimpleScheduler.java b/tajo-core-tests/src/test/java/org/apache/tajo/master/scheduler/TestSimpleScheduler.java
new file mode 100644
index 0000000..328c281
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/master/scheduler/TestSimpleScheduler.java
@@ -0,0 +1,301 @@
+/**
+ * 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.master.scheduler;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.annotation.NotThreadSafe;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.master.QueryInfo;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.master.rm.*;
+import org.apache.tajo.master.scheduler.event.ResourceReserveSchedulerEvent;
+import org.apache.tajo.master.scheduler.event.SchedulerEvent;
+import org.apache.tajo.master.scheduler.event.SchedulerEventType;
+import org.apache.tajo.resource.NodeResource;
+import org.apache.tajo.resource.NodeResources;
+import org.apache.tajo.rpc.CallFuture;
+import org.junit.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.*;
+
+import static org.apache.tajo.ResourceProtos.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@NotThreadSafe
+public class TestSimpleScheduler {
+  private CompositeService service;
+  private SimpleScheduler scheduler;
+  private TajoRMContext rmContext;
+  private AsyncDispatcher dispatcher;
+  private TajoConf conf;
+  private int workerNum = 3;
+  private NodeResource nodeResource;
+  private NodeResource totalResource;
+  private Semaphore barrier;
+  private int testDelay = 50;
+  private static ScheduledExecutorService executorService;
+
+  @BeforeClass
+  public static void setupClass() {
+    executorService = Executors.newScheduledThreadPool(10);
+  }
+
+  @AfterClass
+  public static void tearDownClass() {
+    executorService.shutdown();
+  }
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    nodeResource = NodeResource.createResource(1500, 2, 3);
+    service = new CompositeService(TestSimpleScheduler.class.getSimpleName()) {
+
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        dispatcher = new AsyncDispatcher();
+        addService(dispatcher);
+
+        rmContext = new TajoRMContext(dispatcher);
+        rmContext.getDispatcher().register(NodeEventType.class,
+            new TajoResourceManager.WorkerEventDispatcher(rmContext));
+
+        barrier = new Semaphore(0);
+        scheduler = new MySimpleScheduler(rmContext, barrier);
+        addService(scheduler);
+        rmContext.getDispatcher().register(SchedulerEventType.class, scheduler);
+
+        for (int i = 0; i < workerNum; i++) {
+          WorkerConnectionInfo conn = new WorkerConnectionInfo("host" + i, 28091 + i, 28092, 21000, 28093, 28080);
+          rmContext.getNodes().putIfAbsent(conn.getId(),
+              new NodeStatus(rmContext, NodeResources.clone(nodeResource), conn));
+          rmContext.getDispatcher().getEventHandler().handle(new NodeEvent(conn.getId(), NodeEventType.STARTED));
+        }
+        super.serviceInit(conf);
+      }
+    };
+    service.init(conf);
+    service.start();
+
+    assertEquals(workerNum, rmContext.getNodes().size());
+    totalResource = NodeResources.createResource(0);
+    for(NodeStatus nodeStatus : rmContext.getNodes().values()) {
+      NodeResources.addTo(totalResource, nodeStatus.getTotalResourceCapability());
+    }
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test
+  public void testInitialCapacity() throws InterruptedException {
+    assertEquals(workerNum, scheduler.getNumClusterNodes());
+    assertEquals(0, scheduler.getRunningQuery());
+
+    assertEquals(totalResource, scheduler.getMaximumResourceCapability());
+    assertEquals(totalResource, scheduler.getClusterResource());
+
+    assertEquals(TajoConf.ConfVars.QUERYMASTER_MINIMUM_MEMORY.defaultIntVal,
+        scheduler.getQMMinimumResourceCapability().getMemory());
+
+    assertEquals(TajoConf.ConfVars.TASK_RESOURCE_MINIMUM_MEMORY.defaultIntVal,
+        scheduler.getMinimumResourceCapability().getMemory());
+  }
+
+  @Test(timeout = 10000)
+  public void testSubmitOneQuery() throws InterruptedException {
+    QuerySchedulingInfo schedulingInfo = new QuerySchedulingInfo("default",
+        "user",
+        QueryIdFactory.newQueryId(System.nanoTime(), 0),
+        1,
+        System.currentTimeMillis());
+
+    assertEquals(0, scheduler.getRunningQuery());
+
+    scheduler.submitQuery(schedulingInfo);
+    barrier.acquire();
+    assertEquals(1, scheduler.getRunningQuery());
+
+    assertEquals(totalResource, scheduler.getMaximumResourceCapability());
+    assertEquals(totalResource,
+        NodeResources.add(scheduler.getQMMinimumResourceCapability(), scheduler.getClusterResource()));
+  }
+
+  @Test(timeout = 10000)
+  public void testMaximumSubmitQuery() throws InterruptedException {
+    assertEquals(0, scheduler.getRunningQuery());
+    int maximumParallelQuery = scheduler.getResourceCalculator().computeAvailableContainers(
+        scheduler.getMaximumResourceCapability(), scheduler.getQMMinimumResourceCapability());
+
+    int testParallelNum = 10;
+    for (int i = 0; i < testParallelNum; i++) {
+      QuerySchedulingInfo schedulingInfo = new QuerySchedulingInfo("default",
+          "user",
+          QueryIdFactory.newQueryId(System.nanoTime(), 0),
+          1,
+          System.currentTimeMillis());
+      scheduler.submitQuery(schedulingInfo);
+    }
+
+    barrier.acquire();
+    // allow 50% parallel running
+    assertEquals(Math.floor(maximumParallelQuery * 0.5f), (double) scheduler.getRunningQuery(), 1.0f);
+    assertEquals(testParallelNum, scheduler.getRunningQuery() + scheduler.getQueryQueue().size());
+  }
+
+  @Test(timeout = 10000)
+  public void testReserveResource() throws InterruptedException, ExecutionException {
+    int requestNum = 3;
+    assertEquals(totalResource, scheduler.getMaximumResourceCapability());
+    assertEquals(totalResource, scheduler.getClusterResource());
+
+    QueryId queryId = QueryIdFactory.newQueryId(System.nanoTime(), 0);
+    CallFuture<NodeResourceResponse> callBack = new CallFuture<NodeResourceResponse>();
+    rmContext.getDispatcher().getEventHandler().handle(new ResourceReserveSchedulerEvent(
+        createResourceRequest(queryId, requestNum, new ArrayList<Integer>()), callBack));
+
+    NodeResourceResponse responseProto = callBack.get();
+    assertEquals(queryId, new QueryId(responseProto.getQueryId()));
+    assertEquals(requestNum, responseProto.getResourceCount());
+
+    NodeResource allocations = NodeResources.createResource(0);
+    for (AllocationResourceProto resourceProto : responseProto.getResourceList()) {
+      NodeResources.addTo(allocations, new NodeResource(resourceProto.getResource()));
+    }
+
+    assertEquals(NodeResources.subtract(totalResource, allocations), scheduler.getClusterResource());
+  }
+
+  @Test(timeout = 10000)
+  public void testReserveResourceWithWorkerPriority() throws InterruptedException, ExecutionException {
+    int requestNum = 2;
+    assertEquals(totalResource, scheduler.getMaximumResourceCapability());
+    assertEquals(totalResource, scheduler.getClusterResource());
+
+    List<Integer> targetWorkers = Lists.newArrayList();
+    Map.Entry<Integer, NodeStatus> workerEntry = rmContext.getNodes().entrySet().iterator().next();
+    targetWorkers.add(workerEntry.getKey());
+
+    NodeResource expectResource = NodeResources.multiply(scheduler.getMinimumResourceCapability(), requestNum);
+    assertTrue(NodeResources.fitsIn(expectResource, workerEntry.getValue().getAvailableResource()));
+
+    QueryId queryId = QueryIdFactory.newQueryId(System.nanoTime(), 0);
+    NodeResourceRequest requestProto = createResourceRequest(queryId, requestNum, targetWorkers);
+    CallFuture<NodeResourceResponse> callBack = new CallFuture<NodeResourceResponse>();
+    rmContext.getDispatcher().getEventHandler().handle(new ResourceReserveSchedulerEvent(
+        requestProto, callBack));
+
+    NodeResourceResponse responseProto = callBack.get();
+    assertEquals(queryId, new QueryId(responseProto.getQueryId()));
+    assertEquals(requestNum, responseProto.getResourceCount());
+
+    for (AllocationResourceProto resourceProto : responseProto.getResourceList()) {
+      assertEquals(workerEntry.getKey().intValue(), resourceProto.getWorkerId());
+    }
+  }
+
+  private NodeResourceRequest
+  createResourceRequest(QueryId queryId, int containerNum, List<Integer> candidateWorkers) {
+    NodeResourceRequest.Builder request =
+        NodeResourceRequest.newBuilder();
+    request.setCapacity(scheduler.getMinimumResourceCapability().getProto())
+        .setNumContainers(containerNum)
+        .setPriority(1)
+        .setQueryId(queryId.getProto())
+        .setType(ResourceType.LEAF)
+        .setUserId("test user")
+        .setRunningTasks(0)
+        .addAllCandidateNodes(candidateWorkers)
+        .setQueue("default");
+    return request.build();
+  }
+
+  class MySimpleScheduler extends SimpleScheduler {
+    Semaphore barrier;
+    Map<QueryId, QueryInfo> queryInfoMap = Maps.newHashMap();
+    Map<QueryId, AllocationResourceProto> qmAllocationMap = Maps.newHashMap();
+
+    public MySimpleScheduler(TajoRMContext rmContext, Semaphore barrier) {
+      super(null, rmContext);
+      this.barrier = barrier;
+    }
+
+    @Override
+    public void submitQuery(QuerySchedulingInfo schedulingInfo) {
+      queryInfoMap.put(schedulingInfo.getQueryId(), new QueryInfo(schedulingInfo.getQueryId()) {
+        QueryContext context;
+        @Override
+        public QueryContext getQueryContext() {
+          if(context == null) {
+            context = new QueryContext(conf);
+            context.setUser("user");
+          }
+          return context;
+        }
+      });
+      super.submitQuery(schedulingInfo);
+    }
+
+    @Override
+    protected boolean startQuery(final QueryId queryId, final AllocationResourceProto allocation) {
+      executorService.schedule(new Runnable() {
+        @Override
+        public void run() {
+          barrier.release();
+          qmAllocationMap.put(queryId, allocation);
+          rmContext.getDispatcher().getEventHandler().handle(new SchedulerEvent(SchedulerEventType.RESOURCE_UPDATE));
+        }
+      }, testDelay, TimeUnit.MILLISECONDS);
+      return true;
+    }
+
+    @Override
+    public void handle(SchedulerEvent event) {
+      super.handle(event);
+      barrier.release();
+    }
+
+    @Override
+    protected QueryInfo getQueryInfo(QueryId queryId) {
+      return queryInfoMap.get(queryId);
+    }
+
+    @Override
+    public void stopQuery(QueryId queryId) {
+      queryInfoMap.remove(queryId);
+      AllocationResourceProto allocationResourceProto = qmAllocationMap.remove(queryId);
+      NodeResources.addTo(rmContext.getNodes().get(allocationResourceProto.getWorkerId()).getAvailableResource(),
+          new NodeResource(allocationResourceProto.getResource()));
+      super.stopQuery(queryId);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestIntermediateEntry.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestIntermediateEntry.java b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestIntermediateEntry.java
new file mode 100644
index 0000000..237fb32
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestIntermediateEntry.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.querymaster;
+
+import org.apache.tajo.util.Pair;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestIntermediateEntry {
+  @Test
+  public void testPage() {
+    Task.IntermediateEntry interm = new Task.IntermediateEntry(-1, -1, 1, null);
+
+    List<Pair<Long, Integer>> pages = new ArrayList<Pair<Long, Integer>>();
+    pages.add(new Pair(0L, 1441275));
+    pages.add(new Pair(1441275L, 1447446));
+    pages.add(new Pair(2888721L, 1442507));
+
+    interm.setPages(pages);
+
+    long splitBytes = 3 * 1024 * 1024;
+
+    List<Pair<Long, Long>> splits = interm.split(splitBytes, splitBytes);
+    assertEquals(2, splits.size());
+
+    long[][] expected = { {0, 1441275 + 1447446}, {1441275 + 1447446, 1442507} };
+    for (int i = 0; i < 2; i++) {
+      Pair<Long, Long> eachSplit = splits.get(i);
+      assertEquals(expected[i][0], eachSplit.getFirst().longValue());
+      assertEquals(expected[i][1], eachSplit.getSecond().longValue());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestKillQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestKillQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestKillQuery.java
new file mode 100644
index 0000000..0e3e63e
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestKillQuery.java
@@ -0,0 +1,312 @@
+/**
+ * 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.querymaster;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.hadoop.yarn.event.Event;
+import org.apache.tajo.*;
+import org.apache.tajo.ResourceProtos.ExecutionBlockContextResponse;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.benchmark.TPCH;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.global.GlobalPlanner;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.engine.query.TaskRequestImpl;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.master.event.QueryEvent;
+import org.apache.tajo.master.event.QueryEventType;
+import org.apache.tajo.master.event.StageEvent;
+import org.apache.tajo.master.event.StageEventType;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.serder.PlanProto;
+import org.apache.tajo.resource.NodeResources;
+import org.apache.tajo.session.Session;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.worker.*;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+public class TestKillQuery {
+  private static TajoTestingCluster cluster;
+  private static TajoConf conf;
+  private static TajoClient client;
+  private static String queryStr = "select t1.l_orderkey, t1.l_partkey, t2.c_custkey " +
+      "from lineitem t1 join customer t2 " +
+      "on t1.l_orderkey = t2.c_custkey order by t1.l_orderkey";
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    cluster = new TajoTestingCluster();
+    cluster.startMiniClusterInLocal(1);
+    conf = cluster.getConfiguration();
+    client = cluster.newTajoClient();
+    File file = TPCH.getDataFile("lineitem");
+    client.executeQueryAndGetResult("create external table default.lineitem (l_orderkey int, l_partkey int) "
+        + "using text location 'file://" + file.getAbsolutePath() + "'");
+    assertTrue(client.existTable("default.lineitem"));
+
+    file = TPCH.getDataFile("customer");
+    client.executeQueryAndGetResult("create external table default.customer (c_custkey int, c_name text) "
+        + "using text location 'file://" + file.getAbsolutePath() + "'");
+    assertTrue(client.existTable("default.customer"));
+  }
+
+  @AfterClass
+  public static void tearDown() throws IOException {
+    if (client != null) client.close();
+    if (cluster != null) cluster.shutdownMiniCluster();
+  }
+
+  @Test
+  public final void testKillQueryFromInitState() throws Exception {
+    SQLAnalyzer analyzer = new SQLAnalyzer();
+    QueryContext defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+    Session session = LocalTajoTestingUtility.createDummySession();
+    CatalogService catalog = cluster.getMaster().getCatalog();
+
+    LogicalPlanner planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    LogicalOptimizer optimizer = new LogicalOptimizer(conf, catalog);
+    Expr expr =  analyzer.parse(queryStr);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+
+    optimizer.optimize(plan);
+
+    QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+    QueryContext queryContext = new QueryContext(conf);
+    MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+    GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+    globalPlanner.build(queryContext, masterPlan);
+
+    CountDownLatch barrier  = new CountDownLatch(1);
+    MockAsyncDispatch dispatch = new MockAsyncDispatch(barrier, StageEventType.SQ_INIT);
+
+    QueryMaster qm = cluster.getTajoWorkers().get(0).getWorkerContext().getQueryMaster();
+    QueryMasterTask queryMasterTask = new QueryMasterTask(qm.getContext(),
+        queryId, session, defaultContext, expr.toJson(), NodeResources.createResource(512), dispatch);
+
+    queryMasterTask.init(conf);
+    queryMasterTask.getQueryTaskContext().getDispatcher().start();
+    queryMasterTask.startQuery();
+
+    try{
+      barrier.await(5000, TimeUnit.MILLISECONDS);
+    } catch (InterruptedException e) {
+      fail("Query state : " + queryMasterTask.getQuery().getSynchronizedState());
+    }
+
+    Stage stage = queryMasterTask.getQuery().getStages().iterator().next();
+    assertNotNull(stage);
+
+    // fire kill event
+    queryMasterTask.getEventHandler().handle(new QueryEvent(queryId, QueryEventType.KILL));
+
+    try {
+      cluster.waitForQueryState(queryMasterTask.getQuery(), TajoProtos.QueryState.QUERY_KILLED, 50);
+      assertEquals(TajoProtos.QueryState.QUERY_KILLED, queryMasterTask.getQuery().getSynchronizedState());
+    } catch (Exception e) {
+      e.printStackTrace();
+      if (stage != null) {
+        System.err.println(String.format("Stage: [%s] (Total: %d, Complete: %d, Success: %d, Killed: %d, Failed: %d)",
+            stage.getId().toString(),
+            stage.getTotalScheduledObjectsCount(),
+            stage.getCompletedTaskCount(),
+            stage.getSucceededObjectCount(),
+            stage.getKilledObjectCount(),
+            stage.getFailedObjectCount()));
+      }
+      throw e;
+    } finally {
+      queryMasterTask.stop();
+    }
+  }
+
+  @Test
+  public final void testIgnoreStageStateFromKilled() throws Exception {
+
+    SQLAnalyzer analyzer = new SQLAnalyzer();
+    QueryContext defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+    Session session = LocalTajoTestingUtility.createDummySession();
+    CatalogService catalog = cluster.getMaster().getCatalog();
+
+    LogicalPlanner planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    LogicalOptimizer optimizer = new LogicalOptimizer(conf, catalog);
+    Expr expr =  analyzer.parse(queryStr);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+
+    optimizer.optimize(plan);
+
+    QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+    QueryContext queryContext = new QueryContext(conf);
+    MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+    GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+    globalPlanner.build(queryContext, masterPlan);
+
+    CountDownLatch barrier  = new CountDownLatch(1);
+    MockAsyncDispatch dispatch = new MockAsyncDispatch(barrier, TajoProtos.QueryState.QUERY_RUNNING);
+
+    QueryMaster qm = cluster.getTajoWorkers().get(0).getWorkerContext().getQueryMaster();
+    QueryMasterTask queryMasterTask = new QueryMasterTask(qm.getContext(),
+        queryId, session, defaultContext, expr.toJson(), NodeResources.createResource(512), dispatch);
+
+    queryMasterTask.init(conf);
+    queryMasterTask.getQueryTaskContext().getDispatcher().start();
+    queryMasterTask.startQuery();
+
+    try{
+      barrier.await(5000, TimeUnit.MILLISECONDS);
+    } catch (InterruptedException e) {
+      fail("Query state : " + queryMasterTask.getQuery().getSynchronizedState());
+    }
+
+    Stage stage = queryMasterTask.getQuery().getStages().iterator().next();
+    assertNotNull(stage);
+
+    // fire kill event
+    queryMasterTask.getEventHandler().handle(new QueryEvent(queryId, QueryEventType.KILL));
+
+    try {
+      cluster.waitForQueryState(queryMasterTask.getQuery(), TajoProtos.QueryState.QUERY_KILLED, 50);
+      assertEquals(TajoProtos.QueryState.QUERY_KILLED, queryMasterTask.getQuery().getSynchronizedState());
+    }   finally {
+      queryMasterTask.stop();
+    }
+
+    List<Stage> stages = Lists.newArrayList(queryMasterTask.getQuery().getStages());
+    Stage lastStage = stages.get(stages.size() - 1);
+
+    assertEquals(StageState.KILLED, lastStage.getSynchronizedState());
+
+    lastStage.getStateMachine().doTransition(StageEventType.SQ_START,
+        new StageEvent(lastStage.getId(), StageEventType.SQ_START));
+
+    lastStage.getStateMachine().doTransition(StageEventType.SQ_KILL,
+        new StageEvent(lastStage.getId(), StageEventType.SQ_KILL));
+
+    lastStage.getStateMachine().doTransition(StageEventType.SQ_SHUFFLE_REPORT,
+        new StageEvent(lastStage.getId(), StageEventType.SQ_SHUFFLE_REPORT));
+
+    lastStage.getStateMachine().doTransition(StageEventType.SQ_STAGE_COMPLETED,
+        new StageEvent(lastStage.getId(), StageEventType.SQ_STAGE_COMPLETED));
+
+    lastStage.getStateMachine().doTransition(StageEventType.SQ_FAILED,
+        new StageEvent(lastStage.getId(), StageEventType.SQ_FAILED));
+  }
+
+  @Test
+  public void testKillTask() throws Throwable {
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId eid = QueryIdFactory.newExecutionBlockId(qid, 1);
+    TaskId tid = QueryIdFactory.newTaskId(eid);
+    final TajoConf conf = new TajoConf();
+    TaskRequestImpl taskRequest = new TaskRequestImpl();
+    WorkerConnectionInfo queryMaster = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+
+    TaskAttemptId attemptId = new TaskAttemptId(tid, 1);
+    taskRequest.set(attemptId, new ArrayList<CatalogProtos.FragmentProto>(),
+        null, false, PlanProto.LogicalNodeTree.newBuilder().build(), new QueryContext(conf),
+        null, null, queryMaster.getHostAndQMPort());
+    taskRequest.setInterQuery();
+
+
+    ExecutionBlockContextResponse.Builder requestProtoBuilder =
+        ExecutionBlockContextResponse.newBuilder();
+    requestProtoBuilder.setExecutionBlockId(eid.getProto())
+        .setPlanJson("test")
+        .setQueryContext(new QueryContext(conf).getProto())
+        .setQueryOutputPath("testpath")
+        .setShuffleType(PlanProto.ShuffleType.HASH_SHUFFLE);
+
+    TajoWorker.WorkerContext workerContext = new MockWorkerContext() {
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return null;
+      }
+
+      @Override
+      public TaskExecutor getTaskExecuor() {
+        return null;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return null;
+      }
+    };
+
+    ExecutionBlockContext context = new MockExecutionBlock(workerContext, requestProtoBuilder.build()) {
+      @Override
+      public Path createBaseDir() throws IOException {
+        return new Path("test");
+      }
+    };
+
+    org.apache.tajo.worker.Task task = new TaskImpl(taskRequest, context);
+    task.kill();
+    assertEquals(TajoProtos.TaskAttemptState.TA_KILLED, task.getTaskContext().getState());
+    try {
+      task.run();
+      assertEquals(TajoProtos.TaskAttemptState.TA_KILLED, task.getTaskContext().getState());
+    } catch (Exception e) {
+      assertEquals(TajoProtos.TaskAttemptState.TA_KILLED, task.getTaskContext().getState());
+    }
+  }
+
+  static class MockAsyncDispatch extends AsyncDispatcher {
+    private CountDownLatch latch;
+    private Enum eventType;
+
+    MockAsyncDispatch(CountDownLatch latch, Enum eventType) {
+      super();
+      this.latch = latch;
+      this.eventType = eventType;
+    }
+
+    @Override
+    protected void dispatch(Event event) {
+      if (event.getType() == eventType) {
+        latch.countDown();
+      }
+      super.dispatch(event);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryProgress.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryProgress.java b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryProgress.java
new file mode 100644
index 0000000..f9ed367
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryProgress.java
@@ -0,0 +1,77 @@
+/**
+ * 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.querymaster;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientUtil;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.ipc.ClientProtos;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@Category(IntegrationTest.class)
+public class TestQueryProgress {
+  private static TajoTestingCluster cluster;
+  private static TajoConf conf;
+  private static TajoClient client;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+    conf = cluster.getConfiguration();
+    client = cluster.newTajoClient();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    client.close();
+  }
+
+  @Test(timeout = 10000)
+  public final void testQueryProgress() throws Exception {
+    ClientProtos.SubmitQueryResponse res = client.executeQuery("select l_orderkey from lineitem group by l_orderkey");
+    QueryId queryId = new QueryId(res.getQueryId());
+
+    float prevProgress = 0;
+    while (true) {
+      QueryStatus status = client.getQueryStatus(queryId);
+      if (status == null) continue;
+
+      float progress = status.getProgress();
+
+      if (prevProgress > progress) {
+        fail("Previous progress: " + prevProgress + ", Current progress : " + progress);
+      }
+      prevProgress = progress;
+      assertTrue(progress <= 1.0f);
+
+      if (TajoClientUtil.isQueryComplete(status.getState())) break;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryState.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryState.java b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryState.java
new file mode 100644
index 0000000..978d709
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestQueryState.java
@@ -0,0 +1,99 @@
+/**
+ * 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.querymaster;
+
+import org.apache.tajo.*;
+import org.apache.tajo.annotation.NotThreadSafe;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientUtil;
+import org.apache.tajo.ipc.ClientProtos;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+@NotThreadSafe
+public class TestQueryState {
+  private static TajoTestingCluster cluster;
+  private static TajoClient client;
+
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+    client = cluster.newTajoClient();
+  }
+
+  @AfterClass
+  public static void tearDownClass() {
+    client.close();
+  }
+
+  @Test(timeout = 10000)
+  public void testSucceededState() throws Exception {
+    String queryStr = "select l_orderkey from lineitem group by l_orderkey order by l_orderkey";
+    /*
+    =======================================================
+    Block Id: eb_1429886996479_0001_000001 [LEAF] HASH_SHUFFLE
+    Block Id: eb_1429886996479_0001_000002 [INTERMEDIATE] RANGE_SHUFFLE
+    Block Id: eb_1429886996479_0001_000003 [ROOT] NONE_SHUFFLE
+    Block Id: eb_1429886996479_0001_000004 [TERMINAL]
+    =======================================================
+
+    The order of execution:
+
+    1: eb_1429886996479_0001_000001
+    2: eb_1429886996479_0001_000002
+    3: eb_1429886996479_0001_000003
+    4: eb_1429886996479_0001_000004
+    */
+
+    ClientProtos.SubmitQueryResponse res = client.executeQuery(queryStr);
+    QueryId queryId = new QueryId(res.getQueryId());
+
+    QueryStatus queryState = client.getQueryStatus(queryId);
+    while (!TajoClientUtil.isQueryComplete(queryState.getState())) {
+      try {
+        Thread.sleep(50);
+      } catch (InterruptedException e) {
+        fail("Query state : " + queryState);
+      }
+      queryState = client.getQueryStatus(queryId);
+    }
+
+    QueryMasterTask qmt = cluster.getQueryMasterTask(queryId);
+    Query query = qmt.getQuery();
+
+    assertEquals(TajoProtos.QueryState.QUERY_SUCCEEDED, qmt.getState());
+    assertEquals(TajoProtos.QueryState.QUERY_SUCCEEDED, query.getSynchronizedState());
+    assertEquals(TajoProtos.QueryState.QUERY_SUCCEEDED, query.getState());
+
+    assertFalse(query.getStages().isEmpty());
+    for (Stage stage : query.getStages()) {
+      assertEquals(StageState.SUCCEEDED, stage.getSynchronizedState());
+      assertEquals(StageState.SUCCEEDED, stage.getState());
+    }
+
+    /* get status from TajoMaster */
+    assertEquals(TajoProtos.QueryState.QUERY_SUCCEEDED, client.getQueryStatus(queryId).getState());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestTaskStatusUpdate.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestTaskStatusUpdate.java b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestTaskStatusUpdate.java
new file mode 100644
index 0000000..b468e37
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/querymaster/TestTaskStatusUpdate.java
@@ -0,0 +1,191 @@
+/**
+ * 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.querymaster;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.worker.TajoWorker;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.util.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestTaskStatusUpdate extends QueryTestCaseBase {
+
+  public TestTaskStatusUpdate() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    conf.set(TajoConf.ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname, "false");
+  }
+
+  @Test
+  public final void case1() throws Exception {
+    // select l_linenumber, count(1) as unique_key from lineitem group by l_linenumber;
+    ResultSet res = null;
+    try {
+      res = executeQuery();
+
+      // tpch/lineitem.tbl
+      long[] expectedNumRows = new long[]{5, 2, 2, 2};
+      long[] expectedNumBytes = new long[]{604, 18, 18, 8};
+      long[] expectedReadBytes = new long[]{604, 604, 18, 0};
+
+      assertStatus(2, expectedNumRows, expectedNumBytes, expectedReadBytes);
+    } finally {
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void case2() throws Exception {
+    // ExternalMergeSort
+    ResultSet res = null;
+    try {
+      res = executeQuery();
+
+      // tpch/lineitem.tbl
+      long[] expectedNumRows = new long[]{5, 2, 2, 2, 2, 2};
+      long[] expectedNumBytes = new long[]{604, 162, 162, 138, 138, 194};
+      long[] expectedReadBytes = new long[]{604, 604, 162, 0, 138, 0};
+
+      assertStatus(3, expectedNumRows, expectedNumBytes, expectedReadBytes);
+    } finally {
+      cleanupQuery(res);
+    }
+  }
+
+
+  @Test
+  public final void case3() throws Exception {
+    // Partition Scan
+    ResultSet res = null;
+    try {
+      createColumnPartitionedTable();
+
+      /*
+      |-eb_1404143727281_0002_000005
+         |-eb_1404143727281_0002_000004        (order by)
+            |-eb_1404143727281_0002_000003     (join)
+               |-eb_1404143727281_0002_000002  (scan, filter)
+               |-eb_1404143727281_0002_000001  (scan)
+       */
+      res = executeQuery();
+
+      // in/out * stage(4)
+      long[] expectedNumRows = new long[]{5, 5, 2, 2, 7, 2, 2, 2};
+      long[] expectedNumBytes = new long[]{20, 75, 8, 34, 109, 34, 34, 18};
+      long[] expectedReadBytes = new long[]{20, 20, 8, 8, 109, 0, 34, 0};
+
+      assertStatus(4, expectedNumRows, expectedNumBytes, expectedReadBytes);
+    } finally {
+      cleanupQuery(res);
+    }
+  }
+
+  private void createColumnPartitionedTable() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("ColumnPartitionedTable");
+    ResultSet res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) ");
+    res.close();
+
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+    assertEquals(2, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getSchema().size());
+    assertEquals(3,
+        catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size());
+
+    res = testBase.execute(
+        "insert overwrite into " + tableName + " select l_orderkey, l_partkey, l_quantity from lineitem");
+
+    res.close();
+  }
+
+  private void assertStatus(int numStages,
+                            long[] expectedNumRows,
+                            long[] expectedNumBytes,
+                            long[] expectedReadBytes) throws Exception {
+      List<TajoWorker> tajoWorkers = testingCluster.getTajoWorkers();
+      Collection<QueryMasterTask> finishedTasks = null;
+      for (TajoWorker eachWorker: tajoWorkers) {
+        finishedTasks = eachWorker.getWorkerContext().getQueryMaster().getFinishedQueryMasterTasks();
+        if (finishedTasks != null && !finishedTasks.isEmpty()) {
+          break;
+        }
+      }
+
+      assertNotNull(finishedTasks);
+      assertTrue(!finishedTasks.isEmpty());
+
+      List<QueryMasterTask> finishedTaskList = new ArrayList<QueryMasterTask>(finishedTasks);
+
+      Collections.sort(finishedTaskList, new Comparator<QueryMasterTask>() {
+        @Override
+        public int compare(QueryMasterTask o1, QueryMasterTask o2) {
+          return o2.getQueryId().compareTo(o1.getQueryId());
+        }
+      });
+
+      Query query = finishedTaskList.get(0).getQuery();
+
+      assertNotNull(query);
+
+      List<Stage> stages = new ArrayList<Stage>(query.getStages());
+      assertEquals(numStages, stages.size());
+
+      Collections.sort(stages, new Comparator<Stage>() {
+        @Override
+        public int compare(Stage o1, Stage o2) {
+          return o1.getId().compareTo(o2.getId());
+        }
+      });
+
+      int index = 0;
+      for (Stage eachStage : stages) {
+        TableStats inputStats = eachStage.getInputStats();
+        TableStats resultStats = eachStage.getResultStats();
+
+        assertNotNull(inputStats);
+        assertEquals(expectedNumRows[index], inputStats.getNumRows().longValue());
+        assertEquals(expectedNumBytes[index], inputStats.getNumBytes().longValue());
+        assertEquals(expectedReadBytes[index], inputStats.getReadBytes().longValue());
+
+        index++;
+
+        assertNotNull(resultStats);
+        assertEquals(expectedNumRows[index], resultStats.getNumRows().longValue());
+        assertEquals(expectedNumBytes[index], resultStats.getNumBytes().longValue());
+        assertEquals(expectedReadBytes[index], resultStats.getReadBytes().longValue());
+
+        index++;
+      }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/resource/TestResources.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/resource/TestResources.java b/tajo-core-tests/src/test/java/org/apache/tajo/resource/TestResources.java
new file mode 100644
index 0000000..eb0d732
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/resource/TestResources.java
@@ -0,0 +1,48 @@
+/**
+ * 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.resource;
+
+import org.junit.Test;
+
+import static org.apache.tajo.resource.NodeResources.componentwiseMin;
+import static org.apache.tajo.resource.NodeResources.createResource;
+import static org.apache.tajo.resource.NodeResources.fitsIn;
+import static org.junit.Assert.*;
+
+public class TestResources {
+  @Test
+  public void testFitsIn() {
+    assertTrue(fitsIn(createResource(512, 1, 1), createResource(1024, 2, 1)));
+    assertTrue(fitsIn(createResource(1024, 2, 1), createResource(1024, 2, 1)));
+    assertFalse(fitsIn(createResource(1024, 2, 1), createResource(512, 1, 1)));
+    assertFalse(fitsIn(createResource(512, 2, 1), createResource(1024, 1, 1)));
+    assertFalse(fitsIn(createResource(1024, 1, 1), createResource(512, 2, 1)));
+    assertFalse(fitsIn(createResource(512, 1, 2), createResource(512, 1, 1)));
+  }
+
+  @Test
+  public void testComponentwiseMin() {
+    assertEquals(createResource(1, 1),
+        componentwiseMin(createResource(1, 1), createResource(2, 2)));
+    assertEquals(createResource(1, 1),
+        componentwiseMin(createResource(2, 2), createResource(1, 1)));
+    assertEquals(createResource(1, 1),
+        componentwiseMin(createResource(1, 2), createResource(2, 1)));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestFileFragment.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestFileFragment.java b/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestFileFragment.java
new file mode 100644
index 0000000..d0ab1c0
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestFileFragment.java
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.storage;
+
+import com.google.common.collect.Sets;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.storage.fragment.FragmentConvertor;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.SortedSet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestFileFragment {
+  private Path path;
+  
+  @Before
+  public final void setUp() throws Exception {
+    path = CommonTestingUtil.getTestDir();
+  }
+
+  @Test
+  public final void testGetAndSetFields() {
+    FileFragment fragment1 = new FileFragment("table1_1", new Path(path, "table0"), 0, 500);
+
+    assertEquals("table1_1", fragment1.getTableName());
+    assertEquals(new Path(path, "table0"), fragment1.getPath());
+    assertTrue(0 == fragment1.getStartKey());
+    assertTrue(500 == fragment1.getLength());
+  }
+
+  @Test
+  public final void testGetProtoAndRestore() {
+    FileFragment fragment = new FileFragment("table1_1", new Path(path, "table0"), 0, 500);
+
+    FileFragment fragment1 = FragmentConvertor.convert(FileFragment.class, fragment.getProto());
+    assertEquals("table1_1", fragment1.getTableName());
+    assertEquals(new Path(path, "table0"), fragment1.getPath());
+    assertTrue(0 == fragment1.getStartKey());
+    assertTrue(500 == fragment1.getLength());
+  }
+
+  @Test
+  public final void testCompareTo() {
+    final int num = 10;
+    FileFragment[] tablets = new FileFragment[num];
+    for (int i = num - 1; i >= 0; i--) {
+      tablets[i] = new FileFragment("tablet1_"+i, new Path(path, "tablet0"), i * 500, (i+1) * 500);
+    }
+    
+    Arrays.sort(tablets);
+
+    for(int i = 0; i < num; i++) {
+      assertEquals("tablet1_"+i, tablets[i].getTableName());
+    }
+  }
+
+  @Test
+  public final void testCompareTo2() {
+    final int num = 1860;
+    FileFragment[] tablets = new FileFragment[num];
+    for (int i = num - 1; i >= 0; i--) {
+      tablets[i] = new FileFragment("tablet1_"+i, new Path(path, "tablet0"), (long)i * 6553500, (long)(i+1) * 6553500);
+    }
+
+    SortedSet sortedSet = Sets.newTreeSet();
+    for (FileFragment frag : tablets) {
+      sortedSet.add(frag);
+    }
+    assertEquals(num, sortedSet.size());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestRowFile.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestRowFile.java b/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestRowFile.java
new file mode 100644
index 0000000..e45dd75
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/storage/TestRowFile.java
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.storage;
+
+import com.google.common.collect.Sets;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.proto.CatalogProtos.TableProto;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.FileUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestRowFile {
+  private static final Log LOG = LogFactory.getLog(TestRowFile.class);
+
+  private TajoTestingCluster cluster;
+  private TajoConf conf;
+
+  @Before
+  public void setup() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+    conf = cluster.getConfiguration();
+  }
+
+  @After
+  public void teardown() throws Exception {
+  }
+
+  @Test
+  public void test() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4);
+    schema.addColumn("age", Type.INT8);
+    schema.addColumn("description", Type.TEXT);
+
+    TableMeta meta = CatalogUtil.newTableMeta("ROWFILE");
+
+    FileTablespace sm = (FileTablespace) TablespaceManager.get(cluster.getDefaultFileSystem().getUri()).get();
+
+    Path tablePath = new Path("/test");
+    Path metaPath = new Path(tablePath, ".meta");
+    Path dataPath = new Path(tablePath, "test.tbl");
+    FileSystem fs = sm.getFileSystem();
+    fs.mkdirs(tablePath);
+
+    FileUtil.writeProto(fs, metaPath, meta.getProto());
+
+    Appender appender = sm.getAppender(meta, schema, dataPath);
+    appender.enableStats();
+    appender.init();
+
+    int tupleNum = 200;
+    Tuple tuple;
+    Datum stringDatum = DatumFactory.createText("abcdefghijklmnopqrstuvwxyz");
+    Set<Integer> idSet = Sets.newHashSet();
+
+    tuple = new VTuple(3);
+    long start = System.currentTimeMillis();
+    for(int i = 0; i < tupleNum; i++) {
+      tuple.put(0, DatumFactory.createInt4(i + 1));
+      tuple.put(1, DatumFactory.createInt8(25l));
+      tuple.put(2, stringDatum);
+      appender.addTuple(tuple);
+      idSet.add(i+1);
+    }
+    appender.close();
+
+    TableStats stat = appender.getStats();
+    assertEquals(tupleNum, stat.getNumRows().longValue());
+
+    FileStatus file = fs.getFileStatus(dataPath);
+    TableProto proto = (TableProto) FileUtil.loadProto(
+        cluster.getDefaultFileSystem(), metaPath, TableProto.getDefaultInstance());
+    meta = new TableMeta(proto);
+    FileFragment fragment = new FileFragment("test.tbl", dataPath, 0, file.getLen());
+
+    int tupleCnt = 0;
+    start = System.currentTimeMillis();
+    Scanner scanner = sm.getScanner(meta, schema, fragment);
+    scanner.init();
+    while ((tuple=scanner.next()) != null) {
+      tupleCnt++;
+    }
+    scanner.close();
+
+    assertEquals(tupleNum, tupleCnt);
+
+    tupleCnt = 0;
+    long fileStart = 0;
+    long fileLen = file.getLen()/13;
+
+    for (int i = 0; i < 13; i++) {
+      fragment = new FileFragment("test.tbl", dataPath, fileStart, fileLen);
+      scanner = new RowFile.RowFileScanner(conf, schema, meta, fragment);
+      scanner.init();
+      while ((tuple=scanner.next()) != null) {
+        if (!idSet.remove(tuple.getInt4(0)) && LOG.isDebugEnabled()) {
+          LOG.debug("duplicated! " + tuple.getInt4(0));
+        }
+        tupleCnt++;
+      }
+      scanner.close();
+      fileStart += fileLen;
+      if (i == 11) {
+        fileLen = file.getLen() - fileStart;
+      }
+    }
+    assertEquals(tupleNum, tupleCnt);
+  }
+}


[23/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnNullColumn.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnNullColumn.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnNullColumn.sql
new file mode 100644
index 0000000..6707d27
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnNullColumn.sql
@@ -0,0 +1,13 @@
+select
+  *
+from (
+  select
+    case when id > 2 then null else id end as col1,
+    name as col2
+  from
+    nullsort
+) a
+
+order by
+  col1,
+  col2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextAsc.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextAsc.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextAsc.sql
new file mode 100644
index 0000000..6ed1847
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextAsc.sql
@@ -0,0 +1,6 @@
+select
+  *
+from
+  unicode_sort1
+order by
+  col2 asc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextDesc.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextDesc.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextDesc.sql
new file mode 100644
index 0000000..efbb684
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortOnUnicodeTextDesc.sql
@@ -0,0 +1,6 @@
+select
+  *
+from
+  unicode_sort2
+order by
+  col2 desc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias1.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias1.sql
new file mode 100644
index 0000000..cd8be3e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias1.sql
@@ -0,0 +1 @@
+select l_linenumber, l_orderkey as sortkey from lineitem order by sortkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias2.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias2.sql
new file mode 100644
index 0000000..7a56cac
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias2.sql
@@ -0,0 +1,9 @@
+select
+  lineitem.l_orderkey as l_orderkey,
+  count(l_partkey) as cnt
+from
+  lineitem a
+group by
+  lineitem.l_orderkey
+order by
+  lineitem.l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias3.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias3.sql
new file mode 100644
index 0000000..446138b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAlias3.sql
@@ -0,0 +1,11 @@
+select
+  nation.n_nationkey as n_nationkey,
+  customer.c_name as c_name,
+  count(nation.n_nationkey) as cnt
+from
+  nation inner join customer on n_nationkey = c_nationkey
+group by
+  nation.n_nationkey,
+  customer.c_name
+order by
+  n_nationkey, c_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAliasButOriginalName.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAliasButOriginalName.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAliasButOriginalName.sql
new file mode 100644
index 0000000..1d6396a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAliasButOriginalName.sql
@@ -0,0 +1 @@
+select l_linenumber, l_orderkey as sortkey from lineitem order by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAscDescKeys.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAscDescKeys.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAscDescKeys.sql
new file mode 100644
index 0000000..2eb9d1c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithAscDescKeys.sql
@@ -0,0 +1 @@
+select col1, col2 from table2 order by col1, col2 desc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithConstKeys.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithConstKeys.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithConstKeys.sql
new file mode 100644
index 0000000..ddaf84f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithConstKeys.sql
@@ -0,0 +1,10 @@
+select
+  l_orderkey,
+  l_linenumber,
+  1 as key1,
+  2 as key2
+from
+  lineitem
+order by
+  key1,
+  key2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithDate.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithDate.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithDate.sql
new file mode 100644
index 0000000..da00157
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithDate.sql
@@ -0,0 +1 @@
+select col1, col2, col3 from testSortWithDate order by col1, col2, col3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr1.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr1.sql
new file mode 100644
index 0000000..2aeba26
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr1.sql
@@ -0,0 +1 @@
+select l_linenumber, l_orderkey as sortkey from lineitem order by l_orderkey + 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr2.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr2.sql
new file mode 100644
index 0000000..b7247ff
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithExpr2.sql
@@ -0,0 +1 @@
+select l_linenumber, l_orderkey as sortkey from lineitem order by l_linenumber, l_orderkey, (l_orderkey is null);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithJson.json b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithJson.json
new file mode 100644
index 0000000..efcd0e0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortWithJson.json
@@ -0,0 +1,65 @@
+// select max(l_quantity) as max_quantity, l_orderkey from lineitem group by l_orderkey order by max_quantity;
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "AliasName": "max_quantity",
+            "Expr": {
+                "IsDistinct": false,
+                "Signature": "max",
+                "FuncParams": [
+                    {
+                        "ColumnName": "l_quantity",
+                        "OpType": "Column"
+                    }
+                ],
+                "OpType": "GeneralSetFunction"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "ColumnName": "l_orderkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "SortSpecs": [
+            {
+                "SortKey": {
+                    "ColumnName": "max_quantity",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            }
+        ],
+        "Expr": {
+            "Groups": [
+                {
+                    "GroupType": "OrdinaryGroup",
+                    "Dimensions": [
+                        {
+                            "ColumnName": "l_orderkey",
+                            "OpType": "Column"
+                        }
+                    ]
+                }
+            ],
+            "Expr": {
+                "Relations": [
+                    {
+                        "TableName": "lineitem",
+                        "OpType": "Relation"
+                    }
+                ],
+                "OpType": "RelationList"
+            },
+            "OpType": "Aggregation"
+        },
+        "OpType": "Sort"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSubQuerySortAfterGroupMultiBlocks.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSubQuerySortAfterGroupMultiBlocks.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSubQuerySortAfterGroupMultiBlocks.sql
new file mode 100644
index 0000000..3e7eaab
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSubQuerySortAfterGroupMultiBlocks.sql
@@ -0,0 +1,5 @@
+select l_orderkey, revenue from (
+  select l_orderkey, revenue from (
+    select l_orderkey, sum(l_extendedprice*l_discount) as revenue from lineitem group by l_orderkey
+  ) l1
+) l2 order by l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopK.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopK.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopK.sql
new file mode 100644
index 0000000..331f3b4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopK.sql
@@ -0,0 +1 @@
+select l_orderkey, l_linenumber from lineitem order by l_orderkey desc limit 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopkWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopkWithJson.json b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopkWithJson.json
new file mode 100644
index 0000000..e3a264f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testTopkWithJson.json
@@ -0,0 +1,51 @@
+// select l_orderkey, l_linenumber from lineitem order by l_orderkey desc limit 3;
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "Expr": {
+                "ColumnName": "l_orderkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "ColumnName": "l_linenumber",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "Num": {
+            "Value": "3",
+            "ValueType": "Unsigned_Integer",
+            "OpType": "Literal"
+        },
+        "Expr": {
+            "SortSpecs": [
+                {
+                    "SortKey": {
+                        "ColumnName": "l_orderkey",
+                        "OpType": "Column"
+                    },
+                    "IsAsc": false,
+                    "IsNullFirst": false
+                }
+            ],
+            "Expr": {
+                "Relations": [
+                    {
+                        "TableName": "lineitem",
+                        "OpType": "Relation"
+                    }
+                ],
+                "OpType": "RelationList"
+            },
+            "OpType": "Sort"
+        },
+        "OpType": "Limit"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTPCH/testFirstJoinInQ7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTPCH/testFirstJoinInQ7.sql b/tajo-core-tests/src/test/resources/queries/TestTPCH/testFirstJoinInQ7.sql
new file mode 100644
index 0000000..2dfb83d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTPCH/testFirstJoinInQ7.sql
@@ -0,0 +1,13 @@
+select
+  n1.n_name as supp_nation, n2.n_name as cust_nation, n1.n_nationkey as s_nationkey, n2.n_nationkey as c_nationkey
+from
+  nation n1 join nation n2
+  on
+    n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY'
+UNION ALL
+select
+  n1.n_name as supp_nation, n2.n_name as cust_nation, n1.n_nationkey as s_nationkey, n2.n_nationkey as c_nationkey
+from
+  nation n1 join nation n2
+  on
+    n2.n_name = 'FRANCE' and n1.n_name = 'GERMANY'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ1OrderBy.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ1OrderBy.sql b/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ1OrderBy.sql
new file mode 100644
index 0000000..5864144
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ1OrderBy.sql
@@ -0,0 +1,12 @@
+select
+  l_returnflag,
+  l_linestatus,
+  count(*) as count_order
+from
+  lineitem
+group by
+  l_returnflag,
+  l_linestatus
+order by
+  l_returnflag,
+  l_linestatus;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ2FourJoins.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ2FourJoins.sql b/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ2FourJoins.sql
new file mode 100644
index 0000000..ffaaf87
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTPCH/testQ2FourJoins.sql
@@ -0,0 +1,18 @@
+select
+  s_acctbal,
+  s_name,
+  n_name,
+  p_partkey,
+  p_mfgr,
+  s_address,
+  s_phone,
+  s_comment,
+  ps_supplycost,
+  r_name,
+  p_type,
+  p_size
+from
+  region join nation on n_regionkey = r_regionkey and r_name = 'AMERICA'
+  join supplier on s_nationkey = n_nationkey
+  join partsupp on s_suppkey = ps_suppkey
+  join part on p_partkey = ps_partkey and p_type like '%BRASS' and p_size = 15;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCH14Expr.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCH14Expr.sql b/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCH14Expr.sql
new file mode 100644
index 0000000..8f6047f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCH14Expr.sql
@@ -0,0 +1,12 @@
+select
+  100 *
+  sum(
+    case when p_type like 'PROMO%' then l_extendedprice else 0.0 end
+  ) /
+  sum(
+    l_extendedprice * (1 - l_discount)
+  ) as promo_revenue
+from
+  lineitem, part
+where
+  l_partkey = p_partkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCHQ5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCHQ5.sql b/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCHQ5.sql
new file mode 100644
index 0000000..e7d3d56
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTPCH/testTPCHQ5.sql
@@ -0,0 +1,24 @@
+select
+	n_name,
+	sum(l_extendedprice * (1 - l_discount)) as revenue
+from
+	customer,
+	orders,
+	lineitem,
+	supplier,
+	nation,
+	region
+where
+	c_custkey = o_custkey and
+	l_orderkey = o_orderkey and
+	l_suppkey = s_suppkey and
+	c_nationkey = s_nationkey and
+	s_nationkey = n_nationkey and
+	n_regionkey = r_regionkey and
+	r_name = 'ASIA' and
+	o_orderdate >= '1994-01-01' and
+	o_orderdate < '1995-01-01'
+group by
+	n_name
+order by
+	revenue desc
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case1.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case1.sql
new file mode 100644
index 0000000..8c1116e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case1.sql
@@ -0,0 +1,16 @@
+select
+  *
+from (
+  select
+    col1,
+    col2,
+    null_col,
+    key
+  from
+    testQueryCasesOnColumnPartitionedTable
+  where
+    (key = 45.0 or key = 38.0) and null_col is null
+) test
+order by
+  col1, col2
+;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case10.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case10.sql
new file mode 100644
index 0000000..715d8e8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case10.sql
@@ -0,0 +1 @@
+select col1, key, -key as res from testQueryCasesOnColumnPartitionedTable;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case11.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case11.sql
new file mode 100644
index 0000000..a5bf1db
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case11.sql
@@ -0,0 +1 @@
+select key as key_alias from testQueryCasesOnColumnPartitionedTable
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case12.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case12.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case12.sql
new file mode 100644
index 0000000..2324439
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case12.sql
@@ -0,0 +1,7 @@
+select
+    key as key_alias,
+    count(*) cnt
+from
+    testQueryCasesOnColumnPartitionedTable
+group by key_alias
+order by key_alias desc
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case13.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case13.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case13.sql
new file mode 100644
index 0000000..efb7432
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case13.sql
@@ -0,0 +1,11 @@
+select
+    key_alias as key, cnt
+from (
+    select
+        key as key_alias,
+        count(*) cnt
+    from
+        testQueryCasesOnColumnPartitionedTable
+    group by key_alias
+    order by key_alias desc
+) a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case14.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case14.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case14.sql
new file mode 100644
index 0000000..ac1ad20
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case14.sql
@@ -0,0 +1,3 @@
+select count(*) as cnt
+  from
+    testColumnPartitionedTableWithSmallerExpressions1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case15.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case15.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case15.sql
new file mode 100644
index 0000000..03cf55b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case15.sql
@@ -0,0 +1,3 @@
+select count(*) as cnt
+  from
+    testColumnPartitionedTableWithSmallerExpressions2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case2.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case2.sql
new file mode 100644
index 0000000..ee94778
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case2.sql
@@ -0,0 +1,31 @@
+select
+  *
+from (
+  select
+    col1,
+    col2,
+    null_col,
+    key
+  from
+    testQueryCasesOnColumnPartitionedTable
+  where
+    (key = 45.0 or key = 38.0) and null_col is null
+
+  union all
+
+  select
+    col1,
+    col2,
+    null_col,
+    key
+  from
+    testQueryCasesOnColumnPartitionedTable
+  where
+    (key = 45.0 or key = 38.0) and null_col is null
+
+) t1
+
+order by
+  col1,
+  col2
+;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case3.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case3.sql
new file mode 100644
index 0000000..6cb1ea1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case3.sql
@@ -0,0 +1,8 @@
+select
+  l.l_orderkey,
+  p.col1,
+  key
+  from lineitem as l, testQueryCasesOnColumnPartitionedTable as p
+where
+  (key = 45.0 or key = 38.0) and l.l_orderkey = p.col1;
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case4.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case4.sql
new file mode 100644
index 0000000..477a456
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case4.sql
@@ -0,0 +1 @@
+select pow(key, 2) from testQueryCasesOnColumnPartitionedTable
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case5.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case5.sql
new file mode 100644
index 0000000..180dd72
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case5.sql
@@ -0,0 +1 @@
+select round(pow(key + 1, 2)) from testQueryCasesOnColumnPartitionedTable
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case6.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case6.sql
new file mode 100644
index 0000000..cd54486
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case6.sql
@@ -0,0 +1 @@
+select col1, key from testQueryCasesOnColumnPartitionedTable order by pow(key, 2) desc
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case7.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case7.sql
new file mode 100644
index 0000000..e2c4d83
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case7.sql
@@ -0,0 +1 @@
+select col1, key from testQueryCasesOnColumnPartitionedTable WHERE key BETWEEN 35 AND 48;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case8.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case8.sql
new file mode 100644
index 0000000..fe57eb8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case8.sql
@@ -0,0 +1 @@
+select col1, CASE key WHEN 36 THEN key WHEN 49 THEN key ELSE key END from testQueryCasesOnColumnPartitionedTable;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case9.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case9.sql
new file mode 100644
index 0000000..595e533
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/case9.sql
@@ -0,0 +1 @@
+select col1, CAST(key AS INT) from testQueryCasesOnColumnPartitionedTable;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTablePartitions/lineitemspecial_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTablePartitions/lineitemspecial_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/lineitemspecial_ddl.sql
new file mode 100644
index 0000000..ac49b23
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTablePartitions/lineitemspecial_ddl.sql
@@ -0,0 +1,3 @@
+create external table if not exists lineitemspecial (
+    l_orderkey INT4, l_shipinstruct TEXT, l_shipmode TEXT)
+using text with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupBySubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupBySubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupBySubQuery.sql
new file mode 100644
index 0000000..9f86886
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupBySubQuery.sql
@@ -0,0 +1 @@
+select sum(l_extendedprice * l_discount) as revenue from (select * from lineitem) as l;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupbySubqueryWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupbySubqueryWithJson.json b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupbySubqueryWithJson.json
new file mode 100644
index 0000000..f607a0b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testGroupbySubqueryWithJson.json
@@ -0,0 +1,59 @@
+// select sum(l_extendedprice * l_discount) as revenue from (select * from lineitem) as l;
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "AliasName": "revenue",
+            "Expr": {
+                "IsDistinct": false,
+                "Signature": "sum",
+                "FuncParams": [
+                    {
+                        "LeftExpr": {
+                            "ColumnName": "l_extendedprice",
+                            "OpType": "Column"
+                        },
+                        "RightExpr": {
+                            "ColumnName": "l_discount",
+                            "OpType": "Column"
+                        },
+                        "OpType": "Multiply"
+                    }
+                ],
+                "OpType": "GeneralSetFunction"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "Relations": [
+            {
+                "SubPlan": {
+                    "IsDistinct": false,
+                    "Projections": [
+                        {
+                            "Expr": {
+                                "OpType": "Asterisk"
+                            },
+                            "OpType": "Target"
+                        }
+                    ],
+                    "Expr": {
+                        "Relations": [
+                            {
+                                "TableName": "lineitem",
+                                "OpType": "Relation"
+                            }
+                        ],
+                        "OpType": "RelationList"
+                    },
+                    "OpType": "Projection"
+                },
+                "TableName": "l",
+                "OpType": "TablePrimaryTableSubQuery"
+            }
+        ],
+        "OpType": "RelationList"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery.sql
new file mode 100644
index 0000000..5944365
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery.sql
@@ -0,0 +1,5 @@
+SELECT
+  A.n_regionkey, B.r_regionkey, A.n_name, B.r_name
+FROM
+  (SELECT * FROM nation WHERE n_name LIKE 'A%') A
+  JOIN region B ON A.n_regionkey=B.r_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery2.sql b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery2.sql
new file mode 100644
index 0000000..e08b8fe
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubQuery2.sql
@@ -0,0 +1,4 @@
+SELECT
+  A.n_regionkey, B.r_regionkey, A.n_name, B.r_name
+FROM
+  (SELECT * FROM nation WHERE n_name LIKE 'A%') A, region B WHERE A.n_regionkey=B.r_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubqueryWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubqueryWithJson.json b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubqueryWithJson.json
new file mode 100644
index 0000000..77f639c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testJoinSubqueryWithJson.json
@@ -0,0 +1,108 @@
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "Expr": {
+                "Qualifier": "a",
+                "ColumnName": "n_regionkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "b",
+                "ColumnName": "r_regionkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "a",
+                "ColumnName": "n_name",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "b",
+                "ColumnName": "r_name",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "Relations": [
+            {
+                "JoinType": "INNER",
+                "JoinCondition": {
+                    "LeftExpr": {
+                        "Qualifier": "a",
+                        "ColumnName": "n_regionkey",
+                        "OpType": "Column"
+                    },
+                    "RightExpr": {
+                        "Qualifier": "b",
+                        "ColumnName": "r_regionkey",
+                        "OpType": "Column"
+                    },
+                    "OpType": "Equals"
+                },
+                "IsNatural": false,
+                "LeftExpr": {
+                    "SubPlan": {
+                        "IsDistinct": false,
+                        "Projections": [
+                            {
+                                "Expr": {
+                                    "OpType": "Asterisk"
+                                },
+                                "OpType": "Target"
+                            }
+                        ],
+                        "Expr": {
+                            "SelectCondition": {
+                                "IsNot": false,
+                                "IsCaseInsensitive": false,
+                                "LeftExpr": {
+                                    "ColumnName": "n_name",
+                                    "OpType": "Column"
+                                },
+                                "RightExpr": {
+                                    "Value": "A%",
+                                    "ValueType": "String",
+                                    "OpType": "Literal"
+                                },
+                                "OpType": "LikePredicate"
+                            },
+                            "Expr": {
+                                "Relations": [
+                                    {
+                                        "TableName": "nation",
+                                        "OpType": "Relation"
+                                    }
+                                ],
+                                "OpType": "RelationList"
+                            },
+                            "OpType": "Filter"
+                        },
+                        "OpType": "Projection"
+                    },
+                    "TableName": "a",
+                    "OpType": "TablePrimaryTableSubQuery"
+                },
+                "RightExpr": {
+                    "TableName": "region",
+                    "TableAlias": "b",
+                    "OpType": "Relation"
+                },
+                "OpType": "Join"
+            }
+        ],
+        "OpType": "RelationList"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testTableSubquery1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testTableSubquery1.sql b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testTableSubquery1.sql
new file mode 100644
index 0000000..95fac4f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTableSubQuery/testTableSubquery1.sql
@@ -0,0 +1 @@
+select l_orderkey from (select * from lineitem) as l;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTajoJdbc/create_table_with_date_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTajoJdbc/create_table_with_date_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestTajoJdbc/create_table_with_date_ddl.sql
new file mode 100644
index 0000000..caeeaf9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTajoJdbc/create_table_with_date_ddl.sql
@@ -0,0 +1,10 @@
+-- Sort Table
+-- It is used in TestSortQuery::testSortWithDate
+
+create external table table1 (
+  col1 timestamp,
+	col2 date,
+	col3 time
+) using text
+with ('text.delimiter'='|', 'text.null'='NULL')
+location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case1.sql b/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case1.sql
new file mode 100644
index 0000000..f6d0eb3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case1.sql
@@ -0,0 +1 @@
+select l_linenumber, count(1) as unique_key from lineitem group by l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case2.sql b/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case2.sql
new file mode 100644
index 0000000..c3e09f1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case2.sql
@@ -0,0 +1,5 @@
+select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice*(1-l_discount)) as sum_disc_price, sum
+(l_extendedprice*(1-l_discount)*(1+l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as
+ count_order
+from lineitem
+group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case3.sql b/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case3.sql
new file mode 100644
index 0000000..a0f9c78
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTaskStatusUpdate/case3.sql
@@ -0,0 +1,10 @@
+select *
+from (
+  select a.col1, a.col2, a.key
+  from ColumnPartitionedTable a
+  join ColumnPartitionedTable b on a.key = b.key
+  where
+    (a.key = 45.0 or a.key = 38.0)
+) test
+order by
+  col1, col2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table1_ddl.sql
new file mode 100644
index 0000000..b6196ec
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE TABLE truncate_table1 AS SELECT * FROM default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table2_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table2_ddl.sql
new file mode 100644
index 0000000..f00f593
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestTruncateTable/table2_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} (id int, str text, num int) using text location ${table.path};

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion1.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion1.sql
new file mode 100644
index 0000000..0ba2909
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion1.sql
@@ -0,0 +1,27 @@
+SELECT
+  l_orderkey,
+  l_partkey,
+  query
+FROM
+  (
+  SELECT
+    l_orderkey,
+    l_partkey,
+    'abc' as query
+  FROM
+    lineitem
+  WHERE
+    l_orderkey = 1
+
+  UNION ALL
+
+  SELECT
+    l_orderkey,
+    l_partkey,
+    'bbc' as query
+  FROM
+    lineitem
+  WHERE
+    l_orderkey = 1
+) result
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion2.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion2.sql
new file mode 100644
index 0000000..d54ed27
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testComplexUnion2.sql
@@ -0,0 +1,35 @@
+SELECT *
+FROM
+(
+    SELECT
+        l_orderkey,
+        l_partkey,
+        url
+    FROM
+        (
+          SELECT
+            l_orderkey,
+            l_partkey,
+            CASE
+              WHEN
+                l_partkey IS NOT NULL THEN ''
+              WHEN l_orderkey = 1 THEN '1'
+            ELSE
+              '2'
+            END AS url
+          FROM
+            lineitem
+        ) res1
+        JOIN
+        (
+          SELECT
+            *
+          FROM
+            part
+        ) res2
+        ON l_partkey = p_partkey
+) result
+
+
+
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion1.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion1.sql
new file mode 100644
index 0000000..34ca8d6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion1.sql
@@ -0,0 +1,19 @@
+select
+  num
+from (
+
+select
+  o_custkey as num
+from
+  orders
+
+union
+
+select
+  c_custkey as num
+from
+  customer
+) table1
+
+order by
+  num;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion10.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion10.sql
new file mode 100644
index 0000000..2037564
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion10.sql
@@ -0,0 +1,158 @@
+SELECT * FROM (
+  SELECT
+    *
+  FROM (
+    SELECT
+      n_nationkey,
+      n_name
+
+    FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+
+      UNION
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+    ) T1
+    GROUP BY
+      n_nationkey,
+      n_name
+    ORDER BY
+      n_nationkey desc,
+      n_name desc
+
+   UNION
+
+   SELECT
+    n_nationkey,
+    n_name
+
+   FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+      UNION
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+   ) T2
+
+   GROUP BY
+     n_nationkey,
+     n_name
+
+   ORDER BY
+     n_nationkey desc,
+     n_name desc
+
+  ) TABLE1
+
+  ORDER BY
+    n_nationkey,
+    n_name
+
+  UNION
+
+  SELECT
+    *
+  FROM (
+    SELECT
+      n_nationkey,
+      n_name
+
+    FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+
+      UNION
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+    ) T3
+    GROUP BY
+      n_nationkey,
+      n_name
+    ORDER BY
+      n_nationkey desc,
+      n_name desc
+
+   UNION
+
+   SELECT
+    n_nationkey,
+    n_name
+
+   FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+      UNION
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+   ) T4
+
+   GROUP BY
+     n_nationkey,
+     n_name
+
+   ORDER BY
+     n_nationkey desc,
+     n_name desc
+
+  ) TABLE2
+
+  ORDER BY
+    n_nationkey,
+    n_name
+
+) TABLE3
+
+ORDER BY
+  n_nationkey,
+  n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion11.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion11.sql
new file mode 100644
index 0000000..b3b0feb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion11.sql
@@ -0,0 +1,8 @@
+select col1, col2, col3
+from (
+    select L_RETURNFLAG as col1, L_EXTENDEDPRICE as col2, concat(L_RECEIPTDATE, L_LINESTATUS) as col3 from lineitem
+    union
+    select P_TYPE as col1, P_RETAILPRICE col2, P_NAME col3 from part
+) a
+where col3 like '1993%' and col2 > 46796
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion12.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion12.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion12.sql
new file mode 100644
index 0000000..64ad0a7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion12.sql
@@ -0,0 +1,14 @@
+select col1, col2, col3
+from (
+    select
+        col1, col2, col3
+    from
+        (select
+            L_RETURNFLAG as col1, L_EXTENDEDPRICE as col2, concat(L_RECEIPTDATE, L_LINESTATUS) as col3
+        from
+            lineitem) b
+    union
+    select P_TYPE as col1, P_RETAILPRICE * 100 col2, concat('1993', P_NAME) col3 from part
+) a
+where col3 like '1993%' and col2 > 46796
+order by col2;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion13.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion13.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion13.sql
new file mode 100644
index 0000000..763eef9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion13.sql
@@ -0,0 +1,15 @@
+select col1, col2, col3
+from (
+    select
+        col1, col2, col3
+    from
+        (select
+            L_RETURNFLAG as col1, L_EXTENDEDPRICE as col2, concat(L_RECEIPTDATE, L_LINESTATUS) as col3
+        from
+            lineitem
+        where col2 > 46796) b
+    union
+    select P_TYPE as col1, P_RETAILPRICE * 100 col2, concat('1993', P_NAME) col3 from part
+) a
+where col3 like '1993%'
+order by col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion14.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion14.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion14.sql
new file mode 100644
index 0000000..79c8365
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion14.sql
@@ -0,0 +1,8 @@
+select col1, cnt
+from (
+    select L_RETURNFLAG as col1, count(*) as cnt from lineitem group by col1
+    union
+    select cast(n_regionkey as TEXT) as col1, count(*) as cnt from nation group by col1
+) a
+where a.cnt > 1
+order by a.col1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion15.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion15.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion15.sql
new file mode 100644
index 0000000..19a7eb7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion15.sql
@@ -0,0 +1,15 @@
+select col1, sum(cnt)
+from (
+    select col1, cnt
+    from (  select l_returnflag col1, count(*) cnt from lineitem
+            join orders on l_orderkey = o_orderkey and o_custkey > 0
+            group by l_returnflag) b
+    where col1 = 'N'
+    union
+    select cast(n_regionkey as TEXT) as col1, count(*) as cnt from nation
+    where n_regionkey > 2
+    group by col1
+) a
+where round(cast(a.cnt as FLOAT4)) > 1.0
+group by a.col1
+order by a.col1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion16.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion16.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion16.sql
new file mode 100644
index 0000000..dd9dca4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion16.sql
@@ -0,0 +1,15 @@
+select col1, sum(cnt)
+from (
+    select col1, cnt
+    from (  select l_returnflag col1, count(distinct l_orderkey) cnt from lineitem
+            join orders on l_orderkey = o_orderkey and o_custkey > 0
+            group by l_returnflag) b
+    where col1 = 'N'
+    union
+    select cast(n_regionkey as TEXT) as col1, count(*) as cnt from nation
+    where n_regionkey > 2
+    group by col1
+) a
+where round(cast(a.cnt as FLOAT4)) > 1.0
+group by a.col1
+order by a.col1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion2.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion2.sql
new file mode 100644
index 0000000..bcf2433
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion2.sql
@@ -0,0 +1,18 @@
+select
+  l_orderkey
+from (
+  select
+    l_orderkey
+  from
+    lineitem l1
+
+  union
+
+  select
+    l_orderkey
+  from
+    lineitem l2
+) table1
+
+order by
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion3.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion3.sql
new file mode 100644
index 0000000..12a5b64
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion3.sql
@@ -0,0 +1,19 @@
+select
+  total
+from (
+
+select
+  count(*) as total
+from
+  orders
+
+union
+
+select
+  count(*) as total
+from
+  customer
+) table1
+
+order by
+  total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion4.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion4.sql
new file mode 100644
index 0000000..f42325a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion4.sql
@@ -0,0 +1,16 @@
+select
+  count(*)
+from (
+
+  select
+    count(*) as total
+  from
+    orders
+
+  union
+
+  select
+    count(*) as total
+  from
+    customer
+) table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion5.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion5.sql
new file mode 100644
index 0000000..1d83c5c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion5.sql
@@ -0,0 +1,20 @@
+select
+  count(*)
+from (
+
+  select
+    count(*) as total
+  from
+    orders
+  WHERE
+    o_orderkey > 0
+
+  union
+
+  select
+    count(*) as total
+  from
+    customer
+  WHERE
+    c_custkey > 0
+) table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion6.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion6.sql
new file mode 100644
index 0000000..300cb46
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion6.sql
@@ -0,0 +1,15 @@
+SELECT
+  count(*)
+FROM (
+  SELECT
+    *
+  FROM
+    lineitem
+
+  UNION
+
+  SELECT
+    *
+  FROM
+    lineitem
+) T
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion7.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion7.sql
new file mode 100644
index 0000000..ad3f7d2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion7.sql
@@ -0,0 +1,18 @@
+SELECT
+  orderkey
+FROM (
+  SELECT
+    l_orderkey as orderkey
+  FROM
+    lineitem
+
+  UNION
+
+  SELECT
+    l_orderkey as orderkey
+  FROM
+    lineitem
+) T
+
+order by
+  orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion8.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion8.sql
new file mode 100644
index 0000000..aa8333d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion8.sql
@@ -0,0 +1,24 @@
+SELECT
+  l_returnflag,
+  l_linestatus
+
+FROM (
+  SELECT
+    *
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+
+  UNION
+
+  SELECT
+    *
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+GROUP BY
+  l_returnflag,
+  l_linestatus;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion9.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion9.sql
new file mode 100644
index 0000000..7b0811a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnion9.sql
@@ -0,0 +1,29 @@
+SELECT
+  n_nationkey,
+  n_name
+
+FROM (
+  SELECT
+    *
+  FROM
+    nation
+  WHERE
+    n_regionkey = 0
+
+
+  UNION
+
+  SELECT
+    *
+  FROM
+    nation
+  WHERE
+    n_regionkey = 0
+
+) T
+GROUP BY
+  n_nationkey,
+	n_name
+ORDER BY
+  n_nationkey desc,
+  n_name desc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll1.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll1.sql
new file mode 100644
index 0000000..363512c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll1.sql
@@ -0,0 +1,19 @@
+select
+  num
+from (
+
+select
+  o_custkey as num
+from
+  orders
+
+union all
+
+select
+  c_custkey as num
+from
+  customer
+) table1
+
+order by
+  num;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll10.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll10.sql
new file mode 100644
index 0000000..97c8364
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll10.sql
@@ -0,0 +1,158 @@
+SELECT * FROM (
+  SELECT
+    *
+  FROM (
+    SELECT
+      n_nationkey,
+      n_name
+
+    FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+
+      UNION ALL
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+    ) T1
+    GROUP BY
+      n_nationkey,
+      n_name
+    ORDER BY
+      n_nationkey desc,
+      n_name desc
+
+   UNION all
+
+   SELECT
+    n_nationkey,
+    n_name
+
+   FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+      UNION ALL
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+   ) T2
+
+   GROUP BY
+     n_nationkey,
+     n_name
+
+   ORDER BY
+     n_nationkey desc,
+     n_name desc
+
+  ) TABLE1
+
+  ORDER BY
+    n_nationkey,
+    n_name
+
+  UNION all
+
+  SELECT
+    *
+  FROM (
+    SELECT
+      n_nationkey,
+      n_name
+
+    FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+
+      UNION ALL
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+    ) T3
+    GROUP BY
+      n_nationkey,
+      n_name
+    ORDER BY
+      n_nationkey desc,
+      n_name desc
+
+   UNION all
+
+   SELECT
+    n_nationkey,
+    n_name
+
+   FROM (
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+
+      UNION ALL
+
+      SELECT
+        n_nationkey,
+        n_name
+      FROM
+        nation
+      WHERE
+        n_regionkey = 0
+   ) T4
+
+   GROUP BY
+     n_nationkey,
+     n_name
+
+   ORDER BY
+     n_nationkey desc,
+     n_name desc
+
+  ) TABLE2
+
+  ORDER BY
+    n_nationkey,
+    n_name
+
+) TABLE3
+
+ORDER BY
+  n_nationkey,
+  n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll11.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll11.sql
new file mode 100644
index 0000000..ec1a430
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll11.sql
@@ -0,0 +1,8 @@
+select col1, col2, col3
+from (
+    select L_RETURNFLAG as col1, L_EXTENDEDPRICE as col2, concat(L_RECEIPTDATE, L_LINESTATUS) as col3 from lineitem
+    union all
+    select P_TYPE as col1, P_RETAILPRICE col2, P_NAME col3 from part
+) a
+where col3 like '1993%' and col2 > 46796
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll12.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll12.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll12.sql
new file mode 100644
index 0000000..6b6a9ad
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll12.sql
@@ -0,0 +1,13 @@
+select col1, col2, col3
+from (
+    select
+        col1, col2, col3
+    from
+        (select
+            L_RETURNFLAG as col1, L_EXTENDEDPRICE as col2, concat(L_RECEIPTDATE, L_LINESTATUS) as col3
+        from
+            lineitem) b
+    union all
+    select P_TYPE as col1, P_RETAILPRICE * 100 col2, concat('1993', P_NAME) col3 from part
+) a
+where col3 like '1993%' and col2 > 46796

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll13.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll13.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll13.sql
new file mode 100644
index 0000000..70b0891
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll13.sql
@@ -0,0 +1,14 @@
+select col1, col2, col3
+from (
+    select
+        col1, col2, col3
+    from
+        (select
+            L_RETURNFLAG as col1, L_EXTENDEDPRICE as col2, concat(L_RECEIPTDATE, L_LINESTATUS) as col3
+        from
+            lineitem
+        where col2 > 46796) b
+    union all
+    select P_TYPE as col1, P_RETAILPRICE * 100 col2, concat('1993', P_NAME) col3 from part
+) a
+where col3 like '1993%'

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll14.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll14.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll14.sql
new file mode 100644
index 0000000..f47510e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll14.sql
@@ -0,0 +1,8 @@
+select col1, cnt
+from (
+    select L_RETURNFLAG as col1, count(*) as cnt from lineitem group by col1
+    union all
+    select cast(n_regionkey as TEXT) as col1, count(*) as cnt from nation group by col1
+) a
+where a.cnt > 1
+order by a.col1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll15.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll15.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll15.sql
new file mode 100644
index 0000000..2e382d0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll15.sql
@@ -0,0 +1,15 @@
+select col1, sum(cnt)
+from (
+    select col1, cnt
+    from (  select l_returnflag col1, count(*) cnt from lineitem
+            join orders on l_orderkey = o_orderkey and o_custkey > 0
+            group by l_returnflag) b
+    where col1 = 'N'
+    union all
+    select cast(n_regionkey as TEXT) as col1, count(*) as cnt from nation
+    where n_regionkey > 2
+    group by col1
+) a
+where round(cast(a.cnt as FLOAT4)) > 1.0
+group by a.col1
+order by a.col1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll16.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll16.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll16.sql
new file mode 100644
index 0000000..59e9c1f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll16.sql
@@ -0,0 +1,15 @@
+select col1, sum(cnt)
+from (
+    select col1, cnt
+    from (  select l_returnflag col1, count(distinct l_orderkey) cnt from lineitem
+            join orders on l_orderkey = o_orderkey and o_custkey > 0
+            group by l_returnflag) b
+    where col1 = 'N'
+    union all
+    select cast(n_regionkey as TEXT) as col1, count(*) as cnt from nation
+    where n_regionkey > 2
+    group by col1
+) a
+where round(cast(a.cnt as FLOAT4)) > 1.0
+group by a.col1
+order by a.col1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll2.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll2.sql
new file mode 100644
index 0000000..e5fa5d2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll2.sql
@@ -0,0 +1,18 @@
+select
+  l_orderkey
+from (
+  select
+    l_orderkey
+  from
+    lineitem l1
+
+  union all
+
+  select
+    l_orderkey
+  from
+    lineitem l2
+) table1
+
+order by
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll3.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll3.sql
new file mode 100644
index 0000000..68266ec
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll3.sql
@@ -0,0 +1,19 @@
+select
+  total
+from (
+
+select
+  count(*) as total
+from
+  orders
+
+union all
+
+select
+  count(*) as total
+from
+  customer
+) table1
+
+order by
+  total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll4.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll4.sql
new file mode 100644
index 0000000..31dce06
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll4.sql
@@ -0,0 +1,16 @@
+select
+  count(*)
+from (
+
+  select
+    count(*) as total
+  from
+    orders
+
+  union all
+
+  select
+    count(*) as total
+  from
+    customer
+) table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll5.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll5.sql
new file mode 100644
index 0000000..8a55799
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll5.sql
@@ -0,0 +1,20 @@
+select
+  count(*)
+from (
+
+  select
+    count(*) as total
+  from
+    orders
+  WHERE
+    o_orderkey > 0
+
+  union all
+
+  select
+    count(*) as total
+  from
+    customer
+  WHERE
+    c_custkey > 0
+) table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll6.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll6.sql
new file mode 100644
index 0000000..8052632
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll6.sql
@@ -0,0 +1,15 @@
+SELECT
+  count(*)
+FROM (
+  SELECT
+    *
+  FROM
+    lineitem
+
+  UNION ALL
+
+  SELECT
+    *
+  FROM
+    lineitem
+) T
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll7.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll7.sql
new file mode 100644
index 0000000..3592a6a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll7.sql
@@ -0,0 +1,18 @@
+SELECT
+  orderkey
+FROM (
+  SELECT
+    l_orderkey as orderkey
+  FROM
+    lineitem
+
+  UNION all
+
+  SELECT
+    l_orderkey as orderkey
+  FROM
+    lineitem
+) T
+
+order by
+  orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll8.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll8.sql
new file mode 100644
index 0000000..bf5fbee
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll8.sql
@@ -0,0 +1,24 @@
+SELECT
+  l_returnflag,
+  l_linestatus
+
+FROM (
+  SELECT
+    *
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+
+  UNION ALL
+
+  SELECT
+    *
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+GROUP BY
+  l_returnflag,
+  l_linestatus;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll9.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll9.sql
new file mode 100644
index 0000000..49ddca8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAll9.sql
@@ -0,0 +1,29 @@
+SELECT
+  n_nationkey,
+  n_name
+
+FROM (
+  SELECT
+    *
+  FROM
+    nation
+  WHERE
+    n_regionkey = 0
+
+
+  UNION ALL
+
+  SELECT
+    *
+  FROM
+    nation
+  WHERE
+    n_regionkey = 0
+
+) T
+GROUP BY
+  n_nationkey,
+	n_name
+ORDER BY
+  n_nationkey desc,
+  n_name desc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAlias.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAlias.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAlias.sql
new file mode 100644
index 0000000..f41ee32
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAlias.sql
@@ -0,0 +1,29 @@
+SELECT
+  col1,
+  col2
+
+FROM (
+  SELECT
+    l_returnflag col1, l_linestatus col2, l_orderkey col3
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'N'
+
+  UNION ALL
+
+  SELECT
+    l_returnflag col2, l_linestatus col5, l_orderkey col6
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+
+GROUP BY
+  col1,
+	col2
+
+ORDER BY
+  col1,
+	col2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAliasAndFunction.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAliasAndFunction.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAliasAndFunction.sql
new file mode 100644
index 0000000..598f399
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithDifferentAliasAndFunction.sql
@@ -0,0 +1,29 @@
+SELECT
+  col1,
+  col2
+
+FROM (
+  SELECT
+    l_returnflag col1, concat(l_linestatus, l_shipdate) col2, l_orderkey col3
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'N'
+
+  UNION ALL
+
+  SELECT
+    concat(l_returnflag, l_shipdate) col3, l_linestatus col4, l_orderkey col5
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+
+GROUP BY
+  col1,
+	col2
+
+ORDER BY
+  col1,
+	col2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithSameAliasNames.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithSameAliasNames.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithSameAliasNames.sql
new file mode 100644
index 0000000..1516697
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionAllWithSameAliasNames.sql
@@ -0,0 +1,25 @@
+select
+  *
+from (
+  select
+    l_orderkey
+  from (
+    select
+      l_orderkey
+    from
+      lineitem
+  ) l1
+
+  union all
+
+  select
+    l_orderkey
+  from (
+    select
+      l_orderkey
+    from
+      lineitem
+  ) l1
+) t1
+order by
+  l_orderkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAlias.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAlias.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAlias.sql
new file mode 100644
index 0000000..9fb0146
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAlias.sql
@@ -0,0 +1,29 @@
+SELECT
+  col1,
+  col2
+
+FROM (
+  SELECT
+    l_returnflag col1, l_linestatus col2, l_orderkey col3
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'N'
+
+  UNION
+
+  SELECT
+    l_returnflag col2, l_linestatus col5, l_orderkey col6
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+
+GROUP BY
+  col1,
+	col2
+
+ORDER BY
+  col1,
+	col2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAliasAndFunction.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAliasAndFunction.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAliasAndFunction.sql
new file mode 100644
index 0000000..35048cc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithDifferentAliasAndFunction.sql
@@ -0,0 +1,29 @@
+SELECT
+  col1,
+  col2
+
+FROM (
+  SELECT
+    l_returnflag col1, concat(l_linestatus, l_shipdate) col2, l_orderkey col3
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'N'
+
+  UNION
+
+  SELECT
+    concat(l_returnflag, l_shipdate) col3, l_linestatus col4, l_orderkey col5
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+
+GROUP BY
+  col1,
+	col2
+
+ORDER BY
+  col1,
+	col2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithSameAliasNames.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithSameAliasNames.sql b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithSameAliasNames.sql
new file mode 100644
index 0000000..c39940c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestUnionQuery/testUnionWithSameAliasNames.sql
@@ -0,0 +1,25 @@
+select
+  *
+from (
+  select
+    l_orderkey
+  from (
+    select
+      l_orderkey
+    from
+      lineitem
+  ) l1
+
+  union
+
+  select
+    l_orderkey
+  from (
+    select
+      l_orderkey
+    from
+      lineitem
+  ) l1
+) t1
+order by
+  l_orderkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testComplexOrderBy1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testComplexOrderBy1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testComplexOrderBy1.sql
new file mode 100644
index 0000000..171815c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testComplexOrderBy1.sql
@@ -0,0 +1,5 @@
+select
+  l_orderkey,
+  row_number() over (order by l_quantity * (1 - l_discount)) row_num
+from
+  lineitem
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testFirstValue1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testFirstValue1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testFirstValue1.sql
new file mode 100644
index 0000000..e9c9c73
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testFirstValue1.sql
@@ -0,0 +1,18 @@
+SELECT
+  l_orderkey,
+  first_value(l_shipmode) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_first,
+  first_value(l_linenumber) over (PARTITION BY L_ORDERKEY order by l_linenumber ) as linenumber_first,
+  first_value(l_suppkey_t) over (PARTITION BY L_ORDERKEY order by l_suppkey_t ) as suppkey_first,
+  first_value(l_shipdate_t) over (PARTITION BY L_ORDERKEY order by l_shipdate_t ) as shipdate_first,
+  first_value(l_commitdate_t) over (PARTITION BY L_ORDERKEY order by l_commitdate_t ) as commitdate_first,
+  first_value(l_extendedprice) over (PARTITION BY L_ORDERKEY order by l_extendedprice ) as extendedprice_first,
+  first_value(l_discount_t) over (PARTITION BY L_ORDERKEY order by l_discount_t ) as discount_first
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLag1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLag1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLag1.sql
new file mode 100644
index 0000000..1fd1e9e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLag1.sql
@@ -0,0 +1,18 @@
+SELECT
+  lag(l_shipmode, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_lag,
+  lag(l_linenumber, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_lag,
+  lag(l_suppkey_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_lag,
+  lag(l_shipdate_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipdate_lag,
+  lag(l_commitdate_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as commitdate_lag,
+  lag(l_extendedprice, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_lag,
+  lag(l_discount_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_lag,
+  l_orderkey
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithDefault.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithDefault.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithDefault.sql
new file mode 100644
index 0000000..3638498
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithDefault.sql
@@ -0,0 +1,18 @@
+SELECT
+  lag(l_shipmode, 1, 'default') over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_lag,
+  lag(l_linenumber, 1, 100) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_lag,
+  lag(l_suppkey_t, 1, 1000::int8) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_lag,
+  lag(l_shipdate_t, 1, '15-01-01'::date) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipdate_lag,
+  lag(l_commitdate_t, 1, '15-01-01 12:00:00'::timestamp) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as commitdate_lag,
+  lag(l_extendedprice, 1, 1.234::float8) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_lag,
+  lag(l_discount_t, 1, 0.11::float4) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_lag,
+  l_orderkey
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithNoArgs.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithNoArgs.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithNoArgs.sql
new file mode 100644
index 0000000..1d551d6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLagWithNoArgs.sql
@@ -0,0 +1,18 @@
+SELECT
+  lag(l_shipmode) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_lag,
+  lag(l_linenumber) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_lag,
+  lag(l_suppkey_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_lag,
+  lag(l_shipdate_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipdate_lag,
+  lag(l_commitdate_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as commitdate_lag,
+  lag(l_extendedprice) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_lag,
+  lag(l_discount_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_lag,
+  l_orderkey
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLastValue1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLastValue1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLastValue1.sql
new file mode 100644
index 0000000..150b912
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLastValue1.sql
@@ -0,0 +1,18 @@
+SELECT
+  l_orderkey,
+  last_value(l_shipmode) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_last,
+  last_value(l_linenumber) over (PARTITION BY L_ORDERKEY order by l_linenumber ) as linenumber_last,
+  last_value(l_suppkey_t) over (PARTITION BY L_ORDERKEY order by l_suppkey_t ) as suppkey_last,
+  last_value(l_shipdate_t) over (PARTITION BY L_ORDERKEY order by l_shipdate_t ) as shipdate_last,
+  last_value(l_commitdate_t) over (PARTITION BY L_ORDERKEY order by l_commitdate_t ) as commitdate_last,
+  last_value(l_extendedprice) over (PARTITION BY L_ORDERKEY order by l_extendedprice ) as extendedprice_last,
+  last_value(l_discount_t) over (PARTITION BY L_ORDERKEY order by l_discount_t ) as discount_last
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file


[40/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestUniformRangePartition.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestUniformRangePartition.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestUniformRangePartition.java
new file mode 100644
index 0000000..178af47
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestUniformRangePartition.java
@@ -0,0 +1,1143 @@
+/**
+ * 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.planner;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.SortSpec;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.BaseTupleComparator;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.TupleRange;
+import org.apache.tajo.storage.VTuple;
+import org.junit.Test;
+
+import java.math.BigInteger;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestUniformRangePartition {
+
+  @Test
+  public void testPartitionForINT2Asc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.INT2);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createInt2((short) 1));
+    e.put(0, DatumFactory.createInt2((short) 30000));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForINT2Desc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.INT2);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createInt2((short) 30000));
+    e.put(0, DatumFactory.createInt2((short) 1));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForINT4Asc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.INT4);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createInt4(1));
+    e.put(0, DatumFactory.createInt4(10000));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForINT4Desc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.INT4);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createInt4(10000));
+    e.put(0, DatumFactory.createInt4(1));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForINT8Asc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.INT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createInt8(1));
+    e.put(0, DatumFactory.createInt8(10000));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForInt8Desc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.INT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createInt8(10000));
+    e.put(0, DatumFactory.createInt8(1));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForFloat4Asc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.FLOAT4);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createFloat4((float) 1.0));
+    e.put(0, DatumFactory.createFloat4((float) 10000.0));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForFloat4Desc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.FLOAT4);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createFloat4((float) 10000.0));
+    e.put(0, DatumFactory.createFloat4((float) 1.0));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForFloat8Asc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.FLOAT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createFloat8(1.0));
+    e.put(0, DatumFactory.createFloat8(10000.0));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForFloat8Desc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.FLOAT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createFloat8((float) 10000.0));
+    e.put(0, DatumFactory.createFloat8((float) 1.0));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  /**
+   * It verify overflow and increment in normal case.
+   */
+  @Test
+  public void testIncrementOfText() {
+    Schema schema = new Schema()
+        .addColumn("l_returnflag", Type.TEXT)
+        .addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec[] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createText("A"));
+    s.put(1, DatumFactory.createText("A"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createText("D"));
+    e.put(1, DatumFactory.createText("C"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(12, partitioner.getTotalCardinality().intValue());
+
+    String [] result = new String[12];
+    result[0] = "AA";
+    result[1] = "AB";
+    result[2] = "AC";
+    result[3] = "BA";
+    result[4] = "BB";
+    result[5] = "BC";
+    result[6] = "CA";
+    result[7] = "CB";
+    result[8] = "CC";
+    result[9] = "DA";
+    result[10] = "DB";
+    result[11] = "DC";
+
+    Tuple end = partitioner.increment(s, BigInteger.valueOf(1), 1);
+    assertEquals("A", end.getText(0));
+    assertEquals("B", end.getText(1));
+    for (int i = 2; i < 11; i++ ) {
+      end = partitioner.increment(end, BigInteger.valueOf(1), 1);
+      assertEquals(result[i].charAt(0), end.getText(0).charAt(0));
+      assertEquals(result[i].charAt(1), end.getText(1).charAt(0));
+    }
+  }
+
+  /**
+   * It verify overflow with the number that exceeds the last digit.
+   */
+  @Test
+  public void testIncrementOfText2() {
+    Schema schema = new Schema()
+        .addColumn("l_returnflag", Type.TEXT)
+        .addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createText("A"));
+    s.put(1, DatumFactory.createText("A"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createText("D"));
+    e.put(1, DatumFactory.createText("C"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(12, partitioner.getTotalCardinality().intValue());
+
+    String [] result = new String[12];
+    result[0] = "AA";
+    result[1] = "AB";
+    result[2] = "AC";
+    result[3] = "BA";
+    result[4] = "BB";
+    result[5] = "BC";
+    result[6] = "CA";
+    result[7] = "CB";
+    result[8] = "CC";
+    result[9] = "DA";
+    result[10] = "DB";
+    result[11] = "DC";
+
+    Tuple end = partitioner.increment(s, BigInteger.valueOf(6), 1);
+    assertEquals("C", end.getText(0));
+    assertEquals("A", end.getText(1));
+    end = partitioner.increment(end, BigInteger.valueOf(5), 1);
+    assertEquals("D", end.getText(0));
+    assertEquals("C", end.getText(1));
+  }
+
+  /**
+   * It verify the case where two or more digits are overflow.
+   */
+  @Test
+  public void testIncrementOfText3() {
+    Schema schema = new Schema()
+        .addColumn("l_returnflag", Type.TEXT)
+        .addColumn("l_linestatus", Type.TEXT)
+        .addColumn("final", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(3);
+    s.put(0, DatumFactory.createText("A"));
+    s.put(1, DatumFactory.createText("A"));
+    s.put(2, DatumFactory.createText("A"));
+    VTuple e = new VTuple(3);
+    e.put(0, DatumFactory.createText("D")); //  4
+    e.put(1, DatumFactory.createText("B")); //  2
+    e.put(2, DatumFactory.createText("C")); // x3 = 24
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(24, partitioner.getTotalCardinality().intValue());
+
+    Tuple overflowBefore = partitioner.increment(s, BigInteger.valueOf(5), 2);
+    assertEquals("A", overflowBefore.getText(0));
+    assertEquals("B", overflowBefore.getText(1));
+    assertEquals("C", overflowBefore.getText(2));
+    Tuple overflowed = partitioner.increment(overflowBefore, BigInteger.valueOf(1), 2);
+    assertEquals("B", overflowed.getText(0));
+    assertEquals("A", overflowed.getText(1));
+    assertEquals("A", overflowed.getText(2));
+  }
+
+  @Test
+  public void testIncrementOfUnicode() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("가가가"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("하하하"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    BaseTupleComparator comp = new BaseTupleComparator(schema, sortSpecs);
+
+    Tuple tuple = s;
+    Tuple prevTuple = null;
+    for (int i = 0; i < 100; i++) {
+      tuple = partitioner.increment(tuple, BigInteger.valueOf(30000), 0);
+      if (prevTuple != null) {
+        assertTrue("prev=" + prevTuple + ", current=" + tuple, comp.compare(prevTuple, tuple) < 0);
+      }
+      prevTuple = tuple;
+    }
+  }
+
+  @Test
+  public void testIncrementOfUnicodeOneCharSinglePartition() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("가"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("다"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 1;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testIncrementOfUnicodeOneCharMultiPartition() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("가"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("꽥"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 8;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForUnicodeTextAsc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createText("가가가"));
+    e.put(0, DatumFactory.createText("하하하"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForUnicodeDiffLenBeginTextAsc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createText("가"));
+    e.put(0, DatumFactory.createText("하하하"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForUnicodeDiffLenEndTextAsc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createText("가가가"));
+    e.put(0, DatumFactory.createText("하"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForUnicodeTextDesc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createText("하하하"));
+    e.put(0, DatumFactory.createText("가가가"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForUnicodeDiffLenBeginTextDesc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createText("하"));
+    e.put(0, DatumFactory.createText("가가가"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForUnicodeDiffLenEndTextDesc() {
+    Schema schema = new Schema()
+        .addColumn("col1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    VTuple e = new VTuple(1);
+    s.put(0, DatumFactory.createText("하"));
+    e.put(0, DatumFactory.createText("가가가"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    int partNum = 64;
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testIncrementOfInt8() {
+    Schema schema = new Schema()
+        .addColumn("l_orderkey", Type.INT8)
+        .addColumn("l_linenumber", Type.INT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createInt8(10));
+    s.put(1, DatumFactory.createInt8(20));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createInt8(19));
+    e.put(1, DatumFactory.createInt8(39));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(200, partitioner.getTotalCardinality().longValue());
+
+    Tuple range2 = partitioner.increment(s, BigInteger.valueOf(100), 1);
+    assertEquals(15, range2.getInt4(0));
+    assertEquals(20, range2.getInt4(1));
+    Tuple range3 = partitioner.increment(range2, BigInteger.valueOf(99), 1);
+    assertEquals(19, range3.getInt4(0));
+    assertEquals(39, range3.getInt4(1));
+  }
+
+  @Test public void testIncrementOfInt8AndFinal() {
+    Schema schema = new Schema()
+        .addColumn("l_orderkey", Type.INT8)
+        .addColumn("l_linenumber", Type.INT8)
+        .addColumn("final", Type.INT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(3);
+    s.put(0, DatumFactory.createInt8(1));
+    s.put(1, DatumFactory.createInt8(1));
+    s.put(2, DatumFactory.createInt8(1));
+    VTuple e = new VTuple(3);
+    e.put(0, DatumFactory.createInt8(4)); // 4
+    e.put(1, DatumFactory.createInt8(2)); // 2
+    e.put(2, DatumFactory.createInt8(3)); //x3 = 24
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(24, partitioner.getTotalCardinality().longValue());
+
+    Tuple beforeOverflow = partitioner.increment(s, BigInteger.valueOf(5), 2);
+    assertEquals(1, beforeOverflow.getInt8(0));
+    assertEquals(2, beforeOverflow.getInt8(1));
+    assertEquals(3, beforeOverflow.getInt8(2));
+    Tuple overflow = partitioner.increment(beforeOverflow, BigInteger.valueOf(1), 2);
+    assertEquals(2, overflow.getInt8(0));
+    assertEquals(1, overflow.getInt8(1));
+    assertEquals(1, overflow.getInt8(2));
+  }
+
+  @Test
+  public void testIncrementOfFloat8() {
+    Schema schema = new Schema()
+        .addColumn("l_orderkey", Type.FLOAT8)
+        .addColumn("l_linenumber", Type.FLOAT8)
+        .addColumn("final", Type.FLOAT8);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(3);
+    s.put(0, DatumFactory.createFloat8(1.1d));
+    s.put(1, DatumFactory.createFloat8(1.1d));
+    s.put(2, DatumFactory.createFloat8(1.1d));
+    VTuple e = new VTuple(3);
+    e.put(0, DatumFactory.createFloat8(4.1d)); // 4
+    e.put(1, DatumFactory.createFloat8(2.1d)); // 2
+    e.put(2, DatumFactory.createFloat8(3.1d)); //x3 = 24
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(24, partitioner.getTotalCardinality().longValue());
+
+    Tuple beforeOverflow = partitioner.increment(s, BigInteger.valueOf(5), 2);
+    assertTrue(1.1d == beforeOverflow.getFloat8(0));
+    assertTrue(2.1d == beforeOverflow.getFloat8(1));
+    assertTrue(3.1d == beforeOverflow.getFloat8(2));
+    Tuple overflow = partitioner.increment(beforeOverflow, BigInteger.valueOf(1), 2);
+    assertTrue(2.1d == overflow.getFloat8(0));
+    assertTrue(1.1d == overflow.getFloat8(1));
+    assertTrue(1.1d == overflow.getFloat8(2));
+  }
+
+  @Test
+  public void testIncrementOfInet4() {
+    Schema schema = new Schema()
+        .addColumn("l_orderkey", Type.INET4)
+        .addColumn("l_linenumber", Type.INET4)
+        .addColumn("final", Type.INET4);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(3);
+    s.put(0, DatumFactory.createInet4("127.0.1.1"));
+    s.put(1, DatumFactory.createInet4("127.0.0.1"));
+    s.put(2, DatumFactory.createInet4("128.0.0.253"));
+    VTuple e = new VTuple(3);
+    e.put(0, DatumFactory.createInet4("127.0.1.4")); // 4
+    e.put(1, DatumFactory.createInet4("127.0.0.2")); // 2
+    e.put(2, DatumFactory.createInet4("128.0.0.255")); //x3 = 24
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+
+    UniformRangePartition partitioner = new UniformRangePartition(expected, sortSpecs);
+    assertEquals(24, partitioner.getTotalCardinality().longValue());
+
+    Tuple beforeOverflow = partitioner.increment(s, BigInteger.valueOf(5), 2);
+    assertTrue("127.0.1.1".equals(beforeOverflow.getText(0)));
+    assertTrue("127.0.0.2".equals(beforeOverflow.getText(1)));
+    assertTrue("128.0.0.255".equals(beforeOverflow.getText(2)));
+    Tuple overflow = partitioner.increment(beforeOverflow, BigInteger.valueOf(1), 2);
+    assertTrue("127.0.1.2".equals(overflow.getText(0)));
+    assertTrue("127.0.0.1".equals(overflow.getText(1)));
+    assertTrue("128.0.0.253".equals(overflow.getText(2)));
+  }
+
+  @Test
+  public void testPartition() {
+    Schema schema = new Schema();
+    schema.addColumn("l_returnflag", Type.TEXT);
+    schema.addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createText("A"));
+    s.put(1, DatumFactory.createText("F"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createText("R"));
+    e.put(1, DatumFactory.createText("O"));
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner
+        = new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(31);
+
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+  }
+
+  @Test
+  public void testPartitionForOnePartNum() {
+    Schema schema = new Schema()
+        .addColumn("l_returnflag", Type.TEXT)
+        .addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createText("A"));
+    s.put(1, DatumFactory.createText("F"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createText("R"));
+    e.put(1, DatumFactory.createText("O"));
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(1);
+
+    assertEquals(expected, ranges[0]);
+  }
+
+  @Test
+  public void testPartitionForOnePartNumWithOneOfTheValueNull() {
+    Schema schema = new Schema()
+        .addColumn("l_returnflag", Type.TEXT)
+        .addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createNullDatum());
+    s.put(1, DatumFactory.createText("F"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createText("R"));
+    e.put(1, DatumFactory.createNullDatum());
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(1);
+
+    assertEquals(expected, ranges[0]);
+  }
+
+  @Test
+  public void testPartitionForMultipleChars() {
+    Schema schema = new Schema()
+        .addColumn("KEY1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("AAA"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("ZZZ"));
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(48);
+
+    TupleRange prev = null;
+    for (int i = 0; i < ranges.length; i++) {
+      if (prev != null) {
+        assertTrue(i + "th, prev=" + prev + ",cur=" + ranges[i], prev.compareTo(ranges[i]) < 0);
+      }
+      prev = ranges[i];
+    }
+    assertEquals(48, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[47].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForMultipleChars2() {
+    Schema schema = new Schema()
+        .addColumn("KEY1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("A1"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("A999975"));
+
+    final int partNum = 2;
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForMultipleChars2Desc() {
+    Schema schema = new Schema()
+        .addColumn("KEY1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+    sortSpecs[0].setDescOrder();
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("A999975"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("A1"));
+
+    final int partNum = 48;
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForMultipleCharsWithSameFirstChar() {
+    Schema schema = new Schema()
+        .addColumn("KEY1", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createText("AAA"));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createText("AAZ"));
+
+    final int partNum = 4;
+
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(partNum);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+    assertEquals(partNum, ranges.length);
+    assertTrue(ranges[0].getStart().equals(s));
+    assertTrue(ranges[partNum - 1].getEnd().equals(e));
+  }
+
+  @Test
+  public void testPartitionForOnePartNumWithBothValueNull() {
+    Schema schema = new Schema()
+        .addColumn("l_returnflag", Type.TEXT)
+        .addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createNullDatum());
+    s.put(1, DatumFactory.createNullDatum());
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createNullDatum());
+    e.put(1, DatumFactory.createNullDatum());
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner =
+        new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(1);
+
+    assertEquals(expected, ranges[0]);
+  }
+
+  @Test
+  public void testPartitionWithNull() {
+    Schema schema = new Schema();
+    schema.addColumn("l_returnflag", Type.TEXT);
+    schema.addColumn("l_linestatus", Type.TEXT);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createNullDatum());
+    s.put(1, DatumFactory.createText("F"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createNullDatum());
+    e.put(1, DatumFactory.createText("O"));
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner
+        = new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(10);
+
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+  }
+
+  @Test
+  public void testPartitionWithINET4() {
+    Schema schema = new Schema();
+    schema.addColumn("l_returnflag", Type.INET4);
+    schema.addColumn("l_linestatus", Type.INET4);
+
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(2);
+    s.put(0, DatumFactory.createInet4("127.0.1.10"));
+    s.put(1, DatumFactory.createInet4("127.0.2.10"));
+    VTuple e = new VTuple(2);
+    e.put(0, DatumFactory.createInet4("127.0.1.20"));
+    e.put(1, DatumFactory.createInet4("127.0.2.20"));
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner
+        = new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(10);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev != null) {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+      prev = r;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/global/TestMasterPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/global/TestMasterPlan.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/global/TestMasterPlan.java
new file mode 100644
index 0000000..817d27a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/global/TestMasterPlan.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.planner.global;
+
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.junit.Test;
+
+import static org.apache.tajo.plan.serder.PlanProto.ShuffleType;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestMasterPlan {
+
+  @Test
+  public void testConnect() {
+    MasterPlan masterPlan = new MasterPlan(LocalTajoTestingUtility.newQueryId(), null, null);
+
+    ExecutionBlock eb1 = masterPlan.newExecutionBlock();
+    ExecutionBlock eb2 = masterPlan.newExecutionBlock();
+    ExecutionBlock eb3 = masterPlan.newExecutionBlock();
+
+    masterPlan.addConnect(eb1, eb2, ShuffleType.RANGE_SHUFFLE);
+    assertTrue(masterPlan.isConnected(eb1.getId(), eb2.getId()));
+    assertTrue(masterPlan.isReverseConnected(eb2.getId(), eb1.getId()));
+
+    masterPlan.addConnect(eb3, eb2, ShuffleType.RANGE_SHUFFLE);
+    assertTrue(masterPlan.isConnected(eb1.getId(), eb2.getId()));
+    assertTrue(masterPlan.isConnected(eb3.getId(), eb2.getId()));
+
+    assertTrue(masterPlan.isReverseConnected(eb2.getId(), eb1.getId()));
+    assertTrue(masterPlan.isReverseConnected(eb2.getId(), eb3.getId()));
+
+    masterPlan.disconnect(eb3, eb2);
+    assertFalse(masterPlan.isConnected(eb3, eb2));
+    assertFalse(masterPlan.isReverseConnected(eb2, eb3));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestBNLJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestBNLJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestBNLJoinExec.java
new file mode 100644
index 0000000..71bad20
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestBNLJoinExec.java
@@ -0,0 +1,224 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestBNLJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestBNLJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+
+  private static int OUTER_TUPLE_NUM = 1000;
+  private static int INNER_TUPLE_NUM = 1000;
+
+  private TableDesc employee;
+  private TableDesc people;
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema schema = new Schema();
+    schema.addColumn("managerid", Type.INT4);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("memid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, schema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(schema.size());
+    for (int i = 0; i < OUTER_TUPLE_NUM; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+    employee = CatalogUtil.newTableDesc("default.employee", schema, employeeMeta, employeePath);
+    catalog.createTable(employee);
+
+    Schema peopleSchema = new Schema();
+    peopleSchema.addColumn("empid", Type.INT4);
+    peopleSchema.addColumn("fk_memid", Type.INT4);
+    peopleSchema.addColumn("name", Type.TEXT);
+    peopleSchema.addColumn("age", Type.INT4);
+    TableMeta peopleMeta = CatalogUtil.newTableMeta("TEXT");
+    Path peoplePath = new Path(testDir, "people.csv");
+    appender = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(peopleMeta, peopleSchema, peoplePath);
+    appender.init();
+    tuple = new VTuple(peopleSchema.size());
+    for (int i = 1; i < INNER_TUPLE_NUM; i += 2) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(30 + i) });
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+
+    people = CatalogUtil.newTableDesc("default.people", peopleSchema, peopleMeta, peoplePath);
+    catalog.createTable(people);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  // employee (managerId, empId, memId, deptName)
+  // people (empId, fk_memId, name, age)
+  String[] QUERIES = {
+      "select managerId, e.empId, deptName, e.memId from employee as e, people p",
+      "select managerId, e.empId, deptName, e.memId from employee as e " +
+          "inner join people as p on e.empId = p.empId and e.memId = p.fk_memId" };
+
+  @Test
+  public final void testBNLCrossJoin() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf),
+        expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.BLOCK_NESTED_LOOP_JOIN);
+
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testBNLCrossJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof BNLJoinExec);
+
+    int i = 0;
+    exec.init();
+    while (exec.next() != null) {
+      i++;
+    }
+    exec.close();
+    assertEquals(OUTER_TUPLE_NUM * INNER_TUPLE_NUM / 2, i); // expected 10 * 5
+  }
+
+  @Test
+  public final void testBNLInnerJoin() throws IOException, TajoException {
+    Expr context = analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf),
+        context).getRootBlock().getRoot();
+
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.BLOCK_NESTED_LOOP_JOIN);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testBNLInnerJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(),
+        merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof BNLJoinExec);
+
+    Tuple tuple;
+    int i = 1;
+    int count = 0;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      count++;
+      assertTrue(i == tuple.getInt4(0));
+      assertTrue(i == tuple.getInt4(1));
+      assertTrue(("dept_" + i).equals(tuple.getText(2)));
+      assertTrue(10 + i == tuple.getInt4(3));
+      i += 2;
+    }
+    exec.close();
+    assertEquals(INNER_TUPLE_NUM / 2, count);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestExternalSortExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestExternalSortExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestExternalSortExec.java
new file mode 100644
index 0000000..4ae880f
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestExternalSortExec.java
@@ -0,0 +1,187 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.catalog.*;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Random;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestExternalSortExec {
+  private TajoConf conf;
+  private TajoTestingCluster util;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestExternalSortExec";
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+
+  private final int numTuple = 100000;
+  private Random rnd = new Random(System.currentTimeMillis());
+
+  private TableDesc employee;
+
+  @Before
+  public void setUp() throws Exception {
+    this.conf = new TajoConf();
+    util = new TajoTestingCluster();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(TajoConstants.DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf.setVar(TajoConf.ConfVars.WORKER_TEMPORAL_DIR, testDir.toString());
+
+    Schema schema = new Schema();
+    schema.addColumn("managerid", Type.INT4);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, schema, employeePath);
+    appender.enableStats();
+    appender.init();
+    VTuple tuple = new VTuple(schema.size());
+    for (int i = 0; i < numTuple; i++) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(rnd.nextInt(50)),
+          DatumFactory.createInt4(rnd.nextInt(100)),
+          DatumFactory.createText("dept_" + i),
+      });
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+
+    employee = new TableDesc("default.employee", schema, employeeMeta, employeePath.toUri());
+    catalog.createTable(employee);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    CommonTestingUtil.cleanupTestDir(TEST_PATH);
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      "select managerId, empId from employee order by managerId, empId"
+  };
+
+  @Test
+  public final void testNext() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    Path workDir = new Path(testDir, TestExternalSortExec.class.getName());
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    
+    ProjectionExec proj = (ProjectionExec) exec;
+
+    // TODO - should be planed with user's optimization hint
+    ExternalSortExec extSort;
+    if (!(proj.getChild() instanceof ExternalSortExec)) {
+      UnaryPhysicalExec sortExec = proj.getChild();
+      SeqScanExec scan = sortExec.getChild();
+
+      extSort = new ExternalSortExec(ctx, ((MemSortExec)sortExec).getPlan(), scan);
+      proj.setChild(extSort);
+    } else {
+      extSort = proj.getChild();
+    }
+    extSort.setSortBufferBytesNum(1024*1024);
+
+    Tuple tuple;
+    Tuple preVal = null;
+    Tuple curVal;
+    int cnt = 0;
+    exec.init();
+    long start = System.currentTimeMillis();
+    BaseTupleComparator comparator = new BaseTupleComparator(proj.getSchema(),
+        new SortSpec[]{
+            new SortSpec(new Column("managerid", Type.INT4)),
+            new SortSpec(new Column("empid", Type.INT4))
+        });
+
+    while ((tuple = exec.next()) != null) {
+      curVal = tuple;
+      if (preVal != null) {
+        assertTrue("prev: " + preVal + ", but cur: " + curVal, comparator.compare(preVal, curVal) <= 0);
+      }
+      preVal = new VTuple(curVal);
+      cnt++;
+    }
+    long end = System.currentTimeMillis();
+    assertEquals(numTuple, cnt);
+
+    // for rescan test
+    preVal = null;
+    exec.rescan();
+    cnt = 0;
+    while ((tuple = exec.next()) != null) {
+      curVal = tuple;
+      if (preVal != null) {
+        assertTrue("prev: " + preVal + ", but cur: " + curVal, comparator.compare(preVal, curVal) <= 0);
+      }
+      preVal = curVal;
+      cnt++;
+    }
+    assertEquals(numTuple, cnt);
+    exec.close();
+    System.out.println("Sort Time: " + (end - start) + " msc");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterHashJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterHashJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterHashJoinExec.java
new file mode 100644
index 0000000..5901c49
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterHashJoinExec.java
@@ -0,0 +1,414 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.Appender;
+import org.apache.tajo.storage.FileTablespace;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.storage.VTuple;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.*;
+
+public class TestFullOuterHashJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFullOuterHashJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+  private QueryContext defaultContext;
+
+  private TableDesc dep3;
+  private TableDesc job3;
+  private TableDesc emp3;
+  private TableDesc phone3;
+
+  private final String DEP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep3");
+  private final String JOB3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "job3");
+  private final String EMP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "emp3");
+  private final String PHONE3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "phone3");
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    //----------------- dep3 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    Schema dep3Schema = new Schema();
+    dep3Schema.addColumn("dep_id", Type.INT4);
+    dep3Schema.addColumn("dep_name", Type.TEXT);
+    dep3Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep3Path = new Path(testDir, "dep3.csv");
+    Appender appender1 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(dep3Meta, dep3Schema, dep3Path);
+    appender1.init();
+    VTuple tuple = new VTuple(dep3Schema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createText("dept_" + i),
+          DatumFactory.createInt4(1000 + i) });
+      appender1.addTuple(tuple);
+    }
+
+    appender1.flush();
+    appender1.close();
+    dep3 = CatalogUtil.newTableDesc(DEP3_NAME, dep3Schema, dep3Meta, dep3Path);
+    catalog.createTable(dep3);
+
+    //----------------- job3 ------------------------------
+    //  job_id  | job_title
+    // ----------------------
+    //   101    |  job_101
+    //   102    |  job_102
+    //   103    |  job_103
+
+    Schema job3Schema = new Schema();
+    job3Schema.addColumn("job_id", Type.INT4);
+    job3Schema.addColumn("job_title", Type.TEXT);
+
+
+    TableMeta job3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path job3Path = new Path(testDir, "job3.csv");
+    Appender appender2 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(job3Meta, job3Schema, job3Path);
+    appender2.init();
+    VTuple tuple2 = new VTuple(job3Schema.size());
+    for (int i = 1; i < 4; i++) {
+      int x = 100 + i;
+      tuple2.put(new Datum[] { DatumFactory.createInt4(100 + i),
+          DatumFactory.createText("job_" + x) });
+      appender2.addTuple(tuple2);
+    }
+
+    appender2.flush();
+    appender2.close();
+    job3 = CatalogUtil.newTableDesc(JOB3_NAME, job3Schema, job3Meta, job3Path);
+    catalog.createTable(job3);
+
+
+
+    //---------------------emp3 --------------------
+    // emp_id  | first_name | last_name | dep_id | salary | job_id
+    // ------------------------------------------------------------
+    //  11     |  fn_11     |  ln_11    |  1     | 123    | 101
+    //  13     |  fn_13     |  ln_13    |  3     | 369    | 103
+    //  15     |  fn_15     |  ln_15    |  5     | 615    | null
+    //  17     |  fn_17     |  ln_17    |  7     | 861    | null
+    //  19     |  fn_19     |  ln_19    |  9     | 1107   | null
+    //  21     |  fn_21     |  ln_21    |  1     | 123    | 101
+    //  23     |  fn_23     |  ln_23    |  3     | 369    | 103
+
+    Schema emp3Schema = new Schema();
+    emp3Schema.addColumn("emp_id", Type.INT4);
+    emp3Schema.addColumn("first_name", Type.TEXT);
+    emp3Schema.addColumn("last_name", Type.TEXT);
+    emp3Schema.addColumn("dep_id", Type.INT4);
+    emp3Schema.addColumn("salary", Type.FLOAT4);
+    emp3Schema.addColumn("job_id", Type.INT4);
+
+
+    TableMeta emp3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path emp3Path = new Path(testDir, "emp3.csv");
+    Appender appender3 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(emp3Meta, emp3Schema, emp3Path);
+    appender3.init();
+    VTuple tuple3 = new VTuple(emp3Schema.size());
+
+    for (int i = 1; i < 4; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+
+      int y = 20 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(20 + i),
+          DatumFactory.createText("firstname_" + y),
+          DatumFactory.createText("lastname_" + y),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+    }
+
+    for (int i = 5; i < 10; i += 2) {
+      int x= 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createNullDatum() });
+      appender3.addTuple(tuple3);
+    }
+
+    appender3.flush();
+    appender3.close();
+    emp3 = CatalogUtil.newTableDesc(EMP3_NAME, emp3Schema, emp3Meta, emp3Path);
+    catalog.createTable(emp3);
+
+    //---------------------phone3 --------------------
+    // emp_id  | phone_number
+    // -----------------------------------------------
+    // this table is empty, no rows
+
+    Schema phone3Schema = new Schema();
+    phone3Schema.addColumn("emp_id", Type.INT4);
+    phone3Schema.addColumn("phone_number", Type.TEXT);
+
+
+    TableMeta phone3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path phone3Path = new Path(testDir, "phone3.csv");
+    Appender appender5 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(phone3Meta, phone3Schema, phone3Path);
+    appender5.init();
+
+    appender5.flush();
+    appender5.close();
+    phone3 = CatalogUtil.newTableDesc(PHONE3_NAME, phone3Schema, phone3Meta, phone3Path);
+    catalog.createTable(phone3);
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      // [0] no nulls
+      "select dep3.dep_id, dep_name, emp_id, salary from dep3 full outer join emp3 on dep3.dep_id = emp3.dep_id",
+      // [1] nulls on the right operand
+      "select job3.job_id, job_title, emp_id, salary from job3 full outer join emp3 on job3.job_id=emp3.job_id",
+      // [2] nulls on the left side
+      "select job3.job_id, job_title, emp_id, salary from emp3 full outer join job3 on job3.job_id=emp3.job_id",
+      // [3] one operand is empty
+      "select emp3.emp_id, first_name, phone_number from emp3 full outer join phone3 on emp3.emp_id = phone3.emp_id"
+  };
+
+  @Test
+  public final void testFullOuterHashJoinExec0() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] dep3Frags = FileTablespace.splitNG(conf, DEP3_NAME, dep3.getMeta(), new Path(dep3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(dep3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFullOuterHashJoinExec0");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(12, count);
+
+  }
+
+
+  @Test
+  public final void testFullOuterHashJoinExec1() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] job3Frags = FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFullOuter_HashJoinExec1");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(8, count);
+
+  }
+
+  @Test
+  public final void testFullOuterHashJoinExec2() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[2]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] job3Frags = FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, job3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFullOuterHashJoinExec2");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(8, count);
+
+  }
+
+
+  @Test
+  public final void testFullOuterHashJoinExec3() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[3]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] phone3Frags = FileTablespace.splitNG(conf, PHONE3_NAME, phone3.getMeta(), new Path(phone3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, phone3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFullOuterHashJoinExec3");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged,
+        workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(7, count);
+  }
+}


[04/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..7ab1815
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort_NoBroadcast.plan
@@ -0,0 +1,165 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      TABLE_SUBQUERY(4) as default.a
+        => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+         SCAN(2) on default.orders
+           => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+           => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+           => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+      JOIN(11)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(1) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         SCAN(0) on default.lineitem
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+           => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+           => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+            |-eb_0000000000000_0000_000002
+            |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+
+SCAN(0) on default.lineitem
+  => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+  => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+  => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(1) on default.part
+  => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+  => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+
+JOIN(11)(INNER)
+  => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+  => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+  => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+  => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(15) on eb_0000000000000_0000_000002
+     => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+     => in schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(14) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+     => in schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.a.o_orderkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.a
+  => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+  => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+  => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+   PROJECTION(3)
+     => Targets: default.orders.o_orderkey (INT4), default.orders.o_custkey (INT4)
+     => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+     => in  schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+      SCAN(2) on default.orders
+        => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+        => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+        => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.a.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+SORT(18)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      SCAN(17) on eb_0000000000000_0000_000004
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+      SCAN(16) on eb_0000000000000_0000_000003
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.result
new file mode 100644
index 0000000..5116547
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.result
@@ -0,0 +1,7 @@
+l_orderkey,o_custkey,p_name
+-------------------------------
+1,3,goldenrod lavender spring chocolate lace
+1,3,goldenrod lavender spring chocolate lace
+2,4,blush thistle blue yellow saddle
+3,2,blush thistle blue yellow saddle
+3,2,spring green yellow purple cornsilk

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash.plan
new file mode 100644
index 0000000..5def40e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash.plan
@@ -0,0 +1,216 @@
+explain
+-------------------------------
+GROUP_BY(18)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         TABLE_SUBQUERY(14) as default.f
+           => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+            GROUP_BY(12)(l_orderkey)
+              => exprs: (avg(default.e.l_quantity (FLOAT8)))
+              => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+              => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+              => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+               TABLE_SUBQUERY(11) as default.e
+                 => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+                 => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                 => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                  JOIN(22)(INNER)
+                    => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+                    => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+                    => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+                    => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                     SCAN(8) on default.part
+                       => target list: default.part.p_partkey (INT4)
+                       => out schema: {(1) default.part.p_partkey (INT4)}
+                       => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                     SCAN(7) on default.lineitem as d
+                       => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+                       => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+                       => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+         JOIN(23)(INNER)
+           => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+           => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+            SCAN(5) on default.orders as c
+              => filter: default.c.o_orderkey (INT4) > 0
+              => target list: default.c.o_orderkey (INT4)
+              => out schema: {(1) default.c.o_orderkey (INT4)}
+              => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+            TABLE_SUBQUERY(4) as default.b
+              => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+              => out schema: {(2) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+              => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+               JOIN(21)(INNER)
+                 => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+                 => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+                 => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                 => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                  SCAN(1) on default.part
+                    => target list: default.part.p_partkey (INT4)
+                    => out schema: {(1) default.part.p_partkey (INT4)}
+                    => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                  SCAN(0) on default.lineitem as a
+                    => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+                    => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+                    => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000012)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000012
+   |-eb_0000000000000_0000_000011
+      |-eb_0000000000000_0000_000010
+         |-eb_0000000000000_0000_000008
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000008
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+4: eb_0000000000000_0000_000012
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 10 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+
+GROUP_BY(32)(l_orderkey)
+  => exprs: (avg(default.e.l_quantity (FLOAT8)))
+  => target list: default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)
+  => out schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+  => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+   TABLE_SUBQUERY(11) as default.e
+     => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+     => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+     => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+      PROJECTION(10)
+        => Targets: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+        => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+        => in  schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+         JOIN(22)(INNER)
+           => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+           => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+           => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+           => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+            SCAN(8) on default.part
+              => target list: default.part.p_partkey (INT4)
+              => out schema: {(1) default.part.p_partkey (INT4)}
+              => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+            SCAN(7) on default.lineitem as d
+              => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+              => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+              => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 8 => 10 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.a
+ 2: type=Broadcast, tables=default.c
+
+GROUP_BY(36)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum_12 (FLOAT8)
+  => out schema:{(1) ?sum_12 (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         TABLE_SUBQUERY(14) as default.f
+           => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+            PROJECTION(13)
+              => Targets: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+              => out schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+              => in  schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+               GROUP_BY(12)(l_orderkey)
+                 => exprs: (avg(?avg_11 (PROTOBUF)))
+                 => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+                 => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+                 => in schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+                  SCAN(33) on eb_0000000000000_0000_000008
+                    => out schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+                    => in schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+         JOIN(23)(INNER)
+           => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+           => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+            SCAN(5) on default.orders as c
+              => filter: default.c.o_orderkey (INT4) > 0
+              => target list: default.c.o_orderkey (INT4)
+              => out schema: {(1) default.c.o_orderkey (INT4)}
+              => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+            TABLE_SUBQUERY(4) as default.b
+              => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+              => out schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+              => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+               PROJECTION(3)
+                 => Targets: default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_linenumber (INT4)
+                 => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                 => in  schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                  JOIN(21)(INNER)
+                    => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+                    => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+                    => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                    => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                     SCAN(1) on default.part
+                       => target list: default.part.p_partkey (INT4)
+                       => out schema: {(1) default.part.p_partkey (INT4)}
+                       => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                     SCAN(0) on default.lineitem as a
+                       => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+                       => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+                       => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+GROUP_BY(18)()
+  => exprs: (sum(?sum_12 (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(1) ?sum_12 (FLOAT8)}
+   SCAN(37) on eb_0000000000000_0000_000010
+     => out schema: {(1) ?sum_12 (FLOAT8)}
+     => in schema: {(1) ?sum_12 (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000012 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..cbd07fc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Hash_NoBroadcast.plan
@@ -0,0 +1,328 @@
+explain
+-------------------------------
+GROUP_BY(18)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         TABLE_SUBQUERY(14) as default.f
+           => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+            GROUP_BY(12)(l_orderkey)
+              => exprs: (avg(default.e.l_quantity (FLOAT8)))
+              => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+              => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+              => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+               TABLE_SUBQUERY(11) as default.e
+                 => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+                 => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                 => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                  JOIN(22)(INNER)
+                    => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+                    => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+                    => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+                    => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                     SCAN(8) on default.part
+                       => target list: default.part.p_partkey (INT4)
+                       => out schema: {(1) default.part.p_partkey (INT4)}
+                       => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                     SCAN(7) on default.lineitem as d
+                       => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+                       => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+                       => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+         JOIN(23)(INNER)
+           => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+           => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+            SCAN(5) on default.orders as c
+              => filter: default.c.o_orderkey (INT4) > 0
+              => target list: default.c.o_orderkey (INT4)
+              => out schema: {(1) default.c.o_orderkey (INT4)}
+              => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+            TABLE_SUBQUERY(4) as default.b
+              => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+              => out schema: {(2) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+              => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+               JOIN(21)(INNER)
+                 => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+                 => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+                 => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                 => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                  SCAN(1) on default.part
+                    => target list: default.part.p_partkey (INT4)
+                    => out schema: {(1) default.part.p_partkey (INT4)}
+                    => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                  SCAN(0) on default.lineitem as a
+                    => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+                    => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+                    => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000012)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000012
+   |-eb_0000000000000_0000_000011
+      |-eb_0000000000000_0000_000010
+         |-eb_0000000000000_0000_000009
+            |-eb_0000000000000_0000_000008
+               |-eb_0000000000000_0000_000007
+               |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+12: eb_0000000000000_0000_000012
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.a.l_partkey (INT4), num=32)
+
+SCAN(0) on default.lineitem as a
+  => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+  => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+  => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(1) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.a.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.b.l_orderkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.b
+  => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+  => out schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+  => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+   PROJECTION(3)
+     => Targets: default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_linenumber (INT4)
+     => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+     => in  schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+      JOIN(21)(INNER)
+        => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+        => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+        => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+         SCAN(27) on eb_0000000000000_0000_000002
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(1) default.part.p_partkey (INT4)}
+         SCAN(26) on eb_0000000000000_0000_000001
+           => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+           => in schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+
+SCAN(5) on default.orders as c
+  => filter: default.c.o_orderkey (INT4) > 0
+  => target list: default.c.o_orderkey (INT4)
+  => out schema: {(1) default.c.o_orderkey (INT4)}
+  => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.d.l_partkey (INT4), num=32)
+
+SCAN(7) on default.lineitem as d
+  => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+  => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+  => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(8) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.b.l_orderkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 10 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+
+JOIN(23)(INNER)
+  => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+  => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+  => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+  => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+   SCAN(29) on eb_0000000000000_0000_000004
+     => out schema: {(1) default.c.o_orderkey (INT4)}
+     => in schema: {(1) default.c.o_orderkey (INT4)}
+   SCAN(28) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+     => in schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.d.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+GROUP_BY(32)(l_orderkey)
+  => exprs: (avg(default.e.l_quantity (FLOAT8)))
+  => target list: default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)
+  => out schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+  => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+   TABLE_SUBQUERY(11) as default.e
+     => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+     => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+     => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+      PROJECTION(10)
+        => Targets: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+        => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+        => in  schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+         JOIN(22)(INNER)
+           => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+           => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+           => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+           => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+            SCAN(31) on eb_0000000000000_0000_000007
+              => out schema: {(1) default.part.p_partkey (INT4)}
+              => in schema: {(1) default.part.p_partkey (INT4)}
+            SCAN(30) on eb_0000000000000_0000_000006
+              => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+              => in schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=HASH_SHUFFLE, key=default.f.l_orderkey (INT4), num=32)
+
+TABLE_SUBQUERY(14) as default.f
+  => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+  => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+  => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+   PROJECTION(13)
+     => Targets: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+     => out schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+     => in  schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+      GROUP_BY(12)(l_orderkey)
+        => exprs: (avg(?avg_11 (PROTOBUF)))
+        => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+        => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+        => in schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+         SCAN(33) on eb_0000000000000_0000_000008
+           => out schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+           => in schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 10 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+[q_0000000000000_0000] 9 => 10 (type=HASH_SHUFFLE, key=default.f.l_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+GROUP_BY(36)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum_12 (FLOAT8)
+  => out schema:{(1) ?sum_12 (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         SCAN(35) on eb_0000000000000_0000_000009
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         SCAN(34) on eb_0000000000000_0000_000005
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+GROUP_BY(18)()
+  => exprs: (sum(?sum_12 (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(1) ?sum_12 (FLOAT8)}
+   SCAN(37) on eb_0000000000000_0000_000010
+     => out schema: {(1) ?sum_12 (FLOAT8)}
+     => in schema: {(1) ?sum_12 (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000012 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort.plan
new file mode 100644
index 0000000..5def40e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort.plan
@@ -0,0 +1,216 @@
+explain
+-------------------------------
+GROUP_BY(18)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         TABLE_SUBQUERY(14) as default.f
+           => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+            GROUP_BY(12)(l_orderkey)
+              => exprs: (avg(default.e.l_quantity (FLOAT8)))
+              => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+              => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+              => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+               TABLE_SUBQUERY(11) as default.e
+                 => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+                 => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                 => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                  JOIN(22)(INNER)
+                    => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+                    => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+                    => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+                    => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                     SCAN(8) on default.part
+                       => target list: default.part.p_partkey (INT4)
+                       => out schema: {(1) default.part.p_partkey (INT4)}
+                       => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                     SCAN(7) on default.lineitem as d
+                       => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+                       => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+                       => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+         JOIN(23)(INNER)
+           => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+           => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+            SCAN(5) on default.orders as c
+              => filter: default.c.o_orderkey (INT4) > 0
+              => target list: default.c.o_orderkey (INT4)
+              => out schema: {(1) default.c.o_orderkey (INT4)}
+              => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+            TABLE_SUBQUERY(4) as default.b
+              => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+              => out schema: {(2) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+              => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+               JOIN(21)(INNER)
+                 => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+                 => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+                 => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                 => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                  SCAN(1) on default.part
+                    => target list: default.part.p_partkey (INT4)
+                    => out schema: {(1) default.part.p_partkey (INT4)}
+                    => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                  SCAN(0) on default.lineitem as a
+                    => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+                    => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+                    => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000012)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000012
+   |-eb_0000000000000_0000_000011
+      |-eb_0000000000000_0000_000010
+         |-eb_0000000000000_0000_000008
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000008
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+4: eb_0000000000000_0000_000012
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 10 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+
+GROUP_BY(32)(l_orderkey)
+  => exprs: (avg(default.e.l_quantity (FLOAT8)))
+  => target list: default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)
+  => out schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+  => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+   TABLE_SUBQUERY(11) as default.e
+     => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+     => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+     => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+      PROJECTION(10)
+        => Targets: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+        => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+        => in  schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+         JOIN(22)(INNER)
+           => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+           => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+           => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+           => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+            SCAN(8) on default.part
+              => target list: default.part.p_partkey (INT4)
+              => out schema: {(1) default.part.p_partkey (INT4)}
+              => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+            SCAN(7) on default.lineitem as d
+              => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+              => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+              => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 8 => 10 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.a
+ 2: type=Broadcast, tables=default.c
+
+GROUP_BY(36)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum_12 (FLOAT8)
+  => out schema:{(1) ?sum_12 (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         TABLE_SUBQUERY(14) as default.f
+           => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+            PROJECTION(13)
+              => Targets: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+              => out schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+              => in  schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+               GROUP_BY(12)(l_orderkey)
+                 => exprs: (avg(?avg_11 (PROTOBUF)))
+                 => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+                 => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+                 => in schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+                  SCAN(33) on eb_0000000000000_0000_000008
+                    => out schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+                    => in schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+         JOIN(23)(INNER)
+           => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+           => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+            SCAN(5) on default.orders as c
+              => filter: default.c.o_orderkey (INT4) > 0
+              => target list: default.c.o_orderkey (INT4)
+              => out schema: {(1) default.c.o_orderkey (INT4)}
+              => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+            TABLE_SUBQUERY(4) as default.b
+              => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+              => out schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+              => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+               PROJECTION(3)
+                 => Targets: default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_linenumber (INT4)
+                 => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                 => in  schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                  JOIN(21)(INNER)
+                    => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+                    => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+                    => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                    => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                     SCAN(1) on default.part
+                       => target list: default.part.p_partkey (INT4)
+                       => out schema: {(1) default.part.p_partkey (INT4)}
+                       => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                     SCAN(0) on default.lineitem as a
+                       => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+                       => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+                       => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+GROUP_BY(18)()
+  => exprs: (sum(?sum_12 (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(1) ?sum_12 (FLOAT8)}
+   SCAN(37) on eb_0000000000000_0000_000010
+     => out schema: {(1) ?sum_12 (FLOAT8)}
+     => in schema: {(1) ?sum_12 (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000012 [TERMINAL]
+=======================================================


[16/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..243acc2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+  => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+  => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort.plan
new file mode 100644
index 0000000..35e397b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..243acc2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Sort_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+  => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+  => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.result
new file mode 100644
index 0000000..89720e0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.result
@@ -0,0 +1,27 @@
+len,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment,?multiply
+-------------------------------
+108,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,10
+108,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,20
+108,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,30
+108,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,40
+108,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,50
+115,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,10
+115,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,20
+115,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,30
+115,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,40
+115,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,50
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s,10
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s,20
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s,30
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s,40
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s,50
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca,50
+45,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse,10
+45,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse,20
+45,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse,30
+45,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse,40
+45,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse,50

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash.plan
new file mode 100644
index 0000000..de4fc4f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..6153908
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4)
+  => out schema: {(1) default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+  => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(1) default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort.plan
new file mode 100644
index 0000000..de4fc4f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..6153908
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4)
+  => out schema: {(1) default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+  => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(1) default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.result
new file mode 100644
index 0000000..0ac2083
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinAndCaseWhen.result
@@ -0,0 +1,27 @@
+r_regionkey,n_regionkey,cond
+-------------------------------
+0,0,zero
+0,0,zero
+0,0,zero
+0,0,zero
+0,0,zero
+1,1,one
+1,1,one
+1,1,one
+1,1,one
+1,1,one
+2,2,two
+2,2,two
+2,2,two
+2,2,two
+2,2,two
+3,3,three
+3,3,three
+3,3,three
+3,3,three
+3,3,three
+4,4,four
+4,4,four
+4,4,four
+4,4,four
+4,4,four

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash.plan
new file mode 100644
index 0000000..78b074a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..214097c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Hash_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================


[49/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/TajoTestingCluster.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/TajoTestingCluster.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/TajoTestingCluster.java
new file mode 100644
index 0000000..71ef0ea
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/TajoTestingCluster.java
@@ -0,0 +1,778 @@
+/**
+ * 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;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Closeables;
+import com.google.common.io.Files;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.*;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.apache.hadoop.hdfs.HdfsConfiguration;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.hadoop.util.ShutdownHookManager;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.client.TajoClientUtil;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.engine.planner.global.rewriter.GlobalPlanTestRuleProvider;
+import org.apache.tajo.master.TajoMaster;
+import org.apache.tajo.plan.rewrite.LogicalPlanTestRuleProvider;
+import org.apache.tajo.querymaster.Query;
+import org.apache.tajo.querymaster.QueryMasterTask;
+import org.apache.tajo.querymaster.Stage;
+import org.apache.tajo.querymaster.StageState;
+import org.apache.tajo.service.ServiceTrackerFactory;
+import org.apache.tajo.storage.FileTablespace;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.NetUtils;
+import org.apache.tajo.util.Pair;
+import org.apache.tajo.worker.TajoWorker;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.UUID;
+
+public class TajoTestingCluster {
+	private static Log LOG = LogFactory.getLog(TajoTestingCluster.class);
+	private TajoConf conf;
+  private FileSystem defaultFS;
+  private MiniDFSCluster dfsCluster;
+	private MiniCatalogServer catalogServer;
+  private HBaseTestClusterUtil hbaseUtil;
+
+  private TajoMaster tajoMaster;
+  private List<TajoWorker> tajoWorkers = new ArrayList<TajoWorker>();
+  private boolean isDFSRunning = false;
+  private boolean isTajoClusterRunning = false;
+  private boolean isCatalogServerRunning = false;
+
+	private File clusterTestBuildDir = null;
+
+	/**
+	 * Default parent directory for test output.
+	 */
+	public static final String DEFAULT_TEST_DIRECTORY = "target/" + 
+	    System.getProperty("tajo.test.data.dir", "test-data");
+
+  /**
+   * True If HiveCatalogStore is used. Otherwise, it is FALSE.
+   */
+  public Boolean isHiveCatalogStoreUse = false;
+
+  private static final String LOG_LEVEL;
+
+  static {
+    LOG_LEVEL = System.getProperty("LOG_LEVEL");
+  }
+
+  public TajoTestingCluster() {
+    this(false);
+  }
+
+  public TajoTestingCluster(boolean masterHaEMode) {
+    this.conf = new TajoConf();
+    this.conf.setBoolVar(ConfVars.TAJO_MASTER_HA_ENABLE, masterHaEMode);
+
+    initTestDir();
+    setTestingFlagProperties();
+    initPropertiesAndConfigs();
+  }
+
+  void setTestingFlagProperties() {
+    System.setProperty(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+  }
+
+  void initPropertiesAndConfigs() {
+
+    // Set time zone
+    TimeZone testDefaultTZ = TimeZone.getTimeZone(TajoConstants.DEFAULT_SYSTEM_TIMEZONE);
+    conf.setSystemTimezone(testDefaultTZ);
+    TimeZone.setDefault(testDefaultTZ);
+
+    // Injection of equality testing code of logical plan (de)serialization
+    conf.setClassVar(ConfVars.LOGICAL_PLAN_REWRITE_RULE_PROVIDER_CLASS, LogicalPlanTestRuleProvider.class);
+    conf.setClassVar(ConfVars.GLOBAL_PLAN_REWRITE_RULE_PROVIDER_CLASS, GlobalPlanTestRuleProvider.class);
+
+    conf.setInt(ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES.varname, 4);
+    conf.setInt(ConfVars.WORKER_RESOURCE_AVAILABLE_MEMORY_MB.varname, 2000);
+    conf.setInt(ConfVars.WORKER_RESOURCE_AVAILABLE_DISK_PARALLEL_NUM.varname, 3);
+    conf.setInt(ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM.varname, 2);
+
+    // Client API RPC
+    conf.setIntVar(ConfVars.RPC_CLIENT_WORKER_THREAD_NUM, 2);
+
+    //Client API service RPC Server
+    conf.setIntVar(ConfVars.MASTER_SERVICE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.WORKER_SERVICE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.REST_SERVICE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+
+    // Internal RPC Client
+    conf.setIntVar(ConfVars.INTERNAL_RPC_CLIENT_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.SHUFFLE_RPC_CLIENT_WORKER_THREAD_NUM, 2);
+
+    // Internal RPC Server
+    conf.setIntVar(ConfVars.MASTER_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.QUERY_MASTER_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.WORKER_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.CATALOG_RPC_SERVER_WORKER_THREAD_NUM, 2);
+    conf.setIntVar(ConfVars.SHUFFLE_RPC_SERVER_WORKER_THREAD_NUM, 2);
+
+    // Memory cache termination
+    conf.setIntVar(ConfVars.WORKER_HISTORY_EXPIRE_PERIOD, 1);
+
+    // Python function path
+    conf.setStrings(ConfVars.PYTHON_CODE_DIR.varname, getClass().getResource("/python").toString());
+
+    /* Since Travis CI limits the size of standard output log up to 4MB */
+    if (!StringUtils.isEmpty(LOG_LEVEL)) {
+      Level defaultLevel = Logger.getRootLogger().getLevel();
+      Logger.getLogger("org.apache.tajo").setLevel(Level.toLevel(LOG_LEVEL.toUpperCase(), defaultLevel));
+      Logger.getLogger("org.apache.hadoop").setLevel(Level.toLevel(LOG_LEVEL.toUpperCase(), defaultLevel));
+      Logger.getLogger("org.apache.zookeeper").setLevel(Level.toLevel(LOG_LEVEL.toUpperCase(), defaultLevel));
+      Logger.getLogger("BlockStateChange").setLevel(Level.toLevel(LOG_LEVEL.toUpperCase(), defaultLevel));
+      Logger.getLogger("org.mortbay.log").setLevel(Level.toLevel(LOG_LEVEL.toUpperCase(), defaultLevel));
+    }
+  }
+
+	public TajoConf getConfiguration() {
+		return this.conf;
+	}
+
+  public void initTestDir() {
+    if (clusterTestBuildDir == null) {
+      clusterTestBuildDir = setupClusterTestBuildDir();
+    }
+  }
+
+	/**
+	 * @return Where to write test data on local filesystem; usually
+	 * {@link #DEFAULT_TEST_DIRECTORY}
+	 * @see #setupClusterTestBuildDir()
+	 */
+	public File getTestDir() {
+		return clusterTestBuildDir;
+	}
+
+	/**
+	 * @param subdirName
+	 * @return Path to a subdirectory named <code>subdirName</code> under
+	 * {@link #getTestDir()}.
+	 * @see #setupClusterTestBuildDir()
+	 */
+	public static File getTestDir(final String subdirName) {
+		return new File(new File(DEFAULT_TEST_DIRECTORY), subdirName);
+  }
+
+	public static File setupClusterTestBuildDir() {
+		String randomStr = UUID.randomUUID().toString();
+		String dirStr = getTestDir(randomStr).toString();
+		File dir = new File(dirStr).getAbsoluteFile();
+		// Have it cleaned up on exit
+		dir.deleteOnExit();
+		return dir;
+	}
+
+  ////////////////////////////////////////////////////////
+  // HDFS Section
+  ////////////////////////////////////////////////////////
+  /**
+   * Start a minidfscluster.
+   * @param servers How many DNs to start.
+   * @throws Exception
+   * @see {@link #shutdownMiniDFSCluster()}
+   * @return The mini dfs cluster created.
+   */
+  public MiniDFSCluster startMiniDFSCluster(int servers) throws Exception {
+    return startMiniDFSCluster(servers, null, null);
+  }
+
+  /**
+   * Start a minidfscluster.
+   * Can only create one.
+   * @param servers How many DNs to start.
+   * @param dir Where to home your dfs cluster.
+   * @param hosts hostnames DNs to run on.
+   * @throws Exception
+   * @see {@link #shutdownMiniDFSCluster()}
+   * @return The mini dfs cluster created.
+   * @throws java.io.IOException
+   */
+  public MiniDFSCluster startMiniDFSCluster(int servers,
+                                            File dir,
+                                            final String hosts[])
+      throws IOException {
+
+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dir.toString());
+    conf.setInt(DFSConfigKeys.DFS_REPLICATION_KEY, 1);
+    conf.setBoolean(DFSConfigKeys.DFS_CLIENT_READ_SHORTCIRCUIT_KEY, false);
+    MiniDFSCluster.Builder builder = new MiniDFSCluster.Builder(new HdfsConfiguration(conf));
+    builder.hosts(hosts);
+    builder.numDataNodes(servers);
+    builder.format(true);
+    builder.manageNameDfsDirs(true);
+    builder.manageDataDfsDirs(true);
+    builder.waitSafeMode(true);
+    this.dfsCluster = builder.build();
+
+    // Set this just-started cluster as our filesystem.
+    this.defaultFS = this.dfsCluster.getFileSystem();
+    this.conf.set(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, defaultFS.getUri().toString());
+    this.conf.setVar(TajoConf.ConfVars.ROOT_DIR, defaultFS.getUri() + "/tajo");
+    isDFSRunning = true;
+    return this.dfsCluster;
+  }
+
+  public void shutdownMiniDFSCluster() throws Exception {
+    if (this.dfsCluster != null) {
+      try {
+        FileSystem fs = this.dfsCluster.getFileSystem();
+        if (fs != null) fs.close();
+      } catch (IOException e) {
+        System.err.println("error closing file system: " + e);
+      }
+      // The below throws an exception per dn, AsynchronousCloseException.
+      this.dfsCluster.shutdown();
+    }
+  }
+
+  public boolean isRunningDFSCluster() {
+    return this.defaultFS != null;
+  }
+
+  public MiniDFSCluster getMiniDFSCluster() {
+    return this.dfsCluster;
+  }
+
+  public FileSystem getDefaultFileSystem() {
+    return this.defaultFS;
+  }
+
+  public HBaseTestClusterUtil getHBaseUtil() {
+    return hbaseUtil;
+  }
+
+  ////////////////////////////////////////////////////////
+  // Catalog Section
+  ////////////////////////////////////////////////////////
+  public MiniCatalogServer startCatalogCluster() throws Exception {
+    if(isCatalogServerRunning) throw new IOException("Catalog Cluster already running");
+
+    TajoConf c = getConfiguration();
+
+    conf.set(CatalogConstants.STORE_CLASS, "org.apache.tajo.catalog.store.MemStore");
+    conf.set(CatalogConstants.CATALOG_URI, "jdbc:derby:" + clusterTestBuildDir.getAbsolutePath() + "/db");
+    LOG.info("Apache Derby repository is set to " + conf.get(CatalogConstants.CATALOG_URI));
+    conf.setVar(ConfVars.CATALOG_ADDRESS, "localhost:0");
+
+    catalogServer = new MiniCatalogServer(conf);
+    CatalogServer catServer = catalogServer.getCatalogServer();
+    InetSocketAddress sockAddr = catServer.getBindAddress();
+    c.setVar(ConfVars.CATALOG_ADDRESS, NetUtils.normalizeInetSocketAddress(sockAddr));
+    isCatalogServerRunning = true;
+    return this.catalogServer;
+  }
+
+  public void shutdownCatalogCluster() {
+    if (catalogServer != null) {
+      this.catalogServer.shutdown();
+    }
+    isCatalogServerRunning = false;
+  }
+
+  public MiniCatalogServer getMiniCatalogCluster() {
+    return this.catalogServer;
+  }
+
+  public boolean isHiveCatalogStoreRunning() {
+    return isHiveCatalogStoreUse;
+  }
+
+  ////////////////////////////////////////////////////////
+  // Tajo Cluster Section
+  ////////////////////////////////////////////////////////
+  private void startMiniTajoCluster(File testBuildDir,
+                                               final int numSlaves,
+                                               boolean local) throws Exception {
+    TajoConf c = getConfiguration();
+    c.setVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, "localhost:0");
+    c.setVar(ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS, "localhost:0");
+    c.setVar(ConfVars.RESOURCE_TRACKER_RPC_ADDRESS, "localhost:0");
+    c.setVar(ConfVars.WORKER_PEER_RPC_ADDRESS, "localhost:0");
+    c.setVar(ConfVars.WORKER_TEMPORAL_DIR, "file://" + testBuildDir.getAbsolutePath() + "/tajo-localdir");
+    c.setIntVar(ConfVars.REST_SERVICE_PORT, 0);
+
+    LOG.info("derby repository is set to "+conf.get(CatalogConstants.CATALOG_URI));
+
+    if (!local) {
+      String tajoRootDir = getMiniDFSCluster().getFileSystem().getUri().toString() + "/tajo";
+      c.setVar(ConfVars.ROOT_DIR, tajoRootDir);
+
+      URI defaultTsUri = TajoConf.getWarehouseDir(c).toUri();
+      FileTablespace defaultTableSpace =
+          new FileTablespace(TablespaceManager.DEFAULT_TABLESPACE_NAME, defaultTsUri);
+      defaultTableSpace.init(conf);
+      TablespaceManager.addTableSpaceForTest(defaultTableSpace);
+
+    } else {
+      c.setVar(ConfVars.ROOT_DIR, "file://" + testBuildDir.getAbsolutePath() + "/tajo");
+    }
+
+    setupCatalogForTesting(c, testBuildDir);
+
+    tajoMaster = new TajoMaster();
+    tajoMaster.init(c);
+    tajoMaster.start();
+
+    this.conf.setVar(ConfVars.WORKER_PEER_RPC_ADDRESS, c.getVar(ConfVars.WORKER_PEER_RPC_ADDRESS));
+    this.conf.setVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, c.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS));
+
+    InetSocketAddress tajoMasterAddress = tajoMaster.getContext().getTajoMasterService().getBindAddress();
+
+    this.conf.setVar(ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS,
+        tajoMasterAddress.getHostName() + ":" + tajoMasterAddress.getPort());
+    this.conf.setVar(ConfVars.RESOURCE_TRACKER_RPC_ADDRESS, c.getVar(ConfVars.RESOURCE_TRACKER_RPC_ADDRESS));
+    this.conf.setVar(ConfVars.CATALOG_ADDRESS, c.getVar(ConfVars.CATALOG_ADDRESS));
+    
+    InetSocketAddress tajoRestAddress = tajoMaster.getContext().getRestServer().getBindAddress();
+    
+    this.conf.setIntVar(ConfVars.REST_SERVICE_PORT, tajoRestAddress.getPort());
+
+    startTajoWorkers(numSlaves);
+
+    isTajoClusterRunning = true;
+    LOG.info("Mini Tajo cluster is up");
+    LOG.info("====================================================================================");
+    LOG.info("=                           MiniTajoCluster starts up                              =");
+    LOG.info("====================================================================================");
+    LOG.info("= * Master Address: " + tajoMaster.getMasterName());
+    LOG.info("= * CatalogStore: " + tajoMaster.getCatalogServer().getStoreClassName());
+    LOG.info("------------------------------------------------------------------------------------");
+    LOG.info("= * Warehouse Dir: " + TajoConf.getWarehouseDir(c));
+    LOG.info("= * Worker Tmp Dir: " + c.getVar(ConfVars.WORKER_TEMPORAL_DIR));
+    LOG.info("====================================================================================");
+  }
+
+  private void setupCatalogForTesting(TajoConf c, File testBuildDir) throws IOException {
+    final String HIVE_CATALOG_CLASS_NAME = "org.apache.tajo.catalog.store.HiveCatalogStore";
+    boolean hiveCatalogClassExists = false;
+    try {
+      getClass().getClassLoader().loadClass(HIVE_CATALOG_CLASS_NAME);
+      hiveCatalogClassExists = true;
+    } catch (ClassNotFoundException e) {
+      LOG.info("HiveCatalogStore is not available.");
+    }
+    String driverClass = System.getProperty(CatalogConstants.STORE_CLASS);
+
+    if (hiveCatalogClassExists &&
+        driverClass != null && driverClass.equals(HIVE_CATALOG_CLASS_NAME)) {
+      try {
+        getClass().getClassLoader().loadClass(HIVE_CATALOG_CLASS_NAME);
+        String jdbcUri = "jdbc:derby:;databaseName="+ testBuildDir.toURI().getPath()  + "/metastore_db;create=true";
+        c.set("hive.metastore.warehouse.dir", TajoConf.getWarehouseDir(c).toString() + "/default");
+        c.set("javax.jdo.option.ConnectionURL", jdbcUri);
+        c.set(TajoConf.ConfVars.WAREHOUSE_DIR.varname, conf.getVar(ConfVars.WAREHOUSE_DIR));
+        c.set(CatalogConstants.STORE_CLASS, HIVE_CATALOG_CLASS_NAME);
+        Path defaultDatabasePath = new Path(TajoConf.getWarehouseDir(c).toString() + "/default");
+        FileSystem fs = defaultDatabasePath.getFileSystem(c);
+        if (!fs.exists(defaultDatabasePath)) {
+          fs.mkdirs(defaultDatabasePath);
+        }
+        isHiveCatalogStoreUse = true;
+      } catch (ClassNotFoundException cnfe) {
+        throw new IOException(cnfe);
+      }
+    } else { // for derby
+      c.set(CatalogConstants.STORE_CLASS, "org.apache.tajo.catalog.store.MemStore");
+      c.set(CatalogConstants.CATALOG_URI, "jdbc:derby:" + testBuildDir.getAbsolutePath() + "/db");
+    }
+    c.setVar(ConfVars.CATALOG_ADDRESS, "localhost:0");
+  }
+
+  private void startTajoWorkers(int numSlaves) throws Exception {
+    for(int i = 0; i < 1; i++) {
+      TajoWorker tajoWorker = new TajoWorker();
+
+      TajoConf workerConf  = new TajoConf(this.conf);
+
+      workerConf.setVar(ConfVars.WORKER_INFO_ADDRESS, "localhost:0");
+      workerConf.setVar(ConfVars.WORKER_CLIENT_RPC_ADDRESS, "localhost:0");
+      workerConf.setVar(ConfVars.WORKER_PEER_RPC_ADDRESS, "localhost:0");
+
+      workerConf.setVar(ConfVars.WORKER_QM_RPC_ADDRESS, "localhost:0");
+      
+      tajoWorker.startWorker(workerConf, new String[0]);
+
+      LOG.info("MiniTajoCluster Worker #" + (i + 1) + " started.");
+      tajoWorkers.add(tajoWorker);
+    }
+  }
+
+  public TajoMaster getMaster() {
+    return this.tajoMaster;
+  }
+
+  public List<TajoWorker> getTajoWorkers() {
+    return this.tajoWorkers;
+  }
+
+  public void shutdownMiniTajoCluster() {
+    if(this.tajoMaster != null) {
+      this.tajoMaster.stop();
+    }
+    for(TajoWorker eachWorker: tajoWorkers) {
+      eachWorker.stopWorkerForce();
+    }
+    tajoWorkers.clear();
+    this.tajoMaster= null;
+  }
+
+  ////////////////////////////////////////////////////////
+  // Meta Cluster Section
+  ////////////////////////////////////////////////////////
+  /**
+   * @throws java.io.IOException If a cluster -- dfs or engine -- already running.
+   */
+  void isRunningCluster() throws IOException {
+    if (!isTajoClusterRunning && !isCatalogServerRunning && !isDFSRunning) return;
+    throw new IOException("Cluster already running at " +
+        this.clusterTestBuildDir);
+  }
+
+  /**
+   * This method starts up a tajo cluster with a given number of clusters in
+   * distributed mode.
+   *
+   * @param numSlaves the number of tajo cluster to start up
+   * @throws Exception
+   */
+  public void startMiniCluster(final int numSlaves)
+      throws Exception {
+    startMiniCluster(numSlaves, null);
+  }
+
+  public void startMiniCluster(final int numSlaves, final String [] dataNodeHosts) throws Exception {
+
+    int numDataNodes = numSlaves;
+    if(dataNodeHosts != null && dataNodeHosts.length != 0) {
+      numDataNodes = dataNodeHosts.length;
+    }
+
+    LOG.info("Starting up minicluster with 1 master(s) and " +
+        numSlaves + " worker(s) and " + numDataNodes + " datanode(s)");
+
+    // If we already bring up the cluster, fail.
+    isRunningCluster();
+    if (clusterTestBuildDir != null) {
+      LOG.info("Using passed path: " + clusterTestBuildDir);
+    }
+
+    startMiniDFSCluster(numDataNodes, clusterTestBuildDir, dataNodeHosts);
+    this.dfsCluster.waitClusterUp();
+
+    conf.setInt("hbase.hconnection.threads.core", 5);
+    conf.setInt("hbase.hconnection.threads.max", 50);
+    hbaseUtil = new HBaseTestClusterUtil(conf, clusterTestBuildDir);
+
+    startMiniTajoCluster(this.clusterTestBuildDir, numSlaves, false);
+  }
+
+  public void startMiniClusterInLocal(final int numSlaves) throws Exception {
+    isRunningCluster();
+
+    if (clusterTestBuildDir != null) {
+      LOG.info("Using passed path: " + clusterTestBuildDir);
+    }
+
+    startMiniTajoCluster(this.clusterTestBuildDir, numSlaves, true);
+  }
+
+  public void shutdownMiniCluster() throws IOException {
+    LOG.info("========================================");
+    LOG.info("Minicluster is stopping");
+    LOG.info("========================================");
+
+    try {
+      Thread.sleep(3000);
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+
+    shutdownMiniTajoCluster();
+
+    if(this.catalogServer != null) {
+      shutdownCatalogCluster();
+      isCatalogServerRunning = false;
+    }
+
+    try {
+      Thread.sleep(3000);
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+
+    if(this.dfsCluster != null) {
+      try {
+        FileSystem fs = this.dfsCluster.getFileSystem();
+        if (fs != null) fs.close();
+        this.dfsCluster.shutdown();
+      } catch (IOException e) {
+        System.err.println("error closing file system: " + e);
+      }
+      isDFSRunning = false;
+    }
+
+    if(this.clusterTestBuildDir != null && this.clusterTestBuildDir.exists()) {
+      if(!ShutdownHookManager.get().isShutdownInProgress()) {
+        //TODO clean test dir when ShutdownInProgress
+        LocalFileSystem localFS = LocalFileSystem.getLocal(conf);
+        localFS.delete(new Path(clusterTestBuildDir.toString()), true);
+        localFS.close();
+      }
+      this.clusterTestBuildDir = null;
+    }
+
+    if(hbaseUtil != null) {
+      hbaseUtil.stopZooKeeperCluster();
+      hbaseUtil.stopHBaseCluster();
+    }
+
+    LOG.info("Minicluster is down");
+    isTajoClusterRunning = false;
+  }
+
+  public TajoClient newTajoClient() throws Exception {
+    return new TajoClientImpl(ServiceTrackerFactory.get(getConfiguration()));
+  }
+
+  public static ResultSet run(String[] names,
+                              Schema[] schemas,
+                              KeyValueSet tableOption,
+                              String[][] tables,
+                              String query,
+                              TajoClient client) throws Exception {
+    TajoTestingCluster util = TpchTestBase.getInstance().getTestingCluster();
+
+    FileSystem fs = util.getDefaultFileSystem();
+    Path rootDir = TajoConf.getWarehouseDir(util.getConfiguration());
+    fs.mkdirs(rootDir);
+    for (int i = 0; i < names.length; i++) {
+      createTable(names[i], schemas[i], tableOption, tables[i]);
+    }
+    Thread.sleep(1000);
+    ResultSet res = client.executeQueryAndGetResult(query);
+    return res;
+  }
+
+  public static ResultSet run(String[] names,
+                              Schema[] schemas,
+                              KeyValueSet tableOption,
+                              String[][] tables,
+                              String query) throws Exception {
+    TpchTestBase instance = TpchTestBase.getInstance();
+    TajoTestingCluster util = instance.getTestingCluster();
+    while(true) {
+      if(util.getMaster().isMasterRunning()) {
+        break;
+      }
+      Thread.sleep(1000);
+    }
+    TajoConf conf = util.getConfiguration();
+    TajoClient client = new TajoClientImpl(ServiceTrackerFactory.get(conf));
+
+    try {
+      return run(names, schemas, tableOption, tables, query, client);
+    } finally {
+      client.close();
+    }
+  }
+
+  public static TajoClient newTajoClient(TajoTestingCluster util) throws SQLException, InterruptedException {
+    while(true) {
+      if(util.getMaster().isMasterRunning()) {
+        break;
+      }
+      Thread.sleep(1000);
+    }
+    TajoConf conf = util.getConfiguration();
+    return new TajoClientImpl(ServiceTrackerFactory.get(conf));
+  }
+
+  public static void createTable(String tableName, Schema schema,
+                                 KeyValueSet tableOption, String[] tableDatas) throws Exception {
+    createTable(tableName, schema, tableOption, tableDatas, 1);
+  }
+
+  public static void createTable(String tableName, Schema schema,
+                                 KeyValueSet tableOption, String[] tableDatas, int numDataFiles) throws Exception {
+    TpchTestBase instance = TpchTestBase.getInstance();
+    TajoTestingCluster util = instance.getTestingCluster();
+    TajoClient client = newTajoClient(util);
+    try {
+      FileSystem fs = util.getDefaultFileSystem();
+      Path rootDir = TajoConf.getWarehouseDir(util.getConfiguration());
+      if (!fs.exists(rootDir)) {
+        fs.mkdirs(rootDir);
+      }
+      Path tablePath;
+      if (CatalogUtil.isFQTableName(tableName)) {
+        Pair<String, String> name = CatalogUtil.separateQualifierAndName(tableName);
+        tablePath = new Path(rootDir, new Path(name.getFirst(), name.getSecond()));
+      } else {
+        tablePath = new Path(rootDir, tableName);
+      }
+
+      fs.mkdirs(tablePath);
+      if (tableDatas.length > 0) {
+        int recordPerFile = tableDatas.length / numDataFiles;
+        if (recordPerFile == 0) {
+          recordPerFile = 1;
+        }
+        FSDataOutputStream out = null;
+        for (int j = 0; j < tableDatas.length; j++) {
+          if (out == null || j % recordPerFile == 0) {
+            if (out != null) {
+              out.close();
+            }
+            Path dfsPath = new Path(tablePath, tableName + j + ".tbl");
+            out = fs.create(dfsPath);
+          }
+          out.write((tableDatas[j] + "\n").getBytes());
+        }
+        if (out != null) {
+          out.close();
+        }
+      }
+      TableMeta meta = CatalogUtil.newTableMeta("TEXT", tableOption);
+      client.createExternalTable(tableName, schema, tablePath.toUri(), meta);
+    } finally {
+      client.close();
+    }
+  }
+
+    /**
+    * Write lines to a file.
+    *
+    * @param file File to write lines to
+    * @param lines Strings written to the file
+    * @throws java.io.IOException
+    */
+  private static void writeLines(File file, String... lines)
+      throws IOException {
+    Writer writer = Files.newWriter(file, Charsets.UTF_8);
+    try {
+      for (String line : lines) {
+        writer.write(line);
+        writer.write('\n');
+      }
+    } finally {
+      Closeables.closeQuietly(writer);
+    }
+  }
+
+  public void setAllTajoDaemonConfValue(String key, String value) {
+    tajoMaster.getContext().getConf().set(key, value);
+    setAllWorkersConfValue(key, value);
+  }
+
+  public void setAllWorkersConfValue(String key, String value) {
+    for (TajoWorker eachWorker: tajoWorkers) {
+      eachWorker.getConfig().set(key, value);
+    }
+  }
+
+  public void waitForQuerySubmitted(QueryId queryId) throws Exception {
+    waitForQuerySubmitted(queryId, 50);
+  }
+
+  public void waitForQuerySubmitted(QueryId queryId, int delay) throws Exception {
+    QueryMasterTask qmt = null;
+
+    int i = 0;
+    while (qmt == null || TajoClientUtil.isQueryWaitingForSchedule(qmt.getState())) {
+      try {
+        Thread.sleep(delay);
+
+        if (qmt == null) {
+          qmt = getQueryMasterTask(queryId);
+        }
+      } catch (InterruptedException e) {
+      }
+      if (++i > 200) {
+        throw new IOException("Timed out waiting for query to start");
+      }
+    }
+  }
+
+  public void waitForQueryState(Query query, TajoProtos.QueryState expected, int delay) throws Exception {
+    int i = 0;
+    while (query == null || query.getSynchronizedState() != expected) {
+      try {
+        Thread.sleep(delay);
+      } catch (InterruptedException e) {
+      }
+      if (++i > 200) {
+        throw new IOException("Timed out waiting. expected: " + expected +
+            ", actual: " + query != null ? String.valueOf(query.getSynchronizedState()) : String.valueOf(query));
+      }
+    }
+  }
+
+  public void waitForStageState(Stage stage, StageState expected, int delay) throws Exception {
+
+    int i = 0;
+    while (stage == null || stage.getSynchronizedState() != expected) {
+      try {
+        Thread.sleep(delay);
+      } catch (InterruptedException e) {
+      }
+      if (++i > 200) {
+        throw new IOException("Timed out waiting");
+      }
+    }
+  }
+
+  public QueryMasterTask getQueryMasterTask(QueryId queryId) {
+    QueryMasterTask qmt = null;
+    for (TajoWorker worker : getTajoWorkers()) {
+      qmt = worker.getWorkerContext().getQueryMaster().getQueryMasterTask(queryId, true);
+      if (qmt != null && queryId.equals(qmt.getQueryId())) {
+        break;
+      }
+    }
+    return qmt;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/TpchTestBase.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/TpchTestBase.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/TpchTestBase.java
new file mode 100644
index 0000000..055dd02
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/TpchTestBase.java
@@ -0,0 +1,113 @@
+/**
+ * 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;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.benchmark.TPCH;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.FileUtil;
+import org.apache.tajo.util.KeyValueSet;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.util.Map;
+
+public class TpchTestBase {
+  private static final Log LOG = LogFactory.getLog(TpchTestBase.class);
+
+  String [] names;
+  String [] paths;
+  String [][] tables;
+  Schema[] schemas;
+  Map<String, Integer> nameMap = Maps.newHashMap();
+  protected TPCH tpch;
+  protected LocalTajoTestingUtility util;
+
+  private static TpchTestBase testBase;
+
+  static {
+    try {
+      testBase = new TpchTestBase();
+      testBase.setUp();
+    } catch (Exception e) {
+      LOG.error(e.getMessage(), e);
+    }
+  }
+
+  private TpchTestBase() throws IOException {
+    names = new String[] {"customer", "lineitem", "nation", "orders", "part", "partsupp", "region", "supplier", "empty_orders"};
+    paths = new String[names.length];
+    for (int i = 0; i < names.length; i++) {
+      nameMap.put(names[i], i);
+    }
+
+    tpch = new TPCH();
+    tpch.loadSchemas();
+    tpch.loadQueries();
+
+    schemas = new Schema[names.length];
+    for (int i = 0; i < names.length; i++) {
+      schemas[i] = tpch.getSchema(names[i]);
+    }
+
+    tables = new String[names.length][];
+    File file;
+    for (int i = 0; i < names.length; i++) {
+      file = TPCH.getDataFile(names[i]);
+      tables[i] = FileUtil.readTextFile(file).split("\n");
+      paths[i] = file.getAbsolutePath();
+    }
+    try {
+      Thread.sleep(1000);
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private void setUp() throws Exception {
+    util = new LocalTajoTestingUtility();
+    KeyValueSet opt = new KeyValueSet();
+    opt.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    util.setup(names, paths, schemas, opt);
+  }
+
+  public static TpchTestBase getInstance() {
+    return testBase;
+  }
+
+  public ResultSet execute(String query) throws Exception {
+    return util.execute(query);
+  }
+
+  public TajoTestingCluster getTestingCluster() {
+    return util.getTestingCluster();
+  }
+
+  public void tearDown() throws IOException {
+    try {
+      Thread.sleep(2000);
+    } catch (InterruptedException e) {
+    }
+    util.shutdown();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-core-tests/pom.xml b/tajo-core-tests/pom.xml
new file mode 100644
index 0000000..8f2051d
--- /dev/null
+++ b/tajo-core-tests/pom.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tajo-project</artifactId>
+    <groupId>org.apache.tajo</groupId>
+    <version>0.11.0-SNAPSHOT</version>
+    <relativePath>../tajo-project</relativePath>
+  </parent>
+  <artifactId>tajo-core-tests</artifactId>
+  <packaging>jar</packaging>
+  <name>Tajo Core Tests</name>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <excludes>
+            <exclude>derby.log</exclude>
+            <exclude>benchmark/**</exclude>
+            <exclude>src/test/tpch/**</exclude>
+            <exclude>src/test/resources/dataset/**</exclude>
+            <exclude>src/test/resources/queries/**</exclude>
+            <exclude>src/test/resources/results/**</exclude>
+            <exclude>src/main/resources/META-INF/services/*</exclude>
+            <exclude>src/main/resources/webapps/static/js/*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemProperties>
+            <tajo.test>TRUE</tajo.test>
+          </systemProperties>
+          <argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=152m -Dfile.encoding=UTF-8</argLine>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-deploy-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.1</version>
+        <configuration>
+          <excludes>
+            <exclude>LICENSE</exclude>
+          </excludes>
+          <archive>
+            <addMavenDescriptor>false</addMavenDescriptor>
+          </archive>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <includeScope>runtime</includeScope>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>false</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-algebra</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-plan</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-storage-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-storage-hdfs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-storage-hbase</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-pullserver</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-rpc-protobuf</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-thirdparty-asm</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-ws-rs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-metrics</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-cluster-tests</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-el</groupId>
+          <artifactId>commons-el</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-runtime</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-compiler</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.mortbay.jetty</groupId>
+          <artifactId>jsp-2.1-jetty</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-el</groupId>
+          <artifactId>commons-el</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-runtime</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-compiler</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.mortbay.jetty</groupId>
+          <artifactId>jsp-2.1-jetty</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-server-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-server</artifactId>
+      <version>${hbase.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-server</artifactId>
+      <version>${hbase.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-hadoop-compat</artifactId>
+      <version>${hbase.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-hadoop2-compat</artifactId>
+      <version>${hbase.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>jdk.tools</artifactId>
+          <groupId>jdk.tools</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>com.github.stephenc.jcip</groupId>
+      <artifactId>jcip-annotations</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>parallel-test</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <executions>
+              <execution>
+                <phase>test</phase>
+                <goals>
+                  <goal>test</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration combine.self="override">
+              <forkCount>${maven.fork.count}</forkCount>
+              <reuseForks>true</reuseForks>
+              <trimStackTrace>false</trimStackTrace>
+              <argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=152m -Dfile.encoding=UTF-8</argLine>
+              <useSystemClassLoader>true</useSystemClassLoader>
+              <useManifestOnlyJar>true</useManifestOnlyJar>
+              <systemProperties>
+                <tajo.test>TRUE</tajo.test>
+                <tajo.test.data.dir>test-data${surefire.forkNumber}</tajo.test.data.dir>
+              </systemProperties>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

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

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/TestQueryIdFactory.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/TestQueryIdFactory.java b/tajo-core-tests/src/test/java/org/apache/tajo/TestQueryIdFactory.java
new file mode 100644
index 0000000..8dc95de
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/TestQueryIdFactory.java
@@ -0,0 +1,58 @@
+/**
+ * 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;
+
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestQueryIdFactory {
+  
+  @Before
+  public void setup() {
+  }
+
+  @Test
+  public void testNewQueryId() {
+    QueryId qid1 = LocalTajoTestingUtility.newQueryId();
+    QueryId qid2 = LocalTajoTestingUtility.newQueryId();
+    assertTrue(qid1.compareTo(qid2) < 0);
+  }
+  
+  @Test
+  public void testNewStageId() {
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    MasterPlan plan = new MasterPlan(qid, null, null);
+    ExecutionBlockId stageId1 = plan.newExecutionBlockId();
+    ExecutionBlockId stageId2 = plan.newExecutionBlockId();
+    assertTrue(stageId1.compareTo(stageId2) < 0);
+  }
+  
+  @Test
+  public void testNewTaskId() {
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    MasterPlan plan = new MasterPlan(qid, null, null);
+    ExecutionBlockId subid = plan.newExecutionBlockId();
+    TaskId quid1 = QueryIdFactory.newTaskId(subid);
+    TaskId quid2 = QueryIdFactory.newTaskId(subid);
+    assertTrue(quid1.compareTo(quid2) < 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/TestTajoIds.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/TestTajoIds.java b/tajo-core-tests/src/test/java/org/apache/tajo/TestTajoIds.java
new file mode 100644
index 0000000..d15e282
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/TestTajoIds.java
@@ -0,0 +1,168 @@
+/**
+ * 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;
+
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.server.utils.BuilderUtils;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.util.TajoIdUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestTajoIds {
+  @Test
+  public void testQueryId() {
+    long ts1 = 1315890136000l;
+    long ts2 = 1315890136001l;
+
+    QueryId j1 = createQueryId(ts1, 2);
+    QueryId j2 = createQueryId(ts1, 1);
+    QueryId j3 = createQueryId(ts2, 1);
+    QueryId j4 = createQueryId(ts1, 2);
+
+    assertTrue(j1.equals(j4));
+    assertFalse(j1.equals(j2));
+    assertFalse(j1.equals(j3));
+
+    assertTrue(j1.compareTo(j4) == 0);
+    assertTrue(j1.compareTo(j2) > 0);
+    assertTrue(j1.compareTo(j3) < 0);
+
+    assertTrue(j1.hashCode() == j4.hashCode());
+    assertFalse(j1.hashCode() == j2.hashCode());
+    assertFalse(j1.hashCode() == j3.hashCode());
+
+    QueryId j5 = createQueryId(ts1, 231415);
+    assertEquals("q_" + ts1 + "_0002", j1.toString());
+    assertEquals("q_" + ts1 + "_231415", j5.toString());
+  }
+
+  @Test
+  public void testQueryIds() {
+    long timeId = 1315890136000l;
+    
+    QueryId queryId = createQueryId(timeId, 1);
+    assertEquals("q_" + timeId + "_0001", queryId.toString());
+    
+    ExecutionBlockId subId = QueryIdFactory.newExecutionBlockId(queryId, 2);
+    assertEquals("eb_" + timeId +"_0001_000002", subId.toString());
+    
+    TaskId qId = new TaskId(subId, 5);
+    assertEquals("t_" + timeId + "_0001_000002_000005", qId.toString());
+
+    TaskAttemptId attemptId = new TaskAttemptId(qId, 4);
+    assertEquals("ta_" + timeId + "_0001_000002_000005_04", attemptId.toString());
+  }
+
+  @Test
+  public void testEqualsObject() {
+    long timeId = System.currentTimeMillis();
+    
+    QueryId queryId1 = createQueryId(timeId, 1);
+    QueryId queryId2 = createQueryId(timeId, 2);
+    assertNotSame(queryId1, queryId2);    
+    QueryId queryId3 = createQueryId(timeId, 1);
+    assertEquals(queryId1, queryId3);
+    
+    ExecutionBlockId sid1 = QueryIdFactory.newExecutionBlockId(queryId1, 1);
+    ExecutionBlockId sid2 = QueryIdFactory.newExecutionBlockId(queryId1, 2);
+    assertNotSame(sid1, sid2);
+    ExecutionBlockId sid3 = QueryIdFactory.newExecutionBlockId(queryId1, 1);
+    assertEquals(sid1, sid3);
+    
+    TaskId qid1 = new TaskId(sid1, 9);
+    TaskId qid2 = new TaskId(sid1, 10);
+    assertNotSame(qid1, qid2);
+    TaskId qid3 = new TaskId(sid1, 9);
+    assertEquals(qid1, qid3);
+  }
+
+  @Test
+  public void testCompareTo() {
+    long time = System.currentTimeMillis();
+    
+    QueryId queryId1 = createQueryId(time, 1);
+    QueryId queryId2 = createQueryId(time, 2);
+    QueryId queryId3 = createQueryId(time, 1);
+    assertEquals(-1, queryId1.compareTo(queryId2));
+    assertEquals(1, queryId2.compareTo(queryId1));
+    assertEquals(0, queryId3.compareTo(queryId1));
+
+    ExecutionBlockId sid1 = QueryIdFactory.newExecutionBlockId(queryId1, 1);
+    ExecutionBlockId sid2 = QueryIdFactory.newExecutionBlockId(queryId1, 2);
+    ExecutionBlockId sid3 = QueryIdFactory.newExecutionBlockId(queryId1, 1);
+    assertEquals(-1, sid1.compareTo(sid2));
+    assertEquals(1, sid2.compareTo(sid1));
+    assertEquals(0, sid3.compareTo(sid1));
+    
+    TaskId qid1 = new TaskId(sid1, 9);
+    TaskId qid2 = new TaskId(sid1, 10);
+    TaskId qid3 = new TaskId(sid1, 9);
+    assertEquals(-1, qid1.compareTo(qid2));
+    assertEquals(1, qid2.compareTo(qid1));
+    assertEquals(0, qid3.compareTo(qid1));
+  }
+  
+  @Test
+  public void testConstructFromString() {
+    QueryId qid1 = LocalTajoTestingUtility.newQueryId();
+    QueryId qid2 = TajoIdUtils.parseQueryId(qid1.toString());
+    assertEquals(qid1, qid2);
+
+    MasterPlan plan1 = new MasterPlan(qid1, null, null);
+    ExecutionBlockId sub1 = plan1.newExecutionBlockId();
+    ExecutionBlockId sub2 = TajoIdUtils.createExecutionBlockId(sub1.toString());
+    assertEquals(sub1, sub2);
+    
+    TaskId u1 = QueryIdFactory.newTaskId(sub1);
+    TaskId u2 = new TaskId(u1.getProto());
+    assertEquals(u1, u2);
+
+    TaskAttemptId attempt1 = new TaskAttemptId(u1, 1);
+    TaskAttemptId attempt2 = new TaskAttemptId(attempt1.getProto());
+    assertEquals(attempt1, attempt2);
+  }
+
+  @Test
+  public void testConstructFromPB() {
+    QueryId qid1 = LocalTajoTestingUtility.newQueryId();
+    QueryId qid2 = new QueryId(qid1.getProto());
+    assertEquals(qid1, qid2);
+
+    MasterPlan plan = new MasterPlan(qid1, null, null);
+    ExecutionBlockId sub1 = plan.newExecutionBlockId();
+    ExecutionBlockId sub2 = TajoIdUtils.createExecutionBlockId(sub1.toString());
+    assertEquals(sub1, sub2);
+
+    TaskId u1 = QueryIdFactory.newTaskId(sub1);
+    TaskId u2 = new TaskId(u1.getProto());
+    assertEquals(u1, u2);
+
+    TaskAttemptId attempt1 = new TaskAttemptId(u1, 1);
+    TaskAttemptId attempt2 = new TaskAttemptId(attempt1.getProto());
+    assertEquals(attempt1, attempt2);
+  }
+
+  public static QueryId createQueryId(long timestamp, int id) {
+    ApplicationId appId = BuilderUtils.newApplicationId(timestamp, id);
+
+    return QueryIdFactory.newQueryId(appId.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/benchmark/TestTPCH.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/benchmark/TestTPCH.java b/tajo-core-tests/src/test/java/org/apache/tajo/benchmark/TestTPCH.java
new file mode 100644
index 0000000..53d4350
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/benchmark/TestTPCH.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.benchmark;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(IntegrationTest.class)
+public class TestTPCH extends QueryTestCaseBase {
+
+  public TestTPCH() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testQ1OrderBy() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testQ2FourJoins() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testTPCH14Expr() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testTPCHQ5() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testFirstJoinInQ7() throws Exception {
+    runSimpleTests();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestDDLBuilder.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestDDLBuilder.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestDDLBuilder.java
new file mode 100644
index 0000000..06a54c4
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestDDLBuilder.java
@@ -0,0 +1,133 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tools;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.compress.GzipCodec;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.partition.PartitionMethodDesc;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.FileUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+public class TestDDLBuilder {
+  private static final Schema schema1;
+  private static final TableMeta meta1;
+  private static final PartitionMethodDesc partitionMethod1;
+
+  static {
+    schema1 = new Schema();
+    schema1.addColumn("name", TajoDataTypes.Type.BLOB);
+    schema1.addColumn("addr", TajoDataTypes.Type.TEXT);
+
+    meta1 = CatalogUtil.newTableMeta("TEXT");
+    meta1.putOption(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    meta1.putOption(StorageConstants.COMPRESSION_CODEC, GzipCodec.class.getName());
+
+    Schema expressionSchema = new Schema();
+    expressionSchema.addColumn("key", TajoDataTypes.Type.INT4);
+    expressionSchema.addColumn("key2", TajoDataTypes.Type.TEXT);
+    partitionMethod1 = new PartitionMethodDesc(
+        "db1",
+        "table1",
+        CatalogProtos.PartitionType.COLUMN,
+        "key,key2",
+        expressionSchema);
+  }
+
+  @Test
+  public void testBuildDDLForExternalTable() throws Exception {
+    TableDesc desc = new TableDesc("db1.table1", schema1, meta1, new Path("/table1").toUri());
+    desc.setPartitionMethod(partitionMethod1);
+    desc.setExternal(true);
+    assertEquals(FileUtil.readTextFileFromResource("results/testDDLBuilder/testBuildDDLForExternalTable.result"),
+        DDLBuilder.buildDDLForExternalTable(desc));
+  }
+
+  @Test
+  public void testBuildDDLQuotedTableName() throws Exception {
+    Schema schema2 = new Schema();
+    schema2.addColumn("name", TajoDataTypes.Type.BLOB);
+    schema2.addColumn("addr", TajoDataTypes.Type.TEXT);
+    schema2.addColumn("FirstName", TajoDataTypes.Type.TEXT);
+    schema2.addColumn("LastName", TajoDataTypes.Type.TEXT);
+    schema2.addColumn("with", TajoDataTypes.Type.TEXT);
+
+    Schema expressionSchema2 = new Schema();
+    expressionSchema2.addColumn("BirthYear", TajoDataTypes.Type.INT4);
+
+    PartitionMethodDesc partitionMethod2 = new PartitionMethodDesc(
+        "db1",
+        "table1",
+        CatalogProtos.PartitionType.COLUMN,
+        "key,key2",
+        expressionSchema2);
+
+    TableDesc desc = new TableDesc("db1.TABLE2", schema2, meta1, new Path("/table1").toUri());
+    desc.setPartitionMethod(partitionMethod2);
+    desc.setExternal(true);
+    assertEquals(FileUtil.readTextFileFromResource("results/testDDLBuilder/testBuildDDLQuotedTableName1.result"),
+        DDLBuilder.buildDDLForExternalTable(desc));
+
+    desc = new TableDesc("db1.TABLE1", schema2, meta1, new Path("/table1").toUri());
+    desc.setPartitionMethod(partitionMethod2);
+    desc.setExternal(false);
+    assertEquals(FileUtil.readTextFileFromResource("results/testDDLBuilder/testBuildDDLQuotedTableName2.result"),
+        DDLBuilder.buildDDLForBaseTable(desc));
+  }
+
+  @Test
+  public void testBuildDDLForBaseTable() throws Exception {
+    TableDesc desc = new TableDesc("db1.table2", schema1, meta1, new Path("/table1").toUri());
+    assertEquals(FileUtil.readTextFileFromResource("results/testDDLBuilder/testBuildDDLForBaseTable.result"),
+        DDLBuilder.buildDDLForBaseTable(desc));
+  }
+
+  @Test
+  public void testBuildColumn() throws Exception {
+    String [] tobeUnquoted = {
+        "column_name",
+        "columnname",
+        "column_1",
+    };
+
+    for (String columnName : tobeUnquoted) {
+      assertFalse(CatalogUtil.isShouldBeQuoted(columnName));
+    }
+
+    String [] quoted = {
+        "Column_Name",
+        "COLUMN_NAME",
+        "컬럼",
+        "$column_name",
+        "Column_Name1",
+        "with",
+        "when"
+    };
+
+    for (String columnName : quoted) {
+      assertTrue(CatalogUtil.isShouldBeQuoted(columnName));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestTajoDump.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestTajoDump.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestTajoDump.java
new file mode 100644
index 0000000..aa8070e
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tools/TestTajoDump.java
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tools;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.auth.UserRoleInfo;
+import org.apache.tajo.storage.StorageUtil;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.FileUtil;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintWriter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestTajoDump extends QueryTestCaseBase {
+
+  @Test
+  public void testDump1() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeString("CREATE TABLE \"" + getCurrentDatabase() +
+          "\".\"TableName1\" (\"Age\" int, \"FirstName\" TEXT, lastname TEXT)");
+
+      try {
+        UserRoleInfo userInfo = UserRoleInfo.getCurrentUser();
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        PrintWriter printWriter = new PrintWriter(bos);
+        TajoDump.dump(client, userInfo, getCurrentDatabase(), false, false, false, printWriter);
+        printWriter.flush();
+        printWriter.close();
+        assertStrings(new String(bos.toByteArray()));
+        bos.close();
+      } finally {
+        executeString("DROP TABLE \"" + getCurrentDatabase() + "\".\"TableName1\"");
+      }
+    }
+  }
+
+  @Test
+  public void testDump2() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeString("CREATE TABLE \"" + getCurrentDatabase() +
+          "\".\"TableName2\" (\"Age\" int, \"Name\" Record (\"FirstName\" TEXT, lastname TEXT))");
+
+      try {
+        UserRoleInfo userInfo = UserRoleInfo.getCurrentUser();
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        PrintWriter printWriter = new PrintWriter(bos);
+        TajoDump.dump(client, userInfo, getCurrentDatabase(), false, false, false, printWriter);
+        printWriter.flush();
+        printWriter.close();
+        assertStrings(new String(bos.toByteArray()));
+        bos.close();
+      } finally {
+        executeString("DROP TABLE \"" + getCurrentDatabase() + "\".\"TableName2\"");
+      }
+    }
+  }
+
+  @Test
+  public void testDump3() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeString("CREATE TABLE \"" + getCurrentDatabase() +
+          "\".\"TableName1\" (\"Age\" int, \"FirstName\" TEXT, lastname TEXT)");
+
+      executeString("CREATE INDEX test_idx on \"" + getCurrentDatabase()
+          + "\".\"TableName1\" ( \"Age\" asc null first, \"FirstName\" desc null last )");
+
+      try {
+        UserRoleInfo userInfo = UserRoleInfo.getCurrentUser();
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        PrintWriter printWriter = new PrintWriter(bos);
+        TajoDump.dump(client, userInfo, getCurrentDatabase(), false, false, false, printWriter);
+        printWriter.flush();
+        printWriter.close();
+        assertOutputResult("testDump3.result", new String(bos.toByteArray()), new String[]{"${index.path}"},
+            new String[]{TablespaceManager.getDefault().getTableUri(getCurrentDatabase(), "test_idx").toString()});
+        bos.close();
+      } finally {
+        executeString("DROP INDEX test_idx");
+        executeString("DROP TABLE \"" + getCurrentDatabase() + "\".\"TableName1\"");
+      }
+    }
+  }
+
+  private void assertOutputResult(String expectedResultFile, String actual, String[] paramKeys, String[] paramValues)
+      throws Exception {
+    FileSystem fs = currentResultPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+    Path resultFile = StorageUtil.concatPath(currentResultPath, expectedResultFile);
+    assertTrue(resultFile.toString() + " existence check", fs.exists(resultFile));
+
+    String expectedResult = FileUtil.readTextFile(new File(resultFile.toUri()));
+
+    if (paramKeys != null) {
+      for (int i = 0; i < paramKeys.length; i++) {
+        if (i < paramValues.length) {
+          expectedResult = expectedResult.replace(paramKeys[i], paramValues[i]);
+        }
+      }
+    }
+    assertEquals(expectedResult.trim(), actual.trim());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestDefaultCliOutputFormatter.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestDefaultCliOutputFormatter.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestDefaultCliOutputFormatter.java
new file mode 100644
index 0000000..3b53c60
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestDefaultCliOutputFormatter.java
@@ -0,0 +1,179 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Float8Datum;
+import org.apache.tajo.datum.Int4Datum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.jdbc.MetaDataTuple;
+import org.apache.tajo.jdbc.TajoMetaDataResultSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestDefaultCliOutputFormatter {
+  protected static final TpchTestBase testBase;
+  protected static final TajoTestingCluster cluster;
+
+  /** the base path of result directories */
+  protected static final Path resultBasePath;
+  static {
+    testBase = TpchTestBase.getInstance();
+    cluster = testBase.getTestingCluster();
+    URL resultBaseURL = ClassLoader.getSystemResource("results");
+    resultBasePath = new Path(resultBaseURL.toString());
+  }
+
+  private TajoConf conf;
+  private TajoCli tajoCli;
+  private TajoCli.TajoCliContext cliContext;
+
+  @Before
+  public void setUp() throws Exception {
+    conf = cluster.getConfiguration();
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    tajoCli = new TajoCli(conf, new String[]{}, System.in, out);
+    cliContext = tajoCli.getContext();
+  }
+
+  @After
+  public void tearDown() {
+    if (tajoCli != null) {
+      tajoCli.close();
+    }
+  }
+
+
+  @Test
+  public void testParseErrorMessage() {
+    String message = "java.sql.SQLException: ERROR: no such a table: table1";
+    assertEquals("ERROR: no such a table: table1", DefaultTajoCliOutputFormatter.parseErrorMessage(message));
+
+    String multiLineMessage =
+        "ERROR: java.sql.SQLException: ERROR: no such a table: table1\n" +
+        "com.google.protobuf.ServiceException: java.sql.SQLException: ERROR: no such a table: table1\n" +
+        "\tat org.apache.tajo.client.TajoClient.getTableDesc(TajoClient.java:777)\n" +
+        "\tat org.apache.tajo.cli.tsql.commands.DescTableCommand.invoke(DescTableCommand.java:43)\n" +
+        "\tat org.apache.tajo.cli.tsql.TajoCli.executeMetaCommand(TajoCli.java:300)\n" +
+        "\tat org.apache.tajo.cli.tsql.TajoCli.executeParsedResults(TajoCli.java:280)\n" +
+        "\tat org.apache.tajo.cli.tsql.TajoCli.runShell(TajoCli.java:271)\n" +
+        "\tat org.apache.tajo.cli.tsql.TajoCli.main(TajoCli.java:420)\n" +
+        "Caused by: java.sql.SQLException: ERROR: no such a table: table1\n" +
+        "\t... 6 more";
+
+    assertEquals(multiLineMessage, DefaultTajoCliOutputFormatter.parseErrorMessage(multiLineMessage));
+
+    String noPrefixMessage = "RTFM please";
+    assertEquals("ERROR: "+noPrefixMessage, DefaultTajoCliOutputFormatter.parseErrorMessage(noPrefixMessage));
+
+    String errorMessageWithLine = "ERROR: syntax error at or near '('\n" +
+        "LINE 1:7 select (*) from tc\n" +
+        "                ^";
+    assertEquals(errorMessageWithLine, DefaultTajoCliOutputFormatter.parseErrorMessage(errorMessageWithLine));
+  }
+
+  @Test
+  public void testPrintResultInsertStatement() throws Exception {
+    DefaultTajoCliOutputFormatter outputFormatter = new DefaultTajoCliOutputFormatter();
+    outputFormatter.init(cliContext);
+
+    float responseTime = 10.1f;
+    long numBytes = 102;
+    long numRows = 30;
+
+    TableDesc tableDesc = new TableDesc();
+    TableStats stats = new TableStats();
+    stats.setNumBytes(102);
+    stats.setNumRows(numRows);
+    tableDesc.setStats(stats);
+
+    StringWriter stringWriter = new StringWriter();
+    PrintWriter writer = new PrintWriter(stringWriter);
+    outputFormatter.printResult(writer, null, tableDesc, responseTime, null);
+
+    String expectedOutput = "(" +  numRows + " rows, " + responseTime + " sec, " + numBytes + " B inserted)\n";
+    assertEquals(expectedOutput, stringWriter.toString());
+  }
+
+  @Test
+  public void testPrintResultSelectStatement() throws Exception {
+    DefaultTajoCliOutputFormatter outputFormatter = new DefaultTajoCliOutputFormatter();
+    outputFormatter.init(cliContext);
+
+    float responseTime = 10.1f;
+    long numBytes = 102;
+    long numRows = 30;
+
+    TableDesc tableDesc = new TableDesc();
+    TableStats stats = new TableStats();
+    stats.setNumBytes(102);
+    stats.setNumRows(numRows);
+    tableDesc.setStats(stats);
+
+    final List<MetaDataTuple> resultTables = new ArrayList<MetaDataTuple>();
+
+    String expectedOutput = "col1,  col2,  col3\n";
+    expectedOutput += "-------------------------------\n";
+
+    String prefix = "";
+    for (int i = 0; i < numRows; i++) {
+      MetaDataTuple tuple = new MetaDataTuple(3);
+
+      int index = 0;
+
+      tuple.put(index++, new TextDatum("row_" + i));
+      tuple.put(index++, new Int4Datum(i));
+      tuple.put(index++, new Float8Datum(i));
+
+      expectedOutput += prefix + "row_" + i + ",  " + (new Int4Datum(i)) + ",  " + (new Float8Datum(i));
+      prefix = "\n";
+      resultTables.add(tuple);
+    }
+    expectedOutput += "\n(" +  numRows + " rows, " + responseTime + " sec, " + numBytes + " B selected)\n";
+
+    ResultSet resultSet = new TajoMetaDataResultSet(
+        Arrays.asList("col1", "col2", "col3"),
+        Arrays.asList(TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT4, TajoDataTypes.Type.FLOAT8),
+        resultTables);
+
+    StringWriter stringWriter = new StringWriter();
+    PrintWriter writer = new PrintWriter(stringWriter);
+    outputFormatter.printResult(writer, null, tableDesc, responseTime, resultSet);
+
+    assertEquals(expectedOutput, stringWriter.toString());
+  }
+}


[05/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash.plan
new file mode 100644
index 0000000..038f468
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash.plan
@@ -0,0 +1,116 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(3) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+         SCAN(0) on default.part
+           => target list: default.part.p_partkey (INT4)
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(11)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+           => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+           => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+              => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000009)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000009
+   |-eb_0000000000000_0000_000008
+      |-eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000007
+2: eb_0000000000000_0000_000008
+3: eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.supplier
+ 2: type=Broadcast, tables=default.partsupp
+
+SORT(21)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(3) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+         SCAN(0) on default.part
+           => target list: default.part.p_partkey (INT4)
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(11)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+           => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+           => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+              => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000007
+
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(22) on eb_0000000000000_0000_000007
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..b195e34
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Hash_NoBroadcast.plan
@@ -0,0 +1,201 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(3) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+         SCAN(0) on default.part
+           => target list: default.part.p_partkey (INT4)
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(11)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+           => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+           => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+              => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000009)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000009
+   |-eb_0000000000000_0000_000008
+      |-eb_0000000000000_0000_000007
+         |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+SCAN(1) on default.supplier
+  => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+  => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+  => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(11)(INNER)
+  => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+  => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+  => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+   SCAN(16) on eb_0000000000000_0000_000002
+     => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+     => in schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+   SCAN(15) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(0) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 7 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+
+JOIN(12)(INNER)
+  => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+  => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+  => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+  => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000004
+     => out schema: {(1) default.part.p_partkey (INT4)}
+     => in schema: {(1) default.part.p_partkey (INT4)}
+   SCAN(17) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+     => in schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 7 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+SCAN(3) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 7 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 6 => 7 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+SORT(21)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(20) on eb_0000000000000_0000_000006
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+      SCAN(19) on eb_0000000000000_0000_000005
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000007
+
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(22) on eb_0000000000000_0000_000007
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort.plan
new file mode 100644
index 0000000..038f468
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort.plan
@@ -0,0 +1,116 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(3) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+         SCAN(0) on default.part
+           => target list: default.part.p_partkey (INT4)
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(11)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+           => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+           => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+              => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000009)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000009
+   |-eb_0000000000000_0000_000008
+      |-eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000007
+2: eb_0000000000000_0000_000008
+3: eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.supplier
+ 2: type=Broadcast, tables=default.partsupp
+
+SORT(21)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(3) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+         SCAN(0) on default.part
+           => target list: default.part.p_partkey (INT4)
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(11)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+           => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+           => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+              => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000007
+
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(22) on eb_0000000000000_0000_000007
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..b195e34
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.Sort_NoBroadcast.plan
@@ -0,0 +1,201 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(3) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+         SCAN(0) on default.part
+           => target list: default.part.p_partkey (INT4)
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(11)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+           => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+           => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+              => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000009)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000009
+   |-eb_0000000000000_0000_000008
+      |-eb_0000000000000_0000_000007
+         |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+SCAN(1) on default.supplier
+  => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)
+  => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+  => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(11)(INNER)
+  => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+  => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+  => in schema: {(6) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+   SCAN(16) on eb_0000000000000_0000_000002
+     => out schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+     => in schema: {(4) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_suppkey (INT4)}
+   SCAN(15) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(0) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 7 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+
+JOIN(12)(INNER)
+  => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+  => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)
+  => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+  => in schema: {(5) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000004
+     => out schema: {(1) default.part.p_partkey (INT4)}
+     => in schema: {(1) default.part.p_partkey (INT4)}
+   SCAN(17) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+     => in schema: {(4) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 7 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+SCAN(3) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 7 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 6 => 7 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+SORT(21)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(13)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+      SCAN(20) on eb_0000000000000_0000_000006
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+      SCAN(19) on eb_0000000000000_0000_000005
+        => out schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+        => in schema: {(4) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 7 => 8 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000007
+
+SORT(5)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(22) on eb_0000000000000_0000_000007
+     => out schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.result
new file mode 100644
index 0000000..ede8e7a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin6.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,p_partkey,n_name
+-------------------------------
+4032.68,Supplier#000000002,1,ETHIOPIA
+4192.4,Supplier#000000003,2,ARGENTINA
+4641.08,Supplier#000000004,3,MOROCCO

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash.plan
new file mode 100644
index 0000000..9685885
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash.plan
@@ -0,0 +1,109 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      TABLE_SUBQUERY(4) as default.a
+        => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+         SCAN(2) on default.orders
+           => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+           => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+           => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+      JOIN(11)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(1) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         SCAN(0) on default.lineitem
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+           => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+           => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000005
+2: eb_0000000000000_0000_000006
+3: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.orders
+
+SORT(18)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      TABLE_SUBQUERY(4) as default.a
+        => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+         PROJECTION(3)
+           => Targets: default.orders.o_orderkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+           => in  schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(2) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+      JOIN(11)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(1) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         SCAN(0) on default.lineitem
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+           => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+           => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..7ab1815
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Hash_NoBroadcast.plan
@@ -0,0 +1,165 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      TABLE_SUBQUERY(4) as default.a
+        => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+         SCAN(2) on default.orders
+           => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+           => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+           => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+      JOIN(11)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(1) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         SCAN(0) on default.lineitem
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+           => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+           => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+            |-eb_0000000000000_0000_000002
+            |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+
+SCAN(0) on default.lineitem
+  => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+  => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+  => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(1) on default.part
+  => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+  => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+
+JOIN(11)(INNER)
+  => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+  => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+  => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+  => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(15) on eb_0000000000000_0000_000002
+     => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+     => in schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(14) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+     => in schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.a.o_orderkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.a
+  => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+  => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+  => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+   PROJECTION(3)
+     => Targets: default.orders.o_orderkey (INT4), default.orders.o_custkey (INT4)
+     => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+     => in  schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+      SCAN(2) on default.orders
+        => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+        => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+        => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.a.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+SORT(18)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      SCAN(17) on eb_0000000000000_0000_000004
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+      SCAN(16) on eb_0000000000000_0000_000003
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort.plan
new file mode 100644
index 0000000..9685885
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery.Sort.plan
@@ -0,0 +1,109 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      TABLE_SUBQUERY(4) as default.a
+        => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+         SCAN(2) on default.orders
+           => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+           => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+           => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+      JOIN(11)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(1) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         SCAN(0) on default.lineitem
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+           => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+           => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000005
+2: eb_0000000000000_0000_000006
+3: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.orders
+
+SORT(18)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   JOIN(12)(INNER)
+     => Join Cond: default.lineitem.l_orderkey (INT4) = default.a.o_orderkey (INT4)
+     => target list: default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(4) default.a.o_custkey (INT4), default.a.o_orderkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+      TABLE_SUBQUERY(4) as default.a
+        => Targets: default.a.o_custkey (INT4), default.a.o_orderkey (INT4)
+        => out schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+        => in  schema: {(2) default.a.o_custkey (INT4), default.a.o_orderkey (INT4)}
+         PROJECTION(3)
+           => Targets: default.orders.o_orderkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+           => in  schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(2) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+      JOIN(11)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(2) default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(1) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         SCAN(0) on default.lineitem
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+           => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+           => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.a.o_custkey (INT4) (asc),default.part.p_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+     => in schema: {(3) default.a.o_custkey (INT4), default.lineitem.l_orderkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================


[47/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/v2/TestTajoClientV2.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/v2/TestTajoClientV2.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/v2/TestTajoClientV2.java
new file mode 100644
index 0000000..e1fca63
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/v2/TestTajoClientV2.java
@@ -0,0 +1,274 @@
+/**
+ * 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.v2;
+
+import com.facebook.presto.hive.shaded.com.google.common.collect.Lists;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.exception.*;
+import org.apache.tajo.service.ServiceTracker;
+import org.apache.tajo.service.ServiceTrackerFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.junit.Assert.*;
+
+public class TestTajoClientV2 extends QueryTestCaseBase {
+  private static TajoClient clientv2;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    conf = testingCluster.getConfiguration();
+
+    clientv2 = new TajoClient(new ServiceDiscovery() {
+      ServiceTracker tracker = ServiceTrackerFactory.get(conf);
+      @Override
+      public InetSocketAddress clientAddress() {
+        return tracker.getClientServiceAddress();
+      }
+    });
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    clientv2.close();
+  }
+
+  @Test
+  public void testExecuteUpdate() throws TajoException {
+    clientv2.executeUpdate("create database tajoclientv2");
+    clientv2.selectDB("tajoclientv2");
+    clientv2.selectDB("default");
+    clientv2.executeUpdate("drop database tajoclientv2");
+
+    try {
+      clientv2.selectDB("tajoclientv2");
+      fail();
+    } catch (UndefinedDatabaseException e) {
+    }
+  }
+
+  @Test
+  public void testExecuteQueryType1() throws TajoException, IOException, SQLException {
+    ResultSet res = null;
+    try {
+      res = clientv2.executeQuery("select * from lineitem");
+      assertResultSet(res);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  @Test
+  public void testExecuteQueryType2() throws TajoException, IOException, SQLException {
+    ResultSet res = null;
+    try {
+      res = clientv2.executeQuery("select * from lineitem where l_orderkey > 2");
+      assertResultSet(res);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  @Test
+  public void testExecuteQueryType3() throws TajoException, IOException, SQLException {
+    ResultSet res = null;
+    try {
+      clientv2.executeUpdate("create database client_v2_type3");
+      clientv2.selectDB("client_v2_type3");
+      clientv2.executeUpdate("create table t1 (c1 int)");
+      clientv2.executeUpdate("create table t2 (c2 int)");
+
+      // why we shouldn't use join directly on virtual tables? Currently, join on virtual tables is not supported.
+      res = clientv2.executeQuery("select db_id from information_schema.databases where db_name = 'client_v2_type3'");
+      assertTrue(res.next());
+      int dbId = res.getInt(1);
+      res.close();
+
+      res = clientv2.executeQuery(
+          "select table_name from information_schema.tables where db_id = " + dbId + " order by table_name");
+      assertResultSet(res);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+
+      clientv2.executeUpdate("drop database IF EXISTS client_v2_types3");
+    }
+  }
+
+  @Test
+  public void testExecuteQueryAsync() throws TajoException, IOException, SQLException, ExecutionException,
+      InterruptedException {
+    QueryFuture future = clientv2.executeQueryAsync("select * from lineitem where l_orderkey > 0");
+
+    ResultSet result = future.get();
+    assertResultSet(result);
+
+    assertTrue(future.isDone());
+    assertEquals(QueryState.COMPLETED, future.state());
+    assertTrue(future.isSuccessful());
+    assertFalse(future.isFailed());
+    assertFalse(future.isKilled());
+    assertTrue(1.0f == future.progress());
+    assertEquals("default", future.queue());
+
+    assertTrue(future.submitTime() > 0);
+    assertTrue(future.startTime() > 0);
+    assertTrue(future.finishTime() > 0);
+
+    result.close();
+  }
+
+  @Test(timeout = 10 * 1000)
+  public void testExecuteQueryAsyncWithListener() throws TajoException, IOException, SQLException, ExecutionException,
+      InterruptedException {
+    QueryFuture future = clientv2.executeQueryAsync(
+        "select l_orderkey, sleep(1) from lineitem where l_orderkey > 3");
+
+    final AtomicBoolean success = new AtomicBoolean(false);
+    final List<ResultSet> resultContainer = Lists.newArrayList();
+
+    future.addListener(new FutureListener<QueryFuture>() {
+      @Override
+      public void processingCompleted(QueryFuture future) {
+        try {
+          ResultSet result = future.get();
+          resultContainer.add(result); // for better error handling, it should be verified outside this future.
+
+          assertTrue(future.isDone());
+          assertEquals(QueryState.COMPLETED, future.state());
+          assertTrue(future.isSuccessful());
+          assertFalse(future.isFailed());
+          assertFalse(future.isKilled());
+          assertTrue(1.0f == future.progress());
+          assertEquals("default", future.queue());
+
+          assertTrue(future.submitTime() > 0);
+          assertTrue(future.startTime() > 0);
+          assertTrue(future.finishTime() > 0);
+
+          success.set(true);
+
+        } catch (Throwable t) {
+          throw new RuntimeException(t);
+        }
+      }
+    });
+
+    while(!future.isDone()) {
+      Thread.sleep(100);
+    }
+
+    assertTrue(success.get());
+    assertResultSet(resultContainer.get(0));
+    resultContainer.get(0).close();
+  }
+
+  @Test(expected = QueryKilledException.class, timeout = 10 * 1000)
+  public void testQueryFutureKill() throws Throwable {
+    QueryFuture future = clientv2.executeQueryAsync("select sleep(1) from lineitem where l_orderkey > 4");
+
+    assertTrue(future.isOk());
+    assertFalse(future.isDone());
+    assertFalse(future.isSuccessful());
+    assertFalse(future.isFailed());
+    assertFalse(future.isKilled());
+
+    future.kill();
+    while(!future.isDone()) {
+      Thread.sleep(100);
+    }
+
+    assertTrue(future.isOk());
+    assertTrue(future.isDone());
+    assertFalse(future.isSuccessful());
+    assertFalse(future.isFailed());
+    assertTrue(future.isKilled());
+
+    try {
+      future.get();
+    } catch (ExecutionException e) {
+      throw e.getCause();
+    } finally {
+      future.release();
+    }
+  }
+
+
+  @Test(expected = DuplicateDatabaseException.class)
+  public void testErrorOnExecuteUpdate() throws TajoException, IOException, SQLException {
+    clientv2.executeUpdate("create database default");
+  }
+
+  @Test(expected = UndefinedTableException.class)
+  public void testErrorOnExecuteQuery() throws TajoException, IOException, SQLException {
+    clientv2.executeQuery("select * from unknown_table");
+  }
+
+  @Test(expected = UndefinedTableException.class)
+  public void testErrorOnExecuteQueryAsync() throws TajoException {
+    clientv2.executeQueryAsync("select * from unknown_table");
+  }
+
+  @Test(expected = SQLSyntaxError.class)
+  public void testSyntaxErrorOnUpdateQuery() throws TajoException {
+    clientv2.executeUpdate("drap table unknown-table");
+  }
+
+  @Test(expected = SQLSyntaxError.class)
+  public void testSyntaxErrorOnExecuteQuery() throws TajoException {
+    clientv2.executeQuery("select fail(3, ");
+  }
+
+  @Test(expected = SQLSyntaxError.class)
+  public void testSyntaxErrorOnExecuteQueryAsync() throws TajoException {
+    clientv2.executeQueryAsync("select fail(3, ");
+  }
+
+  @Test(expected = QueryFailedException.class)
+  public void testFailedExecuteQuery() throws TajoException {
+    clientv2.executeQuery("select fail(3, l_orderkey, 'testQueryFailure') from default.lineitem");
+  }
+
+  @Test(expected = QueryFailedException.class)
+  public void testFailedExecuteQueryAsync() throws Throwable {
+    QueryFuture future = clientv2.executeQueryAsync(
+            "select fail(3, l_orderkey, 'testQueryFailure') from default.lineitem");
+    try {
+      future.get();
+    } catch (ExecutionException e) {
+      throw e.getCause();
+    } finally {
+      future.release();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cluster/TestWorkerConnectionInfo.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cluster/TestWorkerConnectionInfo.java b/tajo-core-tests/src/test/java/org/apache/tajo/cluster/TestWorkerConnectionInfo.java
new file mode 100644
index 0000000..03be125
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cluster/TestWorkerConnectionInfo.java
@@ -0,0 +1,36 @@
+/**
+ * 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.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestWorkerConnectionInfo {
+
+  @Test
+  public void testWorkerId() {
+    WorkerConnectionInfo worker = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+    WorkerConnectionInfo worker2 = new WorkerConnectionInfo("host2", 28091, 28092, 21000, 28093, 28080);
+
+    assertNotEquals(worker.getId(), worker2.getId());
+    assertEquals(worker.getId(), new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080).getId());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java
new file mode 100644
index 0000000..da59e8a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java
@@ -0,0 +1,310 @@
+/**
+ * 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.codegen;
+
+
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+public class TestEvalCodeGenerator extends ExprTestBase {
+  private static Schema schema;
+  static {
+    schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col8", TajoDataTypes.Type.BOOLEAN);
+    schema.addColumn("nullable", TajoDataTypes.Type.NULL_TYPE);
+  }
+
+  @Test
+  public void testArithmetic() throws TajoException {
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1+1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col2 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col3 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col4 from table1;", new String [] {"5.5"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col5 from table1;", new String [] {"6.5"});
+  }
+
+  @Test
+  public void testGetField() throws TajoException {
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col4 from table1;", new String [] {"4.5"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col5 from table1;", new String [] {"5.5"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col6 from table1;", new String [] {"F6"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6,abc,t", "select col8 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testNullHandling() throws TajoException {
+    schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 1));
+    schema.addColumn("col8", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col9", TajoDataTypes.Type.BOOLEAN);
+    schema.addColumn("nullable", TajoDataTypes.Type.NULL_TYPE);
+
+    testEval(schema, "table1", ",1,2,3,4.5,6.5,F6,abc,abc,t", "select col0 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,,2,3,4.5,6.5,F6,abc,abc,t,", "select col1 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,,3,4.5,6.5,F6,abc,abc,t,", "select col2 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,,4.5,6.5,F6,abc,abc,t,", "select col3 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,,6.5,F6,abc,abc,t,", "select col4 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,,F6,abc,abc,t,", "select col5 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,,abc,abc,t,", "select col6 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,,abc,t,", "select col7 is null from table1;", new String[]{"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,,t,", "select col8 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,,", "select col9 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,t,", "select nullable is null from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", ",1,2,3,4.5,6.5,F6,abc,abc,t", "select col0 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,,2,3,4.5,6.5,F6,abc,abc,t,", "select col1 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,,3,4.5,6.5,F6,abc,abc,t,", "select col2 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,,4.5,6.5,F6,abc,abc,t,", "select col3 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,,6.5,F6,abc,abc,t,", "select col4 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,,F6,abc,abc,t,", "select col5 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,,abc,abc,t,", "select col6 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,,abc,t,", "select col7 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,,t,", "select col8 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,,", "select col9 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,t,", "select nullable is not null from table1;", new String [] {"f"});
+  }
+
+  @Test
+  public void testComparison() throws TajoException {
+    Schema inetSchema = new Schema();
+    inetSchema.addColumn("addr1", TajoDataTypes.Type.INET4);
+    inetSchema.addColumn("addr2", TajoDataTypes.Type.INET4);
+
+    testSimpleEval("select (1 > null AND false)", new String[] {"f"}); // unknown - false -> false
+    testSimpleEval("select (1::int8 > null) is null", new String[] {"t"});
+
+    testSimpleEval("select 1 = null;", new String [] {""});
+    testSimpleEval("select 1 <> null;", new String [] {""});
+    testSimpleEval("select 1 > null;", new String [] {""});
+    testSimpleEval("select 1 >= null;", new String [] {""});
+    testSimpleEval("select 1 < null;", new String [] {""});
+    testSimpleEval("select 1 <= null;", new String [] {""});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col5 from table1;", new String [] {"f"});
+
+    testEval(inetSchema, "table1", "192.168.0.1,192.168.0.1", "select addr1 = addr2 from table1;", new String[]{"t"});
+    testEval(inetSchema, "table1", "192.168.0.1,192.168.0.2", "select addr1 = addr2 from table1;", new String[]{"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col5 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col5 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col5 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col5 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col5 from table1;", new String [] {"f"});
+  }
+
+  @Test
+  public void testBetweenAsymmetric() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    testEval(schema, "table1", "0,", "select col1 between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between 3 and 1) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 not between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 not between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 not between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between 3 and 1) is null from table1", new String[]{"t"});
+  }
+
+  @Test
+  public void testBetweenSymmetric() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    testEval(schema, "table1", "0,", "select col1 between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between symmetric 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between symmetric 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between symmetric 3 and 1) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between symmetric 3 and 1) is null from table1",
+        new String[]{"t"});
+  }
+
+  @Test
+  public void testUnary() throws TajoException {
+    schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col8", TajoDataTypes.Type.BOOLEAN);
+
+
+    // sign test
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col4 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col5 from table1;", new String [] {"5.1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col1 from table1;", new String [] {"-1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col2 from table1;", new String [] {"-2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col3 from table1;", new String [] {"-3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col4 from table1;", new String [] {"-4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col5 from table1;", new String [] {"-5.1"});
+
+    // not test
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select col8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select NOT (col8) from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select NOT(NOT (col8)) from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,", "select col8 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,", "select (NOT (col8)) is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,", "select (NOT(NOT (col8))) is null from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testAndOr() throws TajoException {
+    testSimpleEval("select true or (false or false) or false;", new String[] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true and true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true and false;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false and true;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false and false;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true or true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true or false;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false or true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false or false;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (true and true) and false;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (true and false) and true;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (false and true) and true;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (1 < 2) and true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (1 < 2) and false;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (1 < 2) or false;", new String [] {"t"});
+  }
+
+  @Test
+  public void testFunction() throws TajoException {
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select upper('abc');", new String [] {"ABC"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select upper('bbc');", new String [] {"BBC"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select upper('chs');", new String [] {"CHS"});
+
+    testSimpleEval("select ltrim('xxtrim', 'xx') ", new String[]{"trim"});
+  }
+
+  @Test
+  public void testStringConcat() throws TajoException {
+    testSimpleEval("select length('123456') as col1 ", new String[]{"6"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 'abc' || 'bbc'", new String [] {"abcbbc"});
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col2", TajoDataTypes.Type.TEXT);
+    testEval(schema, "table1", " trim, abc", "select ltrim(col1) || ltrim(col2) from table1",
+        new String[]{"trimabc"});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java
new file mode 100644
index 0000000..9976d39
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java
@@ -0,0 +1,41 @@
+/**
+ * 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.codegen;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.storage.Tuple;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class TestGeneratorAdapter {
+  @Test
+  public void testGetDescription() throws Exception {
+    assertEquals("I", TajoGeneratorAdapter.getDescription(int.class));
+    assertEquals("Ljava/lang/String;", TajoGeneratorAdapter.getDescription(String.class));
+  }
+
+  @Test
+  public void getMethodDescription() throws Exception {
+    assertEquals("(Lorg/apache/tajo/catalog/Schema;Lorg/apache/tajo/storage/Tuple;)Lorg/apache/tajo/datum/Datum;",
+        TajoGeneratorAdapter.getMethodDescription(Datum.class, new Class[]{Schema.class, Tuple.class}));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
new file mode 100644
index 0000000..f2b6477
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
@@ -0,0 +1,341 @@
+/**
+ * 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.OverridableConf;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.cli.tsql.InvalidStatementException;
+import org.apache.tajo.cli.tsql.ParsedResult;
+import org.apache.tajo.cli.tsql.SimpleParser;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.*;
+import org.apache.tajo.engine.codegen.EvalCodeGenerator;
+import org.apache.tajo.engine.codegen.TajoClassLoader;
+import org.apache.tajo.engine.function.FunctionLoader;
+import org.apache.tajo.engine.json.CoreGsonHelper;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.exception.TajoInternalError;
+import org.apache.tajo.function.FunctionSignature;
+import org.apache.tajo.master.exec.QueryExecutor;
+import org.apache.tajo.plan.*;
+import org.apache.tajo.plan.expr.EvalContext;
+import org.apache.tajo.plan.expr.EvalNode;
+import org.apache.tajo.plan.serder.EvalNodeDeserializer;
+import org.apache.tajo.plan.serder.EvalNodeSerializer;
+import org.apache.tajo.plan.serder.PlanProto;
+import org.apache.tajo.plan.verifier.LogicalPlanVerifier;
+import org.apache.tajo.plan.verifier.PreLogicalPlanVerifier;
+import org.apache.tajo.plan.verifier.VerificationState;
+import org.apache.tajo.storage.LazyTuple;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+import org.apache.tajo.util.BytesUtils;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.*;
+
+public class ExprTestBase {
+  private static TajoTestingCluster util;
+  private static TajoConf conf;
+  private static CatalogService cat;
+  private static SQLAnalyzer analyzer;
+  private static PreLogicalPlanVerifier preLogicalPlanVerifier;
+  private static LogicalPlanner planner;
+  private static LogicalOptimizer optimizer;
+  private static LogicalPlanVerifier annotatedPlanVerifier;
+
+  public static String getUserTimeZoneDisplay(TimeZone tz) {
+    return DateTimeUtil.getTimeZoneDisplayTime(tz);
+  }
+
+  public ExprTestBase() {
+  }
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    conf = util.getConfiguration();
+    util.startCatalogCluster();
+    cat = util.getMiniCatalogCluster().getCatalog();
+    cat.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
+    cat.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    Map<FunctionSignature, FunctionDesc> map = FunctionLoader.load();
+    map = FunctionLoader.loadUserDefinedFunctions(conf, map);
+    for (FunctionDesc funcDesc : map.values()) {
+      cat.createFunction(funcDesc);
+    }
+
+    analyzer = new SQLAnalyzer();
+    preLogicalPlanVerifier = new PreLogicalPlanVerifier(cat);
+    planner = new LogicalPlanner(cat, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(util.getConfiguration(), cat);
+    annotatedPlanVerifier = new LogicalPlanVerifier();
+  }
+
+  @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);
+  }
+
+  public TajoConf getConf() {
+    return new TajoConf(conf);
+  }
+
+  /**
+   * verify query syntax and get raw targets.
+   *
+   * @param context QueryContext
+   * @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(QueryContext context, String query, boolean condition)
+      throws TajoException, InvalidStatementException {
+
+    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).getHistoryStatement());
+    VerificationState state = new VerificationState();
+    preLogicalPlanVerifier.verify(context, state, expr);
+    if (state.getErrors().size() > 0) {
+      if (!condition && state.getErrors().size() > 0) {
+        throw new RuntimeException(state.getErrors().get(0));
+      }
+      assertFalse(state.getErrors().get(0).getMessage(), true);
+    }
+    LogicalPlan plan = planner.createPlan(context, expr, true);
+    optimizer.optimize(context, plan);
+    annotatedPlanVerifier.verify(state, plan);
+
+    if (state.getErrors().size() > 0) {
+      assertFalse(state.getErrors().get(0).getMessage(), true);
+    }
+
+    Target [] targets = plan.getRootBlock().getRawTargets();
+    if (targets == null) {
+      throw new RuntimeException("Wrong query statement or query plan: " + parsedResults.get(0).getHistoryStatement());
+    }
+
+    // Trying regression test for cloning, (de)serialization for json and protocol buffer
+    for (Target t : targets) {
+      try {
+        assertEquals(t.getEvalTree(), t.getEvalTree().clone());
+      } catch (CloneNotSupportedException e) {
+        fail(e.getMessage());
+      }
+    }
+    for (Target t : targets) {
+      assertJsonSerDer(t.getEvalTree());
+    }
+    for (Target t : targets) {
+      assertEvalTreeProtoSerDer(context, t.getEvalTree());
+    }
+    return targets;
+  }
+
+  public void testSimpleEval(String query, String [] expected) throws TajoException {
+    testEval(null, null, null, query, expected);
+  }
+
+  public void testSimpleEval(OverridableConf context, String query, String [] expected) throws TajoException {
+    testEval(context, null, null, null, query, expected);
+  }
+
+  public void testSimpleEval(String query, String [] expected, boolean successOrFail)
+      throws TajoException, IOException {
+
+    testEval(null, null, null, null, query, expected, ',', successOrFail);
+  }
+
+  public void testSimpleEval(OverridableConf context, String query, String [] expected, boolean successOrFail)
+      throws TajoException, IOException {
+    testEval(context, null, null, null, query, expected, ',', successOrFail);
+  }
+
+  public void testEval(Schema schema, String tableName, String csvTuple, String query, String [] expected)
+      throws TajoException {
+    testEval(null, schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple, query,
+        expected, ',', true);
+  }
+
+  public void testEval(OverridableConf context, Schema schema, String tableName, String csvTuple, String query,
+                       String [] expected)
+      throws TajoException {
+    testEval(context, 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 TajoException {
+    testEval(null, schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple,
+        query, expected, delimiter, condition);
+  }
+
+  public void testEval(OverridableConf context, Schema schema, String tableName, String csvTuple, String query,
+                       String [] expected, char delimiter, boolean condition) throws TajoException {
+    QueryContext queryContext;
+    if (context == null) {
+      queryContext = LocalTajoTestingUtility.createDummyContext(conf);
+    } else {
+      queryContext = LocalTajoTestingUtility.createDummyContext(conf);
+      queryContext.putAll(context);
+    }
+
+    String timezoneId = queryContext.get(SessionVars.TIMEZONE);
+    TimeZone timeZone = TimeZone.getTimeZone(timezoneId);
+
+    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;
+      }
+
+      byte[][] tokens = BytesUtils.splitPreserveAllTokens(
+          csvTuple.getBytes(), delimiter, targetIdx, inputSchema.size());
+      lazyTuple = new LazyTuple(inputSchema, tokens,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.
+        boolean nullDatum;
+        Datum datum = lazyTuple.get(i);
+        nullDatum = (datum instanceof TextDatum || datum instanceof CharDatum);
+        nullDatum = nullDatum &&
+            datum.asChars().equals("") || datum.asChars().equals(queryContext.get(SessionVars.NULL_CHAR));
+        nullDatum |= datum.isNull();
+
+        if (nullDatum) {
+          vtuple.put(i, NullDatum.get());
+        } else {
+          vtuple.put(i, lazyTuple.get(i));
+        }
+      }
+      try {
+        cat.createTable(new TableDesc(qualifiedTableName, inputSchema,"TEXT",
+            new KeyValueSet(), CommonTestingUtil.getTestDir().toUri()));
+      } catch (IOException e) {
+        throw new TajoInternalError(e);
+      }
+    }
+
+    Target [] targets;
+
+    TajoClassLoader classLoader = new TajoClassLoader();
+    EvalContext evalContext = new EvalContext();
+
+    try {
+      targets = getRawTargets(queryContext, query, condition);
+
+      EvalCodeGenerator codegen = null;
+      if (queryContext.getBool(SessionVars.CODEGEN)) {
+        codegen = new EvalCodeGenerator(classLoader);
+      }
+
+      QueryExecutor.startScriptExecutors(queryContext, evalContext, targets);
+      Tuple outTuple = new VTuple(targets.length);
+      for (int i = 0; i < targets.length; i++) {
+        EvalNode eval = targets[i].getEvalTree();
+
+        if (queryContext.getBool(SessionVars.CODEGEN)) {
+          eval = codegen.compile(inputSchema, eval);
+        }
+        eval.bind(evalContext, inputSchema);
+
+        outTuple.put(i, eval.eval(vtuple));
+      }
+
+      try {
+        classLoader.clean();
+      } catch (Throwable throwable) {
+        throwable.printStackTrace();
+      }
+
+      for (int i = 0; i < expected.length; i++) {
+        String outTupleAsChars;
+        if (outTuple.type(i) == Type.TIMESTAMP) {
+          outTupleAsChars = TimestampDatum.asChars(outTuple.getTimeDate(i), timeZone, false);
+        } else if (outTuple.type(i) == Type.TIME) {
+          outTupleAsChars = TimeDatum.asChars(outTuple.getTimeDate(i), timeZone, false);
+        } else {
+          outTupleAsChars = outTuple.getText(i);
+        }
+        assertEquals(query, expected[i], outTupleAsChars);
+      }
+    } catch (IOException e) {
+      throw new TajoInternalError(e);
+    } catch (InvalidStatementException e) {
+      assertFalse(e.getMessage(), true);
+    } catch (TajoException 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 {
+        throw e;
+      }
+    } finally {
+      if (schema != null) {
+        cat.dropTable(qualifiedTableName);
+      }
+      QueryExecutor.stopScriptExecutors(evalContext);
+    }
+  }
+
+  public static void assertEvalTreeProtoSerDer(OverridableConf context, EvalNode evalNode) {
+    PlanProto.EvalNodeTree converted = EvalNodeSerializer.serialize(evalNode);
+    assertEquals(evalNode, EvalNodeDeserializer.deserialize(context, null, converted));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
new file mode 100644
index 0000000..ea42783
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
@@ -0,0 +1,424 @@
+/**
+ * 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.Column;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+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.plan.expr.*;
+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.*;
+import static org.junit.Assert.fail;
+
+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);
+    expr.bind(null, schema1);
+
+    assertCloneEqual(expr);
+    VTuple tuple = new VTuple(2);
+    tuple.put(0, DatumFactory.createInt4(1)); // put 0th field
+    tuple.put(1, DatumFactory.createInt4(99)); // put 1th field
+
+    // the result of evaluation must be 100.
+    assertEquals(expr.eval(tuple).asInt4(), 100);
+  }
+
+  public static class MockTrueEval extends EvalNode {
+
+    public MockTrueEval() {
+      super(EvalType.CONST);
+    }
+
+    @Override
+    public String getName() {
+      return this.getClass().getName();
+    }
+
+    @Override
+    public void preOrder(EvalNodeVisitor visitor) {
+      visitor.visit(this);
+    }
+
+    @Override
+    public void postOrder(EvalNodeVisitor visitor) {
+      visitor.visit(this);
+    }
+
+    @Override
+    public Datum eval(Tuple tuple) {
+      super.eval(tuple);
+      return DatumFactory.createBool(true);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return true;
+    }
+
+    @Override
+    public DataType getValueType() {
+      return CatalogUtil.newSimpleDataType(BOOLEAN);
+    }
+
+    @Override
+    public int childNum() {
+      return 0;
+    }
+
+    @Override
+    public EvalNode getChild(int idx) {
+      return null;
+    }
+  }
+
+  public static class MockFalseExpr extends EvalNode {
+
+    public MockFalseExpr() {
+      super(EvalType.CONST);
+    }
+
+    @Override
+    public Datum eval(Tuple tuple) {
+      super.eval(tuple);
+      return DatumFactory.createBool(false);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return true;
+    }
+
+    @Override
+    public String getName() {
+      return this.getClass().getName();
+    }
+
+    @Override
+    public void preOrder(EvalNodeVisitor visitor) {
+      visitor.visit(this);
+    }
+
+    @Override
+    public void postOrder(EvalNodeVisitor visitor) {
+      visitor.visit(this);
+    }
+
+    @Override
+    public DataType getValueType() {
+      return CatalogUtil.newSimpleDataType(BOOLEAN);
+    }
+
+    @Override
+    public int childNum() {
+      return 0;
+    }
+
+    @Override
+    public EvalNode getChild(int idx) {
+      return null;
+    }
+  }
+
+  @Test
+  public void testAndTest() {
+    MockTrueEval trueExpr = new MockTrueEval();
+    MockFalseExpr falseExpr = new MockFalseExpr();
+
+    BinaryEval andExpr = new BinaryEval(EvalType.AND, trueExpr, trueExpr);
+    andExpr.bind(null, null);
+    assertTrue(andExpr.eval(null).asBool());
+
+    andExpr = new BinaryEval(EvalType.AND, falseExpr, trueExpr);
+    andExpr.bind(null, null);
+    assertFalse(andExpr.eval(null).asBool());
+
+    andExpr = new BinaryEval(EvalType.AND, trueExpr, falseExpr);
+    andExpr.bind(null, null);
+    assertFalse(andExpr.eval(null).asBool());
+
+    andExpr = new BinaryEval(EvalType.AND, falseExpr, falseExpr);
+    andExpr.bind(null, null);
+    assertFalse(andExpr.eval(null).asBool());
+  }
+
+  @Test
+  public void testOrTest() {
+    MockTrueEval trueExpr = new MockTrueEval();
+    MockFalseExpr falseExpr = new MockFalseExpr();
+
+    BinaryEval orExpr = new BinaryEval(EvalType.OR, trueExpr, trueExpr);
+    orExpr.bind(null, null);
+    assertTrue(orExpr.eval(null).asBool());
+
+    orExpr = new BinaryEval(EvalType.OR, falseExpr, trueExpr);
+    orExpr.bind(null, null);
+    assertTrue(orExpr.eval(null).asBool());
+
+    orExpr = new BinaryEval(EvalType.OR, trueExpr, falseExpr);
+    orExpr.bind(null, null);
+    assertTrue(orExpr.eval(null).asBool());
+
+    orExpr = new BinaryEval(EvalType.OR, falseExpr, falseExpr);
+    orExpr.bind(null, null);
+    assertFalse(orExpr.eval(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.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, e1, e2);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.LTH, e2, e1);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, e2, e1);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+
+    expr = new BinaryEval(EvalType.GTH, e2, e1);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, e2, e1);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.GTH, e1, e2);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, e1, e2);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+
+    BinaryEval plus = new BinaryEval(EvalType.PLUS, e1, e2);
+    expr = new BinaryEval(EvalType.LTH, e1, plus);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, e1, plus);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.LTH, plus, e1);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.LEQ, plus, e1);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+
+    expr = new BinaryEval(EvalType.GTH, plus, e1);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, plus, e1);
+    assertTrue(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.GTH, e1, plus);
+    assertFalse(expr.bind(null, null).eval(null).asBool());
+    expr = new BinaryEval(EvalType.GEQ, e1, plus);
+    assertFalse(expr.bind(null, null).eval(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.bind(null, null).eval(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.bind(null, null).eval(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.bind(null, null).eval(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.bind(null, null).eval(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.bind(null, null).eval(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();
+    BinaryEval eval = (BinaryEval) 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(), ((BinaryEval)eval.getRightExpr()).getLeftExpr());
+    assertEquals(plus3.getRightExpr(), ((BinaryEval) eval.getRightExpr()).getRightExpr());
+    assertEquals(plus2.getLeftExpr(), ((BinaryEval)((BinaryEval)eval.getRightExpr()).getLeftExpr()).getLeftExpr());
+    assertEquals(plus2.getRightExpr(), ((BinaryEval)((BinaryEval)eval.getRightExpr()).getLeftExpr()).getRightExpr());
+    assertEquals(plus1.getLeftExpr(), ((BinaryEval) ((BinaryEval) eval.getRightExpr()).getRightExpr()).getLeftExpr());
+    assertEquals(plus1.getRightExpr(), ((BinaryEval) ((BinaryEval) eval.getRightExpr()).getRightExpr()).getRightExpr());
+  }
+
+  @Test
+  public final void testBindCheck() {
+    ConstEval e1;
+    ConstEval e2;
+    BinaryEval binEval;
+
+    // Constant
+    e1 = new ConstEval(DatumFactory.createInt4(9));
+    e2 = new ConstEval(DatumFactory.createInt4(34));
+    binEval = new BinaryEval(EvalType.LTH, e1, e2);
+    try {
+      binEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertTrue(binEval.bind(null, null).eval(null).asBool());
+    }
+
+    CaseWhenEval caseWhenEval = new CaseWhenEval();
+    caseWhenEval.addIfCond(new CaseWhenEval.IfThenEval(binEval, new ConstEval(DatumFactory.createInt4(1))));
+    try {
+      caseWhenEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertEquals(caseWhenEval.bind(null, null).eval(null).asInt4(), 1);
+    }
+
+    Schema schema = new Schema(new Column[]{new Column("test", TajoDataTypes.Type.INT4)});
+    Tuple tuple = new VTuple(new Datum[]{DatumFactory.createText("aaa")});
+    RegexPredicateEval regexEval = new RegexPredicateEval(false, new FieldEval("test",
+        CatalogUtil.newSimpleDataType(TajoDataTypes.Type.INT4)), new ConstEval(DatumFactory.createText("a*")), false);
+    try {
+      regexEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertEquals(regexEval.bind(null, schema).eval(tuple).asBool(), true);
+    }
+
+    RowConstantEval rowConstantEval = new RowConstantEval(new Datum[]{});
+    try {
+      rowConstantEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertEquals(rowConstantEval.bind(null, null).eval(null).isNull(), true);
+    }
+  }
+  
+  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/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
new file mode 100644
index 0000000..8c31550
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
@@ -0,0 +1,374 @@
+/**
+ * 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.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.function.FunctionLoader;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.Target;
+import org.apache.tajo.plan.expr.*;
+import org.apache.tajo.plan.exprrewrite.EvalTreeOptimizer;
+import org.apache.tajo.plan.function.GeneralFunction;
+import org.apache.tajo.plan.logical.GroupbyNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.nameresolver.NameResolvingMode;
+import org.apache.tajo.storage.TablespaceManager;
+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.*;
+
+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 QueryContext defaultContext;
+
+  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.getInt4(0);
+      y =  params.getInt4(1);
+      return DatumFactory.createInt4(x + y);
+    }
+  }
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
+      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("TEXT");
+    TableDesc desc = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "people"), schema, meta,
+        CommonTestingUtil.getTestDir().toUri());
+    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, TablespaceManager.getInstance());
+
+    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
+    };
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(util.getConfiguration());
+
+    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(defaultContext, expr);
+    } catch (TajoException e) {
+      throw new RuntimeException(e);
+    }
+
+    return plan.getRootBlock().getRawTargets();
+  }
+
+  public static EvalNode getRootSelection(String query) throws TajoException {
+    Expr block = analyzer.parse(query);
+    LogicalPlan plan = planner.createPlan(defaultContext, block);
+
+    LogicalPlanner.PlanContext context = new LogicalPlanner.PlanContext(defaultContext, plan, plan.getRootBlock(),
+        new EvalTreeOptimizer(), true);
+
+    Selection selection = plan.getRootBlock().getSingletonExpr(OpType.Filter);
+    return planner.getExprAnnotator().createEvalNode(context, selection.getQual(),
+        NameResolvingMode.RELS_AND_SUBEXPRS);
+  }
+
+  @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() {
+    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, TajoException {
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalPlan plan = planner.createPlan(defaultContext, 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);
+    BinaryEval node = (BinaryEval) 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 = (BinaryEval) 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 TajoException {
+    // "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);
+    BinaryEval first = (BinaryEval) cnf[0];
+    BinaryEval second = (BinaryEval) cnf[1];
+    
+    FieldEval field = first.getLeftExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(EvalType.LTH, first.getType());
+    assertEquals(10, first.getRightExpr().bind(null, null).eval(null).asInt4());
+    
+    field = second.getRightExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(EvalType.LTH, second.getType());
+    assertEquals(4, second.getLeftExpr().bind(null, null).eval(null).asInt4());
+  }
+  
+  @Test
+  public final void testTransformCNF2Singleton() throws TajoException {
+    // "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 TajoException {
+    // "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 TajoException {
+    Target [] targets = getRawTargets(QUERIES[0]);
+    EvalNode node = AlgebraicUtil.eliminateConstantExprs(targets[0].getEvalTree());
+    assertEquals(EvalType.CONST, node.getType());
+    assertEquals(7, node.bind(null, null).eval(null).asInt4());
+    node = AlgebraicUtil.eliminateConstantExprs(targets[1].getEvalTree());
+    assertEquals(EvalType.CONST, node.getType());
+    assertTrue(7.0d == node.bind(null, null).eval(null).asFloat8());
+
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalPlan plan = planner.createPlan(defaultContext, 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 TajoException {
+    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 TajoException {
+    Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
+    EvalNode node = getRootSelection(QUERIES[3]);
+    // we expect that score < 3
+    BinaryEval transposed = (BinaryEval) AlgebraicUtil.transpose(node, col1);
+    assertEquals(EvalType.GTH, transposed.getType());
+    FieldEval field = transposed.getLeftExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(1, transposed.getRightExpr().bind(null, null).eval(null).asInt4());
+
+    node = getRootSelection(QUERIES[4]);
+    // we expect that score < 3
+    transposed = (BinaryEval) AlgebraicUtil.transpose(node, col1);
+    assertEquals(EvalType.LTH, transposed.getType());
+    field = transposed.getLeftExpr();
+    assertEquals(col1, field.getColumnRef());
+    assertEquals(2, transposed.getRightExpr().bind(null, null).eval(null).asInt4());
+  }
+
+  @Test
+  public final void testFindDistinctAggFunctions() throws TajoException {
+    String query = "select sum(score) + max(age) from people";
+    Expr expr = analyzer.parse(query);
+    LogicalPlan plan = planner.createPlan(defaultContext, 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()));
+    }
+  }
+
+  @Test
+  public final void testIsJoinQual() throws TajoException {
+    EvalNode evalNode = getRootSelection("select score from people where people.score > people.age");
+    assertFalse(EvalTreeUtil.isJoinQual(evalNode, true));
+  }
+
+  @Test
+  public final void testIsJoinQual2() throws TajoException {
+    EvalNode evalNode = getRootSelection(
+        "select score from people where substr(people.score::text,1,1) > substr(people.age::text,1,1)");
+    assertFalse(EvalTreeUtil.isJoinQual(evalNode, true));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java
new file mode 100644
index 0000000..9f9d294
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java
@@ -0,0 +1,124 @@
+/**
+ * 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.exception.InvalidOperationException;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class TestIntervalType extends ExprTestBase {
+  @Test
+  public void testIntervalPostgresqlCase() throws TajoException {
+
+    // http://www.postgresql.org/docs/8.2/static/functions-datetime.html
+    testSimpleEval("select date '2001-09-28' + 7", new String[]{"2001-10-05"});
+    testSimpleEval("select date '2001-09-28' + interval '1 hour'",
+        new String[]{"2001-09-28 01:00:00"});
+
+    testSimpleEval("select date '2001-09-28' + time '03:00'",
+        new String[]{"2001-09-28 03:00:00"});
+    testSimpleEval("select time '03:00' + date '2001-09-28'",
+        new String[]{"2001-09-28 03:00:00"});
+    testSimpleEval("select interval '1 day' + interval '1 hour'", new String[]{"1 day 01:00:00"});
+
+    testSimpleEval("select timestamp '2001-09-28 01:00' + interval '23 hours'",
+        new String[]{"2001-09-29 00:00:00"});
+
+    testSimpleEval("select time '01:00' + interval '3 hours'", new String[]{"04:00:00"});
+
+    testSimpleEval("select date '2001-10-01' - date '2001-09-28'", new String[]{"3"});
+    testSimpleEval("select date '2001-10-01' - 7", new String[]{"2001-09-24"});
+    testSimpleEval("select date '2001-09-28' - interval '1 hour'",
+        new String[]{"2001-09-27 23:00:00"});
+
+    testSimpleEval("select time '05:00' - time '03:00'", new String[]{"02:00:00"});
+    testSimpleEval("select time '05:00' - interval '2 hours'", new String[]{"03:00:00"});
+    testSimpleEval("select timestamp '2001-09-28 23:00' - interval '23 hours'",
+        new String[]{"2001-09-28 00:00:00"});
+
+    testSimpleEval("select interval '1 day' - interval '1 hour'", new String[]{"23:00:00"});
+
+    testSimpleEval("select timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'", new String[]{"1 day 15:00:00"});
+    testSimpleEval("select 900 * interval '1 second'", new String[]{"00:15:00"});
+    testSimpleEval("select 21 * interval '1 day'", new String[]{"21 days"});
+    testSimpleEval("select 3.5 * interval '1 hour'", new String[]{"03:30:00"});
+    testSimpleEval("select interval '1 hour' / 1.5", new String[]{"00:40:00"});
+  }
+
+  @Test
+  public void testCaseByCase() throws Exception {
+    testSimpleEval("select date '2001-08-28' + interval '10 day 1 hour'",
+        new String[]{"2001-09-07 01:00:00"});
+    testSimpleEval("select interval '10 day 01:00:00' + date '2001-08-28'",
+        new String[]{"2001-09-07 01:00:00"});
+    testSimpleEval("select time '10:20:30' + interval '1 day 01:00:00'",
+        new String[]{"11:20:30"});
+    testSimpleEval("select interval '1 day 01:00:00' + time '10:20:30'",
+        new String[]{"11:20:30"});
+    testSimpleEval("select time '10:20:30' - interval '1 day 01:00:00'",
+        new String[]{"09:20:30"});
+
+    testSimpleEval("select (interval '1 month 20 day' + interval '50 day')", new String[]{"1 month 70 days"});
+    testSimpleEval("select date '2013-01-01' + interval '1 month 70 day'",
+        new String[]{"2013-04-12 00:00:00"});
+    testSimpleEval("select date '2013-01-01' + (interval '1 month 20 day' + interval '50 day')",
+        new String[]{"2013-04-12 00:00:00"});
+    testSimpleEval("select interval '1 month 70 day' + date '2013-01-01'",
+        new String[]{"2013-04-12 00:00:00"});
+    testSimpleEval("select date '2013-01-01' - interval '1 month 70 day'",
+        new String[]{"2012-09-22 00:00:00"});
+
+    testSimpleEval("select timestamp '2001-09-28 23:00' - interval '1 month 2 day 10:20:30'",
+        new String[]{"2001-08-26 12:39:30"});
+    testSimpleEval("select timestamp '2001-09-28 23:00' + interval '1 month 2 day 10:20:30'",
+        new String[]{"2001-10-31 09:20:30"});
+    testSimpleEval("select interval '1 month 2 day 10:20:30' + timestamp '2001-09-28 23:00'",
+        new String[]{"2001-10-31 09:20:30"});
+
+
+    testSimpleEval("select interval '5 month' / 3", new String[]{"1 month 20 days"});
+
+    // Notice: Different from postgresql result(13 days 01:02:36.4992) because of double type precision.
+    testSimpleEval("select interval '1 month' / 2.3", new String[]{"13 days 01:02:36.522"});
+
+    testSimpleEval("select interval '1 month' * 2.3", new String[]{"2 months 9 days"});
+    testSimpleEval("select interval '3 year 5 month 1 hour' / 1.5", new String[]{"2 years 3 months 10 days 00:40:00"});
+
+    testSimpleEval("select date '2001-09-28' - time '03:00'",
+        new String[]{"2001-09-27 21:00:00"});
+
+    testSimpleEval("select date '2014-03-20' + interval '1 day'",
+        new String[]{"2014-03-21 00:00:00"});
+
+    testSimpleEval("select date '2014-03-20' - interval '1 day'",
+        new String[]{"2014-03-19 00:00:00"});
+  }
+
+  @Test
+  public void testWrongFormatLiteral() throws Exception {
+    try {
+      testSimpleEval("select interval '1 month 2 day 23 hours 10:20:30'", new String[]{"DUMMY"});
+      fail("hour and time format can not be used at the same time  in interval.");
+    } catch (InvalidOperationException e) {
+      //success
+    }
+  }
+}


[29/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/util/TestJSPUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/util/TestJSPUtil.java b/tajo-core-tests/src/test/java/org/apache/tajo/util/TestJSPUtil.java
new file mode 100644
index 0000000..f3b6936
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/util/TestJSPUtil.java
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.util;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.TaskId;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.event.TaskAttemptToSchedulerEvent;
+import org.apache.tajo.querymaster.Task;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestJSPUtil {
+  @Test
+  public void testSortTask() throws Exception {
+    List<Task> tasks = new ArrayList<Task>();
+
+    Configuration conf = new TajoConf();
+
+    TaskAttemptToSchedulerEvent.TaskAttemptScheduleContext scheduleContext =
+        new TaskAttemptToSchedulerEvent.TaskAttemptScheduleContext();
+
+    ExecutionBlockId ebId = TajoIdUtils.createExecutionBlockId("eb_000001_00001_00001");
+
+    for (int i = 0; i < 10; i++) {
+      TaskId id = new TaskId(ebId, i);
+      Task task = new Task(conf, scheduleContext, id, true, null);
+      tasks.add(task);
+
+      int launchTime = i + 1;
+      int runningTime = i + 1;
+      if(i < 9) {
+        task.setLaunchTime(launchTime);
+        task.setFinishTime(launchTime + runningTime);
+      }
+    }
+
+    Collections.shuffle(tasks);
+
+    Task[] taskArray = tasks.toArray(new Task[]{});
+    JSPUtil.sortTaskArray(taskArray, "id", "asc");
+    for (int i = 0; i < 10; i++) {
+      assertEquals(i, taskArray[i].getId().getId());
+    }
+
+    taskArray = tasks.toArray(new Task[]{});
+    JSPUtil.sortTaskArray(taskArray, "id", "desc");
+    for (int i = 0; i < 10; i++) {
+      assertEquals(9 - i, taskArray[i].getId().getId());
+    }
+
+    taskArray = tasks.toArray(new Task[]{});
+    JSPUtil.sortTaskArray(taskArray, "runTime", "asc");
+    assertEquals(0, taskArray[0].getId().getId());
+    assertEquals(9, taskArray[9].getId().getId());
+
+    taskArray = tasks.toArray(new Task[]{});
+    JSPUtil.sortTaskArray(taskArray, "runTime", "desc");
+    assertEquals(8, taskArray[0].getId().getId());
+    assertEquals(9, taskArray[9].getId().getId());
+  }
+
+  @Test
+  public void testGetPageNavigationList() {
+    List<String> originList = new ArrayList<String>();
+
+    for (int i = 0; i < 35; i++) {
+      originList.add("Data" + (i + 1));
+    }
+
+    List<String> pageList = JSPUtil.getPageNavigationList(originList, 1, 10);
+    assertEquals(10, pageList.size());
+    assertEquals("Data1", pageList.get(0));
+    assertEquals("Data10", pageList.get(9));
+
+    pageList = JSPUtil.getPageNavigationList(originList, 2, 10);
+    assertEquals(10, pageList.size());
+    assertEquals("Data11", pageList.get(0));
+    assertEquals("Data20", pageList.get(9));
+
+    pageList = JSPUtil.getPageNavigationList(originList, 3, 10);
+    assertEquals(10, pageList.size());
+    assertEquals("Data21", pageList.get(0));
+    assertEquals("Data30", pageList.get(9));
+
+    pageList = JSPUtil.getPageNavigationList(originList, 4, 10);
+    assertEquals(5, pageList.size());
+    assertEquals("Data31", pageList.get(0));
+    assertEquals("Data35", pageList.get(4));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/util/history/TestHistoryWriterReader.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/util/history/TestHistoryWriterReader.java b/tajo-core-tests/src/test/java/org/apache/tajo/util/history/TestHistoryWriterReader.java
new file mode 100644
index 0000000..3d2578c
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/util/history/TestHistoryWriterReader.java
@@ -0,0 +1,313 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.util.history;
+
+import com.google.common.io.Files;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.*;
+import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.TajoProtos.TaskAttemptState;
+import org.apache.tajo.catalog.proto.CatalogProtos.TableStatsProto;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.master.QueryInfo;
+import org.apache.tajo.util.TajoIdUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class TestHistoryWriterReader extends QueryTestCaseBase {
+  public static final String HISTORY_DIR = "/tmp/tajo-test-history";
+  TajoConf tajoConf;
+
+  @Before
+  public void setUp() throws Exception {
+    tajoConf = new TajoConf(testingCluster.getConfiguration());
+    tajoConf.setVar(ConfVars.HISTORY_QUERY_DIR, HISTORY_DIR);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    Path path = TajoConf.getQueryHistoryDir(tajoConf);
+    FileSystem fs = path.getFileSystem(tajoConf);
+    fs.delete(path, true);
+  }
+
+  @Test
+  public void testQueryInfoReadAndWrite() throws Exception {
+    HistoryWriter writer = new HistoryWriter("127.0.0.1:28090", true);
+    try {
+      writer.init(tajoConf);
+      writer.start();
+
+      long startTime = System.currentTimeMillis();
+      QueryInfo queryInfo1 = new QueryInfo(QueryIdFactory.newQueryId(startTime, 1));
+      queryInfo1.setStartTime(startTime);
+      queryInfo1.setProgress(1.0f);
+      queryInfo1.setQueryState(QueryState.QUERY_SUCCEEDED);
+      writer.appendHistory(queryInfo1);
+
+      QueryInfo queryInfo2 = new QueryInfo(QueryIdFactory.newQueryId(startTime, 2));
+      queryInfo2.setStartTime(startTime);
+      queryInfo2.setProgress(0.5f);
+      queryInfo2.setQueryState(QueryState.QUERY_FAILED);
+      writer.appendAndSync(queryInfo2);
+
+      SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
+      Path path = new Path(tajoConf.getVar(ConfVars.HISTORY_QUERY_DIR));
+
+      FileSystem fs = path.getFileSystem(tajoConf);
+      Path parentPath = new Path(path, df.format(startTime) + "/query-list");
+      FileStatus[] histFiles = fs.listStatus(parentPath);
+      assertNotNull(histFiles);
+      assertEquals(1, histFiles.length);
+      assertTrue(histFiles[0].isFile());
+      assertTrue(histFiles[0].getPath().getName().endsWith(".hist"));
+
+      HistoryReader reader = new HistoryReader("127.0.0.1:28090", tajoConf);
+      List<QueryInfo> queryInfos = reader.getQueriesInHistory(1, 2);
+      assertNotNull(queryInfos);
+      assertEquals(2, queryInfos.size());
+
+      QueryInfo foundQueryInfo = queryInfos.get(0);
+      assertEquals(queryInfo2.getQueryId(), foundQueryInfo.getQueryId());
+      assertEquals(queryInfo2.getQueryState(), foundQueryInfo.getQueryState());
+      assertEquals(queryInfo2.getProgress(), foundQueryInfo.getProgress(), 0);
+
+      foundQueryInfo = reader.getQueryByQueryId(queryInfo2.getQueryId());
+      assertEquals(queryInfo2.getQueryId(), foundQueryInfo.getQueryId());
+      assertEquals(queryInfo2.getQueryState(), foundQueryInfo.getQueryState());
+      assertEquals(queryInfo2.getProgress(), foundQueryInfo.getProgress(), 0);
+
+      foundQueryInfo = queryInfos.get(1);
+      assertEquals(queryInfo1.getQueryId(), foundQueryInfo.getQueryId());
+      assertEquals(queryInfo1.getQueryState(), foundQueryInfo.getQueryState());
+      assertEquals(queryInfo1.getProgress(), foundQueryInfo.getProgress(), 0);
+
+      foundQueryInfo = reader.getQueryByQueryId(queryInfo1.getQueryId());
+      assertEquals(queryInfo1.getQueryId(), foundQueryInfo.getQueryId());
+      assertEquals(queryInfo1.getQueryState(), foundQueryInfo.getQueryState());
+      assertEquals(queryInfo1.getProgress(), foundQueryInfo.getProgress(), 0);
+    } finally {
+      writer.stop();
+    }
+  }
+
+  @Test
+  public void testQueryInfoPagination() throws Exception {
+    HistoryWriter writer = new HistoryWriter("127.0.0.1:28090", true);
+    try {
+      writer.init(tajoConf);
+      writer.start();
+
+      long startTime = System.currentTimeMillis();
+      int testSize = 10;
+      QueryInfo queryInfo;
+
+      for (int i = 1; i < testSize + 1; i++) {
+        queryInfo = new QueryInfo(QueryIdFactory.newQueryId(startTime, i));
+        queryInfo.setStartTime(startTime);
+        queryInfo.setProgress(1.0f);
+        queryInfo.setQueryState(QueryState.QUERY_SUCCEEDED);
+
+        if (testSize == i) {
+          writer.appendAndSync(queryInfo);
+        } else {
+          writer.appendHistory(queryInfo);
+        }
+      }
+
+      SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
+      Path path = new Path(tajoConf.getVar(ConfVars.HISTORY_QUERY_DIR));
+
+      FileSystem fs = path.getFileSystem(tajoConf);
+      Path parentPath = new Path(path, df.format(startTime) + "/query-list");
+      FileStatus[] histFiles = fs.listStatus(parentPath);
+      assertNotNull(histFiles);
+      assertEquals(1, histFiles.length);
+      assertTrue(histFiles[0].isFile());
+      assertTrue(histFiles[0].getPath().getName().endsWith(".hist"));
+
+      HistoryReader reader = new HistoryReader("127.0.0.1:28090", tajoConf);
+      List<QueryInfo> queryInfos = reader.getQueriesInHistory(1, testSize);
+      assertNotNull(queryInfos);
+      assertEquals(testSize, queryInfos.size());
+
+      // the pagination api returns a descending ordered list
+      for (int i = 0; i < testSize; i++) {
+        assertEquals(testSize - i, queryInfos.get(i).getQueryId().getSeq());
+      }
+
+      int pages = 5;
+      int pageSize = testSize / pages;
+      int expectIdSequence = testSize;
+      //min startIndex of page is 1
+      for (int i = 1; i < pages + 1; i++) {
+        queryInfos = reader.getQueriesInHistory(i, pageSize);
+        assertNotNull(queryInfos);
+        assertEquals(pageSize, queryInfos.size());
+
+        for (QueryInfo qInfo : queryInfos) {
+          assertEquals(expectIdSequence--, qInfo.getQueryId().getSeq());
+        }
+      }
+    } finally {
+      writer.stop();
+    }
+  }
+
+  @Test
+  public void testQueryHistoryReadAndWrite() throws Exception {
+    HistoryWriter writer = new HistoryWriter("127.0.0.1:28090", true);
+    writer.init(tajoConf);
+    writer.start();
+
+    try {
+      long startTime = System.currentTimeMillis();
+
+      QueryHistory queryHistory = new QueryHistory();
+      QueryId queryId = QueryIdFactory.newQueryId(startTime, 1);
+      queryHistory.setQueryId(queryId.toString());
+      queryHistory.setLogicalPlan("LogicalPlan");
+      List<StageHistory> stages = new ArrayList<StageHistory>();
+      for (int i = 0; i < 3; i++) {
+        ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(queryId, i);
+        StageHistory stageHistory = new StageHistory();
+        stageHistory.setExecutionBlockId(ebId.toString());
+        stageHistory.setStartTime(startTime + i);
+
+        List<TaskHistory> taskHistories = new ArrayList<TaskHistory>();
+        for (int j = 0; j < 5; j++) {
+          TaskHistory taskHistory = new TaskHistory();
+          taskHistory.setId(QueryIdFactory.newTaskAttemptId(QueryIdFactory.newTaskId(ebId), 1).toString());
+          taskHistories.add(taskHistory);
+        }
+        stageHistory.setTasks(taskHistories);
+        stages.add(stageHistory);
+      }
+      queryHistory.setStageHistories(stages);
+
+      writer.appendAndSync(queryHistory);
+
+      SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
+      Path path = new Path(tajoConf.getVar(ConfVars.HISTORY_QUERY_DIR));
+
+      FileSystem fs = path.getFileSystem(tajoConf);
+
+      assertTrue(fs.exists(new Path(path,
+          df.format(startTime) + "/query-detail/" + queryId.toString() + "/query.hist")));
+      for (int i = 0; i < 3; i++) {
+        String ebId = QueryIdFactory.newExecutionBlockId(queryId, i).toString();
+        assertTrue(fs.exists(new Path(path,
+            df.format(startTime) + "/query-detail/" + queryId.toString() + "/" + ebId + ".hist")));
+      }
+
+      HistoryReader reader = new HistoryReader("127.0.0.1:28090", tajoConf);
+      QueryHistory foundQueryHistory = reader.getQueryHistory(queryId.toString());
+      assertNotNull(foundQueryHistory);
+      assertEquals(queryId.toString(), foundQueryHistory.getQueryId());
+      assertEquals(3, foundQueryHistory.getStageHistories().size());
+
+      for (int i = 0; i < 3; i++) {
+        String ebId = QueryIdFactory.newExecutionBlockId(queryId, i).toString();
+        StageHistory stageHistory = foundQueryHistory.getStageHistories().get(i);
+        assertEquals(ebId, stageHistory.getExecutionBlockId());
+        assertEquals(startTime + i, stageHistory.getStartTime());
+
+        // TaskHistory is stored in the other file.
+        assertNull(stageHistory.getTasks());
+
+        List<TaskHistory> tasks = reader.getTaskHistory(queryId.toString(), ebId);
+        assertNotNull(tasks);
+        assertEquals(5, tasks.size());
+
+        for (int j = 0; j < 5; j++) {
+          TaskHistory taskHistory = tasks.get(j);
+          assertEquals(stages.get(i).getTasks().get(j).getId(), taskHistory.getId());
+        }
+      }
+    } finally {
+      writer.stop();
+    }
+  }
+
+  @Test
+  public void testTaskHistoryReadAndWrite() throws Exception {
+    TajoConf tajoConf = new TajoConf();
+    File historyParentDir = Files.createTempDir();
+    historyParentDir.deleteOnExit();
+    tajoConf.setVar(ConfVars.HISTORY_TASK_DIR, "file://" + historyParentDir.getCanonicalPath());
+
+    HistoryWriter writer = new HistoryWriter("127.0.0.1:28090", false);
+    writer.init(tajoConf);
+    writer.start();
+
+    try {
+      // Write TaskHistory
+      TableStatsProto tableStats = TableStatsProto.newBuilder()
+          .setNumRows(10)
+          .setNumBytes(100)
+          .build();
+      long startTime = System.currentTimeMillis() - 2000;
+      TaskAttemptId id1 = TajoIdUtils.parseTaskAttemptId("ta_1412326813565_0001_000001_000001_00");
+      org.apache.tajo.worker.TaskHistory taskHistory1 = new org.apache.tajo.worker.TaskHistory(
+          id1, TaskAttemptState.TA_SUCCEEDED, 1.0f, startTime, System.currentTimeMillis(), tableStats);
+      writer.appendHistory(taskHistory1);
+
+      TaskAttemptId id2 = TajoIdUtils.parseTaskAttemptId("ta_1412326813565_0001_000001_000002_00");
+      org.apache.tajo.worker.TaskHistory taskHistory2 = new org.apache.tajo.worker.TaskHistory(
+          id2, TaskAttemptState.TA_SUCCEEDED, 1.0f, startTime, System.currentTimeMillis() - 500, tableStats);
+      writer.appendAndSync(taskHistory2);
+
+      SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHH");
+      String startDate = df.format(new Date(startTime));
+      Path taskParentPath = new Path(tajoConf.getVar(ConfVars.HISTORY_TASK_DIR),
+          startDate.substring(0, 8) + "/tasks/127.0.0.1_28090");
+
+      FileSystem fs = taskParentPath.getFileSystem(tajoConf);
+      assertTrue(fs.exists(taskParentPath));
+
+      HistoryReader reader = new HistoryReader("127.0.0.1:28090", tajoConf);
+      org.apache.tajo.worker.TaskHistory foundTaskHistory = reader.getTaskHistory(id1.toString(), startTime);
+      assertNotNull(foundTaskHistory);
+      assertEquals(id1, foundTaskHistory.getTaskAttemptId());
+      assertEquals(taskHistory1, foundTaskHistory);
+
+      foundTaskHistory = reader.getTaskHistory(id2.toString(), startTime);
+      assertNotNull(foundTaskHistory);
+      assertEquals(id2, foundTaskHistory.getTaskAttemptId());
+      assertEquals(taskHistory2, foundTaskHistory);
+
+      foundTaskHistory = reader.getTaskHistory("ta_1412326813565_0001_000001_000003_00", startTime);
+      assertNull(foundTaskHistory);
+    } finally {
+      writer.stop();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestMetricsFilter.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestMetricsFilter.java b/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestMetricsFilter.java
new file mode 100644
index 0000000..b70512c
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestMetricsFilter.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.util.metrics;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestMetricsFilter {
+  @Test
+  public void testGroupNameMetricsFilter() {
+    GroupNameMetricsFilter filter = new GroupNameMetricsFilter("tajomaster");
+
+    assertTrue(filter.matches("tajomaster.JVM.Heap.memFree", null));
+    assertTrue(!filter.matches("tajomaster01.JVM.Heap.memFree", null));
+    assertTrue(!filter.matches("server.tajomaster.JVM.Heap.memFree", null));
+    assertTrue(!filter.matches("tajworker.JVM.Heap.memFree", null));
+  }
+
+  @Test
+  public void testRegexpMetricsFilter() {
+    List<String> filterExpressions = new ArrayList<String>();
+    filterExpressions.add("JVM");
+    filterExpressions.add("Query");
+
+    RegexpMetricsFilter filter = new RegexpMetricsFilter(filterExpressions);
+
+    assertTrue(filter.matches("tajomaster.JVM.Heap.memFree", null));
+    assertTrue(filter.matches("tajomaster.Query.numQuery", null));
+
+    assertTrue(!filter.matches("tajomaster.resource.numWorker", null));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestSystemMetrics.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestSystemMetrics.java b/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestSystemMetrics.java
new file mode 100644
index 0000000..8751df9
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/util/metrics/TestSystemMetrics.java
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.util.metrics;
+
+import com.codahale.metrics.Counter;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.metrics.Master;
+import org.apache.tajo.metrics.MetricsUtil;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.metrics.reporter.TajoMetricsScheduledReporter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestSystemMetrics {
+  Path testPropertyFile;
+  Path metricsOutputFile;
+  @Before
+  public void setUp() throws Exception {
+    testPropertyFile =
+        new Path(CommonTestingUtil.getTestDir(), System.currentTimeMillis() + ".properties");
+
+    metricsOutputFile =
+        new Path(CommonTestingUtil.getTestDir(), System.currentTimeMillis() + ".out");
+
+    FileOutputStream out = new FileOutputStream(testPropertyFile.toUri().getPath());
+    out.write("reporter.null=org.apache.tajo.util.metrics.reporter.NullReporter\n".getBytes());
+    out.write("reporter.file=org.apache.tajo.util.metrics.reporter.MetricsFileScheduledReporter\n".getBytes());
+    out.write("reporter.console=org.apache.tajo.util.metrics.reporter.MetricsConsoleScheduledReporter\n".getBytes());
+
+    out.write("MASTER-JVM.reporters=console\n".getBytes());
+    out.write("MASTER.reporters=file\n".getBytes());
+    out.write("test-console-group.reporters=console\n".getBytes());
+    out.write("test-find-console-group.reporters=console,file\n".getBytes());
+
+    out.write(("MASTER.file.filename=" + metricsOutputFile.toUri().getPath() + "\n").getBytes());
+    out.write("MASTER.file.period=5\n".getBytes());
+    out.close();
+  }
+
+  @Test
+  public void testMetricsReporter() throws Exception {
+    TajoConf tajoConf = new TajoConf();
+    tajoConf.set("tajo.metrics.property.file", testPropertyFile.toUri().getPath());
+    TajoSystemMetrics tajoSystemMetrics = new TajoSystemMetrics(tajoConf, org.apache.tajo.metrics.Master.class,
+        "localhost");
+    tajoSystemMetrics.start();
+
+    Collection<TajoMetricsScheduledReporter> reporters = tajoSystemMetrics.getMetricsReporters();
+
+    assertEquals(2, reporters.size());
+
+    TajoMetricsScheduledReporter reporter = reporters.iterator().next();
+    assertEquals(5, reporter.getPeriod());
+
+    for(int i = 0; i < 10; i++) {
+      tajoSystemMetrics.counter(Master.Query.FAILED).inc();
+      tajoSystemMetrics.counter(Master.Query.COMPLETED).inc(2);
+      tajoSystemMetrics.counter(Master.Cluster.ACTIVE_NODES).inc(3);
+    }
+
+    SortedMap<String, Counter> counterMap = tajoSystemMetrics.getRegistry().getCounters();
+    Counter counter1 = counterMap.get("MASTER.QUERY.FAILED");
+    assertNotNull(counter1);
+    assertEquals(10, counter1.getCount());
+
+    Counter counter2 = counterMap.get("MASTER.QUERY.COMPLETED");
+    assertNotNull(counter2);
+    assertEquals(20, counter2.getCount());
+
+    Counter counter3 = counterMap.get("MASTER.CLUSTER.ACTIVE_NODES");
+    assertNotNull(counter3);
+    assertEquals(30, counter3.getCount());
+
+    //test findMetricsItemGroup method
+    Map<String, Map<String, Counter>> groupItems = reporter.findMetricsItemGroup(counterMap);
+    assertEquals(2, groupItems.size());
+
+    Map<String, Counter> group01Items = groupItems.get(MetricsUtil.getCanonicalContextName(Master.Query.class));
+    assertEquals(2, group01Items.size());
+
+    counter1 = group01Items.get(Master.Query.FAILED.name());
+    assertNotNull(counter1);
+    assertEquals(10, counter1.getCount());
+
+    counter2 = group01Items.get(Master.Query.COMPLETED.name());
+    assertNotNull(counter2);
+    assertEquals(20, counter2.getCount());
+
+    Map<String, Counter> group02Items = groupItems.get(MetricsUtil.getCanonicalContextName(Master.Cluster.class));
+    assertEquals(1, group02Items.size());
+
+    reporter.report();
+
+    BufferedReader reader = new BufferedReader(new InputStreamReader(
+        new FileInputStream(metricsOutputFile.toUri().getPath())));
+
+    String line;
+
+    List<String> lines = new ArrayList<String>();
+    while((line = reader.readLine()) != null) {
+      lines.add(line);
+    }
+
+    assertEquals(2, lines.size());
+    tajoSystemMetrics.stop();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    FileSystem fs = testPropertyFile.getFileSystem(new Configuration());
+    fs.delete(testPropertyFile, false);
+    fs.delete(metricsOutputFile, false);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockExecutionBlock.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockExecutionBlock.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockExecutionBlock.java
new file mode 100644
index 0000000..7d7fb1a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockExecutionBlock.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.worker;
+
+import org.apache.tajo.ResourceProtos.ExecutionBlockContextResponse;
+import org.apache.tajo.TaskAttemptId;
+
+import java.io.IOException;
+
+public class MockExecutionBlock extends ExecutionBlockContext {
+
+  public MockExecutionBlock(TajoWorker.WorkerContext workerContext,
+                            ExecutionBlockContextResponse request) throws IOException {
+    super(workerContext, request, null);
+  }
+
+  @Override
+  public void init() throws Throwable {
+    //skip
+  }
+
+  @Override
+  public void fatalError(TaskAttemptId taskAttemptId, String message) {
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeResourceManager.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeResourceManager.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeResourceManager.java
new file mode 100644
index 0000000..8c8427d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeResourceManager.java
@@ -0,0 +1,88 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.ResourceProtos.TaskAllocationProto;
+import org.apache.tajo.ResourceProtos.TaskRequestProto;
+import org.apache.tajo.TaskAttemptId;
+import org.apache.tajo.plan.serder.PlanProto;
+import org.apache.tajo.resource.NodeResource;
+import org.apache.tajo.resource.NodeResources;
+import org.apache.tajo.worker.event.NodeResourceEvent;
+
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.Semaphore;
+
+public class MockNodeResourceManager extends NodeResourceManager {
+
+  volatile boolean enableTaskHandlerEvent = true;
+  private final Semaphore barrier;
+
+  public MockNodeResourceManager(Semaphore barrier, Dispatcher dispatcher, TajoWorker.WorkerContext workerContext) {
+    super(dispatcher, workerContext);
+    this.barrier = barrier;
+  }
+
+  @Override
+  public void handle(NodeResourceEvent event) {
+    super.handle(event);
+    barrier.release();
+  }
+
+  @Override
+  protected void startTask(TaskRequestProto request, NodeResource resource) {
+    if(enableTaskHandlerEvent) {
+      super.startTask(request, resource);
+    }
+  }
+
+  /**
+   * skip task execution and deallocation for testing
+   * */
+  public void setTaskHandlerEvent(boolean flag) {
+    enableTaskHandlerEvent = flag;
+  }
+
+  protected static Queue<TaskAllocationProto> createTaskRequests(
+      ExecutionBlockId ebId, int memory, int size) {
+
+    Queue<TaskAllocationProto>
+        requestProtoList = new LinkedBlockingQueue<TaskAllocationProto>();
+    for (int i = 0; i < size; i++) {
+
+      TaskAttemptId taskAttemptId = QueryIdFactory.newTaskAttemptId(QueryIdFactory.newTaskId(ebId, i), 0);
+      TaskRequestProto.Builder builder = TaskRequestProto.newBuilder();
+      builder.setQueryMasterHostAndPort("localhost:0");
+      builder.setId(taskAttemptId.getProto());
+      builder.setOutputTable("");
+      builder.setPlan(PlanProto.LogicalNodeTree.newBuilder());
+      builder.setClusteredOutput(false);
+
+
+      requestProtoList.add(TaskAllocationProto.newBuilder()
+          .setResource(NodeResources.createResource(memory).getProto())
+          .setTaskRequest(builder.build()).build());
+    }
+    return requestProtoList;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeStatusUpdater.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeStatusUpdater.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeStatusUpdater.java
new file mode 100644
index 0000000..634398f
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockNodeStatusUpdater.java
@@ -0,0 +1,97 @@
+/**
+ * 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.worker;
+
+import com.google.common.collect.Maps;
+import com.google.protobuf.RpcCallback;
+import com.google.protobuf.RpcController;
+import org.apache.tajo.ipc.TajoResourceTrackerProtocol.TajoResourceTrackerProtocolService;
+import org.apache.tajo.resource.NodeResource;
+import org.apache.tajo.resource.NodeResources;
+
+import java.net.ConnectException;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+import static org.apache.tajo.ResourceProtos.*;
+
+public class MockNodeStatusUpdater extends NodeStatusUpdater {
+
+  private CountDownLatch barrier;
+  private Map<Integer, NodeResource> membership = Maps.newHashMap();
+  private Map<Integer, NodeResource> resources = Maps.newHashMap();
+  private MockResourceTracker resourceTracker;
+
+  public MockNodeStatusUpdater(CountDownLatch barrier, TajoWorker.WorkerContext workerContext) {
+    super(workerContext);
+    this.barrier = barrier;
+    this.resourceTracker = new MockResourceTracker();
+  }
+
+  @Override
+  protected TajoResourceTrackerProtocolService.Interface newStub()
+      throws NoSuchMethodException, ConnectException, ClassNotFoundException {
+
+    return resourceTracker;
+  }
+
+  protected MockResourceTracker getResourceTracker() {
+    return resourceTracker;
+  }
+
+  class MockResourceTracker implements TajoResourceTrackerProtocolService.Interface {
+    private NodeHeartbeatRequest lastRequest;
+
+    protected Map<Integer, NodeResource> getTotalResource() {
+      return membership;
+    }
+
+    protected Map<Integer, NodeResource> getAvailableResource() {
+      return membership;
+    }
+
+    protected NodeHeartbeatRequest getLastRequest() {
+      return lastRequest;
+    }
+
+    @Override
+    public void nodeHeartbeat(RpcController controller, NodeHeartbeatRequest request,
+                              RpcCallback<NodeHeartbeatResponse> done) {
+
+      NodeHeartbeatResponse.Builder response = NodeHeartbeatResponse.newBuilder();
+      if (membership.containsKey(request.getWorkerId())) {
+        if (request.hasAvailableResource()) {
+          NodeResource resource = resources.get(request.getWorkerId());
+          NodeResources.update(resource, new NodeResource(request.getAvailableResource()));
+        }
+        done.run(response.setCommand(ResponseCommand.NORMAL).build());
+      } else {
+        if (request.hasConnectionInfo()) {
+          membership.put(request.getWorkerId(), new NodeResource(request.getTotalResource()));
+          resources.put(request.getWorkerId(), new NodeResource(request.getAvailableResource()));
+          done.run(response.setCommand(ResponseCommand.NORMAL).build());
+        } else {
+          done.run(response.setCommand(ResponseCommand.MEMBERSHIP).build());
+        }
+      }
+      lastRequest = request;
+      barrier.countDown();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskExecutor.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskExecutor.java
new file mode 100644
index 0000000..071d26a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskExecutor.java
@@ -0,0 +1,153 @@
+/**
+ * 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.worker;
+
+import org.apache.tajo.ResourceProtos.TaskRequestProto;
+import org.apache.tajo.ResourceProtos.TaskStatusProto;
+import org.apache.tajo.TajoProtos;
+import org.apache.tajo.TaskAttemptId;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.worker.event.TaskStartEvent;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Semaphore;
+
+public class MockTaskExecutor extends TaskExecutor {
+
+  protected final Semaphore barrier;
+
+  public MockTaskExecutor(Semaphore barrier, TajoWorker.WorkerContext workerContext) {
+    super(workerContext);
+    this.barrier = barrier;
+  }
+
+  @Override
+  public void handle(TaskStartEvent event) {
+    super.handle(event);
+    barrier.release();
+  }
+
+  @Override
+  protected Task createTask(final ExecutionBlockContext context, TaskRequestProto taskRequest) {
+    final TaskAttemptId taskAttemptId = new TaskAttemptId(taskRequest.getId());
+
+    //ignore status changed log
+    final TaskAttemptContext taskAttemptContext = new TaskAttemptContext(null, context, taskAttemptId, null, null) {
+      private TajoProtos.TaskAttemptState state;
+
+      @Override
+      public TajoProtos.TaskAttemptState getState() {
+        return state;
+      }
+
+      @Override
+      public void setState(TajoProtos.TaskAttemptState state) {
+        this.state = state;
+      }
+    };
+
+    return new Task() {
+      @Override
+      public void init() throws IOException {
+
+      }
+
+      @Override
+      public void fetch(ExecutorService executorService) {
+
+      }
+
+      @Override
+      public void run() throws Exception {
+        taskAttemptContext.stop();
+        taskAttemptContext.setProgress(1.0f);
+        taskAttemptContext.setState(TajoProtos.TaskAttemptState.TA_SUCCEEDED);
+      }
+
+      @Override
+      public void kill() {
+
+      }
+
+      @Override
+      public void abort() {
+
+      }
+
+      @Override
+      public void cleanup() {
+
+      }
+
+      @Override
+      public boolean hasFetchPhase() {
+        return false;
+      }
+
+      @Override
+      public boolean isProgressChanged() {
+        return false;
+      }
+
+      @Override
+      public boolean isStopped() {
+        return taskAttemptContext.isStopped();
+      }
+
+      @Override
+      public void updateProgress() {
+
+      }
+
+      @Override
+      public TaskAttemptContext getTaskContext() {
+        return taskAttemptContext;
+      }
+
+      @Override
+      public ExecutionBlockContext getExecutionBlockContext() {
+        return context;
+      }
+
+      @Override
+      public TaskStatusProto getReport() {
+        TaskStatusProto.Builder builder = TaskStatusProto.newBuilder();
+      builder.setWorkerName("localhost:0");
+      builder.setId(taskAttemptContext.getTaskId().getProto())
+          .setProgress(taskAttemptContext.getProgress())
+          .setState(taskAttemptContext.getState());
+
+      builder.setInputStats(new TableStats().getProto());
+      return builder.build();
+      }
+
+      @Override
+      public TaskHistory createTaskHistory() {
+        return null;
+      }
+
+      @Override
+      public List<Fetcher> getFetchers() {
+        return null;
+      }
+    };
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskManager.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskManager.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskManager.java
new file mode 100644
index 0000000..76ce9f7
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockTaskManager.java
@@ -0,0 +1,69 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.ResourceProtos.ExecutionBlockContextResponse;
+import org.apache.tajo.ResourceProtos.ExecutionBlockListProto;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.ipc.TajoWorkerProtocol;
+import org.apache.tajo.plan.serder.PlanProto;
+import org.apache.tajo.worker.event.TaskManagerEvent;
+
+import java.io.IOException;
+import java.util.concurrent.Semaphore;
+
+public class MockTaskManager extends TaskManager {
+
+  private final Semaphore barrier;
+
+  public MockTaskManager(Semaphore barrier, Dispatcher dispatcher, TajoWorker.WorkerContext workerContext) {
+    super(dispatcher, workerContext);
+    this.barrier = barrier;
+  }
+
+  @Override
+  protected ExecutionBlockContext createExecutionBlock(ExecutionBlockId executionBlockId, String queryMaster) {
+    try {
+      ExecutionBlockContextResponse.Builder builder = ExecutionBlockContextResponse.newBuilder();
+      builder.setExecutionBlockId(executionBlockId.getProto())
+          .setPlanJson("test")
+          .setQueryContext(new QueryContext(new TajoConf()).getProto())
+          .setQueryOutputPath("testpath")
+          .setShuffleType(PlanProto.ShuffleType.HASH_SHUFFLE);
+      return new MockExecutionBlock(getWorkerContext(), builder.build());
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Override
+  protected void stopExecutionBlock(ExecutionBlockContext context,
+                                    ExecutionBlockListProto cleanupList) {
+    //skip for testing
+  }
+
+  @Override
+  public void handle(TaskManagerEvent event) {
+    super.handle(event);
+    barrier.release();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockWorkerContext.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockWorkerContext.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockWorkerContext.java
new file mode 100644
index 0000000..25f3dca
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/MockWorkerContext.java
@@ -0,0 +1,109 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.fs.LocalDirAllocator;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.ipc.QueryCoordinatorProtocol;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.querymaster.QueryMaster;
+import org.apache.tajo.querymaster.QueryMasterManagerService;
+import org.apache.tajo.service.ServiceTracker;
+import org.apache.tajo.storage.HashShuffleAppenderManager;
+import org.apache.tajo.util.history.HistoryReader;
+import org.apache.tajo.util.history.HistoryWriter;
+import org.apache.tajo.util.metrics.TajoSystemMetrics;
+
+public abstract class MockWorkerContext implements TajoWorker.WorkerContext {
+  TajoSystemMetrics tajoSystemMetrics;
+
+  @Override
+  public QueryMaster getQueryMaster() {
+    return null;
+  }
+
+  public abstract TajoConf getConf();
+
+  @Override
+  public ServiceTracker getServiceTracker() {
+    return null;
+  }
+
+  @Override
+  public QueryMasterManagerService getQueryMasterManagerService() {
+    return null;
+  }
+
+  @Override
+  public CatalogService getCatalog() {
+    return null;
+  }
+
+  @Override
+  public WorkerConnectionInfo getConnectionInfo() {
+    return null;
+  }
+
+  @Override
+  public String getWorkerName() {
+    return null;
+  }
+
+  @Override
+  public LocalDirAllocator getLocalDirAllocator() {
+    return null;
+  }
+
+  @Override
+  public TajoSystemMetrics getMetrics() {
+
+    if (tajoSystemMetrics == null) {
+      tajoSystemMetrics = new TajoSystemMetrics(getConf(), org.apache.tajo.metrics.Node.class, "localhost");
+      tajoSystemMetrics.start();
+    }
+    return tajoSystemMetrics;
+  }
+
+  @Override
+  public HashShuffleAppenderManager getHashShuffleAppenderManager() {
+    return null;
+  }
+
+  @Override
+  public HistoryWriter getTaskHistoryWriter() {
+    return null;
+  }
+
+  @Override
+  public HistoryReader getHistoryReader() {
+    return null;
+  }
+
+  @Override
+  public void cleanup(String strPath) {
+
+  }
+
+  @Override
+  public void cleanupTemporalDirectories() {
+
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestDeletionService.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestDeletionService.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestDeletionService.java
new file mode 100644
index 0000000..98251c1
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestDeletionService.java
@@ -0,0 +1,61 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestDeletionService {
+  DeletionService deletionService;
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() {
+    if(deletionService != null){
+      deletionService.stop();
+    }
+  }
+
+  @Test
+  public final void testTemporalDirectory() throws IOException, InterruptedException {
+    int delay = 1;
+    deletionService = new DeletionService(1, delay);
+    FileSystem fs = FileSystem.getLocal(new Configuration());
+    Path tempPath = CommonTestingUtil.getTestDir();
+    assertTrue(fs.exists(tempPath));
+    deletionService.delete(tempPath);
+    assertTrue(fs.exists(tempPath));
+
+    Thread.sleep(delay * 2 * 1000);
+    assertFalse(fs.exists(tempPath));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestFetcher.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestFetcher.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestFetcher.java
new file mode 100644
index 0000000..a91fc30
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestFetcher.java
@@ -0,0 +1,236 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.fs.*;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.TajoProtos;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.pullserver.TajoPullServerService;
+import org.apache.tajo.pullserver.retriever.FileChunk;
+import org.apache.tajo.storage.HashShuffleAppenderManager;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Random;
+
+import static org.junit.Assert.*;
+
+public class TestFetcher {
+  private String TEST_DATA = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFetcher";
+  private String INPUT_DIR = TEST_DATA+"/in/";
+  private String OUTPUT_DIR = TEST_DATA+"/out/";
+  private TajoConf conf = new TajoConf();
+  private TajoPullServerService pullServerService;
+
+  @Before
+  public void setUp() throws Exception {
+    CommonTestingUtil.getTestDir(TEST_DATA);
+    CommonTestingUtil.getTestDir(INPUT_DIR);
+    CommonTestingUtil.getTestDir(OUTPUT_DIR);
+    conf.setVar(TajoConf.ConfVars.WORKER_TEMPORAL_DIR, INPUT_DIR);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_READ_TIMEOUT, 1);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_CHUNK_MAX_SIZE, 127);
+
+    pullServerService = new TajoPullServerService();
+    pullServerService.init(conf);
+    pullServerService.start();
+  }
+
+  @After
+  public void tearDown(){
+    pullServerService.stop();
+  }
+
+  @Test
+  public void testGet() throws IOException {
+    Random rnd = new Random();
+    QueryId queryId = QueryIdFactory.NULL_QUERY_ID;
+    String sid = "1";
+    String partId = "1";
+
+    int partParentId = HashShuffleAppenderManager.getPartParentId(Integer.parseInt(partId), conf);
+    String dataPath = conf.getVar(ConfVars.WORKER_TEMPORAL_DIR) +
+       queryId.toString() + "/output/" + sid + "/hash-shuffle/" + partParentId + "/" + partId;
+
+    String params = String.format("qid=%s&sid=%s&p=%s&type=%s", queryId, sid, partId, "h");
+
+    Path inputPath = new Path(dataPath);
+    FSDataOutputStream stream = FileSystem.getLocal(conf).create(inputPath, true);
+    for (int i = 0; i < 100; i++) {
+      String data = ""+rnd.nextInt();
+      stream.write(data.getBytes());
+    }
+    stream.flush();
+    stream.close();
+
+    URI uri = URI.create("http://127.0.0.1:" + pullServerService.getPort() + "/?" + params);
+    FileChunk storeChunk = new FileChunk(new File(OUTPUT_DIR + "data"), 0, 0);
+    storeChunk.setFromRemote(true);
+    final Fetcher fetcher = new Fetcher(conf, uri, storeChunk);
+    FileChunk chunk = fetcher.get();
+    assertNotNull(chunk);
+    assertNotNull(chunk.getFile());
+
+    FileSystem fs = FileSystem.getLocal(new TajoConf());
+    FileStatus inStatus = fs.getFileStatus(inputPath);
+    FileStatus outStatus = fs.getFileStatus(new Path(OUTPUT_DIR, "data"));
+
+    assertEquals(inStatus.getLen(), outStatus.getLen());
+    assertEquals(TajoProtos.FetcherState.FETCH_FINISHED, fetcher.getState());
+  }
+
+  @Test
+  public void testAdjustFetchProcess() {
+    assertEquals(0.0f, TaskImpl.adjustFetchProcess(0, 0), 0);
+    assertEquals(0.0f, TaskImpl.adjustFetchProcess(10, 10), 0);
+    assertEquals(0.05f, TaskImpl.adjustFetchProcess(10, 9), 0);
+    assertEquals(0.1f, TaskImpl.adjustFetchProcess(10, 8), 0);
+    assertEquals(0.25f, TaskImpl.adjustFetchProcess(10, 5), 0);
+    assertEquals(0.45f, TaskImpl.adjustFetchProcess(10, 1), 0);
+    assertEquals(0.5f, TaskImpl.adjustFetchProcess(10, 0), 0);
+  }
+
+  @Test
+  public void testStatus() throws Exception {
+    Random rnd = new Random();
+    QueryId queryId = QueryIdFactory.NULL_QUERY_ID;
+    String sid = "1";
+    String ta = "1_0";
+    String partId = "1";
+
+    String dataPath = INPUT_DIR + queryId.toString() + "/output"+ "/" + sid + "/" +ta + "/output/" + partId;
+    String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, "h", ta);
+
+    FSDataOutputStream stream =  FileSystem.getLocal(conf).create(new Path(dataPath), true);
+    for (int i = 0; i < 100; i++) {
+      String data = ""+rnd.nextInt();
+      stream.write(data.getBytes());
+    }
+    stream.flush();
+    stream.close();
+
+    URI uri = URI.create("http://127.0.0.1:" + pullServerService.getPort() + "/?" + params);
+    FileChunk storeChunk = new FileChunk(new File(OUTPUT_DIR + "data"), 0, 0);
+    storeChunk.setFromRemote(true);
+    final Fetcher fetcher = new Fetcher(conf, uri, storeChunk);
+    assertEquals(TajoProtos.FetcherState.FETCH_INIT, fetcher.getState());
+
+    fetcher.get();
+    assertEquals(TajoProtos.FetcherState.FETCH_FINISHED, fetcher.getState());
+  }
+
+  @Test
+  public void testNoContentFetch() throws Exception {
+
+    QueryId queryId = QueryIdFactory.NULL_QUERY_ID;
+    String sid = "1";
+    String ta = "1_0";
+    String partId = "1";
+
+    String dataPath = INPUT_DIR + queryId.toString() + "/output"+ "/" + sid + "/" +ta + "/output/" + partId;
+    String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, "h", ta);
+
+    Path inputPath = new Path(dataPath);
+    FileSystem fs = FileSystem.getLocal(conf);
+    if(fs.exists(inputPath)){
+      fs.delete(new Path(dataPath), true);
+    }
+
+    FSDataOutputStream stream =  FileSystem.getLocal(conf).create(new Path(dataPath).getParent(), true);
+    stream.close();
+
+    URI uri = URI.create("http://127.0.0.1:" + pullServerService.getPort() + "/?" + params);
+    FileChunk storeChunk = new FileChunk(new File(OUTPUT_DIR + "data"), 0, 0);
+    storeChunk.setFromRemote(true);
+    final Fetcher fetcher = new Fetcher(conf, uri, storeChunk);
+    assertEquals(TajoProtos.FetcherState.FETCH_INIT, fetcher.getState());
+
+    fetcher.get();
+    assertEquals(TajoProtos.FetcherState.FETCH_FINISHED, fetcher.getState());
+  }
+
+  @Test
+  public void testFailureStatus() throws Exception {
+    Random rnd = new Random();
+
+    QueryId queryId = QueryIdFactory.NULL_QUERY_ID;
+    String sid = "1";
+    String ta = "1_0";
+    String partId = "1";
+
+    String dataPath = INPUT_DIR + queryId.toString() + "/output"+ "/" + sid + "/" +ta + "/output/" + partId;
+
+    //TajoPullServerService will be throws BAD_REQUEST by Unknown shuffle type
+    String shuffleType = "x";
+    String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, shuffleType, ta);
+
+    FSDataOutputStream stream =  FileSystem.getLocal(conf).create(new Path(dataPath), true);
+
+    for (int i = 0; i < 100; i++) {
+      String data = params + rnd.nextInt();
+      stream.write(data.getBytes());
+    }
+    stream.flush();
+    stream.close();
+
+    URI uri = URI.create("http://127.0.0.1:" + pullServerService.getPort() + "/?" + params);
+    FileChunk storeChunk = new FileChunk(new File(OUTPUT_DIR + "data"), 0, 0);
+    storeChunk.setFromRemote(true);
+    final Fetcher fetcher = new Fetcher(conf, uri, storeChunk);
+    assertEquals(TajoProtos.FetcherState.FETCH_INIT, fetcher.getState());
+
+    fetcher.get();
+    assertEquals(TajoProtos.FetcherState.FETCH_FAILED, fetcher.getState());
+  }
+
+  @Test
+  public void testServerFailure() throws Exception {
+    QueryId queryId = QueryIdFactory.NULL_QUERY_ID;
+    String sid = "1";
+    String ta = "1_0";
+    String partId = "1";
+
+    String dataPath = INPUT_DIR + queryId.toString() + "/output"+ "/" + sid + "/" +ta + "/output/" + partId;
+    String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, "h", ta);
+
+    URI uri = URI.create("http://127.0.0.1:" + pullServerService.getPort() + "/?" + params);
+    FileChunk storeChunk = new FileChunk(new File(OUTPUT_DIR + "data"), 0, 0);
+    storeChunk.setFromRemote(true);
+    final Fetcher fetcher = new Fetcher(conf, uri, storeChunk);
+    assertEquals(TajoProtos.FetcherState.FETCH_INIT, fetcher.getState());
+
+    pullServerService.stop();
+
+    boolean failure = false;
+    try{
+      fetcher.get();
+    } catch (Throwable e){
+      failure = true;
+    }
+    assertTrue(failure);
+    assertEquals(TajoProtos.FetcherState.FETCH_FAILED, fetcher.getState());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeResourceManager.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeResourceManager.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeResourceManager.java
new file mode 100644
index 0000000..1193478
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeResourceManager.java
@@ -0,0 +1,281 @@
+/**
+ * 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.worker;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.rpc.CallFuture;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.event.NodeResourceAllocateEvent;
+import org.apache.tajo.worker.event.NodeResourceDeallocateEvent;
+import org.apache.tajo.worker.event.NodeResourceEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.apache.tajo.ResourceProtos.*;
+import static org.junit.Assert.*;
+public class TestNodeResourceManager {
+
+  private MockNodeResourceManager resourceManager;
+  private NodeStatusUpdater statusUpdater;
+  private TaskManager taskManager;
+  private TaskExecutor taskExecutor;
+  private AsyncDispatcher dispatcher;
+  private AsyncDispatcher taskDispatcher;
+  private TajoWorker.WorkerContext workerContext;
+
+  private CompositeService service;
+  private int taskMemory;
+  private TajoConf conf;
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+
+    taskMemory = 512;
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES, 4);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_MEMORY_MB,
+        taskMemory * conf.getIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES));
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_DISKS, 4);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_DISK_PARALLEL_NUM, 1);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM, 2);
+
+    dispatcher = new AsyncDispatcher();
+    taskDispatcher = new AsyncDispatcher();
+
+    workerContext = new MockWorkerContext() {
+      WorkerConnectionInfo workerConnectionInfo;
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return taskManager;
+      }
+
+      @Override
+      public TaskExecutor getTaskExecuor() {
+        return taskExecutor;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return resourceManager;
+      }
+
+      @Override
+      public WorkerConnectionInfo getConnectionInfo() {
+        if (workerConnectionInfo == null) {
+          workerConnectionInfo = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+        }
+        return workerConnectionInfo;
+      }
+    };
+
+    taskManager = new MockTaskManager(new Semaphore(0), taskDispatcher, workerContext);
+    taskExecutor = new MockTaskExecutor(new Semaphore(0), workerContext);
+    resourceManager = new MockNodeResourceManager(new Semaphore(0), dispatcher, workerContext);
+    statusUpdater = new MockNodeStatusUpdater(new CountDownLatch(0), workerContext);
+
+    service = new CompositeService("MockService") {
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        addIfService(dispatcher);
+        addIfService(taskDispatcher);
+        addIfService(taskManager);
+        addIfService(taskExecutor);
+        addIfService(resourceManager);
+        addIfService(statusUpdater);
+        super.serviceInit(conf);
+      }
+
+      @Override
+      protected void serviceStop() throws Exception {
+        workerContext.getMetrics().stop();
+        super.serviceStop();
+      }
+    };
+
+    service.init(conf);
+    service.start();
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test
+  public void testNodeResourceAllocateEvent() throws Exception {
+    int requestSize = 4;
+    resourceManager.setTaskHandlerEvent(false); //skip task execution
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    ExecutionBlockId ebId = new ExecutionBlockId(LocalTajoTestingUtility.newQueryId(), 0);
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, taskMemory, requestSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    BatchAllocationResponse responseProto = callFuture.get();
+    assertNotEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    // allocated all
+    assertEquals(0, responseProto.getCancellationTaskCount());
+  }
+
+
+  @Test
+  public void testNodeResourceCancellation() throws Exception {
+    int requestSize = conf.getIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES);
+    int overSize = 10;
+    resourceManager.setTaskHandlerEvent(false); //skip task execution
+
+    CallFuture<BatchAllocationResponse> callFuture = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    ExecutionBlockId ebId = new ExecutionBlockId(LocalTajoTestingUtility.newQueryId(), 0);
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(
+        MockNodeResourceManager.createTaskRequests(ebId, taskMemory, requestSize + overSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+    BatchAllocationResponse responseProto = callFuture.get();
+
+    assertEquals(overSize, responseProto.getCancellationTaskCount());
+  }
+
+  @Test
+  public void testNodeResourceDeallocateEvent() throws Exception {
+    int requestSize = 4;
+    resourceManager.setTaskHandlerEvent(false); //skip task execution
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    ExecutionBlockId ebId = new ExecutionBlockId(LocalTajoTestingUtility.newQueryId(), 0);
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, taskMemory, requestSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    BatchAllocationResponse responseProto = callFuture.get();
+    assertNotEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    assertEquals(0, responseProto.getCancellationTaskCount());
+
+    //deallocate
+    for(TaskAllocationProto allocationRequestProto : requestProto.getTaskRequestList()) {
+      // direct invoke handler for testing
+      resourceManager.handle(new NodeResourceDeallocateEvent(
+          allocationRequestProto.getResource(), NodeResourceEvent.ResourceType.TASK));
+    }
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+  }
+
+  @Test(timeout = 30000)
+  public void testParallelRequest() throws Exception {
+    final int parallelCount = conf.getIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES) * 2;
+    final int taskSize = 100000;
+    resourceManager.setTaskHandlerEvent(true);
+
+    final AtomicInteger totalComplete = new AtomicInteger();
+    final AtomicInteger totalCanceled = new AtomicInteger();
+
+    final ExecutionBlockId ebId = new ExecutionBlockId(LocalTajoTestingUtility.newQueryId(), 0);
+    final Queue<TaskAllocationProto>
+        totalTasks = MockNodeResourceManager.createTaskRequests(ebId, taskMemory, taskSize);
+
+
+    TaskAllocationProto task = totalTasks.poll();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.addTaskRequest(task);
+    requestProto.setExecutionBlockId(ebId.getProto());
+    CallFuture<BatchAllocationResponse> callFuture = new CallFuture<BatchAllocationResponse>();
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+    assertTrue(callFuture.get().getCancellationTaskCount() == 0);
+    totalComplete.incrementAndGet();
+
+    // start parallel request
+    ExecutorService executor = Executors.newFixedThreadPool(parallelCount);
+
+    List<Future> futureList = Lists.newArrayList();
+
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < parallelCount; i++) {
+      futureList.add(executor.submit(new Runnable() {
+            @Override
+            public void run() {
+              int complete = 0;
+              while (true) {
+                TaskAllocationProto task = totalTasks.poll();
+                if (task == null) break;
+
+
+                BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+                requestProto.addTaskRequest(task);
+                requestProto.setExecutionBlockId(ebId.getProto());
+
+                CallFuture<BatchAllocationResponse> callFuture = new CallFuture<BatchAllocationResponse>();
+                dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+                try {
+                  BatchAllocationResponse proto = callFuture.get();
+                  if (proto.getCancellationTaskCount() > 0) {
+                    totalTasks.addAll(proto.getCancellationTaskList());
+                    totalCanceled.addAndGet(proto.getCancellationTaskCount());
+                  } else {
+                    complete++;
+                  }
+                } catch (Exception e) {
+                  fail(e.getMessage());
+                }
+              }
+              totalComplete.addAndGet(complete);
+            }
+          })
+      );
+    }
+
+    for (Future future : futureList) {
+      future.get();
+    }
+
+    executor.shutdown();
+    assertEquals(taskSize, totalComplete.get());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeStatusUpdater.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeStatusUpdater.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeStatusUpdater.java
new file mode 100644
index 0000000..ac4b7dd
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestNodeStatusUpdater.java
@@ -0,0 +1,192 @@
+/**
+ * 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.worker;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.event.NodeStatusEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+
+import static org.apache.tajo.ResourceProtos.NodeHeartbeatRequest;
+import static org.junit.Assert.*;
+
+public class TestNodeStatusUpdater {
+
+  private NodeResourceManager resourceManager;
+  private MockNodeStatusUpdater statusUpdater;
+  private MockTaskManager taskManager;
+  private AsyncDispatcher dispatcher;
+  private AsyncDispatcher taskDispatcher;
+  private CompositeService service;
+  private TajoConf conf;
+  private TajoWorker.WorkerContext workerContext;
+
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES, 2);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM, 2);
+
+    workerContext = new MockWorkerContext() {
+      WorkerConnectionInfo workerConnectionInfo;
+
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return taskManager;
+      }
+
+      @Override
+      public TaskExecutor getTaskExecuor() {
+        return null;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return resourceManager;
+      }
+
+      @Override
+      public WorkerConnectionInfo getConnectionInfo() {
+        if (workerConnectionInfo == null) {
+          workerConnectionInfo = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+        }
+        return workerConnectionInfo;
+      }
+    };
+
+    conf.setIntVar(TajoConf.ConfVars.WORKER_HEARTBEAT_IDLE_INTERVAL, 1000);
+    dispatcher = new AsyncDispatcher();
+    resourceManager = new NodeResourceManager(dispatcher, workerContext);
+    taskDispatcher = new AsyncDispatcher();
+    taskManager = new MockTaskManager(new Semaphore(0), taskDispatcher, workerContext) {
+      @Override
+      public int getRunningTasks() {
+        return 0;
+      }
+    };
+
+    service = new CompositeService("MockService") {
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        addIfService(dispatcher);
+        addIfService(taskDispatcher);
+        addIfService(taskManager);
+        addIfService(resourceManager);
+        addIfService(statusUpdater);
+        super.serviceInit(conf);
+      }
+
+      @Override
+      protected void serviceStop() throws Exception {
+        workerContext.getMetrics().stop();
+        super.serviceStop();
+      }
+    };
+
+    service.init(conf);
+    service.start();
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test(timeout = 20000)
+  public void testNodeMembership() throws Exception {
+    CountDownLatch barrier = new CountDownLatch(1);
+    statusUpdater = new MockNodeStatusUpdater(barrier, workerContext);
+    statusUpdater.init(conf);
+    statusUpdater.start();
+
+    MockNodeStatusUpdater.MockResourceTracker resourceTracker = statusUpdater.getResourceTracker();
+    barrier.await();
+
+    assertTrue(resourceTracker.getTotalResource().containsKey(workerContext.getConnectionInfo().getId()));
+    assertEquals(resourceManager.getTotalResource(),
+        resourceTracker.getTotalResource().get(workerContext.getConnectionInfo().getId()));
+
+    assertEquals(resourceManager.getAvailableResource(),
+        resourceTracker.getAvailableResource().get(workerContext.getConnectionInfo().getId()));
+  }
+
+  @Test(timeout = 20000)
+  public void testPing() throws Exception {
+    CountDownLatch barrier = new CountDownLatch(2);
+    statusUpdater = new MockNodeStatusUpdater(barrier, workerContext);
+    statusUpdater.init(conf);
+    statusUpdater.start();
+
+    MockNodeStatusUpdater.MockResourceTracker resourceTracker = statusUpdater.getResourceTracker();
+    barrier.await();
+
+    NodeHeartbeatRequest lastRequest = resourceTracker.getLastRequest();
+    assertTrue(lastRequest.hasWorkerId());
+    assertTrue(lastRequest.hasAvailableResource());
+    assertTrue(lastRequest.hasRunningTasks());
+    assertTrue(lastRequest.hasRunningQueryMasters());
+    assertFalse(lastRequest.hasTotalResource());
+    assertFalse(lastRequest.hasConnectionInfo());
+  }
+
+  @Test(timeout = 20000)
+  public void testResourceReport() throws Exception {
+    CountDownLatch barrier = new CountDownLatch(2);
+    statusUpdater = new MockNodeStatusUpdater(barrier, workerContext);
+    statusUpdater.init(conf);
+    statusUpdater.start();
+
+    assertEquals(0, statusUpdater.getQueueSize());
+    for (int i = 0; i < statusUpdater.getQueueingThreshold(); i++) {
+      dispatcher.getEventHandler().handle(new NodeStatusEvent(NodeStatusEvent.EventType.REPORT_RESOURCE));
+    }
+    barrier.await();
+    assertEquals(0, statusUpdater.getQueueSize());
+  }
+
+  @Test(timeout = 20000)
+  public void testFlushResourceReport() throws Exception {
+    CountDownLatch barrier = new CountDownLatch(2);
+    statusUpdater = new MockNodeStatusUpdater(barrier, workerContext);
+    statusUpdater.init(conf);
+    statusUpdater.start();
+
+    assertEquals(0, statusUpdater.getQueueSize());
+    dispatcher.getEventHandler().handle(new NodeStatusEvent(NodeStatusEvent.EventType.FLUSH_REPORTS));
+
+    barrier.await();
+    assertEquals(0, statusUpdater.getQueueSize());
+  }
+}


[34/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInsertQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInsertQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInsertQuery.java
new file mode 100644
index 0000000..d0088a5
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInsertQuery.java
@@ -0,0 +1,882 @@
+/**
+ * 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.query;
+
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.compress.CompressionCodec;
+import org.apache.hadoop.io.compress.CompressionCodecFactory;
+import org.apache.hadoop.io.compress.DeflateCodec;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.sql.ResultSet;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestInsertQuery extends QueryTestCaseBase {
+
+  @Test
+  public final void testInsertOverwrite() throws Exception {
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+
+    res = executeFile("testInsertOverwrite.sql");
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertInto() throws Exception {
+    // create table and upload test data
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+
+    res = executeFile("testInsertOverwrite.sql");
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeFile("testInsertInto.sql");
+    res.close();
+
+    List<Path> dataFiles = listTableFiles("table1");
+    assertEquals(2, dataFiles.size());
+
+    for (int i = 0; i < dataFiles.size(); i++) {
+      String name = dataFiles.get(i).getName();
+      assertTrue(name.matches("part-[0-9]*-[0-9]*-[0-9]*"));
+      String[] tokens = name.split("-");
+      assertEquals(4, tokens.length);
+      assertEquals(i, Integer.parseInt(tokens[3]));
+    }
+
+    String tableDatas = getTableFileContents("table1");
+
+    String expected = "1|1|17.0\n" +
+        "1|1|36.0\n" +
+        "2|2|38.0\n" +
+        "3|2|45.0\n" +
+        "3|3|49.0\n" +
+        "1|1|17.0\n" +
+        "1|1|36.0\n" +
+        "2|2|38.0\n" +
+        "3|2|45.0\n" +
+        "3|3|49.0\n";
+
+    assertNotNull(tableDatas);
+    assertEquals(expected, tableDatas);
+
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertIntoLocation() throws Exception {
+    Path dfsPath = new Path("/tajo-data/testInsertIntoLocation");
+    assertTestInsertIntoLocation(dfsPath);
+  }
+
+  @Test
+  public final void testInsertIntoLocationDifferentFSs() throws Exception {
+    Path localPath = CommonTestingUtil.getTestDir();
+    assertTestInsertIntoLocation(localPath);
+  }
+
+  public final void assertTestInsertIntoLocation(Path path) throws Exception {
+    FileSystem fs = null;
+
+    try {
+      executeString("insert into location '" + path + "' select l_orderkey, l_partkey, l_linenumber from default.lineitem").close();
+
+      String resultFileData = getTableFileContents(path);
+      String expected = "1|1|1\n" +
+          "1|1|2\n" +
+          "2|2|1\n" +
+          "3|2|1\n" +
+          "3|3|2\n";
+
+      assertEquals(expected, resultFileData);
+
+      fs = path.getFileSystem(testingCluster.getConfiguration());
+
+      FileStatus[] files = fs.listStatus(path);
+      assertNotNull(files);
+      assertEquals(1, files.length);
+
+      for (FileStatus eachFileStatus : files) {
+        String name = eachFileStatus.getPath().getName();
+        assertTrue(name.matches("part-[0-9]*-[0-9]*-[0-9]*"));
+      }
+
+      executeString("insert into location '" + path + "' select l_orderkey, l_partkey, l_linenumber from default.lineitem").close();
+      resultFileData = getTableFileContents(path);
+      expected = "1|1|1\n" +
+          "1|1|2\n" +
+          "2|2|1\n" +
+          "3|2|1\n" +
+          "3|3|2\n";
+
+      assertEquals(expected + expected, resultFileData);
+
+      files = fs.listStatus(path);
+      assertNotNull(files);
+      assertEquals(2, files.length);
+
+      for (FileStatus eachFileStatus : files) {
+        String name = eachFileStatus.getPath().getName();
+        assertTrue(name.matches("part-[0-9]*-[0-9]*-[0-9]*"));
+      }
+    } finally {
+      if (fs != null) {
+        fs.delete(path, true);
+      }
+    }
+  }
+
+  @Test
+  public final void testInsertIntoPartitionedTable() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("testInsertIntoPartitionedTable");
+    executeString("create table " + tableName + " (n_name TEXT, n_regionkey INT4)" +
+        "USING csv PARTITION by column(n_nationkey INT4)" ).close();
+
+    try {
+      executeString("insert into " + tableName + " select n_name, n_regionkey, n_nationkey from default.nation").close();
+
+      ResultSet res = executeString("select * from " + tableName);
+
+      String expected = "n_name,n_regionkey,n_nationkey\n" +
+          "-------------------------------\n" +
+          "ALGERIA,0,0\n" +
+          "ARGENTINA,1,1\n" +
+          "IRAN,4,10\n" +
+          "IRAQ,4,11\n" +
+          "JAPAN,2,12\n" +
+          "JORDAN,4,13\n" +
+          "KENYA,0,14\n" +
+          "MOROCCO,0,15\n" +
+          "MOZAMBIQUE,0,16\n" +
+          "PERU,1,17\n" +
+          "CHINA,2,18\n" +
+          "ROMANIA,3,19\n" +
+          "BRAZIL,1,2\n" +
+          "SAUDI ARABIA,4,20\n" +
+          "VIETNAM,2,21\n" +
+          "RUSSIA,3,22\n" +
+          "UNITED KINGDOM,3,23\n" +
+          "UNITED STATES,1,24\n" +
+          "CANADA,1,3\n" +
+          "EGYPT,4,4\n" +
+          "ETHIOPIA,0,5\n" +
+          "FRANCE,3,6\n" +
+          "GERMANY,3,7\n" +
+          "INDIA,2,8\n" +
+          "INDONESIA,2,9\n";
+
+      assertEquals(expected, resultSetToString(res));
+      res.close();
+
+      executeString("insert into " + tableName + " select n_name, n_regionkey, n_nationkey from default.nation").close();
+      res = executeString("select * from " + tableName);
+      expected = "n_name,n_regionkey,n_nationkey\n" +
+          "-------------------------------\n" +
+          "ALGERIA,0,0\n" +
+          "ALGERIA,0,0\n" +
+          "ARGENTINA,1,1\n" +
+          "ARGENTINA,1,1\n" +
+          "IRAN,4,10\n" +
+          "IRAN,4,10\n" +
+          "IRAQ,4,11\n" +
+          "IRAQ,4,11\n" +
+          "JAPAN,2,12\n" +
+          "JAPAN,2,12\n" +
+          "JORDAN,4,13\n" +
+          "JORDAN,4,13\n" +
+          "KENYA,0,14\n" +
+          "KENYA,0,14\n" +
+          "MOROCCO,0,15\n" +
+          "MOROCCO,0,15\n" +
+          "MOZAMBIQUE,0,16\n" +
+          "MOZAMBIQUE,0,16\n" +
+          "PERU,1,17\n" +
+          "PERU,1,17\n" +
+          "CHINA,2,18\n" +
+          "CHINA,2,18\n" +
+          "ROMANIA,3,19\n" +
+          "ROMANIA,3,19\n" +
+          "BRAZIL,1,2\n" +
+          "BRAZIL,1,2\n" +
+          "SAUDI ARABIA,4,20\n" +
+          "SAUDI ARABIA,4,20\n" +
+          "VIETNAM,2,21\n" +
+          "VIETNAM,2,21\n" +
+          "RUSSIA,3,22\n" +
+          "RUSSIA,3,22\n" +
+          "UNITED KINGDOM,3,23\n" +
+          "UNITED KINGDOM,3,23\n" +
+          "UNITED STATES,1,24\n" +
+          "UNITED STATES,1,24\n" +
+          "CANADA,1,3\n" +
+          "CANADA,1,3\n" +
+          "EGYPT,4,4\n" +
+          "EGYPT,4,4\n" +
+          "ETHIOPIA,0,5\n" +
+          "ETHIOPIA,0,5\n" +
+          "FRANCE,3,6\n" +
+          "FRANCE,3,6\n" +
+          "GERMANY,3,7\n" +
+          "GERMANY,3,7\n" +
+          "INDIA,2,8\n" +
+          "INDIA,2,8\n" +
+          "INDONESIA,2,9\n" +
+          "INDONESIA,2,9\n";
+
+      assertEquals(expected, resultSetToString(res));
+
+      TableDesc tableDesc = testingCluster.getMaster().getCatalog().getTableDesc(getCurrentDatabase(), tableName);
+      assertNotNull(tableDesc);
+
+      Path path = new Path(tableDesc.getUri());
+      FileSystem fs = path.getFileSystem(testingCluster.getConfiguration());
+
+      FileStatus[] files = fs.listStatus(path);
+      assertNotNull(files);
+      assertEquals(25, files.length);
+
+      for (FileStatus eachFileStatus: files) {
+        assertTrue(eachFileStatus.getPath().getName().indexOf("n_nationkey=") == 0);
+        FileStatus[] dataFiles = fs.listStatus(eachFileStatus.getPath());
+        assertEquals(2, dataFiles.length);
+        for (FileStatus eachDataFileStatus: dataFiles) {
+          String name = eachDataFileStatus.getPath().getName();
+          assertTrue(name.matches("part-[0-9]*-[0-9]*-[0-9]*"));
+        }
+      }
+    } finally {
+      executeString("DROP TABLE " + tableName + " PURGE");
+    }
+  }
+
+  @Test
+  public final void testInsertOverwriteSmallerColumns() throws Exception {
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+    TableDesc originalDesc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+
+    res = executeFile("testInsertOverwriteSmallerColumns.sql");
+    res.close();
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+    assertEquals(originalDesc.getSchema(), desc.getSchema());
+
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteWithTargetColumns() throws Exception {
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+    TableDesc originalDesc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+
+    res = executeFile("testInsertOverwriteWithTargetColumns.sql");
+    res.close();
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeString("select * from " + CatalogUtil.denormalizeIdentifier(getCurrentDatabase()) + ".table1");
+
+    assertTrue(res.next());
+    assertEquals(1, res.getLong(1));
+    assertTrue(0f == res.getFloat(2));
+    assertTrue(res.wasNull());
+    assertTrue(17.0 == res.getFloat(3));
+
+    assertTrue(res.next());
+    assertEquals(1, res.getLong(1));
+    assertTrue(0f == res.getFloat(2));
+    assertTrue(res.wasNull());
+    assertTrue(36.0 == res.getFloat(3));
+
+    assertTrue(res.next());
+    assertEquals(2, res.getLong(1));
+    assertTrue(0f == res.getFloat(2));
+    assertTrue(res.wasNull());
+    assertTrue(38.0 == res.getFloat(3));
+
+    assertTrue(res.next());
+    assertTrue(0f == res.getFloat(2));
+    assertTrue(res.wasNull());
+    assertTrue(45.0 == res.getFloat(3));
+
+    assertTrue(res.next());
+    assertEquals(3, res.getLong(1));
+    assertTrue(0f == res.getFloat(2));
+    assertTrue(res.wasNull());
+    assertTrue(49.0 == res.getFloat(3));
+
+    assertFalse(res.next());
+    res.close();
+
+    assertEquals(originalDesc.getSchema(), desc.getSchema());
+
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteWithAsterisk() throws Exception {
+    ResultSet res = executeFile("full_table_csv_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "full_table_csv"));
+
+    res = executeString("insert overwrite into full_table_csv select * from default.lineitem where l_orderkey = 3");
+    res.close();
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "full_table_csv");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(2, desc.getStats().getNumRows().intValue());
+    }
+    executeString("DROP TABLE full_table_csv PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteWithAsteriskAndMore() throws Exception {
+    ResultSet res = executeFile("lineitem_year_month_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "lineitem_year_month"));
+
+    res = executeFile("load_to_lineitem_year_month.sql");
+    res.close();
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "lineitem_year_month");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeQuery();
+    assertResultSet(res);
+    res.close();
+
+    executeString("DROP TABLE lineitem_year_month PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteIntoSelect() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("insertoverwriteintoselect");
+    ResultSet res = executeString("create table " + tableName + " as select l_orderkey from default.lineitem");
+    assertFalse(res.next());
+    res.close();
+
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), tableName));
+    TableDesc orderKeys = catalog.getTableDesc(getCurrentDatabase(), tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, orderKeys.getStats().getNumRows().intValue());
+    }
+
+    // this query will result in the two rows.
+    res = executeString("insert overwrite into " + tableName + " select l_orderkey from default.lineitem where l_orderkey = 3");
+    assertFalse(res.next());
+    res.close();
+
+    assertTrue(catalog.existsTable(getCurrentDatabase(), tableName));
+    orderKeys = catalog.getTableDesc(getCurrentDatabase(), tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(2, orderKeys.getStats().getNumRows().intValue());
+    }
+    executeString("DROP TABLE " + tableName + " PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteCapitalTableName() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("testInsertOverwriteCapitalTableName");
+    ResultSet res = executeString("create table " + tableName + " as select * from default.lineitem");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), tableName));
+
+    res = executeString("insert overwrite into " + tableName + " select * from default.lineitem where l_orderkey = 3");
+    res.close();
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(2, desc.getStats().getNumRows().intValue());
+    }
+    executeString("DROP TABLE " + tableName + " PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteLocation() throws Exception {
+    ResultSet res = executeQuery();
+    res.close();
+    FileSystem fs = FileSystem.get(testingCluster.getConfiguration());
+    assertTrue(fs.exists(new Path("/tajo-data/testInsertOverwriteCapitalTableName")));
+    assertEquals(1, fs.listStatus(new Path("/tajo-data/testInsertOverwriteCapitalTableName")).length);
+  }
+
+  @Test
+  public final void testInsertOverwriteWithCompression() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("testInsertOverwriteWithCompression");
+    ResultSet res = executeFile("testInsertOverwriteWithCompression_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), tableName));
+
+    res = executeQuery();
+    res.close();
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(2, desc.getStats().getNumRows().intValue());
+    }
+
+    FileSystem fs = FileSystem.get(testingCluster.getConfiguration());
+    assertTrue(fs.exists(new Path(desc.getUri())));
+    CompressionCodecFactory factory = new CompressionCodecFactory(testingCluster.getConfiguration());
+
+    for (FileStatus file : fs.listStatus(new Path(desc.getUri()))) {
+      CompressionCodec codec = factory.getCodec(file.getPath());
+      assertTrue(codec instanceof DeflateCodec);
+    }
+    executeString("DROP TABLE " + tableName + " PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteLocationWithCompression() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      ResultSet res = executeQuery();
+      res.close();
+      FileSystem fs = FileSystem.get(testingCluster.getConfiguration());
+      Path path = new Path("/tajo-data/testInsertOverwriteLocationWithCompression");
+      assertTrue(fs.exists(path));
+      assertEquals(1, fs.listStatus(path).length);
+
+      CompressionCodecFactory factory = new CompressionCodecFactory(testingCluster.getConfiguration());
+      for (FileStatus file : fs.listStatus(path)){
+        CompressionCodec codec = factory.getCodec(file.getPath());
+        assertTrue(codec instanceof DeflateCodec);
+      }
+    }
+  }
+
+  @Test
+  public final void testInsertOverwriteWithAsteriskUsingParquet() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      ResultSet res = executeFile("full_table_parquet_ddl.sql");
+      res.close();
+
+      CatalogService catalog = testingCluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable(getCurrentDatabase(), "full_table_parquet"));
+
+      res = executeString(
+          "insert overwrite into full_table_parquet select * from default.lineitem where l_orderkey = 3");
+      res.close();
+      TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "full_table_parquet");
+      if (!testingCluster.isHiveCatalogStoreRunning()) {
+        assertEquals(2, desc.getStats().getNumRows().intValue());
+      }
+
+      res = executeString("select * from full_table_parquet;");
+      assertResultSet(res);
+
+      res = executeString("select l_orderkey, l_partkey from full_table_parquet;");
+      assertResultSet(res, "testInsertOverwriteWithAsteriskUsingParquet2.result");
+
+      executeString("DROP TABLE full_table_parquet PURGE");
+    }
+  }
+
+  @Test
+  public final void testInsertOverwriteIntoParquet() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeString("create table parquet_table " +
+          "(l_orderkey int4, l_shipdate text, l_shipdate_function text) using parquet").close();
+
+      CatalogService catalog = testingCluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable(getCurrentDatabase(), "parquet_table"));
+
+      executeString(
+          "insert overwrite into parquet_table  " +
+              "select l_orderkey, l_shipdate, substr(l_shipdate, 1, 10) from default.lineitem").close();
+
+      TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "parquet_table");
+      if (!testingCluster.isHiveCatalogStoreRunning()) {
+        assertEquals(5, desc.getStats().getNumRows().intValue());
+      }
+
+      ResultSet res = executeString("select l_orderkey, l_shipdate, l_shipdate_function " +
+          "from parquet_table ");
+
+      String expected = "l_orderkey,l_shipdate,l_shipdate_function\n" +
+          "-------------------------------\n" +
+          "1,1996-03-13,1996-03-13\n" +
+          "1,1996-04-12,1996-04-12\n" +
+          "2,1997-01-28,1997-01-28\n" +
+          "3,1994-02-02,1994-02-02\n" +
+          "3,1993-11-09,1993-11-09\n";
+
+      assertEquals(expected, resultSetToString(res));
+
+      executeString("DROP TABLE parquet_table PURGE");
+    }
+  }
+
+  @Test
+  public final void testInsertOverwriteIntoPartitionedParquet() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeString("create table parquet_table " +
+          "(l_orderkey int4, l_shipdate_function text) using parquet partition by column (l_shipdate text)").close();
+
+      CatalogService catalog = testingCluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable(getCurrentDatabase(), "parquet_table"));
+
+      executeString(
+          "insert overwrite into parquet_table  " +
+              "select l_orderkey, substr(l_shipdate, 1, 10), l_shipdate from default.lineitem").close();
+
+      TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "parquet_table");
+      if (!testingCluster.isHiveCatalogStoreRunning()) {
+        assertEquals(5, desc.getStats().getNumRows().intValue());
+      }
+
+      ResultSet res = executeString("select l_orderkey, l_shipdate, l_shipdate_function " +
+          "from parquet_table ");
+
+      String expected = "l_orderkey,l_shipdate,l_shipdate_function\n" +
+          "-------------------------------\n" +
+          "3,1993-11-09,1993-11-09\n" +
+          "3,1994-02-02,1994-02-02\n" +
+          "1,1996-03-13,1996-03-13\n" +
+          "1,1996-04-12,1996-04-12\n" +
+          "2,1997-01-28,1997-01-28\n";
+
+      assertEquals(expected, resultSetToString(res));
+
+      executeString("DROP TABLE parquet_table PURGE");
+    }
+  }
+
+  @Test
+  public final void testInsertOverwriteWithDatabase() throws Exception {
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+
+    res = executeQuery();
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteTableWithNonFromQuery() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("InsertOverwriteWithEvalQuery");
+    ResultSet res = executeString("create table " + tableName +" (col1 int4, col2 float4, col3 text)");
+    res.close();
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), tableName));
+
+    res = executeString("insert overwrite into " + tableName
+        + " select 1::INT4, 2.1::FLOAT4, 'test'; ");
+
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(1, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeString("select * from " + tableName + ";");
+    assertTrue(res.next());
+
+    assertEquals(3, res.getMetaData().getColumnCount());
+    assertEquals(1, res.getInt(1));
+    assertEquals(2.1f, res.getFloat(2), 10);
+    assertEquals("test", res.getString(3));
+
+    res.close();
+    executeString("DROP TABLE " + tableName + " PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteTableWithNonFromQuery2() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("InsertOverwriteWithEvalQuery2");
+    ResultSet res = executeString("create table " + tableName +" (col1 int4, col2 float4, col3 text)");
+    res.close();
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), tableName));
+    res = executeString("insert overwrite into " + tableName + " (col1, col3) select 1::INT4, 'test';");
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(getCurrentDatabase(), tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(1, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeString("select * from " + tableName + ";");
+    assertTrue(res.next());
+
+    assertEquals(3, res.getMetaData().getColumnCount());
+    assertEquals(1, res.getInt(1));
+    assertNull(res.getString(2));
+    assertEquals(0.0, res.getDouble(2), 10);
+    assertEquals("test", res.getString(3));
+
+    res.close();
+    executeString("DROP TABLE " + tableName + " PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwritePathWithNonFromQuery() throws Exception {
+    ResultSet res = executeString("insert overwrite into location " +
+        "'/tajo-data/testInsertOverwritePathWithNonFromQuery' " +
+        "USING csv WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+        "select 1::INT4, 2.1::FLOAT4, 'test'");
+
+    res.close();
+    FileSystem fs = FileSystem.get(testingCluster.getConfiguration());
+    Path path = new Path("/tajo-data/testInsertOverwritePathWithNonFromQuery");
+    assertTrue(fs.exists(path));
+    assertEquals(1, fs.listStatus(path).length);
+
+    CompressionCodecFactory factory = new CompressionCodecFactory(testingCluster.getConfiguration());
+    FileStatus file = fs.listStatus(path)[0];
+    CompressionCodec codec = factory.getCodec(file.getPath());
+    assertTrue(codec instanceof DeflateCodec);
+
+    BufferedReader reader = new BufferedReader(
+        new InputStreamReader(codec.createInputStream(fs.open(file.getPath()))));
+
+    try {
+      String line = reader.readLine();
+      assertNotNull(line);
+
+      String[] tokens = line.split("\\|");
+
+      assertEquals(3, tokens.length);
+      assertEquals("1", tokens[0]);
+      assertEquals("2.1", tokens[1]);
+      assertEquals("test", tokens[2]);
+    } finally {
+      reader.close();
+    }
+  }
+
+  @Test
+  public final void testInsertOverwriteWithUnion() throws Exception {
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+
+    res = executeFile("testInsertOverwriteWithUnion.sql");
+    res.close();
+
+    String tableDatas = getTableFileContents("table1");
+
+    String expected = "1|1|17.0\n" +
+        "1|1|36.0\n" +
+        "2|2|38.0\n" +
+        "3|2|45.0\n" +
+        "3|3|49.0\n" +
+        "1|3|173665.47\n" +
+        "2|4|46929.18\n" +
+        "3|2|193846.25\n";
+
+    assertNotNull(tableDatas);
+    assertEquals(expected, tableDatas);
+
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteWithUnionDifferentAlias() throws Exception {
+    ResultSet res = executeFile("table1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "table1"));
+
+    res = executeFile("testInsertOverwriteWithUnionDifferentAlias.sql");
+    res.close();
+
+    String tableDatas = getTableFileContents("table1");
+
+    String expected = "1|1|17.0\n" +
+        "1|1|36.0\n" +
+        "2|2|38.0\n" +
+        "3|2|45.0\n" +
+        "3|3|49.0\n" +
+        "1|3|173665.47\n" +
+        "2|4|46929.18\n" +
+        "3|2|193846.25\n";
+
+    assertNotNull(tableDatas);
+    assertEquals(expected, tableDatas);
+
+    executeString("DROP TABLE table1 PURGE");
+  }
+
+  @Test
+  public final void testInsertOverwriteLocationWithUnion() throws Exception {
+    ResultSet res = executeFile("testInsertOverwriteLocationWithUnion.sql");
+    res.close();
+
+    String resultDatas= getTableFileContents(new Path("/tajo-data/testInsertOverwriteLocationWithUnion"));
+
+    String expected = "1|1|17.0\n" +
+        "1|1|36.0\n" +
+        "2|2|38.0\n" +
+        "3|2|45.0\n" +
+        "3|3|49.0\n" +
+        "1|3|173665.47\n" +
+        "2|4|46929.18\n" +
+        "3|2|193846.25\n";
+
+    assertNotNull(resultDatas);
+    assertEquals(expected, resultDatas);
+  }
+
+  @Test
+  public final void testInsertOverwriteLocationWithUnionDifferenceAlias() throws Exception {
+    ResultSet res = executeFile("testInsertOverwriteLocationWithUnionDifferenceAlias.sql");
+    res.close();
+
+    String resultDatas= getTableFileContents(new Path("/tajo-data/testInsertOverwriteLocationWithUnionDifferenceAlias"));
+
+    String expected = "1|1|17.0\n" +
+        "1|1|36.0\n" +
+        "2|2|38.0\n" +
+        "3|2|45.0\n" +
+        "3|3|49.0\n" +
+        "1|3|173665.47\n" +
+        "2|4|46929.18\n" +
+        "3|2|193846.25\n";
+
+    assertNotNull(resultDatas);
+    assertEquals(expected, resultDatas);
+  }
+
+  @Test
+  public final void testInsertWithDifferentColumnOrder() throws Exception {
+    ResultSet res = executeFile("nation_diff_col_order.ddl");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "nation_diff"));
+
+    try {
+      res = executeFile("testInsertWithDifferentColumnOrder.sql");
+      res.close();
+
+      res = executeString("select * from nation_diff");
+      assertResultSet(res);
+    } finally {
+      executeString("drop table nation_diff purge;");
+    }
+  }
+
+  @Test
+  public final void testFixedCharSelectWithNoLength() throws Exception {
+    ResultSet res = executeFile("test1_nolength_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "test1"));
+
+    res = executeFile("testInsertIntoSelectWithFixedSizeCharWithNoLength.sql");
+    res.close();
+
+    //remove \0
+    String resultDatas = getTableFileContents("test1").replaceAll("\0","");
+    String expected = "a\n";
+
+    assertNotNull(resultDatas);
+    assertEquals(expected.length(), resultDatas.length());
+    assertEquals(expected, resultDatas);
+    executeString("DROP TABLE test1 PURGE");
+  }
+
+  @Test
+  public final void testFixedCharSelect() throws Exception {
+    ResultSet res = executeFile("test1_ddl.sql");
+    res.close();
+
+    CatalogService catalog = testingCluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(getCurrentDatabase(), "test1"));
+
+    res = executeFile("testInsertIntoSelectWithFixedSizeChar.sql");
+    res.close();
+
+    //remove \0
+    String resultDatas = getTableFileContents("test1").replaceAll("\0","");
+    String expected = "a\n" +
+      "abc\n" +
+      "abcde\n";
+
+    assertNotNull(resultDatas);
+    assertEquals(expected.length(), resultDatas.length());
+    assertEquals(expected, resultDatas);
+    executeString("DROP TABLE test1 PURGE");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java
new file mode 100644
index 0000000..d2585a7
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinOnPartitionedTables.java
@@ -0,0 +1,341 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.annotation.NotThreadSafe;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/*
+ * NOTE: Plan tests are disabled in TestJoinOnPartitionedTables.
+ * A plan reading partitioned table currently contains HDFS paths to input partitions.
+ * An example form of path to an input partition is hdfs://localhost:60305/tajo/warehouse/default/customer_parts/c_nationkey=1.
+ * Here, the different HDFS port is used for each test run, it is difficult to test query plans that read partitioned table.
+ */
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+@NotThreadSafe
+public class TestJoinOnPartitionedTables extends TestJoinQuery {
+
+  public TestJoinOnPartitionedTables(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+    client.executeQuery("CREATE TABLE if not exists customer_parts " +
+        "(c_custkey INT4, c_name TEXT, c_address TEXT, c_phone TEXT, c_acctbal FLOAT8, c_mktsegment TEXT, c_comment TEXT) " +
+        "PARTITION BY COLUMN (c_nationkey INT4) as " +
+        "SELECT c_custkey, c_name, c_address, c_phone, c_acctbal, c_mktsegment, c_comment, c_nationkey FROM customer;");
+    client.executeQueryAndGetResult("create table if not exists nation_partitioned (n_name text) " +
+        "partition by column(n_nationkey int4, n_regionkey int4) " +
+        "as select n_name, n_nationkey, n_regionkey from nation");
+    addEmptyDataFile("nation_partitioned", true);
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+    client.executeQuery("DROP TABLE IF EXISTS customer_parts PURGE");
+    client.executeQuery("DROP TABLE IF EXISTS nation_partitioned PURGE");
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void testPartitionTableJoinSmallTable() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void testNoProjectionJoinQual() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void testPartialFilterPushDown() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void testPartialFilterPushDownOuterJoin() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void testPartialFilterPushDownOuterJoin2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void selfJoinOfPartitionedTable() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select a.c_custkey, b.c_custkey from " +
+          "  (select c_custkey, c_nationkey from customer_parts where c_nationkey < 0 " +
+          "   union all " +
+          "   select c_custkey, c_nationkey from customer_parts where c_nationkey < 0 " +
+          ") a " +
+          "left outer join customer_parts b " +
+          "on a.c_custkey = b.c_custkey " +
+          "and a.c_nationkey > 0")
+  })
+  public void testPartitionMultiplePartitionFilter() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public void testFilterPushDownPartitionColumnCaseWhen() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public void testMultiplePartitionedBroadcastDataFileWithZeroLength() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public void testMultiplePartitionedBroadcastDataFileWithZeroLength2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  public final void testCasebyCase1() throws Exception {
+    // Left outer join with a small table and a large partition table which not matched any partition path.
+    String tableName = CatalogUtil.normalizeIdentifier("largePartitionedTable");
+    executeString(
+        "create table " + tableName + " (l_partkey int4, l_suppkey int4, l_linenumber int4, \n" +
+            "l_quantity float8, l_extendedprice float8, l_discount float8, l_tax float8, \n" +
+            "l_returnflag text, l_linestatus text, l_shipdate text, l_commitdate text, \n" +
+            "l_receiptdate text, l_shipinstruct text, l_shipmode text, l_comment text) \n" +
+            "partition by column(l_orderkey int4) ").close();
+
+    try {
+      executeString("insert overwrite into " + tableName +
+          " select l_partkey, l_suppkey, l_linenumber, \n" +
+          " l_quantity, l_extendedprice, l_discount, l_tax, \n" +
+          " l_returnflag, l_linestatus, l_shipdate, l_commitdate, \n" +
+          " l_receiptdate, l_shipinstruct, l_shipmode, l_comment, l_orderkey from lineitem");
+
+      ResultSet res = executeString(
+          "select a.l_orderkey as key1, b.l_orderkey as key2 from lineitem as a " +
+              "left outer join " + tableName + " b " +
+              "on a.l_partkey = b.l_partkey and b.l_orderkey = 1000"
+      );
+
+      String expected = "key1,key2\n" +
+          "-------------------------------\n" +
+          "1,null\n" +
+          "1,null\n" +
+          "2,null\n" +
+          "3,null\n" +
+          "3,null\n";
+      assertEquals(expected, resultSetToString(res));
+      cleanupQuery(res);
+    } finally {
+      executeString("drop table " + tableName + " purge");
+    }
+  }
+
+  // TODO: This test should be reverted after resolving TAJO-1600
+//  @Test
+  public final void testBroadcastMultiColumnPartitionTable() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("testBroadcastMultiColumnPartitionTable");
+    ResultSet res = testBase.execute(
+        "create table " + tableName + " (col1 int4, col2 float4) partition by column(col3 text, col4 text) ");
+    res.close();
+    TajoTestingCluster cluster = testBase.getTestingCluster();
+    CatalogService catalog = cluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+    try {
+      res = executeString("insert overwrite into " + tableName
+          + " select o_orderkey, o_totalprice, substr(o_orderdate, 6, 2), substr(o_orderdate, 1, 4) from orders");
+      res.close();
+
+      res = executeString(
+          "select distinct a.col3 from " + tableName + " as a " +
+              "left outer join lineitem b " +
+              "on a.col1 = b.l_orderkey order by a.col3"
+      );
+
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop table " + tableName + " purge");
+    }
+  }
+
+  @Test
+  public final void testSelfJoin() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("paritioned_nation");
+    ResultSet res = executeString(
+        "create table " + tableName + " (n_name text,"
+            + "  n_comment text, n_regionkey int8) USING text "
+            + "WITH ('text.delimiter'='|')"
+            + "PARTITION BY column(n_nationkey int8)");
+    res.close();
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+    try {
+      res = executeString(
+          "insert overwrite into " + tableName
+              + " select n_name, n_comment, n_regionkey, n_nationkey from nation");
+      res.close();
+
+      res = executeString(
+          "select a.n_nationkey, a.n_name from nation a join nation b on a.n_nationkey = b.n_nationkey"
+              + " where a.n_nationkey in (1)");
+      String expected = resultSetToString(res);
+      res.close();
+
+      res = executeString(
+          "select a.n_nationkey, a.n_name from " + tableName + " a join " + tableName +
+              " b on a.n_nationkey = b.n_nationkey "
+              + " where a.n_nationkey in (1)");
+      String resultSetData = resultSetToString(res);
+      res.close();
+
+      assertEquals(expected, resultSetData);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop table " + tableName + " purge");
+    }
+  }
+
+  @Test
+  public final void testSelfJoin2() throws Exception {
+    /*
+     https://issues.apache.org/jira/browse/TAJO-1102
+     See the following case.
+     CREATE TABLE orders_partition
+       (o_orderkey INT8, o_custkey INT8, o_totalprice FLOAT8, o_orderpriority TEXT,
+          o_clerk TEXT, o_shippriority INT4, o_comment TEXT) USING TEXT WITH ('text.delimiter'='|')
+       PARTITION BY COLUMN(o_orderdate TEXT, o_orderstatus TEXT);
+
+     select a.o_orderstatus, count(*) as cnt
+      from orders_partition a
+      inner join orders_partition b
+        on a.o_orderdate = b.o_orderdate
+            and a.o_orderstatus = b.o_orderstatus
+            and a.o_orderkey = b.o_orderkey
+      where a.o_orderdate='1995-02-21'
+        and a.o_orderstatus in ('F')
+      group by a.o_orderstatus;
+
+      Because of the where condition[where a.o_orderdate='1995-02-21 and a.o_orderstatus in ('F')],
+        orders_partition table aliased a is small and broadcast target.
+    */
+    String tableName = CatalogUtil.normalizeIdentifier("partitioned_orders");
+    ResultSet res = executeString(
+        "create table " + tableName + " (o_orderkey INT8, o_custkey INT8, o_totalprice FLOAT8, o_orderpriority TEXT,\n" +
+            "o_clerk TEXT, o_shippriority INT4, o_comment TEXT) USING TEXT WITH ('text.delimiter'='|')\n" +
+            "PARTITION BY COLUMN(o_orderdate TEXT, o_orderstatus TEXT, o_orderkey_mod INT8)");
+    res.close();
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+    try {
+      res = executeString(
+          "insert overwrite into " + tableName +
+              " select o_orderkey, o_custkey, o_totalprice, " +
+              " o_orderpriority, o_clerk, o_shippriority, o_comment, o_orderdate, o_orderstatus, o_orderkey % 10 " +
+              " from orders ");
+      res.close();
+
+      res = executeString(
+          "select a.o_orderdate, a.o_orderstatus, a.o_orderkey % 10 as o_orderkey_mod, a.o_totalprice " +
+              "from orders a " +
+              "join orders b on a.o_orderkey = b.o_orderkey " +
+              "where a.o_orderdate = '1993-10-14' and a.o_orderstatus = 'F' and a.o_orderkey % 10 = 1" +
+              " order by a.o_orderkey"
+      );
+      String expected = resultSetToString(res);
+      res.close();
+
+      res = executeString(
+          "select a.o_orderdate, a.o_orderstatus, a.o_orderkey_mod, a.o_totalprice " +
+              "from " + tableName +
+              " a join " + tableName + " b on a.o_orderkey = b.o_orderkey " +
+              "where a.o_orderdate = '1993-10-14' and a.o_orderstatus = 'F' and a.o_orderkey_mod = 1 " +
+              " order by a.o_orderkey"
+      );
+      String resultSetData = resultSetToString(res);
+      res.close();
+
+      cleanupQuery(res);
+      assertEquals(expected, resultSetData);
+    } finally {
+      executeString("drop table " + tableName + " purge");
+    }
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true)
+  @SimpleTest()
+  public final void testBroadcastPartitionTable() throws Exception {
+    // If all tables participate in the BROADCAST JOIN, there is some missing data.
+    executeDDL("customer_partition_ddl.sql", null);
+    ResultSet res = executeFile("insert_into_customer_partition.sql");
+    res.close();
+
+    try {
+      runSimpleTests();
+    } finally {
+      executeString("DROP TABLE customer_broad_parts PURGE");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
new file mode 100644
index 0000000..2fddbfa
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
@@ -0,0 +1,315 @@
+/**
+ * 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.query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.Int4Datum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.util.FileUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestJoinQuery extends QueryTestCaseBase {
+  private static final Log LOG = LogFactory.getLog(TestJoinQuery.class);
+  private static int reference = 0;
+
+  public TestJoinQuery(String joinOption) throws Exception {
+    super(TajoConstants.DEFAULT_DATABASE_NAME, joinOption);
+
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname, "true");
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$DIST_QUERY_BROADCAST_JOIN_THRESHOLD.varname, "" + (5 * 1024));
+
+    testingCluster.setAllTajoDaemonConfValue(
+        ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname,
+        ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.defaultVal);
+
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname,
+        ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.defaultVal);
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD.varname,
+        ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD.defaultVal);
+
+    if (joinOption.indexOf("NoBroadcast") >= 0) {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname, "false");
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$DIST_QUERY_BROADCAST_JOIN_THRESHOLD.varname, "-1");
+    }
+
+    if (joinOption.indexOf("Hash") >= 0) {
+      testingCluster.setAllTajoDaemonConfValue(
+          ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname, String.valueOf(256 * 1048576));
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname,
+          String.valueOf(256 * 1048576));
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD.varname,
+          String.valueOf(256 * 1048576));
+    }
+    if (joinOption.indexOf("Sort") >= 0) {
+      testingCluster.setAllTajoDaemonConfValue(
+          ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname, String.valueOf(1));
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname,
+          String.valueOf(1));
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD.varname,
+          String.valueOf(1));
+    }
+  }
+
+  @Parameters
+  public static Collection<Object[]> generateParameters() {
+    return Arrays.asList(new Object[][]{
+        {"Hash_NoBroadcast"},
+        {"Sort_NoBroadcast"},
+        {"Hash"},
+        {"Sort"},
+    });
+  }
+
+  public static void setup() throws Exception {
+    if (reference++ == 0) {
+      createCommonTables();
+    }
+  }
+
+  public static void classTearDown() throws SQLException {
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname,
+        ConfVars.$TEST_BROADCAST_JOIN_ENABLED.defaultVal);
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$DIST_QUERY_BROADCAST_JOIN_THRESHOLD.varname,
+        ConfVars.$DIST_QUERY_BROADCAST_JOIN_THRESHOLD.defaultVal);
+
+    testingCluster.setAllTajoDaemonConfValue(
+        ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname,
+        ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.defaultVal);
+
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.varname,
+        ConfVars.$EXECUTOR_HASH_JOIN_SIZE_THRESHOLD.defaultVal);
+    testingCluster.setAllTajoDaemonConfValue(ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD.varname,
+        ConfVars.$EXECUTOR_GROUPBY_INMEMORY_HASH_THRESHOLD.defaultVal);
+
+    if (--reference == 0) {
+      dropCommonTables();
+    }
+  }
+
+  protected static void createCommonTables() throws Exception {
+    LOG.info("Create common tables for join tests");
+
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    String[] data = new String[]{"1|table11-1", "2|table11-2", "3|table11-3", "4|table11-4", "5|table11-5"};
+    TajoTestingCluster.createTable("jointable11", schema, tableOptions, data, 2);
+
+    schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    data = new String[]{"1|table12-1", "2|table12-2"};
+    TajoTestingCluster.createTable("jointable12", schema, tableOptions, data, 2);
+
+    schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    data = new String[]{"2|table13-2", "3|table13-3"};
+    TajoTestingCluster.createTable("jointable13", schema, tableOptions, data);
+
+    schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    data = new String[]{"1|table14-1", "2|table14-2", "3|table14-3", "4|table14-4"};
+    TajoTestingCluster.createTable("jointable14", schema, tableOptions, data);
+
+    schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    data = new String[]{};
+    TajoTestingCluster.createTable("jointable15", schema, tableOptions, data);
+
+    schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    data = new String[]{"1000000|a", "1000001|b", "2|c", "3|d", "4|e"};
+    TajoTestingCluster.createTable("jointable1", schema, tableOptions, data, 1);
+
+    data = new String[10000];
+    for (int i = 0; i < data.length; i++) {
+      data[i] = i + "|" + "this is testLeftOuterJoinLeftSideSmallTabletestLeftOuterJoinLeftSideSmallTable" + i;
+    }
+    TajoTestingCluster.createTable("jointable_large", schema, tableOptions, data, 2);
+
+    // According to node type(leaf or non-leaf) Broadcast join is determined differently by Repartitioner.
+    // testMultipleBroadcastDataFileWithZeroLength testcase is for the leaf node
+    createMultiFile("nation", 2, new TupleCreator() {
+      public Tuple createTuple(String[] columnDatas) {
+        return new VTuple(new Datum[]{
+            new Int4Datum(Integer.parseInt(columnDatas[0])),
+            new TextDatum(columnDatas[1]),
+            new Int4Datum(Integer.parseInt(columnDatas[2])),
+            new TextDatum(columnDatas[3])
+        });
+      }
+    });
+    addEmptyDataFile("nation_multifile", false);
+  }
+
+  protected static void dropCommonTables() throws SQLException {
+    LOG.info("Clear common tables for join tests");
+
+    client.executeQuery("DROP TABLE IF EXISTS jointable11 PURGE;");
+    client.executeQuery("DROP TABLE IF EXISTS jointable12 PURGE;");
+    client.executeQuery("DROP TABLE IF EXISTS jointable13 PURGE;");
+    client.executeQuery("DROP TABLE IF EXISTS jointable14 PURGE;");
+    client.executeQuery("DROP TABLE IF EXISTS jointable15 PURGE;");
+    client.executeQuery("DROP TABLE IF EXISTS jointable1 PURGE");
+    client.executeQuery("DROP TABLE IF EXISTS jointable_large PURGE");
+    client.executeQuery("DROP TABLE IF EXISTS nation_multifile PURGE");
+  }
+
+  interface TupleCreator {
+    Tuple createTuple(String[] columnDatas);
+  }
+
+  private static String buildSchemaString(String tableName) throws TajoException {
+    TableDesc desc = client.getTableDesc(tableName);
+    StringBuffer sb = new StringBuffer();
+    for (Column column : desc.getSchema().getRootColumns()) {
+      sb.append(column.getSimpleName()).append(" ").append(column.getDataType().getType());
+      TajoDataTypes.DataType dataType = column.getDataType();
+      if (dataType.getLength() > 0) {
+        sb.append("(").append(dataType.getLength()).append(")");
+      }
+      sb.append(",");
+    }
+    sb.deleteCharAt(sb.length()-1);
+    return sb.toString();
+  }
+
+  private static String buildMultifileDDlString(String tableName) throws TajoException {
+    String multiTableName = tableName + "_multifile";
+    StringBuilder sb = new StringBuilder("create table ").append(multiTableName).append(" (");
+    sb.append(buildSchemaString(tableName)).append(" )");
+    return sb.toString();
+  }
+
+  protected static void createMultiFile(String tableName, int numRowsEachFile, TupleCreator tupleCreator) throws Exception {
+    // make multiple small file
+    String multiTableName = tableName + "_multifile";
+    String sql = buildMultifileDDlString(tableName);
+    client.executeQueryAndGetResult(sql);
+
+    TableDesc table = client.getTableDesc(multiTableName);
+    assertNotNull(table);
+
+    TableMeta tableMeta = table.getMeta();
+    Schema schema = table.getLogicalSchema();
+
+    File file = new File("src/test/tpch/" + tableName + ".tbl");
+
+    if (!file.exists()) {
+      file = new File(System.getProperty("user.dir") + "/tajo-core/src/test/tpch/" + tableName + ".tbl");
+    }
+    String[] rows = FileUtil.readTextFile(file).split("\n");
+
+    assertTrue(rows.length > 0);
+
+    int fileIndex = 0;
+
+    Appender appender = null;
+    for (int i = 0; i < rows.length; i++) {
+      if (i % numRowsEachFile == 0) {
+        if (appender != null) {
+          appender.flush();
+          appender.close();
+        }
+        Path dataPath = new Path(table.getUri().toString(), fileIndex + ".csv");
+        fileIndex++;
+        appender = (((FileTablespace) TablespaceManager.getLocalFs()))
+            .getAppender(tableMeta, schema, dataPath);
+        appender.init();
+      }
+      String[] columnDatas = rows[i].split("\\|");
+      Tuple tuple = tupleCreator.createTuple(columnDatas);
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+  }
+
+  protected static void addEmptyDataFile(String tableName, boolean isPartitioned) throws Exception {
+    TableDesc table = client.getTableDesc(tableName);
+
+    Path path = new Path(table.getUri());
+    FileSystem fs = path.getFileSystem(conf);
+    if (isPartitioned) {
+      List<Path> partitionPathList = getPartitionPathList(fs, path);
+      for (Path eachPath: partitionPathList) {
+        Path dataPath = new Path(eachPath, 0 + "_empty.csv");
+        OutputStream out = fs.create(dataPath);
+        out.close();
+      }
+    } else {
+      Path dataPath = new Path(path, 0 + "_empty.csv");
+      OutputStream out = fs.create(dataPath);
+      out.close();
+    }
+  }
+
+  protected static List<Path> getPartitionPathList(FileSystem fs, Path path) throws Exception {
+    FileStatus[] files = fs.listStatus(path);
+    List<Path> paths = new ArrayList<Path>();
+    if (files != null) {
+      for (FileStatus eachFile: files) {
+        if (eachFile.isFile()) {
+          paths.add(path);
+          return paths;
+        } else {
+          paths.addAll(getPartitionPathList(fs, eachFile.getPath()));
+        }
+      }
+    }
+
+    return paths;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java
new file mode 100644
index 0000000..d3cde3d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestMultipleJoinTypes.java
@@ -0,0 +1,106 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.SQLException;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+public class TestMultipleJoinTypes extends TestJoinQuery {
+
+  public TestMultipleJoinTypes(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+  }
+
+  @Test
+  @QueryTestCaseBase.Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @QueryTestCaseBase.SimpleTest()
+  public final void testJoinWithMultipleJoinTypes() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinsWithCaseWhen() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinsWithCaseWhen2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(prepare = {
+      "CREATE TABLE customer_broad_parts (" +
+          "  c_nationkey INT4," +
+          "  c_name    TEXT," +
+          "  c_address    TEXT," +
+          "  c_phone    TEXT," +
+          "  c_acctbal    FLOAT8," +
+          "  c_mktsegment    TEXT," +
+          "  c_comment    TEXT" +
+          ") PARTITION BY COLUMN (c_custkey INT4)",
+      "INSERT OVERWRITE INTO customer_broad_parts" +
+          "  SELECT" +
+          "    c_nationkey," +
+          "    c_name," +
+          "    c_address," +
+          "    c_phone," +
+          "    c_acctbal," +
+          "    c_mktsegment," +
+          "    c_comment," +
+          "    c_custkey" +
+          "  FROM customer"
+  }, cleanup = {
+      "DROP TABLE customer_broad_parts PURGE"
+  }, queries = {
+      @QuerySpec("select a.l_orderkey, b.o_orderkey, c.c_custkey from lineitem a " +
+          "inner join orders b on a.l_orderkey = b.o_orderkey " +
+          "left outer join customer_broad_parts c on a.l_orderkey = c.c_custkey and c.c_custkey < 0")
+  })
+  public final void testInnerAndOuterWithEmpty() throws Exception {
+    runSimpleTests();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNetTypes.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNetTypes.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNetTypes.java
new file mode 100644
index 0000000..bd8f830
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNetTypes.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.engine.query;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.ResultSet;
+
+public class TestNetTypes extends QueryTestCaseBase {
+
+  @Before
+  public final void setUp() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeDDL("table1_ddl.sql", "table1");
+      executeDDL("table2_ddl.sql", "table2");
+    }
+  }
+
+  @Test
+  public final void testSelect() throws Exception {
+    // Skip all tests when HiveCatalogStore is used.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // select name, addr from table1;
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testGroupby() throws Exception {
+    // Skip all tests when HiveCatalogStore is used.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // select name, addr, count(1) from table1 group by name, addr;
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testGroupby2() throws Exception {
+    // Skip all tests when HiveCatalogStore is used.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // select addr, count(*) from table1 group by addr;
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testSort() throws Exception {
+    // Skip all tests when HiveCatalogStore is used.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // select * from table1 order by addr;
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testSort2() throws Exception {
+    // Skip all tests when HiveCatalogStore is used.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // select addr from table2 order by addr;
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testJoin() throws Exception {
+    // Skip all tests when HiveCatalogStore is used.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // select * from table1 as t1, table2 as t2 where t1.addr = t2.addr;
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNullValues.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNullValues.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNullValues.java
new file mode 100644
index 0000000..66848e6
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestNullValues.java
@@ -0,0 +1,322 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import static org.junit.Assert.*;
+
+/**
+ * This is the unit test for null values. This test needs specialized data sets.
+ * So, We separated it from other unit tests using TPC-H data set.
+ */
+@Category(IntegrationTest.class)
+public class TestNullValues {
+
+  private static TajoClient client;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    client =  TpchTestBase.getInstance().getTestingCluster().newTajoClient();
+  }
+
+  @AfterClass
+  public static void tearDown() {
+    client.close();
+  }
+
+  @Test
+  public final void testIsNull() throws Exception {
+    String [] table = new String[] {"nulltable1"};
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.INT4);
+    schema.addColumn("col2", Type.TEXT);
+    schema.addColumn("col3", Type.FLOAT4);
+    Schema [] schemas = new Schema[] {schema};
+    String [] data = {
+        "1|filled|0.1",
+        "2||",
+        "3|filled|0.2"
+    };
+    KeyValueSet opts = new KeyValueSet();
+    opts.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    ResultSet res = TajoTestingCluster
+        .run(table, schemas, opts, new String[][]{data},
+            "select * from nulltable1 where col3 is null", client);
+
+    try {
+      assertTrue(res.next());
+      assertEquals(2, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testIsNotNull() throws Exception {
+    String [] table = new String[] {"nulltable2"};
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.INT4);
+    schema.addColumn("col2", Type.TEXT);
+    Schema [] schemas = new Schema[] {schema};
+    String [] data = {
+        "1|filled|",
+        "||",
+        "3|filled|"
+    };
+    KeyValueSet opts = new KeyValueSet();
+    opts.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    ResultSet res = TajoTestingCluster
+        .run(table, schemas, opts, new String[][]{data},
+            "select * from nulltable2 where col1 is not null", client);
+    try {
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testIsNotNull2() throws Exception {
+    String [] table = new String[] {"nulltable3"};
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.INT8);
+    schema.addColumn("col2", Type.INT8);
+    schema.addColumn("col3", Type.INT8);
+    schema.addColumn("col4", Type.INT8);
+    schema.addColumn("col5", Type.INT8);
+    schema.addColumn("col6", Type.INT8);
+    schema.addColumn("col7", Type.INT8);
+    schema.addColumn("col8", Type.INT8);
+    schema.addColumn("col9", Type.INT8);
+    schema.addColumn("col10", Type.INT8);
+    Schema [] schemas = new Schema[] {schema};
+    String [] data = {
+        ",,,,672287821,1301460,1,313895860387,126288907,1024",
+        ",,,43578,19,13,6,3581,2557,1024"
+    };
+    KeyValueSet opts = new KeyValueSet();
+    opts.set(StorageConstants.TEXT_DELIMITER, ",");
+    ResultSet res = TajoTestingCluster
+        .run(table, schemas, opts, new String[][]{data},
+            "select * from nulltable3 where col1 is null and col2 is null and col3 is null and col4 = 43578", client);
+    try {
+      assertTrue(res.next());
+      assertEquals(43578, res.getLong(4));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testIsNotNull3() throws Exception {
+    String [] table = new String[] {"nulltable4"};
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.INT8);
+    schema.addColumn("col2", Type.INT8);
+    schema.addColumn("col3", Type.INT8);
+    schema.addColumn("col4", Type.INT8);
+    schema.addColumn("col5", Type.INT8);
+    schema.addColumn("col6", Type.INT8);
+    schema.addColumn("col7", Type.INT8);
+    schema.addColumn("col8", Type.INT8);
+    schema.addColumn("col9", Type.INT8);
+    schema.addColumn("col10", Type.INT8);
+    Schema [] schemas = new Schema[] {schema};
+    String [] data = {
+        "\\N,,,,672287821,",
+        ",\\N,,43578"
+    };
+    KeyValueSet opts = new KeyValueSet();
+    opts.set(StorageConstants.TEXT_DELIMITER, ",");
+    opts.set(StorageConstants.TEXT_NULL, "\\\\N");
+    ResultSet res = TajoTestingCluster
+        .run(table, schemas, opts, new String[][]{data},
+            "select * from nulltable4 where col1 is null and col2 is null and col3 is null and col5 is null and col4 = 43578"
+            , client);
+    try {
+      assertTrue(res.next());
+      assertEquals(43578, res.getLong(4));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testResultSetNullSimpleQuery() throws Exception {
+    String tableName = "nulltable5";
+    ResultSet res = null;
+
+    try {
+      res = runNullTableQuery(tableName, "select col1, col2, col3, col4 from " + tableName, client);
+      int numRows = 0;
+
+      String expected =
+              "null|a|1.0|true\n" +
+              "2|null|2.0|false\n" +
+              "3|c|null|true\n" +
+              "4|d|4.0|null";
+
+      String result = "";
+
+      String prefix = "";
+      while(res.next()) {
+        for (int i = 0; i < 4; i++) {
+          result += prefix + res.getObject(i + 1);
+          prefix = "|";
+        }
+        prefix = "\n";
+
+        assertResultSetNull(res, numRows, false, new int[]{1,2,3,4});
+        assertResultSetNull(res, numRows, true, new int[]{1,2,3,4});
+        numRows++;
+      }
+      assertEquals(4, numRows);
+      assertEquals(expected, result);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  @Test
+  public final void testResultSetNull() throws Exception {
+    String tableName = "nulltable6";
+    String query = "select " +
+        "col1, coalesce(col1, 99999), " +
+        "col2, coalesce(col2, 'null_value'), " +
+        "col3, coalesce(col3, 99999.0)," +
+        "col4 " +
+        "from " + tableName;
+
+    ResultSet res = null;
+
+    try {
+      res = runNullTableQuery(tableName, query, client);
+      int numRows = 0;
+      String expected =
+          "null|99999|a|a|1.0|1.0|true\n" +
+          "2|2|null|null_value|2.0|2.0|false\n" +
+          "3|3|c|c|null|99999.0|true\n" +
+          "4|4|d|d|4.0|4.0|null";
+
+      String result = "";
+
+      String prefix = "";
+      while(res.next()) {
+        for (int i = 0; i < 7; i++) {
+          result += prefix + res.getObject(i + 1);
+          prefix = "|";
+        }
+        prefix = "\n";
+
+        assertResultSetNull(res, numRows, false, new int[]{1,3,5,7});
+        assertResultSetNull(res, numRows, true, new int[]{1,3,5,7});
+        numRows++;
+      }
+      assertEquals(4, numRows);
+      assertEquals(expected, result);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  private ResultSet runNullTableQuery(String tableName, String query, TajoClient client) throws Exception {
+    String [] table = new String[] {tableName};
+    Schema schema = new Schema();
+    schema.addColumn("col1", Type.INT4);
+    schema.addColumn("col2", Type.TEXT);
+    schema.addColumn("col3", Type.FLOAT4);
+    schema.addColumn("col4", Type.BOOLEAN);
+    Schema [] schemas = new Schema[] {schema};
+    String [] data = {
+        "\\N|a|1.0|t",
+        "2|\\N|2.0|f",
+        "3|c|\\N|t",
+        "4|d|4.0|\\N"
+    };
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    if (client == null) {
+      return TajoTestingCluster.run(table, schemas, tableOptions, new String[][]{data}, query);
+    } else {
+      return TajoTestingCluster.run(table, schemas, tableOptions, new String[][]{data}, query, client);
+    }
+  }
+
+  private void assertResultSetNull(ResultSet res, int numRows, boolean useName, int[] nullIndex) throws SQLException {
+    if (numRows == 0) {
+      if (useName) {
+        assertEquals(0, res.getInt(res.getMetaData().getColumnName(nullIndex[numRows])));
+      } else {
+        assertEquals(0, res.getInt(nullIndex[numRows]));
+      }
+    }
+
+    if (numRows == 1) {
+      if (useName) {
+        assertNull(res.getString(res.getMetaData().getColumnName(nullIndex[numRows])));
+      } else {
+        assertNull(res.getString(nullIndex[numRows]));
+      };
+    }
+
+    if (numRows == 2) {
+      if (useName) {
+        assertEquals(0.0, res.getDouble(res.getMetaData().getColumnName(nullIndex[numRows])), 10);
+      } else {
+        assertEquals(0.0, res.getDouble(nullIndex[numRows]), 10);
+      }
+    }
+
+    if (numRows == 3) {
+      if (useName) {
+        assertEquals(false, res.getBoolean(res.getMetaData().getColumnName(nullIndex[numRows])));
+      } else {
+        assertEquals(false, res.getBoolean(nullIndex[numRows]));
+      }
+    }
+  }
+}


[32/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java
new file mode 100644
index 0000000..6eb2841
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTablePartitions.java
@@ -0,0 +1,1301 @@
+/**
+ * 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.query;
+
+import com.google.common.collect.Maps;
+import org.apache.hadoop.fs.*;
+import org.apache.hadoop.io.compress.CompressionCodec;
+import org.apache.hadoop.io.compress.CompressionCodecFactory;
+import org.apache.hadoop.io.compress.DeflateCodec;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.exception.ReturnStateUtil;
+import org.apache.tajo.catalog.proto.CatalogProtos.PartitionDescProto;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.planner.global.DataChannel;
+import org.apache.tajo.engine.planner.global.ExecutionBlock;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.ipc.ClientProtos;
+import org.apache.tajo.jdbc.FetchResultSet;
+import org.apache.tajo.jdbc.TajoMemoryResultSet;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.querymaster.QueryMasterTask;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.worker.TajoWorker;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.util.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.ShuffleType.SCATTERED_HASH_SHUFFLE;
+import static org.junit.Assert.*;
+
+@RunWith(Parameterized.class)
+public class TestTablePartitions extends QueryTestCaseBase {
+
+  private NodeType nodeType;
+
+  public TestTablePartitions(NodeType nodeType) throws IOException {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+    this.nodeType = nodeType;
+  }
+
+  @Parameterized.Parameters
+  public static Collection<Object[]> generateParameters() {
+    return Arrays.asList(new Object[][] {
+      //type
+      {NodeType.INSERT},
+      {NodeType.CREATE_TABLE},
+    });
+  }
+
+  @Test
+  public final void testCreateColumnPartitionedTable() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testCreateColumnPartitionedTable");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+      assertEquals(2, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getSchema().size());
+      assertEquals(3, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size());
+
+      res = testBase.execute(
+        "insert overwrite into " + tableName + " select l_orderkey, l_partkey, " +
+          "l_quantity from lineitem");
+    } else {
+      res = testBase.execute(
+        "create table " + tableName + "(col1 int4, col2 int4) partition by column(key float8) "
+          + " as select l_orderkey, l_partkey, l_quantity from lineitem");
+    }
+
+    MasterPlan plan = getQueryPlan(res);
+    ExecutionBlock rootEB = plan.getRoot();
+
+    assertEquals(1, plan.getChildCount(rootEB.getId()));
+
+    ExecutionBlock insertEB = plan.getChild(rootEB.getId(), 0);
+    assertNotNull(insertEB);
+
+    assertEquals(nodeType, insertEB.getPlan().getType());
+    assertEquals(1, plan.getChildCount(insertEB.getId()));
+
+    ExecutionBlock scanEB = plan.getChild(insertEB.getId(), 0);
+
+    List<DataChannel> list = plan.getOutgoingChannels(scanEB.getId());
+    assertEquals(1, list.size());
+    DataChannel channel = list.get(0);
+    assertNotNull(channel);
+    assertEquals(SCATTERED_HASH_SHUFFLE, channel.getShuffleType());
+    assertEquals(1, channel.getShuffleKeys().length);
+
+    TableDesc tableDesc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"key"},
+      tableDesc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+    res.close();
+  }
+
+  @Test
+  public final void testCreateColumnPartitionedTableWithJoin() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testCreateColumnPartitionedTableWithJoin");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+      assertEquals(2, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getSchema().size());
+      assertEquals(3, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size());
+
+      res = testBase.execute(
+        "insert overwrite into " + tableName + " select l_orderkey, l_partkey, " +
+          "l_quantity from lineitem join orders on l_orderkey = o_orderkey");
+
+    } else {
+      res = testBase.execute("create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) "
+        + " AS select l_orderkey, l_partkey, l_quantity from lineitem join orders on l_orderkey = o_orderkey");
+    }
+
+    MasterPlan plan = getQueryPlan(res);
+    ExecutionBlock rootEB = plan.getRoot();
+
+    assertEquals(1, plan.getChildCount(rootEB.getId()));
+
+    ExecutionBlock insertEB = plan.getChild(rootEB.getId(), 0);
+    assertNotNull(insertEB);
+    assertEquals(nodeType, insertEB.getPlan().getType());
+    assertEquals(1, plan.getChildCount(insertEB.getId()));
+
+    ExecutionBlock scanEB = plan.getChild(insertEB.getId(), 0);
+
+    List<DataChannel> list = plan.getOutgoingChannels(scanEB.getId());
+    assertEquals(1, list.size());
+    DataChannel channel = list.get(0);
+    assertNotNull(channel);
+    assertEquals(SCATTERED_HASH_SHUFFLE, channel.getShuffleType());
+    assertEquals(1, channel.getShuffleKeys().length);
+
+    TableDesc tableDesc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"key"},
+      tableDesc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+    res.close();
+  }
+
+  @Test
+  public final void testCreateColumnPartitionedTableWithSelectedColumns() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testCreateColumnPartitionedTableWithSelectedColumns");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4, null_col int4) partition by column(key float8) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+      assertEquals(3, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getSchema().size());
+      assertEquals(4, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size());
+
+      res = executeString("insert overwrite into " + tableName + " (col1, col2, key) select l_orderkey, " +
+        "l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString("create table " + tableName + " (col1 int4, col2 int4, null_col int4)"
+        + " partition by column(key float8) AS select l_orderkey, l_partkey, null, l_quantity from lineitem");
+    }
+    res.close();
+
+    TableDesc tableDesc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"key"},
+      tableDesc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableByOneColumn() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableByOneColumn");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4, null_col int4) partition by column(key float8) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString("insert overwrite into " + tableName
+        + " (col1, col2, key) select l_orderkey, l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString("create table " + tableName + " (col1 int4, col2 int4, null_col int4) "
+        + " partition by column(key float8) as select l_orderkey, l_partkey, null, l_quantity from lineitem");
+    }
+    res.close();
+
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    assertPartitionDirectories(desc);
+
+    res = executeString(
+        "select distinct * from " + tableName + " where (key = 45.0 or key = 38.0) and null_col is null");
+
+    Map<Double, int []> resultRows1 = Maps.newHashMap();
+    resultRows1.put(45.0d, new int[]{3, 2});
+    resultRows1.put(38.0d, new int[]{2, 2});
+
+    for (int i = 0; i < 2; i++) {
+      assertTrue(res.next());
+      assertEquals(resultRows1.get(res.getDouble(4))[0], res.getInt(1));
+      assertEquals(resultRows1.get(res.getDouble(4))[1], res.getInt(2));
+    }
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName,
+      new String[]{"key"}, desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+    res.close();
+  }
+
+  private void assertPartitionDirectories(TableDesc desc) throws IOException {
+    FileSystem fs = FileSystem.get(conf);
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(path));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=17.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=36.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=49.0")));
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+  }
+
+  @Test
+  public final void testQueryCasesOnColumnPartitionedTable() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testQueryCasesOnColumnPartitionedTable");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4, null_col int4) partition by column(key float8) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString(
+        "insert overwrite into " + tableName
+          + " (col1, col2, key) select l_orderkey, l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString("create table " + tableName + " (col1 int4, col2 int4, null_col int4) "
+        + " partition by column(key float8) as select l_orderkey, l_partkey, null, l_quantity from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    assertPartitionDirectories(desc);
+
+    res = executeFile("case1.sql");
+    assertResultSet(res, "case1.result");
+    res.close();
+
+    res = executeFile("case2.sql");
+    assertResultSet(res, "case2.result");
+    res.close();
+
+    res = executeFile("case3.sql");
+    assertResultSet(res, "case3.result");
+    res.close();
+
+    // select pow(key, 2) from testQueryCasesOnColumnPartitionedTable
+    res = executeFile("case4.sql");
+    assertResultSet(res, "case4.result");
+    res.close();
+
+    // select round(pow(key + 1, 2)) from testQueryCasesOnColumnPartitionedTable
+    res = executeFile("case5.sql");
+    assertResultSet(res, "case5.result");
+    res.close();
+
+    // select col1, key from testQueryCasesOnColumnPartitionedTable order by pow(key, 2) desc
+    res = executeFile("case6.sql");
+    assertResultSet(res, "case6.result");
+    res.close();
+
+    // select col1, key from testQueryCasesOnColumnPartitionedTable WHERE key BETWEEN 35 AND 48;
+    res = executeFile("case7.sql");
+    assertResultSet(res, "case7.result");
+    res.close();
+
+    // select col1, CASE key WHEN 36 THEN key WHEN 49 THEN key ELSE key END from testQueryCasesOnColumnPartitionedTable;
+    res = executeFile("case8.sql");
+    assertResultSet(res, "case8.result");
+    res.close();
+
+    // select col1, CAST(key AS INT) from testQueryCasesOnColumnPartitionedTable;
+    res = executeFile("case9.sql");
+    assertResultSet(res, "case9.result");
+    res.close();
+
+    // select col1, (!(key > 35)) from testQueryCasesOnColumnPartitionedTable;
+    res = executeFile("case10.sql");
+    assertResultSet(res, "case10.result");
+    res.close();
+
+    // alias partition column
+    res = executeFile("case11.sql");
+    assertResultSet(res, "case11.result");
+    res.close();
+
+    // alias partition column in group by, order by
+    res = executeFile("case12.sql");
+    assertResultSet(res, "case12.result");
+    res.close();
+
+    // alias partition column in stage
+    res = executeFile("case13.sql");
+    assertResultSet(res, "case13.result");
+    res.close();
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"key"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+    res.close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableByThreeColumns() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableByThreeColumns");
+
+    if (nodeType == NodeType.INSERT) {
+      res = testBase.execute(
+        "create table " + tableName + " (col4 text) partition by column(col1 int4, col2 int4, col3 float8) ");
+      res.close();
+      TajoTestingCluster cluster = testBase.getTestingCluster();
+      CatalogService catalog = cluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString("insert overwrite into " + tableName
+        + " select l_returnflag, l_orderkey, l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString( "create table " + tableName + " (col4 text) "
+        + " partition by column(col1 int4, col2 int4, col3 float8) as select l_returnflag, l_orderkey, l_partkey, " +
+        "l_quantity from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    Path path = new Path(desc.getUri());
+
+    FileSystem fs = FileSystem.get(conf);
+    assertTrue(fs.isDirectory(path));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1/col3=17.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2/col3=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2/col3=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3/col3=49.0")));
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeString("select * from " + tableName + " where col2 = 2");
+
+    Map<Double, int []> resultRows1 = Maps.newHashMap();
+    resultRows1.put(45.0d, new int[]{3, 2});
+    resultRows1.put(38.0d, new int[]{2, 2});
+
+
+    for (int i = 0; i < 2; i++) {
+      assertTrue(res.next());
+      assertEquals(resultRows1.get(res.getDouble(4))[0], res.getInt(2));
+      assertEquals(resultRows1.get(res.getDouble(4))[1], res.getInt(3));
+    }
+    res.close();
+
+    Map<Double, int []> resultRows2 = Maps.newHashMap();
+    resultRows2.put(49.0d, new int[]{3, 3});
+    resultRows2.put(45.0d, new int[]{3, 2});
+    resultRows2.put(38.0d, new int[]{2, 2});
+
+    res = executeString("select * from " + tableName + " where (col1 = 2 or col1 = 3) and col2 >= 2");
+
+    for (int i = 0; i < 3; i++) {
+      assertTrue(res.next());
+      assertEquals(resultRows2.get(res.getDouble(4))[0], res.getInt(2));
+      assertEquals(resultRows2.get(res.getDouble(4))[1], res.getInt(3));
+    }
+
+    res = executeString("SELECT col1, col2, col3 FROM " + tableName);
+    String result = resultSetToString(res);
+    res.close();
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1", "col2", "col3"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+    res.close();
+  }
+
+  @Test
+  public final void testInsertIntoColumnPartitionedTableByThreeColumns() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testInsertIntoColumnPartitionedTableByThreeColumns");
+
+    if (nodeType == NodeType.INSERT) {
+      res = testBase.execute(
+        "create table " + tableName + " (col4 text) partition by column(col1 int4, col2 int4, col3 float8) ");
+      res.close();
+      TajoTestingCluster cluster = testBase.getTestingCluster();
+      CatalogService catalog = cluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString("insert into " + tableName
+        + " select l_returnflag, l_orderkey, l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString( "create table " + tableName + " (col4 text) "
+        + " partition by column(col1 int4, col2 int4, col3 float8) as select l_returnflag, l_orderkey, l_partkey, " +
+        "l_quantity from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1", "col2", "col3"},
+      desc.getStats().getNumRows());
+
+    Path path = new Path(desc.getUri());
+
+    FileSystem fs = FileSystem.get(conf);
+    verifyDirectoriesForThreeColumns(fs, path, 1);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    res = executeString("select * from " + tableName + " where col2 = 2");
+
+    Map<Double, int []> resultRows1 = Maps.newHashMap();
+    resultRows1.put(45.0d, new int[]{3, 2});
+    resultRows1.put(38.0d, new int[]{2, 2});
+
+    for (int i = 0; i < 2; i++) {
+      assertTrue(res.next());
+      assertEquals(resultRows1.get(res.getDouble(4))[0], res.getInt(2));
+      assertEquals(resultRows1.get(res.getDouble(4))[1], res.getInt(3));
+    }
+    res.close();
+
+    Map<Double, int []> resultRows2 = Maps.newHashMap();
+    resultRows2.put(49.0d, new int[]{3, 3});
+    resultRows2.put(45.0d, new int[]{3, 2});
+    resultRows2.put(38.0d, new int[]{2, 2});
+
+    res = executeString("select * from " + tableName + " where (col1 = 2 or col1 = 3) and col2 >= 2");
+
+    for (int i = 0; i < 3; i++) {
+      assertTrue(res.next());
+      assertEquals(resultRows2.get(res.getDouble(4))[0], res.getInt(2));
+      assertEquals(resultRows2.get(res.getDouble(4))[1], res.getInt(3));
+    }
+    res.close();
+
+    // insert into already exists partitioned table
+    res = executeString("insert into " + tableName
+        + " select l_returnflag, l_orderkey, l_partkey, l_quantity from lineitem");
+    res.close();
+
+    desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+
+    // TODO: When inserting into already exists partitioned table, table status need to change correctly.
+//    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1", "col2", "col3"},
+//      desc.getStats().getNumRows());
+
+    path = new Path(desc.getUri());
+
+    verifyDirectoriesForThreeColumns(fs, path, 2);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    String expected = "N\n" +
+        "N\n" +
+        "N\n" +
+        "N\n" +
+        "N\n" +
+        "N\n" +
+        "R\n" +
+        "R\n" +
+        "R\n" +
+        "R\n";
+
+    String tableData = getTableFileContents(new Path(desc.getUri()));
+    assertEquals(expected, tableData);
+
+    res = executeString("select * from " + tableName + " where col2 = 2");
+    String resultSetData = resultSetToString(res);
+    res.close();
+    expected = "col4,col1,col2,col3\n" +
+        "-------------------------------\n" +
+        "N,2,2,38.0\n" +
+        "N,2,2,38.0\n" +
+        "R,3,2,45.0\n" +
+        "R,3,2,45.0\n";
+    assertEquals(expected, resultSetData);
+
+    res = executeString("select * from " + tableName + " where (col1 = 2 or col1 = 3) and col2 >= 2");
+    resultSetData = resultSetToString(res);
+    res.close();
+    expected = "col4,col1,col2,col3\n" +
+        "-------------------------------\n" +
+        "N,2,2,38.0\n" +
+        "N,2,2,38.0\n" +
+        "R,3,2,45.0\n" +
+        "R,3,2,45.0\n" +
+        "R,3,3,49.0\n" +
+        "R,3,3,49.0\n";
+    assertEquals(expected, resultSetData);
+
+    // Check not to remove existing partition directories.
+    res = executeString("insert overwrite into " + tableName
+        + " select l_returnflag, l_orderkey, l_partkey, 30.0 as l_quantity from lineitem "
+        + " where l_orderkey = 1 and l_partkey = 1 and  l_linenumber = 1");
+    res.close();
+
+    verifyDirectoriesForThreeColumns(fs, path, 3);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // TODO: If there is existing another partition directory, we must add its rows number to result row numbers.
+      // desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+      // assertEquals(6, desc.getStats().getNumRows().intValue());
+    }
+
+    verifyKeptExistingData(res, tableName);
+
+    // insert overwrite empty result to partitioned table
+    res = executeString("insert overwrite into " + tableName
+      + " select l_returnflag, l_orderkey, l_partkey, l_quantity from lineitem where l_orderkey > 100");
+    res.close();
+
+    verifyDirectoriesForThreeColumns(fs, path, 4);
+    verifyKeptExistingData(res, tableName);
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  private final void verifyKeptExistingData(ResultSet res, String tableName) throws Exception {
+    res = executeString("select * from " + tableName + " where col2 = 1");
+    String resultSetData = resultSetToString(res);
+    res.close();
+    String expected = "col4,col1,col2,col3\n" +
+      "-------------------------------\n" +
+      "N,1,1,17.0\n" +
+      "N,1,1,17.0\n" +
+      "N,1,1,30.0\n" +
+      "N,1,1,36.0\n" +
+      "N,1,1,36.0\n";
+
+    assertEquals(expected, resultSetData);
+  }
+
+  private final void verifyDirectoriesForThreeColumns(FileSystem fs, Path path, int step) throws Exception {
+    assertTrue(fs.isDirectory(path));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1")));
+
+    if (step == 1 || step == 2) {
+      assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1/col3=17.0")));
+    } else {
+      assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1/col3=17.0")));
+      assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1/col3=30.0")));
+    }
+
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2/col3=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2/col3=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3/col3=49.0")));
+  }
+
+  @Test
+  public final void testColumnPartitionedTableByOneColumnsWithCompression() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableByOneColumnsWithCompression");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col2 int4, col3 float8) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "PARTITION BY column(col1 int4)");
+      res.close();
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString(
+        "insert overwrite into " + tableName + " select l_partkey, l_quantity, l_orderkey from lineitem");
+    } else {
+      res = executeString(
+        "create table " + tableName + " (col2 int4, col3 float8) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "PARTITION BY column(col1 int4) as select l_partkey, l_quantity, l_orderkey from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    FileSystem fs = FileSystem.get(conf);
+    assertTrue(fs.exists(new Path(desc.getUri())));
+    CompressionCodecFactory factory = new CompressionCodecFactory(conf);
+
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3")));
+
+    for (FileStatus partition : fs.listStatus(path)){
+      assertTrue(fs.isDirectory(partition.getPath()));
+      for (FileStatus file : fs.listStatus(partition.getPath())) {
+        CompressionCodec codec = factory.getCodec(file.getPath());
+        assertTrue(codec instanceof DeflateCodec);
+      }
+    }
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableByTwoColumnsWithCompression() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableByTwoColumnsWithCompression");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString("create table " + tableName + " (col3 float8, col4 text) USING text " +
+        "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+        "PARTITION by column(col1 int4, col2 int4)");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString(
+        "insert overwrite into " + tableName +
+          " select  l_quantity, l_returnflag, l_orderkey, l_partkey from lineitem");
+    } else {
+      res = executeString("create table " + tableName + " (col3 float8, col4 text) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "PARTITION by column(col1 int4, col2 int4) as select  l_quantity, l_returnflag, l_orderkey, " +
+        "l_partkey from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    FileSystem fs = FileSystem.get(conf);
+    assertTrue(fs.exists(new Path(desc.getUri())));
+    CompressionCodecFactory factory = new CompressionCodecFactory(conf);
+
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3")));
+
+    for (FileStatus partition1 : fs.listStatus(path)){
+      assertTrue(fs.isDirectory(partition1.getPath()));
+      for (FileStatus partition2 : fs.listStatus(partition1.getPath())) {
+        assertTrue(fs.isDirectory(partition2.getPath()));
+        for (FileStatus file : fs.listStatus(partition2.getPath())) {
+          CompressionCodec codec = factory.getCodec(file.getPath());
+          assertTrue(codec instanceof DeflateCodec);
+        }
+      }
+    }
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1", "col2"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableByThreeColumnsWithCompression() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableByThreeColumnsWithCompression");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col4 text) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "partition by column(col1 int4, col2 int4, col3 float8)");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString(
+        "insert overwrite into " + tableName +
+          " select l_returnflag, l_orderkey, l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString("create table " + tableName + " (col4 text) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "partition by column(col1 int4, col2 int4, col3 float8) as select l_returnflag, l_orderkey, l_partkey, " +
+        "l_quantity from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    FileSystem fs = FileSystem.get(conf);
+    assertTrue(fs.exists(new Path(desc.getUri())));
+    CompressionCodecFactory factory = new CompressionCodecFactory(conf);
+
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1/col3=17.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2/col3=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2/col3=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3/col3=49.0")));
+
+    for (FileStatus partition1 : fs.listStatus(path)){
+      assertTrue(fs.isDirectory(partition1.getPath()));
+      for (FileStatus partition2 : fs.listStatus(partition1.getPath())) {
+        assertTrue(fs.isDirectory(partition2.getPath()));
+        for (FileStatus partition3 : fs.listStatus(partition2.getPath())) {
+          assertTrue(fs.isDirectory(partition3.getPath()));
+          for (FileStatus file : fs.listStatus(partition3.getPath())) {
+            CompressionCodec codec = factory.getCodec(file.getPath());
+            assertTrue(codec instanceof DeflateCodec);
+          }
+        }
+      }
+    }
+
+    res = executeString("select * from " + tableName + " where col2 = 2");
+
+    Map<Double, int []> resultRows1 = Maps.newHashMap();
+    resultRows1.put(45.0d, new int[]{3, 2});
+    resultRows1.put(38.0d, new int[]{2, 2});
+
+    int i = 0;
+    while (res.next()) {
+      assertEquals(resultRows1.get(res.getDouble(4))[0], res.getInt(2));
+      assertEquals(resultRows1.get(res.getDouble(4))[1], res.getInt(3));
+      i++;
+    }
+    res.close();
+    assertEquals(2, i);
+
+    Map<Double, int []> resultRows2 = Maps.newHashMap();
+    resultRows2.put(49.0d, new int[]{3, 3});
+    resultRows2.put(45.0d, new int[]{3, 2});
+    resultRows2.put(38.0d, new int[]{2, 2});
+
+    res = executeString("select * from " + tableName + " where (col1 = 2 or col1 = 3) and col2 >= 2");
+    i = 0;
+    while(res.next()) {
+      assertEquals(resultRows2.get(res.getDouble(4))[0], res.getInt(2));
+      assertEquals(resultRows2.get(res.getDouble(4))[1], res.getInt(3));
+      i++;
+    }
+
+    res.close();
+    assertEquals(3, i);
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1", "col2", "col3"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableNoMatchedPartition() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableNoMatchedPartition");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col4 text) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "partition by column(col1 int4, col2 int4, col3 float8)");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString(
+        "insert overwrite into " + tableName +
+          " select l_returnflag , l_orderkey, l_partkey, l_quantity from lineitem");
+    } else {
+      res = executeString("create table " + tableName + " (col4 text) USING text " +
+          "WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') " +
+          "partition by column(col1 int4, col2 int4, col3 float8) as select l_returnflag , l_orderkey, l_partkey, " +
+        "l_quantity from lineitem");
+    }
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    FileSystem fs = FileSystem.get(conf);
+    assertTrue(fs.exists(new Path(desc.getUri())));
+    CompressionCodecFactory factory = new CompressionCodecFactory(conf);
+
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=1/col2=1/col3=17.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=2/col2=2/col3=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=2/col3=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/col1=3/col2=3/col3=49.0")));
+
+    for (FileStatus partition1 : fs.listStatus(path)){
+      assertTrue(fs.isDirectory(partition1.getPath()));
+      for (FileStatus partition2 : fs.listStatus(partition1.getPath())) {
+        assertTrue(fs.isDirectory(partition2.getPath()));
+        for (FileStatus partition3 : fs.listStatus(partition2.getPath())) {
+          assertTrue(fs.isDirectory(partition3.getPath()));
+          for (FileStatus file : fs.listStatus(partition3.getPath())) {
+            CompressionCodec codec = factory.getCodec(file.getPath());
+            assertTrue(codec instanceof DeflateCodec);
+          }
+        }
+      }
+    }
+
+    res = executeString("select * from " + tableName + " where col2 = 9");
+    assertFalse(res.next());
+    res.close();
+
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col1", "col2", "col3"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableWithSmallerExpressions1() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableWithSmallerExpressions1");
+    res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4, null_col int4) partition by column(key float8) ");
+    res.close();
+
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+    ClientProtos.SubmitQueryResponse response = client.executeQuery("insert overwrite into " + tableName
+        + " select l_orderkey, l_partkey from lineitem");
+
+    assertTrue(ReturnStateUtil.isError(response.getState()));
+    assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns");
+
+    res = executeFile("case14.sql");
+    assertResultSet(res, "case14.result");
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"key"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableWithSmallerExpressions2() throws Exception {
+    ResultSet res = null;
+    ClientProtos.SubmitQueryResponse response = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableWithSmallerExpressions2");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 int4, col2 int4, null_col int4) partition by column(key float8) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      response = client.executeQuery("insert overwrite into " + tableName
+        + " select l_returnflag , l_orderkey, l_partkey from lineitem");
+
+      assertTrue(ReturnStateUtil.isError(response.getState()));
+      assertEquals(response.getState().getMessage(), "INSERT has smaller expressions than target columns");
+
+      res = executeFile("case15.sql");
+      assertResultSet(res, "case15.result");
+      res.close();
+
+      TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+      verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"key"},
+        desc.getStats().getNumRows());
+
+      executeString("DROP TABLE " + tableName + " PURGE").close();
+    }
+  }
+
+
+  @Test
+  public final void testColumnPartitionedTableWithSmallerExpressions3() throws Exception {
+    ResultSet res = executeString("create database testinsertquery1;");
+    res.close();
+    res = executeString("create database testinsertquery2;");
+    res.close();
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString("create table testinsertquery1.table1 " +
+        "(col1 int4, col2 int4, col3 float8)");
+      res.close();
+
+      res = executeString("create table testinsertquery2.table1 " +
+        "(col1 int4, col2 int4, col3 float8)");
+      res.close();
+
+      CatalogService catalog = testingCluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable("testinsertquery1", "table1"));
+      assertTrue(catalog.existsTable("testinsertquery2", "table1"));
+
+      res = executeString("insert overwrite into testinsertquery1.table1 " +
+        "select l_orderkey, l_partkey, l_quantity from default.lineitem;");
+      res.close();
+    } else {
+      res = executeString("create table testinsertquery1.table1 " +
+        "(col1 int4, col2 int4, col3 float8) as select l_orderkey, l_partkey, l_quantity from default.lineitem;");
+      res.close();
+    }
+
+    TableDesc desc = catalog.getTableDesc("testinsertquery1", "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString("insert overwrite into testinsertquery2.table1 " +
+        "select col1, col2, col3 from testinsertquery1.table1;");
+      res.close();
+    } else {
+      res = executeString("create table testinsertquery2.table1 " +
+        "(col1 int4, col2 int4, col3 float8) as select col1, col2, col3 from testinsertquery1.table1;");
+      res.close();
+    }
+    desc = catalog.getTableDesc("testinsertquery2", "table1");
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    executeString("DROP TABLE testinsertquery1.table1 PURGE").close();
+    executeString("DROP TABLE testinsertquery2.table1 PURGE").close();
+    executeString("DROP DATABASE testinsertquery1").close();
+    executeString("DROP DATABASE testinsertquery2").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableWithSmallerExpressions5() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableWithSmallerExpressions5");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 text) partition by column(col2 text) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString("insert overwrite into " + tableName + "(col1) select l_returnflag from lineitem");
+
+    } else {
+      res = executeString("create table " + tableName + " (col1 text) partition by column(col2 text) " +
+        " as select l_returnflag, null from lineitem");
+    }
+    res.close();
+    res = executeString("select * from " + tableName);
+    assertResultSet(res);
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col2"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  @Test
+  public final void testColumnPartitionedTableWithSmallerExpressions6() throws Exception {
+    ResultSet res = null;
+    String tableName = CatalogUtil.normalizeIdentifier("testColumnPartitionedTableWithSmallerExpressions6");
+
+    if (nodeType == NodeType.INSERT) {
+      res = executeString(
+        "create table " + tableName + " (col1 text) partition by column(col2 text) ");
+      res.close();
+
+      assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+
+      res = executeString(
+        "insert overwrite into " + tableName + "(col1) select l_returnflag from lineitem where l_orderkey = 1");
+    } else {
+      res = executeString( "create table " + tableName + " (col1 text) partition by column(col2 text) " +
+        " as select l_returnflag, null from lineitem where l_orderkey = 1");
+    }
+    res.close();
+
+    res = executeString("select * from " + tableName);
+    assertResultSet(res);
+    res.close();
+
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, tableName, new String[]{"col2"},
+      desc.getStats().getNumRows());
+
+    executeString("DROP TABLE " + tableName + " PURGE").close();
+  }
+
+  private MasterPlan getQueryPlan(ResultSet res) {
+    QueryId queryId;
+    if (res instanceof TajoMemoryResultSet) {
+      queryId = ((TajoMemoryResultSet) res).getQueryId();
+    } else {
+      queryId = ((FetchResultSet) res).getQueryId();
+    }
+
+    for (TajoWorker eachWorker : testingCluster.getTajoWorkers()) {
+      QueryMasterTask queryMasterTask = eachWorker.getWorkerContext().getQueryMaster().getQueryMasterTask(queryId, true);
+      if (queryMasterTask != null) {
+        return queryMasterTask.getQuery().getPlan();
+      }
+    }
+
+    fail("Can't find query from workers" + queryId);
+    return null;
+  }
+
+  @Test
+  public void testScatteredHashShuffle() throws Exception {
+    testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$DIST_QUERY_TABLE_PARTITION_VOLUME.varname, "2");
+    testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.SHUFFLE_HASH_APPENDER_PAGE_VOLUME.varname, "1");
+    try {
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+      tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+      Schema schema = new Schema();
+      schema.addColumn("col1", TajoDataTypes.Type.TEXT);
+      schema.addColumn("col2", TajoDataTypes.Type.TEXT);
+
+      List<String> data = new ArrayList<String>();
+      int totalBytes = 0;
+      Random rand = new Random(System.currentTimeMillis());
+      String col2Data = "Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2" +
+          "Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2" +
+          "Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2Column-2";
+
+      int index = 0;
+      while(true) {
+        int col1RandomValue = 1;
+        String str = col1RandomValue + "|col2-" + index + "-" + col2Data;
+        data.add(str);
+
+        totalBytes += str.getBytes().length;
+
+        if (totalBytes > 4 * 1024 * 1024) {
+          break;
+        }
+        index++;
+      }
+
+      TajoTestingCluster.createTable("testscatteredhashshuffle", schema, tableOptions, data.toArray(new String[]{}), 3);
+      CatalogService catalog = testingCluster.getMaster().getCatalog();
+      assertTrue(catalog.existsTable("default", "testscatteredhashshuffle"));
+
+      if (nodeType == NodeType.INSERT) {
+        executeString("create table test_partition (col2 text) partition by column (col1 text)").close();
+        executeString("insert into test_partition select col2, col1 from testscatteredhashshuffle").close();
+      } else {
+        executeString("create table test_partition (col2 text) PARTITION BY COLUMN (col1 text) AS select col2, " +
+          "col1 from testscatteredhashshuffle").close();
+      }
+
+      ResultSet res = executeString("select col1 from test_partition");
+
+      int numRows = 0;
+      while (res.next()) {
+        numRows++;
+      }
+      assertEquals(data.size(), numRows);
+
+      TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, "test_partition");
+      verifyPartitionDirectoryFromCatalog(DEFAULT_DATABASE_NAME, "test_partition", new String[]{"col1"},
+        desc.getStats().getNumRows());
+
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$DIST_QUERY_TABLE_PARTITION_VOLUME.varname,
+          TajoConf.ConfVars.$DIST_QUERY_TABLE_PARTITION_VOLUME.defaultVal);
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.SHUFFLE_HASH_APPENDER_PAGE_VOLUME.varname,
+          TajoConf.ConfVars.SHUFFLE_HASH_APPENDER_PAGE_VOLUME.defaultVal);
+      executeString("DROP TABLE test_partition PURGE").close();
+      executeString("DROP TABLE testScatteredHashShuffle PURGE").close();
+    }
+  }
+
+  @Test
+  public final void TestSpecialCharPartitionKeys1() throws Exception {
+    // See - TAJO-947: ColPartitionStoreExec can cause URISyntaxException due to special characters.
+
+    executeDDL("lineitemspecial_ddl.sql", "lineitemspecial.tbl");
+
+    if (nodeType == NodeType.INSERT) {
+      executeString("CREATE TABLE IF NOT EXISTS pTable947 (id int, name text) PARTITION BY COLUMN (type text)")
+        .close();
+      executeString("INSERT OVERWRITE INTO pTable947 SELECT l_orderkey, l_shipinstruct, l_shipmode FROM lineitemspecial")
+        .close();
+    } else {
+      executeString("CREATE TABLE IF NOT EXISTS pTable947 (id int, name text) PARTITION BY COLUMN (type text)" +
+        " AS  SELECT l_orderkey, l_shipinstruct, l_shipmode FROM lineitemspecial")
+        .close();
+    }
+
+    ResultSet res = executeString("select * from pTable947 where type='RA:*?><I/L#%S' or type='AIR'");
+
+    String resStr = resultSetToString(res);
+    String expected =
+        "id,name,type\n" +
+            "-------------------------------\n"
+            + "3,NONE,AIR\n"
+            + "3,TEST SPECIAL CHARS,RA:*?><I/L#%S\n";
+
+    assertEquals(expected, resStr);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE pTable947 PURGE").close();
+  }
+
+  @Test
+  public final void TestSpecialCharPartitionKeys2() throws Exception {
+    // See - TAJO-947: ColPartitionStoreExec can cause URISyntaxException due to special characters.
+
+    executeDDL("lineitemspecial_ddl.sql", "lineitemspecial.tbl");
+
+    if (nodeType == NodeType.INSERT) {
+      executeString("CREATE TABLE IF NOT EXISTS pTable948 (id int, name text) PARTITION BY COLUMN (type text)")
+        .close();
+      executeString("INSERT OVERWRITE INTO pTable948 SELECT l_orderkey, l_shipinstruct, l_shipmode FROM lineitemspecial")
+        .close();
+    } else {
+      executeString("CREATE TABLE IF NOT EXISTS pTable948 (id int, name text) PARTITION BY COLUMN (type text)" +
+        " AS SELECT l_orderkey, l_shipinstruct, l_shipmode FROM lineitemspecial")
+        .close();
+    }
+
+    ResultSet res = executeString("select * from pTable948 where type='RA:*?><I/L#%S'");
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    res = executeString("select * from pTable948 where type='RA:*?><I/L#%S' or type='AIR01'");
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE pTable948 PURGE").close();
+  }
+
+  @Test
+  public final void testIgnoreFilesInIntermediateDir() throws Exception {
+    // See - TAJO-1219: Files located in intermediate directories of partitioned table should be ignored
+    // It verifies that Tajo ignores files located in intermediate directories of partitioned table.
+
+    if (nodeType == NodeType.INSERT) {
+      Path testDir = CommonTestingUtil.getTestDir();
+
+      executeString(
+        "CREATE EXTERNAL TABLE testIgnoreFilesInIntermediateDir (col1 int) USING CSV PARTITION BY COLUMN (col2 text) " +
+          "LOCATION '" + testDir + "'");
+
+      FileSystem fs = testDir.getFileSystem(conf);
+      FSDataOutputStream fos = fs.create(new Path(testDir, "table1.data"));
+      fos.write("a|b|c".getBytes());
+      fos.close();
+
+      ResultSet res = executeString("select * from testIgnoreFilesInIntermediateDir;");
+      assertFalse(res.next());
+      res.close();
+    }
+  }
+
+  /**
+   * Verify added partitions to a table. This would check each partition's directory using record of table.
+   *
+   *
+   * @param databaseName
+   * @param tableName
+   * @param partitionColumns
+   * @param numRows
+   * @throws Exception
+   */
+  private void verifyPartitionDirectoryFromCatalog(String databaseName, String tableName,
+                                                   String[] partitionColumns, Long numRows) throws Exception {
+    int rowCount = 0;
+
+    // Get all partition column values
+    StringBuilder query = new StringBuilder();
+    query.append("SELECT");
+    for (int i = 0; i < partitionColumns.length; i++) {
+      String partitionColumn = partitionColumns[i];
+      if (i > 0) {
+        query.append(",");
+      }
+      query.append(" ").append(partitionColumn);
+    }
+    query.append(" FROM ").append(tableName);
+    ResultSet res = executeString(query.toString());
+
+    StringBuilder partitionName = new StringBuilder();
+    PartitionDescProto partitionDescProto = null;
+
+    // Check whether that partition's directory exist or doesn't exist.
+    while(res.next()) {
+      partitionName.delete(0, partitionName.length());
+
+      for (int i = 0; i < partitionColumns.length; i++) {
+        String partitionColumn = partitionColumns[i];
+        if (i > 0) {
+          partitionName.append("/");
+        }
+        partitionName.append(partitionColumn).append("=").append(res.getString(partitionColumn));
+      }
+      partitionDescProto = catalog.getPartition(databaseName, tableName, partitionName.toString());
+      assertNotNull(partitionDescProto);
+      assertTrue(partitionDescProto.getPath().indexOf(tableName + "/" + partitionName.toString()) > 0);
+
+      rowCount++;
+    }
+
+    res.close();
+
+    // Check row count.
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(numRows, new Long(rowCount));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTableSubQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTableSubQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTableSubQuery.java
new file mode 100644
index 0000000..bc643ab
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTableSubQuery.java
@@ -0,0 +1,81 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.junit.Test;
+
+import java.sql.ResultSet;
+
+public class TestTableSubQuery extends QueryTestCaseBase {
+
+  public TestTableSubQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testTableSubquery1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupBySubQuery() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testJoinSubQuery() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testJoinSubQuery2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testGroupbySubqueryWithJson() throws Exception {
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testJoinSubqueryWithJson() throws Exception {
+    /*
+    SELECT
+      A.n_regionkey, B.r_regionkey, A.n_name, B.r_name
+    FROM
+      (SELECT * FROM nation WHERE n_name LIKE 'A%') A
+    JOIN region B ON A.n_regionkey=B.r_regionkey;
+    */
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTruncateTable.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTruncateTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTruncateTable.java
new file mode 100644
index 0000000..3ae0c60
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestTruncateTable.java
@@ -0,0 +1,96 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class TestTruncateTable extends QueryTestCaseBase {
+
+  @Test
+  public final void testTruncateTable() throws Exception {
+    try {
+      ResultSet res = executeFile("table1_ddl.sql");
+      res.close();
+      assertTableExists("truncate_table1");
+
+      res = executeString("select * from truncate_table1");
+      int numRows = 0;
+      while (res.next()) {
+        numRows++;
+      }
+      assertEquals(5, numRows);
+      res.close();
+
+      executeString("truncate table truncate_table1");
+      assertTableExists("truncate_table1");
+
+      res = executeString("select * from truncate_table1");
+      numRows = 0;
+      while (res.next()) {
+        numRows++;
+      }
+      assertEquals(0, numRows);
+      res.close();
+    } finally {
+      executeString("DROP TABLE truncate_table1 PURGE");
+    }
+  }
+
+  @Test
+  public final void testTruncateExternalTable() throws TajoException, SQLException {
+    try {
+      List<String> createdNames = executeDDL("table2_ddl.sql", "truncate_table2", "truncate_table2");
+      assertTableExists(createdNames.get(0));
+
+      ResultSet res = executeString("select * from truncate_table2");
+      int numRows = 0;
+      while (res.next()) {
+        numRows++;
+      }
+      assertEquals(4, numRows);
+      res.close();
+
+      executeString("truncate table truncate_table2");
+      fail("Can't truncate external table");
+    } catch (Exception e) {
+      // succeeded
+      assertTableExists("truncate_table2");
+
+      ResultSet res = executeString("select * from truncate_table2");
+      int numRows = 0;
+      while (res.next()) {
+        numRows++;
+      }
+      assertEquals(4, numRows);
+      res.close();
+    } finally {
+      executeString("DROP TABLE truncate_table2 PURGE");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestUnionQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestUnionQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestUnionQuery.java
new file mode 100644
index 0000000..21500e9
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestUnionQuery.java
@@ -0,0 +1,693 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+
+import static org.junit.Assert.assertEquals;
+
+/*
+ * Notations
+ * - S - select
+ * - SA - select *
+ * - U - union
+ * - G - group by
+ * - O - order by
+ */
+@Category(IntegrationTest.class)
+public class TestUnionQuery extends QueryTestCaseBase {
+
+  public TestUnionQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  /**
+   * S (SA U SA) O
+   */
+  public final void testUnionAll1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S (S U S) O
+   */
+  public final void testUnionAll2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S O ((S G) U (S G))
+   */
+  public final void testUnionAll3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S G (S G)
+   */
+  public final void testUnionAll4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S G (S F G)
+   */
+  public final void testUnionAll5() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S G (SA)
+   */
+  public final void testUnionAll6() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S (SA)
+   */
+  public final void testUnionAll7() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll8() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll9() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll10() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll11() throws Exception {
+    // test filter pushdown
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll12() throws Exception {
+    // test filter pushdown
+    // with stage in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll13() throws Exception {
+    // test filter pushdown
+    // with stage in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll14() throws Exception {
+    // test filter pushdown
+    // with group by stage in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll15() throws Exception {
+    // test filter pushdown
+    // with group by out of union query and join in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAll16() throws Exception {
+    // test filter pushdown
+    // with count distinct out of union query and join in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S (SA U SA) O
+   */
+  public final void testUnion1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S (S U S) O
+   */
+  public final void testUnion2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S O ((S G) U (S G))
+   */
+  public final void testUnion3() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S G (S G)
+   */
+  public final void testUnion4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S G (S F G)
+   */
+  public final void testUnion5() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S G (SA)
+   */
+  public final void testUnion6() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  /**
+   * S (SA)
+   */
+  public final void testUnion7() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion8() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion9() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion10() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion11() throws Exception {
+    // test filter pushdown
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion12() throws Exception {
+    // test filter pushdown
+    // with stage in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion13() throws Exception {
+    // test filter pushdown
+    // with stage in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion14() throws Exception {
+    // test filter pushdown
+    // with group by stage in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion15() throws Exception {
+    // test filter pushdown
+    // with group by out of union query and join in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnion16() throws Exception {
+    // test filter pushdown
+    // with count distinct out of union query and join in union query
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAllWithSameAliasNames() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAllWithDifferentAlias() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionAllWithDifferentAliasAndFunction() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionWithSameAliasNames() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionWithDifferentAlias() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionWithDifferentAliasAndFunction() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLeftUnionWithJoin() throws Exception {
+    // https://issues.apache.org/jira/browse/TAJO-881
+    ResultSet res = executeString(
+        "select * from ( " +
+        "  select a.id, b.c_name, a.code from ( " +
+        "    select l_orderkey as id, 'lineitem' as code from lineitem " +
+        "    union all " +
+        "    select o_orderkey as id, 'order' as code from orders " +
+         "  ) a " +
+         "  join customer b on a.id = b.c_custkey" +
+        ") c order by id, code"
+    );
+
+    String expected =
+        "id,c_name,code\n" +
+            "-------------------------------\n" +
+            "1,Customer#000000001,lineitem\n" +
+            "1,Customer#000000001,lineitem\n" +
+            "1,Customer#000000001,order\n" +
+            "2,Customer#000000002,lineitem\n" +
+            "2,Customer#000000002,order\n" +
+            "3,Customer#000000003,lineitem\n" +
+            "3,Customer#000000003,lineitem\n" +
+            "3,Customer#000000003,order\n";
+
+    assertEquals(expected, resultSetToString(res));
+
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testRightUnionWithJoin() throws Exception {
+    // https://issues.apache.org/jira/browse/TAJO-881
+    ResultSet res = executeString(
+            "select * from ( " +
+            "  select a.id, b.c_name, a.code from customer b " +
+            "  join ( " +
+            "    select l_orderkey as id, 'lineitem' as code from lineitem " +
+            "    union all " +
+            "    select o_orderkey as id, 'order' as code from orders " +
+            "  ) a on a.id = b.c_custkey" +
+            ") c order by id, code"
+    );
+
+    String expected =
+        "id,c_name,code\n" +
+            "-------------------------------\n" +
+            "1,Customer#000000001,lineitem\n" +
+            "1,Customer#000000001,lineitem\n" +
+            "1,Customer#000000001,order\n" +
+            "2,Customer#000000002,lineitem\n" +
+            "2,Customer#000000002,order\n" +
+            "3,Customer#000000003,lineitem\n" +
+            "3,Customer#000000003,lineitem\n" +
+            "3,Customer#000000003,order\n";
+
+    assertEquals(expected, resultSetToString(res));
+
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testAllUnionWithJoin() throws Exception {
+    // https://issues.apache.org/jira/browse/TAJO-881
+    ResultSet res = executeString(
+        "select * from ( " +
+        "  select a.id, a.code as code, b.name, b.code as code2 from ( " +
+        "    select l_orderkey as id, 'lineitem' as code from lineitem " +
+        "    union all " +
+        "    select o_orderkey as id, 'order' as code from orders " +
+        "  ) a " +
+        "  join ( " +
+        "    select c_custkey as id, c_name as name, 'customer' as code from customer " +
+        "    union all " +
+        "    select p_partkey as id, p_name as name, 'part' as code from part " +
+        "  ) b on a.id = b.id" +
+        ") c order by id, code, code2"
+    );
+
+    String expected =
+        "id,code,name,code2\n" +
+            "-------------------------------\n" +
+            "1,lineitem,Customer#000000001,customer\n" +
+            "1,lineitem,Customer#000000001,customer\n" +
+            "1,lineitem,goldenrod lavender spring chocolate lace,part\n" +
+            "1,lineitem,goldenrod lavender spring chocolate lace,part\n" +
+            "1,order,Customer#000000001,customer\n" +
+            "1,order,goldenrod lavender spring chocolate lace,part\n" +
+            "2,lineitem,Customer#000000002,customer\n" +
+            "2,lineitem,blush thistle blue yellow saddle,part\n" +
+            "2,order,Customer#000000002,customer\n" +
+            "2,order,blush thistle blue yellow saddle,part\n" +
+            "3,lineitem,Customer#000000003,customer\n" +
+            "3,lineitem,Customer#000000003,customer\n" +
+            "3,lineitem,spring green yellow purple cornsilk,part\n" +
+            "3,lineitem,spring green yellow purple cornsilk,part\n" +
+            "3,order,Customer#000000003,customer\n" +
+            "3,order,spring green yellow purple cornsilk,part\n";
+
+    assertEquals(expected, resultSetToString(res));
+
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testUnionWithCrossJoin() throws Exception {
+    // https://issues.apache.org/jira/browse/TAJO-881
+    ResultSet res = executeString(
+        "select * from ( " +
+        "  select a.id, b.c_name, a.code from ( " +
+            "    select l_orderkey as id, 'lineitem' as code from lineitem " +
+            "    union all " +
+            "    select o_orderkey as id, 'order' as code from orders " +
+            "  ) a, " +
+            "  customer b " +
+        ") c order by id, code, c_name"
+    );
+
+    String expected =
+        "id,c_name,code\n" +
+            "-------------------------------\n" +
+            "1,Customer#000000001,lineitem\n" +
+            "1,Customer#000000001,lineitem\n" +
+            "1,Customer#000000002,lineitem\n" +
+            "1,Customer#000000002,lineitem\n" +
+            "1,Customer#000000003,lineitem\n" +
+            "1,Customer#000000003,lineitem\n" +
+            "1,Customer#000000004,lineitem\n" +
+            "1,Customer#000000004,lineitem\n" +
+            "1,Customer#000000005,lineitem\n" +
+            "1,Customer#000000005,lineitem\n" +
+            "1,Customer#000000001,order\n" +
+            "1,Customer#000000002,order\n" +
+            "1,Customer#000000003,order\n" +
+            "1,Customer#000000004,order\n" +
+            "1,Customer#000000005,order\n" +
+            "2,Customer#000000001,lineitem\n" +
+            "2,Customer#000000002,lineitem\n" +
+            "2,Customer#000000003,lineitem\n" +
+            "2,Customer#000000004,lineitem\n" +
+            "2,Customer#000000005,lineitem\n" +
+            "2,Customer#000000001,order\n" +
+            "2,Customer#000000002,order\n" +
+            "2,Customer#000000003,order\n" +
+            "2,Customer#000000004,order\n" +
+            "2,Customer#000000005,order\n" +
+            "3,Customer#000000001,lineitem\n" +
+            "3,Customer#000000001,lineitem\n" +
+            "3,Customer#000000002,lineitem\n" +
+            "3,Customer#000000002,lineitem\n" +
+            "3,Customer#000000003,lineitem\n" +
+            "3,Customer#000000003,lineitem\n" +
+            "3,Customer#000000004,lineitem\n" +
+            "3,Customer#000000004,lineitem\n" +
+            "3,Customer#000000005,lineitem\n" +
+            "3,Customer#000000005,lineitem\n" +
+            "3,Customer#000000001,order\n" +
+            "3,Customer#000000002,order\n" +
+            "3,Customer#000000003,order\n" +
+            "3,Customer#000000004,order\n" +
+            "3,Customer#000000005,order\n";
+
+    assertEquals(expected, resultSetToString(res));
+
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testThreeJoinInUnion() throws Exception {
+    // https://issues.apache.org/jira/browse/TAJO-881
+    ResultSet res = executeString(
+      "select orders.o_orderkey \n" +
+          "from orders\n" +
+          "join lineitem on orders.o_orderkey = lineitem.l_orderkey\n" +
+          "join customer on orders.o_custkey =  customer.c_custkey\n" +
+          "union all \n" +
+          "select nation.n_nationkey from nation"
+    );
+    String expected =
+        "o_orderkey\n" +
+            "-------------------------------\n" +
+            "1\n" +
+            "1\n" +
+            "2\n" +
+            "3\n" +
+            "3\n" +
+            "0\n" +
+            "1\n" +
+            "2\n" +
+            "3\n" +
+            "4\n" +
+            "5\n" +
+            "6\n" +
+            "7\n" +
+            "8\n" +
+            "9\n" +
+            "10\n" +
+            "11\n" +
+            "12\n" +
+            "13\n" +
+            "14\n" +
+            "15\n" +
+            "16\n" +
+            "17\n" +
+            "18\n" +
+            "19\n" +
+            "20\n" +
+            "21\n" +
+            "22\n" +
+            "23\n" +
+            "24\n";
+
+    assertEquals(expected, resultSetToString(res));
+
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testUnionCaseOfFirstEmptyAndJoin() throws Exception {
+    ResultSet res = executeString(
+        "select a.c_custkey, b.c_custkey from " +
+            "  (select c_custkey, c_nationkey from customer where c_nationkey < 0 " +
+            "   union all " +
+            "   select c_custkey, c_nationkey from customer where c_nationkey > 0 " +
+            ") a " +
+            "left outer join customer b " +
+            "on a.c_custkey = b.c_custkey "
+    );
+
+    String expected =
+        "c_custkey,c_custkey\n" +
+            "-------------------------------\n" +
+            "1,1\n" +
+            "2,2\n" +
+            "3,3\n" +
+            "4,4\n" +
+            "5,5\n";
+
+    assertEquals(expected, resultSetToString(res));
+    res.close();
+  }
+
+  @Test
+  public void testTajo1368Case1() throws Exception {
+    ResultSet res = executeString(
+        "select * from " +
+            "   (select c_custkey, c_nationkey from customer where c_nationkey < 0 " +
+            "   union all " +
+            "   select c_custkey, c_nationkey from customer where c_nationkey > 0 " +
+            ") a " +
+            "union all " +
+            "select * from " +
+            "   (select c_custkey, c_nationkey from customer where c_nationkey < 0 " +
+            "   union all " +
+            "   select c_custkey, c_nationkey from customer where c_nationkey > 0 " +
+            ") b ");
+
+    String expected = "c_custkey,c_nationkey\n" +
+        "-------------------------------\n" +
+        "1,15\n" +
+        "2,13\n" +
+        "3,1\n" +
+        "4,4\n" +
+        "5,3\n" +
+        "1,15\n" +
+        "2,13\n" +
+        "3,1\n" +
+        "4,4\n" +
+        "5,3\n";
+
+    assertEquals(expected, resultSetToString(res));
+    res.close();
+  }
+
+  @Test
+  public void testTajo1368Case2() throws Exception {
+    ResultSet res = executeString("select * from ( "+
+        "select c_custkey, c_nationkey from ( " +
+        "select c_custkey, c_nationkey from ( " +
+        "select c_custkey, c_nationkey from customer) a " +
+        "union all " +
+        "select c_custkey, c_nationkey from ( " +
+        "select c_custkey, c_nationkey from customer) a " +
+        " ) a " +
+        " ) a ");
+
+    String expected = "c_custkey,c_nationkey\n" +
+        "-------------------------------\n" +
+        "1,15\n" +
+        "2,13\n" +
+        "3,1\n" +
+        "4,4\n" +
+        "5,3\n" +
+        "1,15\n" +
+        "2,13\n" +
+        "3,1\n" +
+        "4,4\n" +
+        "5,3\n";
+
+    assertEquals(expected, resultSetToString(res));
+    res.close();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testComplexUnion1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest
+  public void testComplexUnion2() throws Exception {
+    runSimpleTests();
+  }
+}


[44/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestBuiltinFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestBuiltinFunctions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestBuiltinFunctions.java
new file mode 100644
index 0000000..72fdd6f
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestBuiltinFunctions.java
@@ -0,0 +1,824 @@
+/**
+ * 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.function;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+
+import static org.junit.Assert.assertEquals;
+
+@Category(IntegrationTest.class)
+public class TestBuiltinFunctions extends QueryTestCaseBase {
+
+  public TestBuiltinFunctions() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public void testMaxLong() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testMaxLongWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value", TajoDataTypes.Type.INT8);
+    String[] data = new String[]{ "1|-111", "2|\\N", "3|-333" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select max(value) as max_value from testbuiltin11");
+      String ascExpected = "max_value\n" +
+              "-------------------------------\n" +
+              "-111\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testMinMaxDate() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("value", TajoDataTypes.Type.DATE);
+    String[] data = new String[]{ "2014-01-02", "2014-12-01", "2015-01-01", "1999-08-09", "2000-03-01" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value, max(value) as max_value from testbuiltin11");
+      String ascExpected = "min_value,max_value\n" +
+              "-------------------------------\n" +
+              "1999-08-09,2015-01-01\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testMinMaxDateWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("value", TajoDataTypes.Type.DATE);
+    String[] data = new String[]{ "2014-01-02", "2014-12-01", "\\N", "\\N", "2000-03-01" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value, max(value) as max_value from testbuiltin11");
+      String ascExpected = "min_value,max_value\n" +
+              "-------------------------------\n" +
+              "2000-03-01,2014-12-01\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testMinMaxTime() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("value", TajoDataTypes.Type.TIME);
+    String[] data = new String[]{ "11:11:11", "23:12:50", "00:00:01", "09:59:59", "12:13:14" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value, max(value) as max_value from testbuiltin11");
+      String ascExpected = "min_value,max_value\n" +
+              "-------------------------------\n" +
+              "00:00:01,23:12:50\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testMinMaxTimeWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("value", TajoDataTypes.Type.TIME);
+    String[] data = new String[]{ "11:11:11", "\\N", "\\N", "09:59:59", "12:13:14" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value, max(value) as max_value from testbuiltin11");
+      String ascExpected = "min_value,max_value\n" +
+              "-------------------------------\n" +
+              "09:59:59,12:13:14\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testMinMaxTimestamp() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("value", TajoDataTypes.Type.TIMESTAMP);
+    String[] data = new String[]{ "1999-01-01 11:11:11", "2015-01-01 23:12:50", "2016-12-24 00:00:01", 
+            "1977-05-04 09:59:59", "2002-11-21 12:13:14" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value, max(value) as max_value from testbuiltin11");
+      String ascExpected = "min_value,max_value\n" +
+              "-------------------------------\n" +
+              "1977-05-04 09:59:59,2016-12-24 00:00:01\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testMinMaxTimestampWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("value", TajoDataTypes.Type.TIMESTAMP);
+    String[] data = new String[]{ "1999-01-01 11:11:11", "2015-01-01 23:12:50", "\\N",
+            "\\N", "2002-11-21 12:13:14" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value, max(value) as max_value from testbuiltin11");
+      String ascExpected = "min_value,max_value\n" +
+              "-------------------------------\n" +
+              "1999-01-01 11:11:11,2015-01-01 23:12:50\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testMinLong() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testMinLongWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value", TajoDataTypes.Type.INT8);
+    String[] data = new String[]{ "1|111", "2|\\N", "3|333" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(value) as min_value from testbuiltin11");
+      String ascExpected = "min_value\n" +
+          "-------------------------------\n" +
+          "111\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testMaxString() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testMaxStringWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    String[] data = new String[]{ "1|\\N", "2|\\N", "3|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select max(name) as max_name from testbuiltin11");
+      String ascExpected = "max_name\n" +
+          "-------------------------------\n" +
+          "null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testMinString() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testMinStringWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("name", TajoDataTypes.Type.TEXT);
+    String[] data = new String[]{ "1|def", "2|\\N", "3|abc" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select min(name) as min_name from testbuiltin11");
+      String ascExpected = "min_name\n" +
+          "-------------------------------\n" +
+          "abc\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testCount() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testAvgDouble() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testAvgLong() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testAvgInt() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testAvgLongOverflow() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testAvgWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{ "1|\\N|-111|1.2|-50.5", "2|1|\\N|\\N|52.5", "3|2|-333|2.8|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select avg(value_int) as avg_int, avg(value_long) as avg_long, avg(value_float) as avg_float, avg(value_double) as avg_double from testbuiltin11");
+      String ascExpected = "avg_int,avg_long,avg_float,avg_double\n" +
+          "-------------------------------\n" +
+          "1.5,-222.0,2.0,1.0\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testAvgWithAllNulls() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{ "1|\\N|\\N|\\N|\\N", "2|\\N|\\N|\\N|\\N", "3|\\N|\\N|\\N|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select avg(value_int) as avg_int, avg(value_long) as avg_long, avg(value_float) as avg_float, avg(value_double) as avg_double from testbuiltin11");
+      String ascExpected = "avg_int,avg_long,avg_float,avg_double\n" +
+          "-------------------------------\n" +
+          "null,null,null,null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testSumWithNull() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{ "1|\\N|-111|1.2|-50.5", "2|1|\\N|\\N|52.5", "3|2|-333|2.8|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select sum(value_int) as sum_int, sum(value_long) as sum_long, sum(value_float) as sum_float, sum(value_double) as sum_double from testbuiltin11");
+      String ascExpected = "sum_int,sum_long,sum_float,sum_double\n" +
+          "-------------------------------\n" +
+          "3,-444,4.0,2.0\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testSumWithAllNulls() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{ "1|\\N|\\N|\\N|\\N", "2|\\N|\\N|\\N|\\N", "3|\\N|\\N|\\N|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select sum(value_int) as sum_int, sum(value_long) as sum_long, sum(value_float) as sum_float, sum(value_double) as sum_double from testbuiltin11");
+      String ascExpected = "sum_int,sum_long,sum_float,sum_double\n" +
+          "-------------------------------\n" +
+          "null,null,null,null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testStdDevSamp() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+        "1|\\N|-111|1.2|-50.5",
+        "2|1|\\N|\\N|52.5",
+        "3|2|-333|2.8|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select stddev_samp(value_int) as sdsamp_int, stddev_samp(value_long) as sdsamp_long, stddev_samp(value_float) as sdsamp_float, stddev_samp(value_double) as sdsamp_double from testbuiltin11");
+      String ascExpected = "sdsamp_int,sdsamp_long,sdsamp_float,sdsamp_double\n" +
+          "-------------------------------\n" +
+          "0.7071067811865476,156.97770542341354,1.1313707824635184,72.8319984622144\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testStdDevSampWithFewNumbers() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+        "1|\\N|\\N|\\N|-50.5",
+        "2|1|\\N|\\N|\\N",
+        "3|\\N|\\N|\\N|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select stddev_samp(value_int) as sdsamp_int, stddev_samp(value_long) as sdsamp_long, stddev_samp(value_float) as sdsamp_float, stddev_samp(value_double) as sdsamp_double from testbuiltin11");
+      String ascExpected = "sdsamp_int,sdsamp_long,sdsamp_float,sdsamp_double\n" +
+          "-------------------------------\n" +
+          "null,null,null,null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testStdDevPop() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+        "1|\\N|-111|1.2|-50.5",
+        "2|1|\\N|\\N|52.5",
+        "3|2|-333|2.8|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select stddev_pop(value_int) as sdpop_int, stddev_pop(value_long) as sdpop_long, stddev_pop(value_float) as sdpop_float, stddev_pop(value_double) as sdpop_double from testbuiltin11");
+      String ascExpected = "sdpop_int,sdpop_long,sdpop_float,sdpop_double\n" +
+          "-------------------------------\n" +
+          "0.5,111.0,0.7999999523162842,51.5\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testStdDevPopWithFewNumbers() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+        "1|\\N|\\N|\\N|-50.5",
+        "2|1|\\N|\\N|\\N",
+        "3|\\N|\\N|\\N|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select stddev_pop(value_int) as sdpop_int, stddev_pop(value_long) as sdpop_long, stddev_pop(value_float) as sdpop_float, stddev_pop(value_double) as sdpop_double from testbuiltin11");
+      String ascExpected = "sdpop_int,sdpop_long,sdpop_float,sdpop_double\n" +
+          "-------------------------------\n" +
+          "0.0,null,null,0.0\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+
+  }
+
+  @Test
+  public void testVarSamp() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+            "1|\\N|-111|1.2|-50.5",
+            "2|1|\\N|\\N|52.5",
+            "3|2|-333|2.8|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select var_samp(value_int) as vs_int, var_samp(value_long) as vs_long, var_samp(value_float) as vs_float, var_samp(value_double) as vs_double from testbuiltin11");
+      String ascExpected = "vs_int,vs_long,vs_float,vs_double\n" +
+              "-------------------------------\n" +
+              "0.5,24642.0,1.279999847412114,5304.5\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testVarSampWithFewNumbers() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+            "1|\\N|\\N|\\N|-50.5",
+            "2|1|\\N|\\N|\\N",
+            "3|\\N|\\N|\\N|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select var_samp(value_int) as vsamp_int, var_samp(value_long) as vsamp_long, var_samp(value_float) as vsamp_float, var_samp(value_double) as vsamp_double from testbuiltin11");
+      String ascExpected = "vsamp_int,vsamp_long,vsamp_float,vsamp_double\n" +
+              "-------------------------------\n" +
+              "null,null,null,null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testVarPop() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+            "1|\\N|-111|1.2|-50.5",
+            "2|1|\\N|\\N|52.5",
+            "3|2|-333|2.8|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select var_pop(value_int) as vpop_int, var_pop(value_long) as vpop_long, var_pop(value_float) as vpop_float, var_pop(value_double) as vpop_double from testbuiltin11");
+      String ascExpected = "vpop_int,vpop_long,vpop_float,vpop_double\n" +
+              "-------------------------------\n" +
+              "0.25,12321.0,0.639999923706057,2652.25\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+  @Test
+  public void testVarPopWithFewNumbers() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+            "1|\\N|\\N|\\N|-50.5",
+            "2|1|\\N|\\N|\\N",
+            "3|\\N|\\N|\\N|\\N" };
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select var_pop(value_int) as vpop_int, var_pop(value_long) as vpop_long, var_pop(value_float) as vpop_float, var_pop(value_double) as vpop_double from testbuiltin11");
+      String ascExpected = "vpop_int,vpop_long,vpop_float,vpop_double\n" +
+              "-------------------------------\n" +
+              "0.0,null,null,0.0\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+
+//  @Test
+//  public void testRandom() throws Exception {
+//    ResultSet res = executeQuery();
+//    while(res.next()) {
+//      assertTrue(res.getInt(2) >= 0 && res.getInt(2) < 3);
+//    }
+//    cleanupQuery(res);
+//  }
+
+  @Test
+  public void testSplitPart() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testSplitPartByString() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testSplitPartNested() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+  
+  @Test
+  public void testRankWithTwoTables() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+    
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    String[] data = new String[] {"1", "3", "2", "4"};
+    TajoTestingCluster.createTable("rank_table1", schema, tableOptions, data, 1);
+    schema = new Schema();
+    schema.addColumn("refid", TajoDataTypes.Type.INT4);
+    schema.addColumn("value", TajoDataTypes.Type.TEXT);
+    data = new String[] {"1|efgh", "2|abcd", "4|erjk", "8|dfef"};
+    TajoTestingCluster.createTable("rank_table2", schema, tableOptions, data, 1);
+    ResultSet res = null;
+    
+    try {
+      res = executeString("select rank() over (order by id) from rank_table1 a, rank_table2 b "
+          + " where a.id = b.refid");
+      String expectedString = "?windowfunction\n" +
+          "-------------------------------\n" +
+          "1\n" +
+          "2\n" +
+          "3\n";
+      
+      assertEquals(expectedString, resultSetToString(res));
+    } finally {
+      if (res != null) {
+        try {
+        res.close();
+        } catch(Throwable ignored) {}
+      }
+      executeString("DROP TABLE rank_table1 PURGE");
+      executeString("DROP TABLE rank_table2 PURGE");
+    }
+  }
+
+  @Test
+  public void testCorr() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_int", TajoDataTypes.Type.INT4);
+    schema.addColumn("value_long", TajoDataTypes.Type.INT8);
+    schema.addColumn("value_float", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("value_double", TajoDataTypes.Type.FLOAT8);
+    String[] data = new String[]{
+        "1|\\N|-111|1.2|-50.5",
+        "2|1|\\N|\\N|52.5",
+        "3|2|-333|2.8|\\N",
+        "4|3|-555|2.8|43.2",
+        "5|4|-111|1.1|10.2",};
+    TajoTestingCluster.createTable("testbuiltin11", schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select corr(value_int, value_long) as corr1, corr(value_long, value_float) as corr2, corr(value_float, value_double) as corr3, corr(value_double, value_int) as corr4 from testbuiltin11");
+      String ascExpected = "corr1,corr2,corr3,corr4\n" +
+          "-------------------------------\n" +
+          "0.5,-0.9037045658322675,0.7350290063698216,-0.8761489936497805\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testbuiltin11 PURGE");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
new file mode 100644
index 0000000..c214f66
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
@@ -0,0 +1,242 @@
+/**
+ * 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.function;
+
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.exception.UndefinedFunctionException;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class TestConditionalExpressions extends ExprTestBase {
+  @Test
+  public void testCaseWhens1() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT1);
+    schema.addColumn("col2", TajoDataTypes.Type.INT2);
+    schema.addColumn("col3", TajoDataTypes.Type.INT4);
+    schema.addColumn("col4", TajoDataTypes.Type.INT8);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col6", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col7", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col8", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col9", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case when col1 between 1 and 3 then 10 else 100 end from table1;",
+        new String [] {"10"});
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case when col1 > 1 then 10 when col1 > 2 then 20 else 100 end from table1;",
+        new String [] {"100"});
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case col1 when 1 then 10 when 2 then 20 else 100 end from table1;",
+        new String [] {"10"});
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case col9 when 1 then 10 when 2 then 20 else 100 end is null from table1;",
+        new String [] {"f"});
+  }
+
+  @Test
+  public void testCaseWhensWithNullReturn() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col2", TajoDataTypes.Type.TEXT);
+
+    testEval(schema, "table1", "str1,str2",
+        "SELECT CASE WHEN col1 IS NOT NULL THEN col2 ELSE NULL END FROM table1",
+        new String[]{"str2"});
+    testEval(schema, "table1", ",str2",
+        "SELECT CASE WHEN col1 IS NOT NULL THEN col2 ELSE NULL END FROM table1",
+        new String[]{""});
+  }
+
+  @Test
+  public void testCaseWhensWithCommonExpression() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE WHEN col1 = 1 THEN 1 WHEN col1 = 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"1"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE WHEN col2 = 1 THEN 1 WHEN col2 = 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE WHEN col3 = 1 THEN 1 WHEN col3 = 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"3"});
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"1"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"3"});
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN 'aaa' WHEN 2 THEN 'bbb' ELSE 'ccc' END FROM table1",
+        new String [] {"aaa"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN 'aaa' WHEN 2 THEN 'bbb' ELSE 'ccc' END FROM table1",
+        new String [] {"bbb"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN 'aaa' WHEN 2 THEN 'bbb' ELSE 'ccc' END FROM table1",
+        new String [] {"ccc"});
+  }
+
+  @Test
+  public void testCaseWhensWithCommonExpressionAndNull() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {""});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"3"});
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE NULL END FROM table1",
+        new String [] {"1"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE NULL END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE NULL END FROM table1",
+        new String [] {""});
+  }
+
+  @Test
+  public void testCoalesceText() throws Exception {
+    testSimpleEval("select coalesce('value1', 'value2');", new String[]{"value1"});
+    testSimpleEval("select coalesce(null, 'value2');", new String[]{"value2"});
+    testSimpleEval("select coalesce(null, null, 'value3');", new String[]{"value3"});
+    testSimpleEval("select coalesce('value1', null, 'value3');", new String[]{"value1"});
+    testSimpleEval("select coalesce(null, 'value2', 'value3');", new String[]{"value2"});
+    testSimpleEval("select coalesce('value1');", new String[]{"value1"});
+    testSimpleEval("select coalesce(null);", new String[]{""});
+
+    //no matched function
+    try {
+      testSimpleEval("select coalesce(null, 2, 'value3');", new String[]{"2"});
+      fail("coalesce(NULL, INT, TEXT) not defined. So should throw exception.");
+    } catch (UndefinedFunctionException e) {
+      //success
+    }
+  }
+
+  @Test
+  public void testCoalesceLong() throws Exception {
+    testSimpleEval("select coalesce(1, 2);", new String[]{"1"});
+    testSimpleEval("select coalesce(null, 2);", new String[]{"2"});
+    testSimpleEval("select coalesce(null, null, 3);", new String[]{"3"});
+    testSimpleEval("select coalesce(1, null, 3);", new String[]{"1"});
+    testSimpleEval("select coalesce(null, 2, 3);", new String[]{"2"});
+    testSimpleEval("select coalesce(1);", new String[]{"1"});
+    testSimpleEval("select coalesce(null);", new String[]{""});
+
+    //no matched function
+    try {
+      testSimpleEval("select coalesce(null, 'value2', 3);", new String[]{"2"});
+      fail("coalesce(NULL, TEXT, INT) not defined. So should throw exception.");
+    } catch (UndefinedFunctionException e) {
+      //success
+    }
+  }
+
+  @Test
+  public void testCoalesceDouble() throws Exception {
+    testSimpleEval("select coalesce(1.0, 2.0);", new String[]{"1.0"});
+    testSimpleEval("select coalesce(null, 2.0);", new String[]{"2.0"});
+    testSimpleEval("select coalesce(null, null, 3.0);", new String[]{"3.0"});
+    testSimpleEval("select coalesce(1.0, null, 3.0);", new String[]{"1.0"});
+    testSimpleEval("select coalesce(null, 2.0, 3.0);", new String[]{"2.0"});
+    testSimpleEval("select coalesce(1.0);", new String[]{"1.0"});
+    testSimpleEval("select coalesce(null);", new String[]{""});
+
+    //no matched function
+    try {
+      testSimpleEval("select coalesce('value1', null, 3.0);", new String[]{"1.0"});
+      fail("coalesce(TEXT, NULL, FLOAT8) not defined. So should throw exception.");
+    } catch (UndefinedFunctionException e) {
+      // success
+    }
+
+    try {
+      testSimpleEval("select coalesce(null, 'value2', 3.0);", new String[]{"2.0"});
+      fail("coalesce(NULL, TEXT, FLOAT8) not defined. So should throw exception.");
+    } catch (UndefinedFunctionException e) {
+      //success
+    }
+  }
+
+  @Test
+  public void testCoalesceBoolean() throws Exception {
+    testSimpleEval("select coalesce(null, false);", new String[]{"f"});
+    testSimpleEval("select coalesce(null, null, true);", new String[]{"t"});
+    testSimpleEval("select coalesce(true, null, false);", new String[]{"t"});
+    testSimpleEval("select coalesce(null, true, false);", new String[]{"t"});
+ }
+
+  @Test
+  public void testCoalesceTimestamp() throws Exception {
+    testSimpleEval("select coalesce(null, timestamp '2014-01-01 00:00:00');",
+        new String[]{"2014-01-01 00:00:00"});
+    testSimpleEval("select coalesce(null, null, timestamp '2014-01-01 00:00:00');",
+        new String[]{"2014-01-01 00:00:00"});
+    testSimpleEval("select coalesce(timestamp '2014-01-01 00:00:00', null, timestamp '2014-01-02 00:00:00');",
+        new String[]{"2014-01-01 00:00:00"});
+    testSimpleEval("select coalesce(null, timestamp '2014-01-01 00:00:00', timestamp '2014-02-01 00:00:00');",
+        new String[]{"2014-01-01 00:00:00"});
+  }
+
+  @Test
+  public void testCoalesceTime() throws Exception {
+    testSimpleEval("select coalesce(null, time '12:00:00');",
+        new String[]{"12:00:00"});
+    testSimpleEval("select coalesce(null, null, time '12:00:00');",
+        new String[]{"12:00:00"});
+    testSimpleEval("select coalesce(time '12:00:00', null, time '13:00:00');",
+        new String[]{"12:00:00"});
+    testSimpleEval("select coalesce(null, time '12:00:00', time '13:00:00');",
+        new String[]{"12:00:00"});
+  }
+
+  @Test
+  public void testCoalesceDate() throws Exception {
+    testSimpleEval("select coalesce(null, date '2014-01-01');", new String[]{"2014-01-01"});
+    testSimpleEval("select coalesce(null, null, date '2014-01-01');", new String[]{"2014-01-01"});
+    testSimpleEval("select coalesce(date '2014-01-01', null, date '2014-02-01');", new String[]{"2014-01-01"});
+    testSimpleEval("select coalesce(null, date '2014-01-01', date '2014-02-01');", new String[]{"2014-01-01"});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java
new file mode 100644
index 0000000..9dd8653
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java
@@ -0,0 +1,483 @@
+/**
+ * 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.function;
+
+
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.TimestampDatum;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
+import org.junit.Test;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
+
+public class TestDateTimeFunctions extends ExprTestBase {
+  @Test
+  public void testToTimestamp() throws TajoException {
+    long expectedTimestamp = System.currentTimeMillis();
+    TimestampDatum expected = DatumFactory.createTimestmpDatumWithUnixTime((int)(expectedTimestamp/ 1000));
+
+    // (expectedTimestamp / 1000) means the translation from millis seconds to unix timestamp
+    String q1 = String.format("select to_timestamp(%d);", (expectedTimestamp / 1000));
+    testSimpleEval(q1, new String[]{expected.toString()});
+
+    testSimpleEval("select to_timestamp('1997-12-30 11:40:50.345', 'YYYY-MM-DD HH24:MI:SS.MS');",
+        new String[]{"1997-12-30 11:40:50.345"});
+    testSimpleEval("select to_timestamp('1997-12-30 11:40:50.345 PM', 'YYYY-MM-DD HH24:MI:SS.MS PM');",
+        new String[]{"1997-12-30 23:40:50.345"});
+    testSimpleEval("select to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');",
+        new String[]{"0097-02-16 08:14:30"});
+    testSimpleEval("select to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS');",
+        new String[]{"0097-02-16 08:14:30"});
+    testSimpleEval("select to_timestamp('1985 September 12', 'YYYY FMMonth DD');",
+        new String[]{"1985-09-12 00:00:00"});
+    testSimpleEval("select to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD');",
+        new String[]{"1582-08-21 00:00:00"});
+    testSimpleEval("select to_timestamp('05121445482000', 'MMDDHH24MISSYYYY');",
+        new String[]{"2000-05-12 14:45:48"});
+    testSimpleEval("select to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay');",
+        new String[]{"2000-01-09 00:00:00"});
+    testSimpleEval("select to_timestamp('97/Feb/16', 'YY/Mon/DD');",
+        new String[]{"1997-02-16 00:00:00"});
+    testSimpleEval("select to_timestamp('19971116', 'YYYYMMDD');",
+        new String[]{"1997-11-16 00:00:00"});
+    testSimpleEval("select to_timestamp('20000-1116', 'YYYY-MMDD');",
+        new String[]{"20000-11-16 00:00:00"});
+    testSimpleEval("select to_timestamp('9-1116', 'Y-MMDD');",
+        new String[]{"2009-11-16 00:00:00"});
+    testSimpleEval("select to_timestamp('95-1116', 'YY-MMDD');",
+        new String[]{"1995-11-16 00:00:00"});
+    testSimpleEval("select to_timestamp('995-1116', 'YYY-MMDD');",
+        new String[]{"1995-11-16 00:00:00"});
+    testSimpleEval("select to_timestamp('2005426', 'YYYYWWD');",
+        new String[]{"2005-10-15 00:00:00"});
+    testSimpleEval("select to_timestamp('2005300', 'YYYYDDD');",
+        new String[]{"2005-10-27 00:00:00"});
+    testSimpleEval("select to_timestamp('2005527', 'IYYYIWID');",
+        new String[]{"2006-01-01 00:00:00"});
+    testSimpleEval("select to_timestamp('005527', 'IYYIWID');",
+        new String[]{"2006-01-01 00:00:00"});
+    testSimpleEval("select to_timestamp('05527', 'IYIWID');",
+        new String[]{"2006-01-01 00:00:00"});
+    testSimpleEval("select to_timestamp('5527', 'IIWID');",
+        new String[]{"2006-01-01 00:00:00"});
+    testSimpleEval("select to_timestamp('2005364', 'IYYYIDDD');",
+        new String[]{"2006-01-01 00:00:00"});
+    testSimpleEval("select to_timestamp('20050302', 'YYYYMMDD');",
+        new String[]{"2005-03-02 00:00:00"});
+    testSimpleEval("select to_timestamp('2005 03 02', 'YYYYMMDD');",
+        new String[]{"2005-03-02 00:00:00"});
+    testSimpleEval("select to_timestamp(' 2005 03 02', 'YYYYMMDD');",
+        new String[]{"2005-03-02 00:00:00"});
+    testSimpleEval("select to_timestamp('  20050302', 'YYYYMMDD');",
+        new String[]{"2005-03-02 00:00:00"});
+  }
+
+  @Test
+  public void testToChar() throws TajoException {
+    long expectedTimestamp = System.currentTimeMillis();
+    TimeMeta tm = new TimeMeta();
+    DateTimeUtil.toJulianTimeMeta(DateTimeUtil.javaTimeToJulianTime(expectedTimestamp), tm);
+    // (expectedTimestamp / 1000) means the translation from millis seconds to unix timestamp
+    String q = String.format("select to_char(to_timestamp(%d), 'yyyy-MM');", (expectedTimestamp / 1000));
+    testSimpleEval(q, new String[]{String.format("%04d-%02d", tm.years, tm.monthOfYear)});
+
+    q = "select to_char(to_timestamp('1997-12-30 11:40:00', 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')";
+    testSimpleEval(q, new String[]{"1997-12-30 11:40:00"});
+
+    q = "select to_char(to_timestamp('1997-12-30 00:00:00', 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')";
+    testSimpleEval(q, new String[]{"1997-12-30 00:00:00"});
+  }
+
+  @Test
+  public void testExtract() throws TajoException {
+    TimeZone GMT = TimeZone.getTimeZone("GMT");
+    TimeZone PST = TimeZone.getTimeZone("PST");
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", TIMESTAMP);
+    testEval(schema2, "table1",
+        "1970-01-17 10:09:37",
+        "select extract(year from col1), extract(month from col1), extract(day from col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+    testEval(schema2, "table1",
+        "1970-01-17 10:09:37" + getUserTimeZoneDisplay(GMT),
+        "select extract(year from col1), extract(month from col1), extract(day from col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+    testEval(schema2, "table1",
+        "1970-01-17 10:09:37" + getUserTimeZoneDisplay(PST),
+        "select extract(year from col1), extract(month from col1), extract(day from col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+
+    // Currently TIME type can be loaded with INT8 type.
+    Schema schema3 = new Schema();
+    schema3.addColumn("col1", TIME);
+    testEval(schema3, "table1",
+        "10:09:37.5",
+        "select extract(hour from col1), extract(minute from col1), extract(second from col1) from table1;",
+        new String[]{"10.0", "9.0", "37.5"});
+    testEval(schema3, "table1",
+        "10:09:37.5" + getUserTimeZoneDisplay(GMT),
+        "select extract(hour from col1), extract(minute from col1), extract(second from col1) from table1;",
+        new String[]{"10.0", "9.0", "37.5"});
+    testEval(schema3, "table1",
+        "10:09:37.5" + getUserTimeZoneDisplay(PST),
+        "select extract(hour from col1), extract(minute from col1), extract(second from col1) from table1;",
+        new String[]{"18.0", "9.0", "37.5"});
+
+    Schema schema4 = new Schema();
+    schema4.addColumn("col1", DATE);
+    testEval(schema4, "table1",
+        "1970-01-17",
+        "select extract(year from col1), extract(month from col1), extract(day from col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+
+    testSimpleEval("select extract(century from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"20.0"});
+
+    testSimpleEval("select extract(century from DATE '1970-01-17');", new String[]{"20.0"});
+
+    testSimpleEval("select extract(decade from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"197.0"});
+
+    testSimpleEval("select extract(decade from DATE '1970-01-17');", new String[]{"197.0"});
+
+    testSimpleEval("select extract(millennium from TIMESTAMP '2001-02-16 10:09:37');", new String[]{"3.0"});
+    testSimpleEval("select extract(millennium from TIMESTAMP '2000-02-16 10:09:37');", new String[]{"2.0"});
+
+    testSimpleEval("select extract(millennium from DATE '2001-02-16');", new String[]{"3.0"});
+    testSimpleEval("select extract(millennium from DATE '2000-02-16');", new String[]{"2.0"});
+
+    testSimpleEval("select extract(year from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"1970.0"});
+    testSimpleEval("select extract(month from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"1.0"});
+    testSimpleEval("select extract(day from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"17.0"});
+
+    testSimpleEval("select extract(hour from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"10.0"});
+    testSimpleEval("select extract(minute from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"9.0"});
+    testSimpleEval("select extract(second from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"37.0"});
+    testSimpleEval("select extract(second from TIMESTAMP '1970-01-17 10:09:37.5');", new String[]{"37.5"});
+
+    testSimpleEval("select extract(hour from TIME '10:09:37');", new String[]{"10.0"});
+    testSimpleEval("select extract(minute from TIME '10:09:37');", new String[]{"9.0"});
+    testSimpleEval("select extract(second from TIME '10:09:37');", new String[]{"37.0"});
+    testSimpleEval("select extract(second from TIME '10:09:37.5');", new String[]{"37.5"});
+
+    testSimpleEval("select extract(year from DATE '1970-01-17');", new String[]{"1970.0"});
+    testSimpleEval("select extract(month from DATE '1970-01-17');", new String[]{"1.0"});
+    testSimpleEval("select extract(day from DATE '1970-01-17');", new String[]{"17.0"});
+
+    testSimpleEval("select extract(milliseconds from TIMESTAMP '1970-01-17 10:09:37.5');", new String[]{"37500.0"});
+    testSimpleEval("select extract(milliseconds from TIME '10:09:37.123');", new String[]{"37123.0"});
+
+    testSimpleEval("select extract(microseconds from TIMESTAMP '1970-01-17 10:09:37.5');", new String[]{"3.75E7"});
+    testSimpleEval("select extract(microseconds from TIME '10:09:37.123');", new String[]{"3.7123E7"});
+
+    testSimpleEval("select extract(dow from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"6.0"});
+    testSimpleEval("select extract(dow from TIMESTAMP '1970-01-18 10:09:37');", new String[]{"0.0"});
+    testSimpleEval("select extract(isodow from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"6.0"});
+    testSimpleEval("select extract(isodow from TIMESTAMP '1970-01-18 10:09:37');", new String[]{"7.0"});
+
+    testSimpleEval("select extract(year from TIMESTAMP '2006-01-02 10:09:37');", new String[]{"2006.0"});
+    testSimpleEval("select extract(year from TIMESTAMP '2006-01-01 10:09:37');", new String[]{"2006.0"});
+    testSimpleEval("select extract(isoyear from TIMESTAMP '2006-01-02 10:09:37');", new String[]{"2006.0"});
+    testSimpleEval("select extract(isoyear from TIMESTAMP '2006-01-01 10:09:37');", new String[]{"2005.0"});
+
+    testSimpleEval("select extract(quarter from TIMESTAMP '2006-02-01 10:09:37');", new String[]{"1.0"});
+    testSimpleEval("select extract(quarter from TIMESTAMP '2006-04-01 10:09:37');", new String[]{"2.0"});
+    testSimpleEval("select extract(quarter from TIMESTAMP '2006-07-01 10:09:37');", new String[]{"3.0"});
+    testSimpleEval("select extract(quarter from TIMESTAMP '2006-12-01 10:09:37');", new String[]{"4.0"});
+
+    testSimpleEval("select extract(week from TIMESTAMP '1970-01-17 10:09:37');", new String[]{"3.0"});
+
+    testSimpleEval("select extract(dow from DATE '1970-01-17');", new String[]{"6.0"});
+    testSimpleEval("select extract(dow from DATE '1970-01-18');", new String[]{"0.0"});
+    testSimpleEval("select extract(isodow from DATE '1970-01-17');", new String[]{"6.0"});
+    testSimpleEval("select extract(isodow from DATE '1970-01-18');", new String[]{"7.0"});
+
+    testSimpleEval("select extract(year from DATE '2006-01-02');", new String[]{"2006.0"});
+    testSimpleEval("select extract(year from DATE '2006-01-01');", new String[]{"2006.0"});
+    testSimpleEval("select extract(isoyear from DATE '2006-01-02');", new String[]{"2006.0"});
+    testSimpleEval("select extract(isoyear from DATE '2006-01-01');", new String[]{"2005.0"});
+
+    testSimpleEval("select extract(quarter from DATE '2006-02-01');", new String[]{"1.0"});
+    testSimpleEval("select extract(quarter from DATE '2006-04-01');", new String[]{"2.0"});
+    testSimpleEval("select extract(quarter from DATE '2006-07-01');", new String[]{"3.0"});
+    testSimpleEval("select extract(quarter from DATE '2006-12-01');", new String[]{"4.0"});
+
+    testSimpleEval("select extract(week from DATE '1970-01-17');", new String[]{"3.0"});
+  }
+
+  @Test
+  public void testDatePart() throws TajoException {
+    TimeZone GMT = TimeZone.getTimeZone("GMT");
+    TimeZone PST = TimeZone.getTimeZone("PST");
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("col1", TIMESTAMP);
+
+    testEval(schema2, "table1",
+        "1970-01-17 22:09:37",
+        "select date_part('year', col1), date_part('month', col1), date_part('day', col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+    testEval(schema2, "table1",
+        "1970-01-17 22:09:37" + getUserTimeZoneDisplay(GMT),
+        "select date_part('year', col1), date_part('month', col1), date_part('day', col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+    testEval(schema2, "table1",
+        "1970-01-17 22:09:37" + getUserTimeZoneDisplay(PST),
+        "select date_part('year', col1), date_part('month', col1), date_part('day', col1) from table1;",
+        new String[]{"1970.0", "1.0", "18.0"});
+
+    Schema schema3 = new Schema();
+    schema3.addColumn("col1", TIME);
+    testEval(schema3, "table1", "10:09:37.5",
+        "select date_part('hour', col1), date_part('minute', col1), date_part('second', col1) from table1;",
+        new String[]{"10.0", "9.0", "37.5"});
+    testEval(schema3, "table1", "10:09:37.5" + getUserTimeZoneDisplay(GMT),
+        "select date_part('hour', col1), date_part('minute', col1), date_part('second', col1) from table1;",
+        new String[]{"10.0", "9.0", "37.5"});
+    testEval(schema3, "table1", "10:09:37.5" + getUserTimeZoneDisplay(PST),
+        "select date_part('hour', col1), date_part('minute', col1), date_part('second', col1) from table1;",
+        new String[]{"18.0", "9.0", "37.5"});
+
+    Schema schema4 = new Schema();
+    schema4.addColumn("col1", DATE);
+    testEval(schema4, "table1",
+        "1970-01-17",
+        "select date_part('year', col1), date_part('month', col1), date_part('day', col1) from table1;",
+        new String[]{"1970.0", "1.0", "17.0"});
+
+    testSimpleEval("select date_part('century', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"20.0"});
+
+    testSimpleEval("select date_part('century', DATE '1970-01-17');", new String[]{"20.0"});
+
+    testSimpleEval("select date_part('decade', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"197.0"});
+
+    testSimpleEval("select date_part('decade', DATE '1970-01-17');", new String[]{"197.0"});
+
+    testSimpleEval("select date_part('millennium', TIMESTAMP '2001-02-16 10:09:37');", new String[]{"3.0"});
+    testSimpleEval("select date_part('millennium', TIMESTAMP '2000-02-16 10:09:37');", new String[]{"2.0"});
+
+    testSimpleEval("select date_part('millennium', DATE '2001-02-16');", new String[]{"3.0"});
+    testSimpleEval("select date_part('millennium', DATE '2000-02-16');", new String[]{"2.0"});
+
+    testSimpleEval("select date_part('year', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"1970.0"});
+    testSimpleEval("select date_part('month', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"1.0"});
+    testSimpleEval("select date_part('day', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"17.0"});
+
+    testSimpleEval("select date_part('hour', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"10.0"});
+    testSimpleEval("select date_part('minute', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"9.0"});
+    testSimpleEval("select date_part('second', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"37.0"});
+    testSimpleEval("select date_part('second', TIMESTAMP '1970-01-17 10:09:37.5');", new String[]{"37.5"});
+
+    testSimpleEval("select date_part('hour', TIME '10:09:37');", new String[]{"10.0"});
+    testSimpleEval("select date_part('minute', TIME '10:09:37');", new String[]{"9.0"});
+    testSimpleEval("select date_part('second', TIME '10:09:37');", new String[]{"37.0"});
+    testSimpleEval("select date_part('second', TIME '10:09:37.5');", new String[]{"37.5"});
+
+    testSimpleEval("select date_part('year', DATE '1970-01-17');", new String[]{"1970.0"});
+    testSimpleEval("select date_part('month', DATE '1970-01-17');", new String[]{"1.0"});
+    testSimpleEval("select date_part('day', DATE '1970-01-17');", new String[]{"17.0"});
+
+    testSimpleEval("select date_part('milliseconds', TIMESTAMP '1970-01-17 10:09:37.5');", new String[]{"37500.0"});
+    testSimpleEval("select date_part('milliseconds', TIME '10:09:37.123');", new String[]{"37123.0"});
+
+    testSimpleEval("select date_part('microseconds', TIMESTAMP '1970-01-17 10:09:37.5');", new String[]{"3.75E7"});
+    testSimpleEval("select date_part('microseconds', TIME '10:09:37.123');", new String[]{"3.7123E7"});
+
+    testSimpleEval("select date_part('dow', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"6.0"});
+    testSimpleEval("select date_part('dow', TIMESTAMP '1970-01-18 10:09:37');", new String[]{"0.0"});
+    testSimpleEval("select date_part('isodow', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"6.0"});
+    testSimpleEval("select date_part('isodow', TIMESTAMP '1970-01-18 10:09:37');", new String[]{"7.0"});
+
+    testSimpleEval("select date_part('year', TIMESTAMP '2006-01-02 10:09:37');", new String[]{"2006.0"});
+    testSimpleEval("select date_part('year', TIMESTAMP '2006-01-01 10:09:37');", new String[]{"2006.0"});
+    testSimpleEval("select date_part('isoyear', TIMESTAMP '2006-01-02 10:09:37');", new String[]{"2006.0"});
+    testSimpleEval("select date_part('isoyear', TIMESTAMP '2006-01-01 10:09:37');", new String[]{"2005.0"});
+
+    testSimpleEval("select date_part('quarter', TIMESTAMP '2006-02-01 10:09:37');", new String[]{"1.0"});
+    testSimpleEval("select date_part('quarter', TIMESTAMP '2006-04-01 10:09:37');", new String[]{"2.0"});
+    testSimpleEval("select date_part('quarter', TIMESTAMP '2006-07-01 10:09:37');", new String[]{"3.0"});
+    testSimpleEval("select date_part('quarter', TIMESTAMP '2006-12-01 10:09:37');", new String[]{"4.0"});
+
+    testSimpleEval("select date_part('week', TIMESTAMP '1970-01-17 10:09:37');", new String[]{"3.0"});
+
+    testSimpleEval("select date_part('dow', DATE '1970-01-17');", new String[]{"6.0"});
+    testSimpleEval("select date_part('dow', DATE '1970-01-18');", new String[]{"0.0"});
+    testSimpleEval("select date_part('isodow', DATE '1970-01-17');", new String[]{"6.0"});
+    testSimpleEval("select date_part('isodow', DATE '1970-01-18');", new String[]{"7.0"});
+
+    testSimpleEval("select date_part('year', DATE '2006-01-02');", new String[]{"2006.0"});
+    testSimpleEval("select date_part('year', DATE '2006-01-01');", new String[]{"2006.0"});
+    testSimpleEval("select date_part('isoyear', DATE '2006-01-02');", new String[]{"2006.0"});
+    testSimpleEval("select date_part('isoyear', DATE '2006-01-01');", new String[]{"2005.0"});
+
+    testSimpleEval("select date_part('quarter', DATE '2006-02-01');", new String[]{"1.0"});
+    testSimpleEval("select date_part('quarter', DATE '2006-04-01');", new String[]{"2.0"});
+    testSimpleEval("select date_part('quarter', DATE '2006-07-01');", new String[]{"3.0"});
+    testSimpleEval("select date_part('quarter', DATE '2006-12-01');", new String[]{"4.0"});
+
+    testSimpleEval("select date_part('week', DATE '1970-01-17');", new String[]{"3.0"});
+  }
+
+  @Test
+  public void testUtcUsecTo() throws TajoException {
+     testSimpleEval("select utc_usec_to('day' ,1274259481071200);", new String[]{1274227200000000L+""});
+     testSimpleEval("select utc_usec_to('hour' ,1274259481071200);", new String[]{1274256000000000L+""});
+     testSimpleEval("select utc_usec_to('month' ,1274259481071200);", new String[]{1272672000000000L+""});
+     testSimpleEval("select utc_usec_to('year' ,1274259481071200);", new String[]{1262304000000000L+""});
+     testSimpleEval("select utc_usec_to('week' ,1207929480000000, 2);", new String[]{1207612800000000L+""});
+  }
+
+  @Test
+  public void testToDate() throws TajoException {
+    testSimpleEval("select to_date('2014-01-04', 'YYYY-MM-DD')", new String[]{"2014-01-04"});
+    testSimpleEval("select to_date('2014-01-04', 'YYYY-MM-DD') + interval '1 day'",
+        new String[]{"2014-01-05 00:00:00"});
+
+    testSimpleEval("SELECT to_date('201404', 'yyyymm');", new String[]{"2014-04-01"});
+  }
+
+  @Test
+  public void testAddMonths() throws Exception {
+    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT2);",
+        new String[]{"2014-02-17 00:00:00"});
+    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT4);",
+        new String[]{"2014-02-17 00:00:00"});
+    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT8);",
+        new String[]{"2014-02-17 00:00:00"});
+
+    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT2);",
+        new String[]{"2014-02-17 12:10:20"});
+    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT4);",
+        new String[]{"2014-02-17 12:10:20"});
+    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT8);",
+        new String[]{"2014-02-17 12:10:20"});
+
+    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT2);",
+        new String[]{"2013-11-05 00:00:00"});
+    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT4);",
+        new String[]{"2013-11-05 00:00:00"});
+    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT8);",
+        new String[]{"2013-11-05 00:00:00"});
+
+    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT2);",
+        new String[]{"2013-11-05 12:10:20"});
+    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT4);",
+        new String[]{"2013-11-05 12:10:20"});
+    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT8);",
+        new String[]{"2013-11-05 12:10:20"});
+  }
+
+  @Test
+  public void testAddDays() throws TajoException {
+    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT2);",
+        new String[]{"2014-01-04 00:00:00"});
+    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT4);",
+        new String[]{"2014-01-04 00:00:00"});
+    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT8);",
+        new String[]{"2014-01-04 00:00:00"});
+
+    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT2);",
+        new String[]{"2014-01-04 12:10:20"});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT4);",
+        new String[]{"2014-01-04 12:10:20"});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT8);",
+        new String[]{"2014-01-04 12:10:20"});
+
+    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT2);",
+        new String[]{"2013-11-28 00:00:00"});
+    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT4);",
+        new String[]{"2013-11-28 00:00:00"});
+    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT8);",
+        new String[]{"2013-11-28 00:00:00"});
+
+    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT2);",
+        new String[]{"2013-11-28 12:10:20"});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT4);",
+        new String[]{"2013-11-28 12:10:20"});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT8);",
+        new String[]{"2013-11-28 12:10:20"});
+  }
+
+  @Test
+  public void testDateTimeNow() throws TajoException {
+    TimeZone originalTimezone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("GMT-6"));
+
+    QueryContext context = new QueryContext(getConf());
+    context.put(SessionVars.TIMEZONE, "GMT-6");
+
+    try {
+      Date expectedDate = new Date(System.currentTimeMillis());
+
+      testSimpleEval(context, "select to_char(now(), 'yyyy-MM-dd');",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+      testSimpleEval(context, "select cast(extract(year from now()) as INT4);",
+          new String[]{dateFormat(expectedDate, "yyyy")});
+      testSimpleEval(context, "select current_date();",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+      testSimpleEval(context, "select cast(extract(hour from current_time()) as INT4);",
+          new String[]{String.valueOf(Integer.parseInt(dateFormat(expectedDate, "HH")))});
+
+      expectedDate.setDate(expectedDate.getDate() + 1);
+
+      testSimpleEval(context, "select current_date() + 1;",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+    } finally {
+      TimeZone.setDefault(originalTimezone);
+    }
+  }
+
+  @Test
+  public void testTimeValueKeyword() throws TajoException {
+    TimeZone originTimeZone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("GMT-6"));
+
+    QueryContext context = new QueryContext(getConf());
+    context.put(SessionVars.TIMEZONE, "GMT-6");
+
+    try {
+      Date expectedDate = new Date(System.currentTimeMillis());
+
+      testSimpleEval(context, "select to_char(current_timestamp, 'yyyy-MM-dd');",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+      testSimpleEval(context, "select cast(extract(year from current_timestamp) as INT4);",
+          new String[]{dateFormat(expectedDate, "yyyy")});
+      testSimpleEval(context, "select current_date;",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+      testSimpleEval(context, "select cast(extract(hour from current_time) as INT4);",
+          new String[]{String.valueOf(Integer.parseInt(dateFormat(expectedDate, "HH")))});
+    } finally {
+      TimeZone.setDefault(originTimeZone);
+    }
+  }
+
+  private String dateFormat(Date date, String format) {
+    SimpleDateFormat df = new SimpleDateFormat(format);
+    return df.format(date);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
new file mode 100644
index 0000000..cf34c33
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
@@ -0,0 +1,45 @@
+/***
+ * 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.function;
+
+import com.google.common.collect.Lists;
+import org.apache.tajo.catalog.FunctionDesc;
+import org.apache.tajo.util.StringUtils;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import static org.apache.tajo.LocalTajoTestingUtility.getResultText;
+import static org.junit.Assert.assertEquals;
+
+
+public class TestFunctionLoader {
+
+  @Test
+  public void testFindScalarFunctions() throws IOException {
+    List<FunctionDesc> collections = Lists.newArrayList(FunctionLoader.findScalarFunctions());
+    Collections.sort(collections);
+    String functionList = StringUtils.join(collections, "\n");
+
+    String result = getResultText(TestFunctionLoader.class, "testFindScalarFunctions.result");
+    assertEquals(result.trim(), functionList.trim());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestGeneralFunction.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestGeneralFunction.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestGeneralFunction.java
new file mode 100644
index 0000000..81ddba5
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestGeneralFunction.java
@@ -0,0 +1,49 @@
+/**
+ * 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.function;
+
+import org.junit.Test;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.Int8Datum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.function.builtin.Date;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+
+import java.util.Calendar;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestGeneralFunction {
+
+  @Test
+  public void testDate() {
+    Date date = new Date();
+    Tuple tuple = new VTuple(new Datum[] {new TextDatum("25/12/2012 00:00:00")});
+    Int8Datum unixtime = (Int8Datum) date.eval(tuple);
+    Calendar c = Calendar.getInstance();
+    c.setTimeInMillis(unixtime.asInt8());
+    assertEquals(2012, c.get(Calendar.YEAR));
+    assertEquals(11, c.get(Calendar.MONTH));
+    assertEquals(25, c.get(Calendar.DAY_OF_MONTH));
+    assertEquals(0, c.get(Calendar.HOUR_OF_DAY));
+    assertEquals(0, c.get(Calendar.MINUTE));
+    assertEquals(0, c.get(Calendar.SECOND));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestJsonFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestJsonFunctions.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestJsonFunctions.java
new file mode 100644
index 0000000..1792075
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestJsonFunctions.java
@@ -0,0 +1,66 @@
+/**
+ * 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.function;
+
+
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+public class TestJsonFunctions extends ExprTestBase {
+  static final String JSON_DOCUMENT = "{\"map\" : {\"name\" : \"tajo\"}, \"array\" : [1,2,3]}";
+  static final String JSON_ARRAY = "[100,200,300,400,500]";
+  static final String JSON_COMPLEX_ARRAY = "[100, \"test\", \"2015-08-13 11:58:59\", 0.899999999999]";
+  static final String JSON_EMPTY_ARRAY = "[]";
+
+  @Test
+  public void testJsonExtractPathText() throws TajoException {
+    testSimpleEval("select json_extract_path_text('" + JSON_DOCUMENT + "', '$.map.name') ", new String[]{"tajo"});
+    testSimpleEval("select json_extract_path_text('" + JSON_DOCUMENT + "', '$.array[1]') ", new String[]{"2"});
+  }
+
+  @Test
+  public void testJsonArrayGet() throws TajoException {
+    testSimpleEval("select json_array_get('" + JSON_ARRAY + "', 0)", new String[]{"100"});
+    testSimpleEval("select json_array_get('" + JSON_ARRAY + "', 2)", new String[]{"300"});
+    testSimpleEval("select json_array_get('" + JSON_ARRAY + "', -1)", new String[]{"500"});
+    testSimpleEval("select json_array_get('" + JSON_ARRAY + "', -2)", new String[]{"400"});
+    testSimpleEval("select json_array_get('" + JSON_ARRAY + "', 10)", new String[]{""});
+    testSimpleEval("select json_array_get('" + JSON_ARRAY + "', -10)", new String[]{""});
+    testSimpleEval("select json_array_get('" + JSON_EMPTY_ARRAY + "', 0)", new String[]{""});
+  }
+
+  @Test
+  public void testJsonArrayContains() throws TajoException {
+    testSimpleEval("select json_array_contains('" + JSON_COMPLEX_ARRAY + "', 100)", new String[]{"t"});
+    testSimpleEval("select json_array_contains('" + JSON_COMPLEX_ARRAY + "', 'test')", new String[]{"t"});
+    testSimpleEval("select json_array_contains('" + JSON_COMPLEX_ARRAY + "', '2015-08-13 11:58:59'::timestamp)",
+        new String[]{"t"});
+    testSimpleEval("select json_array_contains('" + JSON_COMPLEX_ARRAY + "', '2015-08-13 11:58:59'::date)",
+        new String[]{"f"});
+    testSimpleEval("select json_array_contains('" + JSON_COMPLEX_ARRAY + "', 1000)", new String[]{"f"});
+    testSimpleEval("select json_array_contains('" + JSON_COMPLEX_ARRAY + "', 0.899999999999)", new String[]{"t"});
+  }
+
+  @Test
+  public void testJsonArrayLength() throws TajoException {
+    testSimpleEval("select json_array_length('" + JSON_ARRAY + "')", new String[]{"5"});
+    testSimpleEval("select json_array_length('" + JSON_EMPTY_ARRAY + "')", new String[]{"0"});
+  }
+}


[09/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash.plan
new file mode 100644
index 0000000..170763c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+        => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+         SCAN(7) on default.part as p
+           => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+           => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+           => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+           => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+           => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+           => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(3) on default.supplier as s
+              => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+              => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+              => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(5) on default.partsupp as ps
+              => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+              => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+              => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.ps
+ 1: type=Broadcast, tables=default.p
+ 2: type=Broadcast, tables=default.s
+ 3: type=Broadcast, tables=default.r
+
+SORT(26)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+        => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+         SCAN(7) on default.part as p
+           => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+           => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+           => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+           => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+           => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+           => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(3) on default.supplier as s
+              => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+              => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+              => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(5) on default.partsupp as ps
+              => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+              => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+              => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..0b27fec
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Hash_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+        => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+         SCAN(7) on default.part as p
+           => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+           => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+           => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+           => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+           => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+           => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(3) on default.supplier as s
+              => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+              => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+              => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(5) on default.partsupp as ps
+              => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+              => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+              => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), num=32)
+
+SCAN(5) on default.partsupp as ps
+  => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+  => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+  => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.s.s_suppkey (INT4), num=32)
+
+SCAN(3) on default.supplier as s
+  => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+  => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+  => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.s.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.ps.ps_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+  => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+  => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+  => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+     => in schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.p.p_partkey (INT4), num=32)
+
+SCAN(7) on default.part as p
+  => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+  => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+  => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n
+  => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+  => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as r
+  => target list: default.r.r_regionkey (INT4)
+  => out schema: {(1) default.r.r_regionkey (INT4)}
+  => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.ps.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.p.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+  => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+  => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+  => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+     => in schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+     => in schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+  => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+  => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(1) default.r.r_regionkey (INT4)}
+     => in schema: {(1) default.r.r_regionkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+     => in schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort.plan
new file mode 100644
index 0000000..170763c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+        => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+         SCAN(7) on default.part as p
+           => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+           => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+           => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+           => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+           => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+           => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(3) on default.supplier as s
+              => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+              => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+              => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(5) on default.partsupp as ps
+              => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+              => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+              => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.ps
+ 1: type=Broadcast, tables=default.p
+ 2: type=Broadcast, tables=default.s
+ 3: type=Broadcast, tables=default.r
+
+SORT(26)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+        => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+         SCAN(7) on default.part as p
+           => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+           => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+           => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+           => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+           => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+           => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(3) on default.supplier as s
+              => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+              => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+              => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(5) on default.partsupp as ps
+              => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+              => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+              => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..0b27fec
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.Sort_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+        => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+         SCAN(7) on default.part as p
+           => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+           => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+           => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+           => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+           => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+           => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(3) on default.supplier as s
+              => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+              => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+              => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+            SCAN(5) on default.partsupp as ps
+              => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+              => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+              => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), num=32)
+
+SCAN(5) on default.partsupp as ps
+  => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)
+  => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+  => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.s.s_suppkey (INT4), num=32)
+
+SCAN(3) on default.supplier as s
+  => target list: default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)
+  => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+  => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.s.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.ps.ps_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+  => target list: default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+  => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+  => in schema: {(9) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+     => in schema: {(2) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.p.p_partkey (INT4), num=32)
+
+SCAN(7) on default.part as p
+  => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)
+  => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+  => in schema: {(9) default.p.p_brand (TEXT), default.p.p_comment (TEXT), default.p.p_container (TEXT), default.p.p_mfgr (TEXT), default.p.p_name (TEXT), default.p.p_partkey (INT4), default.p.p_retailprice (FLOAT8), default.p.p_size (INT4), default.p.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n
+  => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+  => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as r
+  => target list: default.r.r_regionkey (INT4)
+  => out schema: {(1) default.r.r_regionkey (INT4)}
+  => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.ps.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.p.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.p.p_partkey (INT4) = default.ps.ps_partkey (INT4)
+  => target list: default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)
+  => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+  => in schema: {(10) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+     => in schema: {(2) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+     => in schema: {(8) default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+  => target list: default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+  => in schema: {(4) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(1) default.r.r_regionkey (INT4)}
+     => in schema: {(1) default.r.r_regionkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+     => in schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.n.n_regionkey (INT4) = default.ps.ps_suppkey (INT4) AND default.s.s_nationkey (INT4) = default.n.n_nationkey (INT4)
+     => target list: default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(12) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(3) default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+        => in schema: {(9) default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.ps.ps_suppkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.n.n_name (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(10)
+  => Sort Keys: default.s.s_acctbal (FLOAT8) (asc),default.s.s_name (TEXT) (asc),default.n.n_name (TEXT) (asc),default.p.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+     => in schema: {(8) default.n.n_name (TEXT), default.p.p_mfgr (TEXT), default.p.p_partkey (INT4), default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.result
new file mode 100644
index 0000000..b7be304
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithMultipleJoinQual1.result
@@ -0,0 +1,2 @@
+s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash.plan
new file mode 100644
index 0000000..c86757c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash.plan
@@ -0,0 +1,90 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SELECTION(2)
+        => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+         JOIN(7)(INNER)
+           => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+           => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+           => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+            SCAN(0) on default.nation as n1
+              => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+              => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+              => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+            SCAN(1) on default.nation as n2
+              => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+              => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+              => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(11)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SELECTION(2)
+     => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+      JOIN(7)(INNER)
+        => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+         SCAN(0) on default.nation as n1
+           => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+           => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+           => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+         SCAN(1) on default.nation as n2
+           => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+           => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..155f466
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Hash_NoBroadcast.plan
@@ -0,0 +1,117 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SELECTION(2)
+        => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+         JOIN(7)(INNER)
+           => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+           => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+           => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+            SCAN(0) on default.nation as n1
+              => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+              => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+              => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+            SCAN(1) on default.nation as n2
+              => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+              => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+              => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+  => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+  => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SELECTION(2)
+     => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+      JOIN(7)(INNER)
+        => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+         SCAN(10) on eb_0000000000000_0000_000002
+           => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+           => in schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+         SCAN(9) on eb_0000000000000_0000_000001
+           => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================


[12/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash.plan
new file mode 100644
index 0000000..988980c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.empty_orders
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..742e346
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_custkey (INT4)
+  => out schema: {(1) default.customer.c_custkey (INT4)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+SCAN(1) on default.empty_orders
+  => target list: default.empty_orders.o_orderkey (INT4)
+  => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+  => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(1) default.empty_orders.o_orderkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(1) default.customer.c_custkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort.plan
new file mode 100644
index 0000000..988980c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.empty_orders
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..742e346
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_custkey (INT4)
+  => out schema: {(1) default.customer.c_custkey (INT4)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+SCAN(1) on default.empty_orders
+  => target list: default.empty_orders.o_orderkey (INT4)
+  => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+  => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(1) default.empty_orders.o_orderkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(1) default.customer.c_custkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.result
new file mode 100644
index 0000000..e27c711
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithEmptyTable.result
@@ -0,0 +1,2 @@
+c_custkey,o_orderkey
+-------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash.plan
new file mode 100644
index 0000000..b2f4ff1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash.plan
@@ -0,0 +1,57 @@
+explain
+-------------------------------
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(0) on default.region as a
+        => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(1) on default.region as b
+        => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.a
+
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(0) on default.region as a
+        => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(1) on default.region as b
+        => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..79d5e7a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan
@@ -0,0 +1,84 @@
+explain
+-------------------------------
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(0) on default.region as a
+        => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(1) on default.region as b
+        => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as b
+  => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+  => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+  => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region as a
+  => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+  => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+  => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.r_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.r_regionkey (INT4), num=32)
+
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort.plan
new file mode 100644
index 0000000..b2f4ff1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort.plan
@@ -0,0 +1,57 @@
+explain
+-------------------------------
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(0) on default.region as a
+        => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(1) on default.region as b
+        => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.a
+
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(0) on default.region as a
+        => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(1) on default.region as b
+        => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..79d5e7a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan
@@ -0,0 +1,84 @@
+explain
+-------------------------------
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(0) on default.region as a
+        => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(1) on default.region as b
+        => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as b
+  => target list: default.b.r_name (TEXT), default.b.r_regionkey (INT4)
+  => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+  => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region as a
+  => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4)
+  => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+  => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.r_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.r_regionkey (INT4), num=32)
+
+SELECTION(6)
+  => Search Cond: default.a.r_name (TEXT) <= default.b.r_name (TEXT)
+   JOIN(7)(INNER)
+     => Join Cond: default.a.r_regionkey (INT4) = default.b.r_regionkey (INT4)
+     => target list: default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)
+     => out schema: {(3) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT)}
+     => in schema: {(4) default.a.r_name (TEXT), default.a.r_regionkey (INT4), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+        => in schema: {(2) default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+        => in schema: {(2) default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.result
new file mode 100644
index 0000000..850ee29
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.result
@@ -0,0 +1,7 @@
+r_regionkey,r_name,r_name
+-------------------------------
+0,AFRICA,AFRICA
+1,AMERICA,AMERICA
+2,ASIA,ASIA
+3,EUROPE,EUROPE
+4,MIDDLE EAST,MIDDLE EAST

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash.plan
new file mode 100644
index 0000000..0120a2b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash.plan
@@ -0,0 +1,53 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(1) on default.customer as a
+     => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(0) on default.nation as b
+     => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.a
+
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(1) on default.customer as a
+     => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(0) on default.nation as b
+     => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..afc6b06
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Hash_NoBroadcast.plan
@@ -0,0 +1,80 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(1) on default.customer as a
+     => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(0) on default.nation as b
+     => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.n_nationkey (INT4), num=32)
+
+SCAN(0) on default.nation as b
+  => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.c_nationkey (INT4), num=32)
+
+SCAN(1) on default.customer as a
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+  => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+  => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.n_nationkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.c_nationkey (INT4), num=32)
+
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort.plan
new file mode 100644
index 0000000..0120a2b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort.plan
@@ -0,0 +1,53 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(1) on default.customer as a
+     => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(0) on default.nation as b
+     => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.a
+
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(1) on default.customer as a
+     => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(0) on default.nation as b
+     => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..afc6b06
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.Sort_NoBroadcast.plan
@@ -0,0 +1,80 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(1) on default.customer as a
+     => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(0) on default.nation as b
+     => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.n_nationkey (INT4), num=32)
+
+SCAN(0) on default.nation as b
+  => target list: default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.c_nationkey (INT4), num=32)
+
+SCAN(1) on default.customer as a
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)
+  => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+  => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.b.n_nationkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.a.c_nationkey (INT4), num=32)
+
+JOIN(5)(INNER)
+  => Join Cond: default.b.n_nationkey (INT4) = default.a.c_nationkey (INT4)
+  => target list: default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)
+  => out schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+  => in schema: {(12) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT), default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+     => in schema: {(8) default.a.c_acctbal (FLOAT8), default.a.c_address (TEXT), default.a.c_comment (TEXT), default.a.c_custkey (INT4), default.a.c_mktsegment (TEXT), default.a.c_name (TEXT), default.a.c_nationkey (INT4), default.a.c_phone (TEXT)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+     => in schema: {(4) default.b.n_comment (TEXT), default.b.n_name (TEXT), default.b.n_nationkey (INT4), default.b.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.result
new file mode 100644
index 0000000..5b5384f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinAsterisk.result
@@ -0,0 +1,7 @@
+n_nationkey,n_name,n_regionkey,n_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+1,ARGENTINA,1,al foxes promise slyly according to the regular accounts. bold requests alon,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,CANADA,1,eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,EGYPT,4,y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+13,JORDAN,4,ic deposits are blithely about the carefully regular pa,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+15,MOROCCO,0,rns. blithely bold courts among the closely regular packages use furiously bold platelets?,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash.plan
new file mode 100644
index 0000000..21e765d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..4250b5c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4)
+  => out schema: {(1) default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(1) default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(1) default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================


[27/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/tweets/sample1.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/tweets/sample1.json b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/tweets/sample1.json
new file mode 100644
index 0000000..78a9071
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/tweets/sample1.json
@@ -0,0 +1,4 @@
+{"coordinates":null,"favorited":false,"truncated":false,"created_at":"Mon Sep 24 03:35:21 +0000 2012","id_str":"250075927172759552","entities":{"urls":[],"hashtags":[{"text":"freebandnames","indices":[20,34]}],"user_mentions":[]},"in_reply_to_user_id_str":null,"contributors":null,"text":"Aggressive Ponytail #freebandnames","metadata":{"iso_language_code":"en","result_type":"recent"},"retweet_count":1,"in_reply_to_status_id_str":null,"id":250075927172759552,"geo":null,"retweeted":false,"in_reply_to_user_id":null,"place":null,"user":{"profile_sidebar_fill_color":"DDEEF6","profile_sidebar_border_color":"C0DEED","profile_background_tile":false,"name":"Sean Cummings","profile_image_url":"http://a0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg","created_at":"Mon Apr 26 06:01:55 +0000 2010","location":"LA, CA","follow_request_sent":null,"profile_link_color":"0084B4","is_translator":false,"id_str":"137238150","entities":{"url":{"urls":[{"expanded_url":null,"url":"","i
 ndices":[0,0]}]},"description":{"urls":[]}},"default_profile":true,"contributors_enabled":false,"favourites_count":0,"url":null,"profile_image_url_https":"https://si0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg","utc_offset":-28800,"id":137238150,"profile_use_background_image":true,"listed_count":2,"profile_text_color":"333333","lang":"en","followers_count":70,"protected":false,"notifications":null,"profile_background_image_url_https":"https://si0.twimg.com/images/themes/theme1/bg.png","profile_background_color":"C0DEED","verified":false,"geo_enabled":true,"time_zone":"Pacific Time (US & Canada)","description":"Born 330 Live 310","default_profile_image":false,"profile_background_image_url":"http://a0.twimg.com/images/themes/theme1/bg.png","statuses_count":579,"friends_count":110,"following":null,"show_all_inline_media":false,"screen_name":"sean_cummings"},"in_reply_to_screen_name":null,"source":"<a>Twitter for Mac<\/a>","in_reply_to_status_id":null}
+{"coordinates":null,"favorited":false,"truncated":false,"created_at":"Fri Sep 21 23:40:54 +0000 2012","id_str":"249292149810667520","entities":{"urls":[],"hashtags":[{"text":"FreeBandNames","indices":[20,34]}],"user_mentions":[]},"in_reply_to_user_id_str":null,"contributors":null,"text":"Thee Namaste Nerdz. #FreeBandNames","metadata":{"iso_language_code":"pl","result_type":"recent"},"retweet_count":2,"in_reply_to_status_id_str":null,"id":249292149810667520,"geo":null,"retweeted":false,"in_reply_to_user_id":null,"place":null,"user":{"profile_sidebar_fill_color":"DDFFCC","profile_sidebar_border_color":"BDDCAD","profile_background_tile":true,"name":"Chaz Martenstein","profile_image_url":"http://a0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg","created_at":"Tue Apr 07 19:05:07 +0000 2009","location":"Durham, NC","follow_request_sent":null,"profile_link_color":"0084B4","is_translator":false,"id_str":"29516238","entities":{"url":{"urls":[{"expanded_url":null,"url":"http://bu
 llcityrecords.com/wnng/","indices":[0,32]}]},"description":{"urls":[]}},"default_profile":false,"contributors_enabled":false,"favourites_count":8,"url":"http://bullcityrecords.com/wnng/","profile_image_url_https":"https://si0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg","utc_offset":-18000,"id":29516238,"profile_use_background_image":true,"listed_count":118,"profile_text_color":"333333","lang":"en","followers_count":2052,"protected":false,"notifications":null,"profile_background_image_url_https":"https://si0.twimg.com/profile_background_images/9423277/background_tile.bmp","profile_background_color":"9AE4E8","verified":false,"geo_enabled":false,"time_zone":"Eastern Time (US & Canada)","description":"You will come to Durham, North Carolina. I will sell you some records then, here in Durham, North Carolina. Fun will happen.","default_profile_image":false,"profile_background_image_url":"http://a0.twimg.com/profile_background_images/9423277/background_tile.bmp","statuses_c
 ount":7579,"friends_count":348,"following":null,"show_all_inline_media":true,"screen_name":"bullcityrecords"},"in_reply_to_screen_name":null,"source":"web","in_reply_to_status_id":null}
+{"coordinates":null,"favorited":false,"truncated":false,"created_at":"Fri Sep 21 23:30:20 +0000 2012","id_str":"249289491129438208","entities":{"urls":[],"hashtags":[{"text":"freebandnames","indices":[29,43]}],"user_mentions":[]},"in_reply_to_user_id_str":null,"contributors":null,"text":"Mexican Heaven, Mexican Hell #freebandnames","metadata":{"iso_language_code":"en","result_type":"recent"},"retweet_count":3,"in_reply_to_status_id_str":null,"id":249289491129438208,"geo":null,"retweeted":false,"in_reply_to_user_id":null,"place":null,"user":{"profile_sidebar_fill_color":"99CC33","profile_sidebar_border_color":"829D5E","profile_background_tile":false,"name":"Thomas John Wakeman","profile_image_url":"http://a0.twimg.com/profile_images/2219333930/Froggystyle_normal.png","created_at":"Tue Sep 01 21:21:35 +0000 2009","location":"Kingston New York","follow_request_sent":null,"profile_link_color":"D02B55","is_translator":false,"id_str":"70789458","entities":{"url":{"urls":[{"expanded_url":n
 ull,"url":"","indices":[0,0]}]},"description":{"urls":[]}},"default_profile":false,"contributors_enabled":false,"favourites_count":19,"url":null,"profile_image_url_https":"https://si0.twimg.com/profile_images/2219333930/Froggystyle_normal.png","utc_offset":-18000,"id":70789458,"profile_use_background_image":true,"listed_count":1,"profile_text_color":"3E4415","lang":"en","followers_count":63,"protected":false,"notifications":null,"profile_background_image_url_https":"https://si0.twimg.com/images/themes/theme5/bg.gif","profile_background_color":"352726","verified":false,"geo_enabled":false,"time_zone":"Eastern Time (US & Canada)","description":"Science Fiction Writer, sort of. Likes Superheroes, Mole People, Alt. Timelines.","default_profile_image":false,"profile_background_image_url":"http://a0.twimg.com/images/themes/theme5/bg.gif","statuses_count":1048,"friends_count":63,"following":null,"show_all_inline_media":false,"screen_name":"MonkiesFist"},"in_reply_to_screen_name":null,"sour
 ce":"web","in_reply_to_status_id":null}
+{"coordinates":null,"favorited":false,"truncated":false,"created_at":"Fri Sep 21 22:51:18 +0000 2012","id_str":"249279667666817024","entities":{"urls":[],"hashtags":[{"text":"freebandnames","indices":[20,34]}],"user_mentions":[]},"in_reply_to_user_id_str":null,"contributors":null,"text":"The Foolish Mortals #freebandnames","metadata":{"iso_language_code":"en","result_type":"recent"},"retweet_count":4,"in_reply_to_status_id_str":null,"id":249279667666817024,"geo":null,"retweeted":false,"in_reply_to_user_id":null,"place":null,"user":{"profile_sidebar_fill_color":"BFAC83","profile_sidebar_border_color":"615A44","profile_background_tile":true,"name":"Marty Elmer","profile_image_url":"http://a0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png","created_at":"Mon May 04 00:05:00 +0000 2009","location":"Wisconsin, USA","follow_request_sent":null,"profile_link_color":"3B2A26","is_translator":false,"id_str":"37539828","entities":{"url":{"urls":[{"expanded_url":null,"url":"ht
 tp://www.omnitarian.me","indices":[0,24]}]},"description":{"urls":[]}},"default_profile":false,"contributors_enabled":false,"favourites_count":647,"url":"http://www.omnitarian.me","profile_image_url_https":"https://si0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png","utc_offset":-21600,"id":37539828,"profile_use_background_image":true,"listed_count":52,"profile_text_color":"000000","lang":"en","followers_count":608,"protected":false,"notifications":null,"profile_background_image_url_https":"https://si0.twimg.com/profile_background_images/106455659/rect6056-9.png","profile_background_color":"EEE3C4","verified":false,"geo_enabled":false,"time_zone":"Central Time (US & Canada)","description":"Cartoonist, Illustrator, and T-Shirt connoisseur","default_profile_image":false,"profile_background_image_url":"http://a0.twimg.com/profile_background_images/106455659/rect6056-9.png","statuses_count":3575,"friends_count":249,"following":null,"show_all_inline_media":true,"scree
 n_name":"Omnitarian"},"in_reply_to_screen_name":null,"source":"<a>Twitter for iPhone<\/a>","in_reply_to_status_id":null}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter1/table1.tbl
new file mode 100644
index 0000000..5acccf6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter1/table1.tbl
@@ -0,0 +1,5 @@
+1||ooo||1.1||a
+2||ppp||2.3||
+3||qqq||||
+4||||4.5||
+||xxx||5.6||e
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter2/table2.tbl
new file mode 100644
index 0000000..b26cdfd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/multibytes_delimiter2/table2.tbl
@@ -0,0 +1,5 @@
+1ㅎoooㅎ1.1ㅎa
+2ㅎpppㅎ2.3ㅎ
+3ㅎqqqㅎㅎ
+4ㅎㅎ4.5ㅎ
+ㅎxxxㅎ5.6ㅎe
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/timezoned/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/timezoned/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/timezoned/table1.tbl
new file mode 100644
index 0000000..38e8bd9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectQuery/timezoned/table1.tbl
@@ -0,0 +1,3 @@
+1980-4-1 01:50:30.010|1980-04-01
+80/4/1 1:50:30 AM|80/4/1
+1980 April 1 1:50:30|1980-04-01
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table1/table1.tbl
new file mode 100644
index 0000000..a1ebde3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table1/table1.tbl
@@ -0,0 +1,5 @@
+1997-11-09 20:34:56|1996-04-12|15:34:56
+1997-11-09 20:34:56|1996-03-13|19:34:56
+1993-11-09 20:34:56|1997-01-28|08:34:56
+1995-11-09 20:34:56|1994-02-02|17:34:56
+1995-11-09 20:34:56|1993-11-09|20:34:56
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table2/table2.tbl
new file mode 100644
index 0000000..bc237af
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSortQuery/table2/table2.tbl
@@ -0,0 +1,24 @@
+1,2132
+1,15635
+1,24027
+1,63700
+1,67310
+1,155190
+2,106170
+3,4297
+3,19036
+3,29380
+3,62143
+3,128449
+3,183095
+4,88035
+5,37531
+5,108570
+5,123927
+6,139636
+7,79251
+7,94780
+7,145243
+7,151894
+7,157238
+7,163073

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestTablePartitions/lineitemspecial.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestTablePartitions/lineitemspecial.tbl b/tajo-core-tests/src/test/resources/dataset/TestTablePartitions/lineitemspecial.tbl
new file mode 100644
index 0000000..2241213
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestTablePartitions/lineitemspecial.tbl
@@ -0,0 +1,5 @@
+1|DELIVER IN PERSON|TRUCK|
+1|TAKE BACK RETURN|MAIL|
+2|TAKE BACK RETURN|RAIL|
+3|NONE|AIR|
+3|TEST SPECIAL CHARS|RA:*?><I/L#%S|

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestTajoJdbc/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestTajoJdbc/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestTajoJdbc/table1/table1.tbl
new file mode 100644
index 0000000..52fa2fe
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestTajoJdbc/table1/table1.tbl
@@ -0,0 +1,5 @@
+1997-11-09 20:34:56|1996-04-12|15:34:56
+1997-11-09 20:34:56|1996-03-13|19:34:56
+1993-11-09 20:34:56|1997-01-28|08:34:56
+1995-11-09 20:34:56|1994-02-02|17:34:56
+1995-11-09 20:34:56|1993-11-09|20:34:56

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestTruncateTable/truncate_table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestTruncateTable/truncate_table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestTruncateTable/truncate_table2/table2.tbl
new file mode 100644
index 0000000..f99db9c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestTruncateTable/truncate_table2/table2.tbl
@@ -0,0 +1,4 @@
+4|jkl1|7
+5|opq2|8
+6|stu3|9
+7|kkk4|10

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

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/python/__init__.py
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/python/__init__.py b/tajo-core-tests/src/test/resources/python/__init__.py
new file mode 100644
index 0000000..8093a2f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/python/__init__.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+############################################################################
+#  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.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/python/test_funcs.py
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/python/test_funcs.py b/tajo-core-tests/src/test/resources/python/test_funcs.py
new file mode 100644
index 0000000..1167afd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/python/test_funcs.py
@@ -0,0 +1,33 @@
+############################################################################
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+from tajo_util import output_type
+
+@output_type('int4')
+def return_one():
+    return 1
+
+@output_type("text")
+def helloworld():
+    return 'Hello, World'
+
+# No decorator - blob
+def concat_py(str):
+    return str+str
+
+@output_type('int4')
+def add_py(a,b):
+    return a+b

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/python/test_funcs2.py
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/python/test_funcs2.py b/tajo-core-tests/src/test/resources/python/test_funcs2.py
new file mode 100644
index 0000000..8a6f608
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/python/test_funcs2.py
@@ -0,0 +1,32 @@
+############################################################################
+#  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.
+
+from tajo_util import output_type
+
+#Percent- Percentage
+@output_type("float8")
+def percent(num, total):
+    return num * 100 / float(total)
+
+#commaFormat- format a number with commas, 12345-> 12,345
+@output_type("text")
+def comma_format(num):
+    return '{:,}'.format(num)
+
+#concatMultiple- concat multiple words
+@output_type("text")
+def concat4(word1, word2, word3, word4):
+    return word1 + " " + word2 + " " + word3 + " " + word4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/python/test_udaf.py
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/python/test_udaf.py b/tajo-core-tests/src/test/resources/python/test_udaf.py
new file mode 100644
index 0000000..da5a3fd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/python/test_udaf.py
@@ -0,0 +1,76 @@
+############################################################################
+#  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.
+
+from tajo_util import output_type
+
+
+class AvgPy:
+    sum = 0
+    cnt = 0
+
+    def __init__(self):
+        self.reset()
+
+    def reset(self):
+        self.sum = 0
+        self.cnt = 0
+
+    # eval at the first stage
+    def eval(self, item):
+        self.sum += item
+        self.cnt += 1
+
+    # get intermediate result
+    def get_partial_result(self):
+        return [self.sum, self.cnt]
+
+    # merge intermediate results
+    def merge(self, list):
+        self.sum += list[0]
+        self.cnt += list[1]
+
+    # get final result
+    @output_type('float8')
+    def get_final_result(self):
+        return self.sum / float(self.cnt)
+
+
+class CountPy:
+    cnt = 0
+
+    def __init__(self):
+        self.reset()
+
+    def reset(self):
+        self.cnt = 0
+
+    # eval at the first stage
+    def eval(self):
+        self.cnt += 1
+
+    # get intermediate result
+    def get_partial_result(self):
+        return self.cnt
+
+    # merge intermediate results
+    def merge(self, cnt):
+        self.cnt += cnt
+
+    # get final result
+    @output_type('int4')
+    def get_final_result(self):
+        return self.cnt
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
new file mode 100644
index 0000000..567aed8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE EFG ADD COLUMN cool text;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition1.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition1.sql
new file mode 100644
index 0000000..1154683
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition1.sql
@@ -0,0 +1 @@
+ALTER TABLE partitioned_table ADD PARTITION (col3 = 1 , col4 = 2)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition2.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition2.sql
new file mode 100644
index 0000000..315ac47
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_add_partition2.sql
@@ -0,0 +1 @@
+ALTER TABLE partitioned_table ADD IF NOT EXISTS PARTITION (col3 = 1 , col4 = 2)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql
new file mode 100644
index 0000000..b5d672f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql
@@ -0,0 +1 @@
+ALTER TABLE partitioned_table DROP PARTITION (col3 = 1 , col4 = 2)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql
new file mode 100644
index 0000000..0d4c932
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql
@@ -0,0 +1 @@
+ALTER TABLE partitioned_table DROP IF EXISTS PARTITION (col3 = 1 , col4 = 2)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
new file mode 100644
index 0000000..7c326ff
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE XYZ RENAME COLUMN num TO renum;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
new file mode 100644
index 0000000..1808eaa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
@@ -0,0 +1 @@
+ ALTER TABLE ABC RENAME TO "DEF";

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_delimiter.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_delimiter.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_delimiter.sql
new file mode 100644
index 0000000..031e700
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_delimiter.sql
@@ -0,0 +1 @@
+ALTER TABLE ALTX SET PROPERTY 'text.delimiter'='|';

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_timezone.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_timezone.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_timezone.sql
new file mode 100644
index 0000000..24b237e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_set_property_timezone.sql
@@ -0,0 +1 @@
+ALTER TABLE ALTY SET PROPERTY 'timezone'='GMT-7';

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/create_partitioned_table.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/create_partitioned_table.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/create_partitioned_table.sql
new file mode 100644
index 0000000..b349349
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/create_partitioned_table.sql
@@ -0,0 +1 @@
+create table partitioned_table (col1 int4, col2 int4) partition by column(col3 int4, col4 int4)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/table1_ddl.sql
new file mode 100644
index 0000000..f00f593
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} (id int, str text, num int) using text location ${table.path};

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/table2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/table2_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/table2_ddl.sql
new file mode 100644
index 0000000..887029d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/table2_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} (xx text, yy text, zz text) USING TEXT WITH('text.delimiter'='+') LOCATION ${table.path};

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty.sql
new file mode 100644
index 0000000..dd0bd83
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty.sql
@@ -0,0 +1 @@
+select * from ALTX;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty2.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty2.sql
new file mode 100644
index 0000000..2e854aa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/testAlterTableSetProperty2.sql
@@ -0,0 +1 @@
+select * from ALTY;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgDouble.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgDouble.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgDouble.sql
new file mode 100644
index 0000000..a9afc5c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgDouble.sql
@@ -0,0 +1 @@
+select l_orderkey, avg(l_discount) as revenue from lineitem group by l_orderkey order by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgInt.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgInt.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgInt.sql
new file mode 100644
index 0000000..4983563
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgInt.sql
@@ -0,0 +1 @@
+select avg(l_partkey) as total_avg from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLong.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLong.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLong.sql
new file mode 100644
index 0000000..324c6cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLong.sql
@@ -0,0 +1 @@
+select avg(l_orderkey) as total_avg from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLongOverflow.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLongOverflow.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLongOverflow.sql
new file mode 100644
index 0000000..51a2ac1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testAvgLongOverflow.sql
@@ -0,0 +1 @@
+select avg(cast(l_quantity * 25264513 as INT4)) as avg from lineitem where l_quantity > 0;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testCount.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testCount.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testCount.sql
new file mode 100644
index 0000000..1773e38
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testCount.sql
@@ -0,0 +1 @@
+select count(*) as rownum from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxLong.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxLong.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxLong.sql
new file mode 100644
index 0000000..0566377
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxLong.sql
@@ -0,0 +1 @@
+select max(l_orderkey) as total_max from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxString.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxString.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxString.sql
new file mode 100644
index 0000000..f594017
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMaxString.sql
@@ -0,0 +1 @@
+select max(l_orderkey::text) as total_max from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinLong.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinLong.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinLong.sql
new file mode 100644
index 0000000..0f3cfee
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinLong.sql
@@ -0,0 +1 @@
+select min(l_orderkey) as total_min from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinString.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinString.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinString.sql
new file mode 100644
index 0000000..9cc6629
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testMinString.sql
@@ -0,0 +1 @@
+select min(l_orderkey::text) as total_min from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testRandom.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testRandom.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testRandom.sql
new file mode 100644
index 0000000..9f2a456
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testRandom.sql
@@ -0,0 +1 @@
+select l_orderkey, random(3) as rndnum from lineitem group by l_orderkey, rndnum;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPart.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPart.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPart.sql
new file mode 100644
index 0000000..528d60c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPart.sql
@@ -0,0 +1 @@
+select split_part(l_shipinstruct, ' ', 1) from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartByString.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartByString.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartByString.sql
new file mode 100644
index 0000000..cd6a664
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartByString.sql
@@ -0,0 +1 @@
+select split_part(l_shipinstruct, 'KE', 1) from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartNested.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartNested.sql b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartNested.sql
new file mode 100644
index 0000000..b7add04
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestBuiltinFunctions/testSplitPartNested.sql
@@ -0,0 +1 @@
+select split_part(split_part(l_shipinstruct, ' ', 1), 'A', 2) from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql
new file mode 100644
index 0000000..c2d7604
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql
@@ -0,0 +1,2 @@
+create table testCtasWithGroupby (col1 float, col2 float) partition by column(key float8) as
+select sum(l_orderkey) as total1, avg(l_partkey) as total2, l_quantity as key from lineitem group by l_quantity;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql
new file mode 100644
index 0000000..fb4eba3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql
@@ -0,0 +1,13 @@
+create table testCtasWithLimit (col1 float, col2 float) partition by column(key float8) as
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2,
+  l_quantity as key
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithManagedTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithManagedTable.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithManagedTable.sql
new file mode 100644
index 0000000..1dd5e90
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithManagedTable.sql
@@ -0,0 +1,12 @@
+create table "MANAGED_TABLE1" (col1 float, col2 float) using rcfile as
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithMultipleUnions.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithMultipleUnions.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithMultipleUnions.sql
new file mode 100644
index 0000000..7176a2a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithMultipleUnions.sql
@@ -0,0 +1,12 @@
+create table testCtasWithMultipleUnions as
+select * from
+   (select c_custkey, c_nationkey from customer where c_nationkey < 0
+   union all
+   select c_custkey, c_nationkey from customer where c_nationkey > 0
+) a
+union all
+select * from
+   (select c_custkey, c_nationkey from customer where c_nationkey < 0
+   union all
+   select c_custkey, c_nationkey from customer where c_nationkey > 0
+) b;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOptions.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOptions.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOptions.sql
new file mode 100644
index 0000000..b7dde15
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOptions.sql
@@ -0,0 +1,13 @@
+create table testCtasWithOptions (col1 float, col2 float)
+using text with ('text.delimiter'='\u0001') as
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql
new file mode 100644
index 0000000..686d2e1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql
@@ -0,0 +1,11 @@
+create table testCtasWithOrderby (col1 float, col2 float) partition by column(key float8) as
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2,
+  l_quantity as key
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithStoreType.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithStoreType.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithStoreType.sql
new file mode 100644
index 0000000..bee1a89
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithStoreType.sql
@@ -0,0 +1,12 @@
+create table testCtasWithStoreType (col1 float, col2 float) using rcfile as
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithTextFile.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithTextFile.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithTextFile.sql
new file mode 100644
index 0000000..5581d16
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithTextFile.sql
@@ -0,0 +1,12 @@
+create table testCtasWithTextFile (col1 float, col2 float) using text as
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql
new file mode 100644
index 0000000..739f23f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql
@@ -0,0 +1,35 @@
+create table testCtasWithUnion (col1 float, col2 float) partition by column(key float8) as
+
+select
+  *
+from (
+
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2,
+  l_quantity as key
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3
+
+union
+
+select
+  sum(l_orderkey) as total1,
+  avg(l_partkey) as total2,
+  l_quantity as key
+from
+  lineitem
+group by
+  l_quantity
+order by
+  l_quantity
+limit
+  3
+
+) t1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check1.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check1.sql
new file mode 100644
index 0000000..3fb90bb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check1.sql
@@ -0,0 +1 @@
+select distinct * from testCtasWithoutTableDefinition where (key = 45.0 or key = 38.0);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check2.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check2.sql
new file mode 100644
index 0000000..1b354b7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/check2.sql
@@ -0,0 +1 @@
+select distinct * from testCtasWithColumnedPartition where (key = 45.0 or key = 38.0);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql
new file mode 100644
index 0000000..76b852a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql
@@ -0,0 +1,2 @@
+create table testCtasWithColumnedPartition (col1 float, col2 float) partition by column(key float8) as
+select l_orderkey as col1, l_partkey as col2, l_quantity as key from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql
new file mode 100644
index 0000000..bf16e63
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql
@@ -0,0 +1 @@
+select * from testCtasWithGroupby order by key;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql
new file mode 100644
index 0000000..fa0fbd7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql
@@ -0,0 +1 @@
+select * from testCtasWithLimit order by key;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithMultipleUnions.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithMultipleUnions.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithMultipleUnions.sql
new file mode 100644
index 0000000..71b7034
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithMultipleUnions.sql
@@ -0,0 +1 @@
+select * from testCtasWithMultipleUnions;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOptions.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOptions.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOptions.sql
new file mode 100644
index 0000000..ac25e10
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOptions.sql
@@ -0,0 +1 @@
+select * from testCtasWithOptions;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql
new file mode 100644
index 0000000..7013b39
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql
@@ -0,0 +1 @@
+select * from testCtasWithOrderby order by key;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithStoreType.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithStoreType.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithStoreType.sql
new file mode 100644
index 0000000..9e7e337
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithStoreType.sql
@@ -0,0 +1 @@
+select * from testCtasWithStoreType;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithTextFile.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithTextFile.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithTextFile.sql
new file mode 100644
index 0000000..f81442b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithTextFile.sql
@@ -0,0 +1 @@
+select * from testCtasWithTextFile;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql
new file mode 100644
index 0000000..933e18a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql
@@ -0,0 +1 @@
+select * from testCtasWithUnion order by key;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql
new file mode 100644
index 0000000..e30f261
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql
@@ -0,0 +1,2 @@
+create table testCtasWithoutTableDefinition partition by column(key float8) as
+select l_orderkey as col1, l_partkey as col2, l_quantity as key from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO1224Case1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO1224Case1.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO1224Case1.sql
new file mode 100644
index 0000000..d05a563
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO1224Case1.sql
@@ -0,0 +1 @@
+select count(*) from tajo1224;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO415Case.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO415Case.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO415Case.sql
new file mode 100644
index 0000000..4b915d3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO415Case.sql
@@ -0,0 +1,36 @@
+select
+  c_custkey,
+  o_orderkey,
+  a.cnt
+
+from (
+
+  select
+    c_custkey,
+    count(*) as cnt
+
+  from
+    customer
+
+  group by
+    c_custkey
+
+) a left outer join (
+
+  select
+    o_orderkey,
+    count(*) as cnt
+
+  from
+    orders
+
+  where
+    o_orderkey is not null
+
+  group by
+    o_orderkey
+
+) b on (a.c_custkey = b.o_orderkey)
+
+order by
+  c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO418Case.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO418Case.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO418Case.sql
new file mode 100644
index 0000000..2e62923
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO418Case.sql
@@ -0,0 +1,29 @@
+SELECT
+  l_returnflag,
+  l_linestatus
+
+FROM (
+  SELECT
+    *
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'N'
+
+  UNION ALL
+
+  SELECT
+    *
+  FROM
+    lineitem
+  WHERE
+    l_returnflag = 'R'
+) T
+
+GROUP BY
+  l_returnflag,
+	l_linestatus
+
+ORDER BY
+  l_returnflag,
+	l_linestatus
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO619Case.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO619Case.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO619Case.sql
new file mode 100644
index 0000000..15355b8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO619Case.sql
@@ -0,0 +1,4 @@
+select
+  count(1)
+from
+  lineitem as l1 join lineitem as l2 on l1.l_returnflag = l2.l_returnflag;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO718Case.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO718Case.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO718Case.sql
new file mode 100644
index 0000000..73e9f6a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO718Case.sql
@@ -0,0 +1,10 @@
+SELECT
+  "lineitem".l_orderkey AS l_orderkey,
+  "lineitem".l_orderkey AS l_orderkey1,
+  COUNT ("lineitem".l_orderkey) AS T57801e5322bc50
+FROM
+  "lineitem"
+GROUP BY
+  l_orderkey, l_orderkey1
+ORDER BY
+  l_orderkey, l_orderkey1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO739Case.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO739Case.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO739Case.sql
new file mode 100644
index 0000000..3525621
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO739Case.sql
@@ -0,0 +1,5 @@
+select nation.n_nationkey as n_nationkey,
+       nation.n_name as n_name
+from nation
+inner join (select c_nationkey as n_nationkey from customer) a
+on nation.n_nationkey = a.n_nationkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case1.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case1.sql
new file mode 100644
index 0000000..765110a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case1.sql
@@ -0,0 +1,10 @@
+select
+  l_orderkey,
+  '##' as col1
+from
+  lineitem
+  join orders on l_orderkey = o_orderkey
+group by
+  l_orderkey
+order by
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case2.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case2.sql
new file mode 100644
index 0000000..f404088
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case2.sql
@@ -0,0 +1,9 @@
+select
+  l_orderkey,
+  '##' as col1
+from
+  lineitem join orders on l_orderkey = o_orderkey
+group by
+  l_orderkey, col1
+order by
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case3.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case3.sql
new file mode 100644
index 0000000..f9ee355
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case3.sql
@@ -0,0 +1,10 @@
+insert OVERWRITE into T3
+  select
+    l_orderkey,
+    '##' as col1
+  from
+    lineitem join orders on l_orderkey = o_orderkey
+  group by
+    l_orderkey, col1
+  order by
+    l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case4.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case4.sql
new file mode 100644
index 0000000..ba99b70
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO914Case4.sql
@@ -0,0 +1,10 @@
+  select
+    l_orderkey,
+    '##' as col1,
+    sum(l_orderkey) as s1
+  from
+    lineitem join orders o1 on l_orderkey = o1.o_orderkey join orders o2 on l_orderkey = o2.o_orderkey
+  group by
+    l_orderkey, col1
+  order by
+    l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO917Case1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO917Case1.sql b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO917Case1.sql
new file mode 100644
index 0000000..5b3039c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCaseByCases/testTAJO917Case1.sql
@@ -0,0 +1,13 @@
+select
+    temp.r_regionkey as r_regionkey
+from
+    (
+    select
+        region.r_regionkey as r_regionkey
+    from
+        region
+    ) temp
+join
+    region b
+on
+    temp.r_regionkey = b.r_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndex.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndex.sql b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndex.sql
new file mode 100644
index 0000000..1cb8936
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndex.sql
@@ -0,0 +1 @@
+create index l_orderkey_idx on lineitem (l_orderkey asc null first);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnExpression.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnExpression.sql b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnExpression.sql
new file mode 100644
index 0000000..0d19cb3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnExpression.sql
@@ -0,0 +1 @@
+create index l_orderkey_100_lt10_idx on lineitem (l_orderkey*100 asc null first) where l_orderkey*100 > 10;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnLocation.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnLocation.sql b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnLocation.sql
new file mode 100644
index 0000000..1cb8936
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnLocation.sql
@@ -0,0 +1 @@
+create index l_orderkey_idx on lineitem (l_orderkey asc null first);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiAttrs.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiAttrs.sql b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiAttrs.sql
new file mode 100644
index 0000000..3487d2e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiAttrs.sql
@@ -0,0 +1 @@
+create index l_orderkey_partkey_idx on lineitem (l_orderkey asc, l_partkey desc null last);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiExprs.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiExprs.sql b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiExprs.sql
new file mode 100644
index 0000000..7938005
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexOnMultiExprs.sql
@@ -0,0 +1 @@
+create index l_orderkey_100_l_linenumber_10_lt10_idx on lineitem (l_orderkey*100-l_linenumber*10 asc null first) where l_orderkey*100 > 10;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexWithCondition.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexWithCondition.sql b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexWithCondition.sql
new file mode 100644
index 0000000..ad4ee47
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateIndex/testCreateIndexWithCondition.sql
@@ -0,0 +1 @@
+create index l_orderkey_partkey_lt10_idx on lineitem (l_orderkey asc, l_partkey desc) where l_partkey > 10;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types.sql
new file mode 100644
index 0000000..891a139
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types.sql
@@ -0,0 +1,50 @@
+-- Some types were commented out due to Hive meta test.
+
+create table various_types (
+  col0 bit,
+  col1 BIT(10),
+  col2 bit varying,
+  col3 bit VARYING(10),
+  col4 tinyint,
+  col5 smallInt,
+  col6 integer,
+  col7 biginT,
+  col8 real,
+  col9 float,
+  col10 float(53),
+  col11 double,
+  col12 doublE precision,
+  col13 numeric,
+  col14 numeric(10),
+  col15 numeric(10,2),
+  col16 decimal,
+  col17 decimal(10),
+  col18 decimal(10,2),
+  col19 char,
+  col20 character,
+  col21 chaR(10),
+  col22 character(10),
+  col23 varchar,
+  col24 character varying,
+  col25 varchar(255),
+  col26 character varying (255),
+  col27 nchar,
+  col28 nchar(255),
+  col29 national character,
+  col30 national character(255),
+  col31 nvarchar,
+  col32 nvarchar(255),
+  col33 natIonal character varying,
+  col34 national character varying (255),
+  col35 date,
+  col36 time,
+  col37 timetz,
+  col38 time With time zone,
+  col39 timesTamptz,
+  col40 timestamp with time zone,
+  col41 binary,
+  col42 binary(10),
+  col43 varbinary(10),
+  col44 binary Varying(10),
+  col45 blOb
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types_for_hive_catalog.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types_for_hive_catalog.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types_for_hive_catalog.sql
new file mode 100644
index 0000000..3eda994
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/create_table_various_types_for_hive_catalog.sql
@@ -0,0 +1,50 @@
+-- Some types were commented out due to Hive meta test.
+
+create table various_types (
+--  col0 bit,
+--  col1 BIT(10),
+--  col2 bit varying,
+--  col3 bit VARYING(10),
+  col4 tinyint,
+  col5 smallInt,
+  col6 integer,
+  col7 biginT,
+  col8 real,
+  col9 float,
+  col10 float(53),
+  col11 double,
+  col12 doublE precision,
+--  col13 numeric,
+--  col14 numeric(10),
+--  col15 numeric(10,2),
+--  col16 decimal,
+--  col17 decimal(10),
+--  col18 decimal(10,2),
+--  col19 char,
+--  col20 character,
+--  col21 chaR(10),
+--  col22 character(10),
+--  col23 varchar,
+--  col24 character varying,
+--  col25 varchar(255),
+--  col26 character varying (255),
+--  col27 nchar,
+--  col28 nchar(255),
+--  col29 national character,
+--  col30 national character(255),
+--  col31 nvarchar,
+--  col32 nvarchar(255),
+--  col33 natIonal character varying,
+--  col34 national character varying (255),
+--  col35 date,
+--  col36 time,
+--  col37 timetz,
+--  col38 time With time zone,
+--  col39 timesTamptz,
+--  col40 timestamp with time zone,
+  col41 binary,
+--  col42 binary(10),
+--  col43 varbinary(10),
+--  col44 binary Varying(10),
+  col45 blOb
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_1.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_1.sql
new file mode 100644
index 0000000..2084456
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_1.sql
@@ -0,0 +1 @@
+SELECT "aGe", "teXt", "Number" FROM "TABLE1";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_2.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_2.sql
new file mode 100644
index 0000000..4b05657
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_2.sql
@@ -0,0 +1 @@
+SELECT "tb1"."aGe" as "AgE", "tb1"."teXt" as "TEXT", "Number" as "NUMBER" FROM "TABLE1" "tb1";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_3.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_3.sql
new file mode 100644
index 0000000..fbb00a0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_3.sql
@@ -0,0 +1,22 @@
+SELECT
+  *
+FROM (
+  SELECT
+    "tb1"."aGe",
+    "tb1"."teXt",
+    "Number"
+  FROM
+    "TABLE1" "tb1"
+
+  UNION
+
+  SELECT
+    "aGe",
+    "teXt",
+    "Number"
+  FROM
+    "tablE1"
+) T1
+ORDER BY
+  "aGe";
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_1.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_1.sql
new file mode 100644
index 0000000..d8293d0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_1.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} ("aGe" int, "teXt" text, "Number" int) using text location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_2.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_2.sql
new file mode 100644
index 0000000..d8293d0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_mixed_chars_ddl_2.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} ("aGe" int, "teXt" text, "Number" int) using text location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_1.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_1.sql
new file mode 100644
index 0000000..39a7bfa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_1.sql
@@ -0,0 +1 @@
+SELECT "아이디", "텍스트", "숫자" FROM "테이블1";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_2.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_2.sql
new file mode 100644
index 0000000..f51364d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_2.sql
@@ -0,0 +1 @@
+SELECT "아이디" as "진짜아이디", "텍스트" as text, "숫자" FROM "테이블1" as "테이블 별명"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_3.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_3.sql
new file mode 100644
index 0000000..7e8b64c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_3.sql
@@ -0,0 +1 @@
+SELECT "아이디" "진짜아이디", char_length("텍스트") as "길이", "숫자" * 2 FROM "테이블1" "테이블 별명"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_ddl.sql
new file mode 100644
index 0000000..1706d80
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/quoted_identifier_non_ascii_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} ("아이디" int, "텍스트" text, "숫자" int) using text location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/table1_ddl.sql
new file mode 100644
index 0000000..e26975a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} (id int, str text, num int) using text location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord1.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord1.sql
new file mode 100644
index 0000000..d147361
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord1.sql
@@ -0,0 +1 @@
+CREATE TABLE D9.nested_table (f1 int, nested_field record (f2 int4, f3 int8), f3 text);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord2.sql b/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord2.sql
new file mode 100644
index 0000000..f794d21
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestCreateTable/testNestedRecord2.sql
@@ -0,0 +1 @@
+CREATE TABLE D9.nested_table2 (f1 int, nf1 record (f1 int4, f3 double), nf2 record (f1 int4, nf1 record (f1 int4, f2 text), nf2 record (f1 int4, f2 text), f2 double), f2 text);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestDropTable/drop_table_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
new file mode 100644
index 0000000..c58f459
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
@@ -0,0 +1 @@
+DROP TABLE abc PURGE;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestDropTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestDropTable/table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestDropTable/table1_ddl.sql
new file mode 100644
index 0000000..0d56ec8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestDropTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE TABLE ${0} (id int, str text, num int);

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter.sql
new file mode 100644
index 0000000..8d5de04
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter.sql
@@ -0,0 +1 @@
+select sum(l_extendedprice*l_discount) as revenue from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter2.sql
new file mode 100644
index 0000000..d72dc99
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameter2.sql
@@ -0,0 +1 @@
+select count(*) + max(l_orderkey) as merged from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameterWithSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameterWithSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameterWithSubQuery.sql
new file mode 100644
index 0000000..6f2c77c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexParameterWithSubQuery.sql
@@ -0,0 +1,6 @@
+select
+  count(*) as total
+from (
+  select * from lineitem
+  union all
+  select * from lineitem ) l;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexTargetWithPythonUdaf.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexTargetWithPythonUdaf.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexTargetWithPythonUdaf.sql
new file mode 100644
index 0000000..551655f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testComplexTargetWithPythonUdaf.sql
@@ -0,0 +1 @@
+select countpy() + max(l_orderkey) as merged from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation1.sql
new file mode 100644
index 0000000..6fe604e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation1.sql
@@ -0,0 +1 @@
+select l_orderkey, max(l_orderkey) as maximum, count(distinct l_linenumber) as unique_key from lineitem group by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation2.sql
new file mode 100644
index 0000000..6bf8a8a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation2.sql
@@ -0,0 +1 @@
+select l_orderkey, count(*) as cnt, count(distinct l_linenumber) as unique_key from lineitem group by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation3.sql
new file mode 100644
index 0000000..0156bef
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation3.sql
@@ -0,0 +1 @@
+select count(*), count(distinct l_orderkey), sum(distinct l_orderkey) from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation4.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation4.sql
new file mode 100644
index 0000000..0e6e14a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation4.sql
@@ -0,0 +1 @@
+select l_linenumber, count(*), count(distinct l_orderkey), sum(distinct l_orderkey) from lineitem group by l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation5.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation5.sql
new file mode 100644
index 0000000..a4d1472
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation5.sql
@@ -0,0 +1 @@
+select sum(distinct l_orderkey), l_linenumber, count(distinct l_orderkey), count(*) from lineitem group by l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation6.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation6.sql
new file mode 100644
index 0000000..242eb18
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation6.sql
@@ -0,0 +1,9 @@
+select
+  count(distinct l_orderkey) as v0,
+  sum(l_orderkey) as v1,
+  sum(l_linenumber) as v2,
+  count(*) as v4
+from
+  lineitem
+group by
+  l_orderkey;
\ No newline at end of file


[17/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash.plan
new file mode 100644
index 0000000..724e240
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash.plan
@@ -0,0 +1,51 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..9a40283
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Hash_NoBroadcast.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort.plan
new file mode 100644
index 0000000..724e240
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort.plan
@@ -0,0 +1,51 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..9a40283
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.Sort_NoBroadcast.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.result
new file mode 100644
index 0000000..304b867
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.3.result
@@ -0,0 +1,27 @@
+r_regionkey,r_name,r_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+1,AMERICA,hs use ironic, even requests. s,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+1,AMERICA,hs use ironic, even requests. s,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+1,AMERICA,hs use ironic, even requests. s,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+1,AMERICA,hs use ironic, even requests. s,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+1,AMERICA,hs use ironic, even requests. s,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+2,ASIA,ges. thinly even pinto beans ca,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+2,ASIA,ges. thinly even pinto beans ca,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+2,ASIA,ges. thinly even pinto beans ca,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+2,ASIA,ges. thinly even pinto beans ca,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+2,ASIA,ges. thinly even pinto beans ca,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+3,EUROPE,ly final courts cajole furiously final excuse,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+3,EUROPE,ly final courts cajole furiously final excuse,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+3,EUROPE,ly final courts cajole furiously final excuse,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,EUROPE,ly final courts cajole furiously final excuse,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+3,EUROPE,ly final courts cajole furiously final excuse,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash.plan
new file mode 100644
index 0000000..724e240
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash.plan
@@ -0,0 +1,51 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..9a40283
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Hash_NoBroadcast.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort.plan
new file mode 100644
index 0000000..724e240
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort.plan
@@ -0,0 +1,51 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..9a40283
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.Sort_NoBroadcast.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.result
new file mode 100644
index 0000000..a7dd7b5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.4.result
@@ -0,0 +1,27 @@
+c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment
+-------------------------------
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to 
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash.plan
new file mode 100644
index 0000000..35e397b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.5.Hash.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), length(default.region.r_comment (TEXT)) as len
+        => out schema: {(4) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.customer.c_custkey (INT4) * 10 as ?multiply
+        => out schema: {(9) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: len (INT4) (asc),default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+     => in schema: {(13) ?multiply (INT4), default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4), len (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================


[25/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testFilterPushDownPartitionColumnCaseWhen.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testFilterPushDownPartitionColumnCaseWhen.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testFilterPushDownPartitionColumnCaseWhen.sql
new file mode 100644
index 0000000..f5f426b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testFilterPushDownPartitionColumnCaseWhen.sql
@@ -0,0 +1,6 @@
+select c_custkey, c_nationkey, c_name, o_custkey, (case when a.c_nationkey > 3 then 4 else 3 end)
+from customer_parts a
+inner join orders b
+on a.c_custkey = b.o_custkey
+where a.c_custkey = (case when a.c_name like 'Customer%' and a.c_nationkey > 3 then 4 else 3 end)
+order by c_custkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength.sql
new file mode 100644
index 0000000..8e35e26
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength.sql
@@ -0,0 +1,3 @@
+select * from customer a
+ left outer join nation_partitioned b on a.c_nationkey = b.n_nationkey
+ where b.n_nationkey is not null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength2.sql
new file mode 100644
index 0000000..58a4ad2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testMultiplePartitionedBroadcastDataFileWithZeroLength2.sql
@@ -0,0 +1,5 @@
+select b.o_orderkey, b.o_orderdate, b.o_custkey, a.c_custkey, a.c_name, c.n_nationkey, c.n_name
+from customer a
+ left outer join orders b on a.c_custkey = b.o_custkey
+ left outer join nation_partitioned c on a.c_nationkey = c.n_nationkey
+ where c.n_nationkey is not null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testNoProjectionJoinQual.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testNoProjectionJoinQual.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testNoProjectionJoinQual.sql
new file mode 100644
index 0000000..1db9c1c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testNoProjectionJoinQual.sql
@@ -0,0 +1 @@
+select count(*) from customer_parts t1, customer_parts t2 where t1.c_nationkey = t2.c_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDown.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDown.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDown.sql
new file mode 100644
index 0000000..fc9063a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDown.sql
@@ -0,0 +1,9 @@
+select
+  upper(c_name) as c_name, count(1)
+from
+  customer_parts
+where
+  c_name is not null and
+  c_nationkey = 1
+group by
+  c_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin.sql
new file mode 100644
index 0000000..bbb2c45
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin.sql
@@ -0,0 +1,4 @@
+select a.n_nationkey, a.n_name, b.c_custkey, b.c_nationkey, b.c_name
+from nation a
+left outer join customer_parts b on a.n_nationkey = b.c_custkey
+and b.c_nationkey = 1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin2.sql
new file mode 100644
index 0000000..b30b2cb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartialFilterPushDownOuterJoin2.sql
@@ -0,0 +1,5 @@
+-- In the case of no partition directory
+select a.n_nationkey, a.n_name, b.c_custkey, b.c_nationkey, b.c_name
+from nation a
+left outer join customer_parts b on a.n_nationkey = b.c_custkey
+and b.c_nationkey = 100

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartitionTableJoinSmallTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartitionTableJoinSmallTable.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartitionTableJoinSmallTable.sql
new file mode 100644
index 0000000..27e2066
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testPartitionTableJoinSmallTable.sql
@@ -0,0 +1,11 @@
+select
+  c_custkey,
+  c_name,
+  c_nationkey,
+  n_nationkey
+from
+  customer_parts, nation
+where
+  c_nationkey = n_nationkey
+order by
+  c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_customer_large_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_customer_large_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_customer_large_ddl.sql
new file mode 100644
index 0000000..a9122f3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_customer_large_ddl.sql
@@ -0,0 +1,7 @@
+-- Large customer Table
+-- It is used for broadcast join
+
+create external table if not exists customer_large (
+    c_custkey INT4, c_name TEXT, c_address TEXT, c_nationkey INT4,
+    c_phone TEXT, c_acctbal FLOAT8, c_mktsegment TEXT, c_comment TEXT)
+using text with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_lineitem_large_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_lineitem_large_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_lineitem_large_ddl.sql
new file mode 100644
index 0000000..f8d574f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_lineitem_large_ddl.sql
@@ -0,0 +1,7 @@
+-- Large lineitem Table
+-- It is used for broadcast join
+
+create external table if not exists lineitem_large ( l_orderkey INT4, l_partkey INT4, l_suppkey INT4, l_linenumber INT4, l_quantity FLOAT8,
+    l_extendedprice FLOAT8, l_discount FLOAT8, l_tax FLOAT8, l_returnflag TEXT, l_linestatus TEXT, l_shipdate TEXT, l_commitdate TEXT,
+    l_receiptdate TEXT, l_shipinstruct TEXT, l_shipmode TEXT, l_comment TEXT)
+using text with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_orders_large_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_orders_large_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_orders_large_ddl.sql
new file mode 100644
index 0000000..8f99e5e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/create_orders_large_ddl.sql
@@ -0,0 +1,7 @@
+-- Large Orders Table
+-- It is used for broadcast join
+
+create external table if not exists orders_large ( o_orderkey INT4, o_custkey INT4,
+   o_orderstatus TEXT, o_totalprice FLOAT8, o_orderdate TEXT,
+   o_orderpriority TEXT, o_clerk TEXT, o_shippriority INT4, o_comment TEXT)
+using text with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/customer_partition_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/customer_partition_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/customer_partition_ddl.sql
new file mode 100644
index 0000000..7d07474
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/customer_partition_ddl.sql
@@ -0,0 +1,9 @@
+CREATE TABLE customer_broad_parts (
+  c_nationkey INT4,
+  c_name    TEXT,
+  c_address    TEXT,
+  c_phone    TEXT,
+  c_acctbal    FLOAT8,
+  c_mktsegment    TEXT,
+  c_comment    TEXT
+) PARTITION BY COLUMN (c_custkey    INT4);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer.sql
new file mode 100644
index 0000000..29152b6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer.sql
@@ -0,0 +1,11 @@
+INSERT OVERWRITE INTO customer_parts
+  SELECT
+    c_custkey,
+    c_name,
+    c_address,
+    c_phone,
+    c_acctbal,
+    c_mktsegment,
+    c_comment,
+    c_nationkey
+  FROM customer;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer_partition.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer_partition.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer_partition.sql
new file mode 100644
index 0000000..3a500a1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/insert_into_customer_partition.sql
@@ -0,0 +1,11 @@
+INSERT OVERWRITE INTO customer_broad_parts
+  SELECT
+    c_nationkey,
+    c_name,
+    c_address,
+    c_phone,
+    c_acctbal,
+    c_mktsegment,
+    c_comment,
+    c_custkey
+  FROM customer;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/nation_multifile_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/nation_multifile_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/nation_multifile_ddl.sql
new file mode 100644
index 0000000..c3f595a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/nation_multifile_ddl.sql
@@ -0,0 +1,5 @@
+create table nation_multifile (
+    n_nationkey int,
+    n_name text,
+    n_regionkey int,
+    n_comment text);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table1_ddl.sql
new file mode 100644
index 0000000..454581a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table1_ddl.sql
@@ -0,0 +1,3 @@
+create external table testOuterJoinAndCaseWhen1 (id int, name text, score float, type text) using text
+with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table2_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table2_ddl.sql
new file mode 100644
index 0000000..ac1e1f6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/oj_table2_ddl.sql
@@ -0,0 +1,3 @@
+create external table testOuterJoinAndCaseWhen2 (id int, name text, score float, type text) using text
+with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/orders_multifile_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/orders_multifile_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/orders_multifile_ddl.sql
new file mode 100644
index 0000000..64f70f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/orders_multifile_ddl.sql
@@ -0,0 +1,5 @@
+create table orders_multifile (
+    o_orderkey int,
+    o_custkey int,
+    o_orderstatus text
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/partitioned_customer_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/partitioned_customer_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/partitioned_customer_ddl.sql
new file mode 100644
index 0000000..1d2c3fe
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/partitioned_customer_ddl.sql
@@ -0,0 +1,19 @@
+CREATE TABLE if not exists customer_parts (
+  c_custkey    INT4,
+  c_name    TEXT,
+  c_address    TEXT,
+  c_phone    TEXT,
+  c_acctbal    FLOAT8,
+  c_mktsegment    TEXT,
+  c_comment    TEXT
+) PARTITION BY COLUMN (c_nationkey INT4) as
+  SELECT
+    c_custkey,
+    c_name,
+    c_address,
+    c_phone,
+    c_acctbal,
+    c_mktsegment,
+    c_comment,
+    c_nationkey
+  FROM customer;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int4_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int4_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int4_ddl.sql
new file mode 100644
index 0000000..c991f71
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int4_ddl.sql
@@ -0,0 +1,3 @@
+create external table ${0} (id int, name text, score float, type text) using text
+with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int8_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int8_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int8_ddl.sql
new file mode 100644
index 0000000..8f0b8de
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/table1_int8_ddl.sql
@@ -0,0 +1,3 @@
+create external table ${0} (id bigint, name text, score float, type text) using text
+with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition1.sql
new file mode 100644
index 0000000..b61ad38
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition1.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  n1.n_name,
+  n2.n_name
+from nation n1 join nation n2 on n1.n_name = upper(n2.n_name)
+order by n1.n_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition2.sql
new file mode 100644
index 0000000..33effbb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition2.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  n1.n_name,
+  upper(n2.n_name) as name
+from nation n1 join nation n2 on n1.n_name = upper(n2.n_name)
+order by n1.n_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition3.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition3.sql
new file mode 100644
index 0000000..5674269
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition3.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  n1.n_name,
+  n2.n_name
+from nation n1 join nation n2 on lower(n1.n_name) = lower(n2.n_name)
+order by n1.n_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition4.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition4.sql
new file mode 100644
index 0000000..45d8adf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition4.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  substr(n1.n_name, 1, 4) name1,
+  substr(n2.n_name, 1, 4) name2
+from nation n1 join nation n2 on substr(n1.n_name, 1, 4) = substr(n2.n_name, 1, 4)
+order by n1.n_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition5.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition5.sql
new file mode 100644
index 0000000..f604bc7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition5.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  substr(n1.n_name, 1, 4) name1,
+  substr(n2.n_name, 1, 4) name2
+from nation n1 join (select * from nation) n2 on substr(n1.n_name, 1, 4) = substr(n2.n_name, 1, 4)
+order by n1.n_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition6.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition6.sql
new file mode 100644
index 0000000..0ef3143
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition6.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  substr(n1.n_name, 1, 4) name1,
+  substr(n2.n_name, 1, 4) name2
+from nation n1 join (select * from nation union all select * from nation) n2 on substr(n1.n_name, 1, 4) = substr(n2.n_name, 1, 4)
+order by n1.n_nationkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition7.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition7.sql
new file mode 100644
index 0000000..4931c83
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinCondition7.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  n1.n_name,
+  n2.n_name
+from nation n1 join (select * from nation union all select * from nation) n2 on substr(n1.n_name, 1, 4) = substr(n2.n_name, 1, 4)
+order by n1.n_nationkey,n2.n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen.sql
new file mode 100644
index 0000000..b2c49a4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen.sql
@@ -0,0 +1,11 @@
+select
+  r_name,
+  case when
+    s_name is null then 'N/O'
+  else
+    s_name
+  end as s1
+from
+  region inner join nation on n_regionkey = r_regionkey
+  left outer join supplier on s_nationkey = n_nationkey
+order by r_name, s1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen2.sql
new file mode 100644
index 0000000..5e2918f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testComplexJoinsWithCaseWhen2.sql
@@ -0,0 +1,9 @@
+select
+  r_name,
+  case when s_name is null then 'N/O'
+  else s_name end as s1
+from region inner join (
+  select * from nation
+  left outer join supplier on s_nationkey = n_nationkey
+) t on n_regionkey = r_regionkey
+order by r_name, s1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithEmptyTable1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..1e0cb56
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithEmptyTable1.sql
@@ -0,0 +1,8 @@
+select
+  c_custkey,
+  empty_orders.o_orderkey
+from
+  customer, empty_orders
+where c_custkey = o_orderkey
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.sql
new file mode 100644
index 0000000..4e20e16
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.sql
@@ -0,0 +1,2 @@
+select a.r_name as a_name, b.r_name as b_name from region a, region b
+where a_name < b_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testDifferentTypesJoinCondition.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testDifferentTypesJoinCondition.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testDifferentTypesJoinCondition.sql
new file mode 100644
index 0000000..6bd0a4c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testDifferentTypesJoinCondition.sql
@@ -0,0 +1 @@
+select * from table20 t3 join table21 t4 on t3.id = t4.id;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoin1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoin1.sql
new file mode 100644
index 0000000..ccaa5fb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoin1.sql
@@ -0,0 +1,8 @@
+select
+  c_custkey,
+  orders.o_orderkey
+from
+  orders full outer join customer on c_custkey = o_orderkey
+order by
+  c_custkey,
+  orders.o_orderkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoinWithEmptyTable1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..b9e3efd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testFullOuterJoinWithEmptyTable1.sql
@@ -0,0 +1,8 @@
+select
+  c_custkey,
+  empty_orders.o_orderkey
+from
+  empty_orders full outer join customer on c_custkey = o_orderkey
+order by
+  c_custkey,
+  empty_orders.o_orderkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinAndCaseWhen.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinAndCaseWhen.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinAndCaseWhen.sql
new file mode 100644
index 0000000..d058aba
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinAndCaseWhen.sql
@@ -0,0 +1,18 @@
+select
+  r_regionkey,
+  n_regionkey,
+  case
+    when r_regionkey = 1 then 'one'
+    when r_regionkey = 2 then 'two'
+    when r_regionkey = 3 then 'three'
+    when r_regionkey = 4 then 'four'
+    else 'zero'
+  end as cond
+from
+  region,
+  nation
+where
+  r_regionkey = n_regionkey
+order by
+  r_regionkey,
+  n_regionkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithEmptyTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithEmptyTable.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithEmptyTable.sql
new file mode 100644
index 0000000..1e0cb56
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithEmptyTable.sql
@@ -0,0 +1,8 @@
+select
+  c_custkey,
+  empty_orders.o_orderkey
+from
+  customer, empty_orders
+where c_custkey = o_orderkey
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.sql
new file mode 100644
index 0000000..90f4822
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testInnerJoinWithThetaJoinConditionInWhere.sql
@@ -0,0 +1,3 @@
+select a.r_regionkey, a.r_name, b.r_name from region a join region b
+on a.r_regionkey = b.r_regionkey
+where a.r_name <= b.r_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinAsterisk.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinAsterisk.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinAsterisk.sql
new file mode 100644
index 0000000..e3de03c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinAsterisk.sql
@@ -0,0 +1,3 @@
+select *
+from nation b
+join customer a on b.n_nationkey = a.c_nationkey

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvals1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvals1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvals1.sql
new file mode 100644
index 0000000..3a123bb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvals1.sql
@@ -0,0 +1,11 @@
+select
+  r_regionkey,
+  n_regionkey,
+  (r_regionkey + n_regionkey) as plus
+from
+  region,
+  nation
+where
+  r_regionkey = n_regionkey
+order by
+  r_regionkey, n_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsFilterPushdown.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsFilterPushdown.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsFilterPushdown.sql
new file mode 100644
index 0000000..680311d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsFilterPushdown.sql
@@ -0,0 +1,13 @@
+select * from (
+select
+  r_regionkey,
+  n_regionkey,
+  (r_regionkey + n_regionkey) as plus
+from
+  region,
+  nation
+where
+  r_regionkey = n_regionkey
+order by
+  r_regionkey, n_regionkey
+) where plus > 10
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs1.sql
new file mode 100644
index 0000000..3638393
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs1.sql
@@ -0,0 +1,14 @@
+select
+  n_regionkey + n_nationkey as v1,
+  n_regionkey,
+  r_regionkey,
+  (r_regionkey + n_regionkey) as plus1,
+  (r_regionkey + n_regionkey) as plus2,
+  ((r_regionkey + n_regionkey) / 2) as result
+from
+  region,
+  nation
+where
+  r_regionkey = n_regionkey and r_regionkey > 0
+order by
+  n_regionkey + n_nationkey, n_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs2.sql
new file mode 100644
index 0000000..a5b75d4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinCoReferredEvalsWithSameExprs2.sql
@@ -0,0 +1,22 @@
+select
+  n_regionkey + n_nationkey as v1,
+  n_regionkey,
+  r_regionkey,
+  (r_regionkey + n_regionkey) as plus1,
+  (r_regionkey + n_regionkey) as plus2,
+  ((r_regionkey + n_regionkey) / 2) as result,
+  sum(r_regionkey + n_regionkey) as total
+from
+  region,
+  nation
+where
+  r_regionkey = n_regionkey and r_regionkey > 0
+group by
+  n_regionkey + n_nationkey,
+  n_regionkey,
+  r_regionkey,
+  (r_regionkey + n_regionkey),
+  ((r_regionkey + n_regionkey) / 2)
+
+order by
+  n_regionkey + n_nationkey, n_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinFilterOfRowPreservedTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinFilterOfRowPreservedTable1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinFilterOfRowPreservedTable1.sql
new file mode 100644
index 0000000..50ea371
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinFilterOfRowPreservedTable1.sql
@@ -0,0 +1,8 @@
+select
+  r_name,
+  r_regionkey,
+  n_name,
+  n_regionkey
+from
+  region left outer join nation on n_regionkey = r_regionkey and r_name in ('AMERICA', 'ASIA')
+order by r_name,n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabases.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabases.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabases.sql
new file mode 100644
index 0000000..eb5a2c5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabases.sql
@@ -0,0 +1,25 @@
+select
+	s_acctbal,
+	s_name,
+	n_name,
+	JOINS.part_.p_partkey,
+	p_mfgr,
+	JOINS.supplier_.s_address,
+	JOINS.supplier_.s_phone,
+	s_comment
+from
+	JOINS.part_,
+	JOINS.supplier_,
+	partsupp,
+	nation,
+	region
+where
+	p_partkey = ps_partkey
+	and s_suppkey = ps_suppkey
+	and s_nationkey = n_nationkey
+	and n_regionkey = r_regionkey
+order by
+  s_acctbal,
+  s_name,
+  n_name,
+  p_partkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabasesWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabasesWithJson.json b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabasesWithJson.json
new file mode 100644
index 0000000..874305d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinOnMultipleDatabasesWithJson.json
@@ -0,0 +1,210 @@
+/*
+ select
+ s_acctbal,
+ s_name,
+ n_name,
+ JOINS.part_.p_partkey,
+ p_mfgr,
+ JOINS.supplier_.s_address,
+ JOINS.supplier_.s_phone,
+ s_comment
+ from
+ JOINS.part_,
+ JOINS.supplier_,
+ partsupp,
+ nation,
+ region
+ where
+ p_partkey = ps_partkey
+ and s_suppkey = ps_suppkey
+ and s_nationkey = n_nationkey
+ and n_regionkey = r_regionkey
+ order by
+ s_acctbal,
+ s_name,
+ n_name,
+ p_partkey;
+ */
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "Expr": {
+                "ColumnName": "s_acctbal",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "ColumnName": "s_name",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "ColumnName": "n_name",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "joins.part_",
+                "ColumnName": "p_partkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "ColumnName": "p_mfgr",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "joins.supplier_",
+                "ColumnName": "s_address",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "joins.supplier_",
+                "ColumnName": "s_phone",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "ColumnName": "s_comment",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "SortSpecs": [
+            {
+                "SortKey": {
+                    "ColumnName": "s_acctbal",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "s_name",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "n_name",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "p_partkey",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            }
+        ],
+        "Expr": {
+            "SelectCondition": {
+                "LeftExpr": {
+                    "LeftExpr": {
+                        "ColumnName": "p_partkey",
+                        "OpType": "Column"
+                    },
+                    "RightExpr": {
+                        "ColumnName": "ps_partkey",
+                        "OpType": "Column"
+                    },
+                    "OpType": "Equals"
+                },
+                "RightExpr": {
+                    "LeftExpr": {
+                        "LeftExpr": {
+                            "ColumnName": "s_suppkey",
+                            "OpType": "Column"
+                        },
+                        "RightExpr": {
+                            "ColumnName": "ps_suppkey",
+                            "OpType": "Column"
+                        },
+                        "OpType": "Equals"
+                    },
+                    "RightExpr": {
+                        "LeftExpr": {
+                            "LeftExpr": {
+                                "ColumnName": "s_nationkey",
+                                "OpType": "Column"
+                            },
+                            "RightExpr": {
+                                "ColumnName": "n_nationkey",
+                                "OpType": "Column"
+                            },
+                            "OpType": "Equals"
+                        },
+                        "RightExpr": {
+                            "LeftExpr": {
+                                "ColumnName": "n_regionkey",
+                                "OpType": "Column"
+                            },
+                            "RightExpr": {
+                                "ColumnName": "r_regionkey",
+                                "OpType": "Column"
+                            },
+                            "OpType": "Equals"
+                        },
+                        "OpType": "And"
+                    },
+                    "OpType": "And"
+                },
+                "OpType": "And"
+            },
+            "Expr": {
+                "Relations": [
+                    {
+                        "TableName": "joins.part_",
+                        "OpType": "Relation"
+                    },
+                    {
+                        "TableName": "joins.supplier_",
+                        "OpType": "Relation"
+                    },
+                    {
+                        "TableName": "partsupp",
+                        "OpType": "Relation"
+                    },
+                    {
+                        "TableName": "nation",
+                        "OpType": "Relation"
+                    },
+                    {
+                        "TableName": "region",
+                        "OpType": "Relation"
+                    }
+                ],
+                "OpType": "RelationList"
+            },
+            "OpType": "Filter"
+        },
+        "OpType": "Sort"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson.json b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson.json
new file mode 100644
index 0000000..f6b34cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson.json
@@ -0,0 +1,92 @@
+// select length(r_comment) as len, *, c_custkey*10 from customer, region order by len,r_regionkey,r_name
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "AliasName": "len",
+            "Expr": {
+                "Signature": "length",
+                "FuncParams": [
+                    {
+                        "ColumnName": "r_comment",
+                        "OpType": "Column"
+                    }
+                ],
+                "OpType": "Function"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "OpType": "Asterisk"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "LeftExpr": {
+                    "ColumnName": "c_custkey",
+                    "OpType": "Column"
+                },
+                "RightExpr": {
+                    "Value": "10",
+                    "ValueType": "Unsigned_Integer",
+                    "OpType": "Literal"
+                },
+                "OpType": "Multiply"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "SortSpecs": [
+            {
+                "SortKey": {
+                    "ColumnName": "len",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "r_regionkey",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "r_name",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "c_custkey",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            }
+        ],
+        "Expr": {
+            "Relations": [
+                {
+                    "TableName": "customer",
+                    "OpType": "Relation"
+                },
+                {
+                    "TableName": "region",
+                    "OpType": "Relation"
+                }
+            ],
+            "OpType": "RelationList"
+        },
+        "OpType": "Sort"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson2.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson2.json b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson2.json
new file mode 100644
index 0000000..353636a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithJson2.json
@@ -0,0 +1,219 @@
+/*
+ select t.n_nationkey, t.n_name, t.n_regionkey, t.n_comment, ps.ps_availqty, s.s_suppkey
+ from (
+ select n_nationkey, n_name, n_regionkey, n_comment
+ from nation n
+ join region r on (n.n_regionkey = r.r_regionkey)
+ ) t
+ join supplier s on (s.s_nationkey = t.n_nationkey)
+ join partsupp ps on (s.s_suppkey = ps.ps_suppkey)
+ where t.n_name in ('ARGENTINA','ETHIOPIA', 'MOROCCO');
+ */
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "Expr": {
+                "Qualifier": "t",
+                "ColumnName": "n_nationkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "t",
+                "ColumnName": "n_name",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "t",
+                "ColumnName": "n_regionkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "t",
+                "ColumnName": "n_comment",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "ps",
+                "ColumnName": "ps_availqty",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "Expr": {
+                "Qualifier": "s",
+                "ColumnName": "s_suppkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "SelectCondition": {
+            "IsNot": false,
+            "LeftExpr": {
+                "Qualifier": "t",
+                "ColumnName": "n_name",
+                "OpType": "Column"
+            },
+            "RightExpr": {
+                "Values": [
+                    {
+                        "Value": "ARGENTINA",
+                        "ValueType": "String",
+                        "OpType": "Literal"
+                    },
+                    {
+                        "Value": "ETHIOPIA",
+                        "ValueType": "String",
+                        "OpType": "Literal"
+                    },
+                    {
+                        "Value": "MOROCCO",
+                        "ValueType": "String",
+                        "OpType": "Literal"
+                    }
+                ],
+                "OpType": "ValueList"
+            },
+            "OpType": "InPredicate"
+        },
+        "Expr": {
+            "Relations": [
+                {
+                    "JoinType": "INNER",
+                    "JoinCondition": {
+                        "LeftExpr": {
+                            "Qualifier": "s",
+                            "ColumnName": "s_suppkey",
+                            "OpType": "Column"
+                        },
+                        "RightExpr": {
+                            "Qualifier": "ps",
+                            "ColumnName": "ps_suppkey",
+                            "OpType": "Column"
+                        },
+                        "OpType": "Equals"
+                    },
+                    "IsNatural": false,
+                    "LeftExpr": {
+                        "JoinType": "INNER",
+                        "JoinCondition": {
+                            "LeftExpr": {
+                                "Qualifier": "s",
+                                "ColumnName": "s_nationkey",
+                                "OpType": "Column"
+                            },
+                            "RightExpr": {
+                                "Qualifier": "t",
+                                "ColumnName": "n_nationkey",
+                                "OpType": "Column"
+                            },
+                            "OpType": "Equals"
+                        },
+                        "IsNatural": false,
+                        "LeftExpr": {
+                            "SubPlan": {
+                                "IsDistinct": false,
+                                "Projections": [
+                                    {
+                                        "Expr": {
+                                            "ColumnName": "n_nationkey",
+                                            "OpType": "Column"
+                                        },
+                                        "OpType": "Target"
+                                    },
+                                    {
+                                        "Expr": {
+                                            "ColumnName": "n_name",
+                                            "OpType": "Column"
+                                        },
+                                        "OpType": "Target"
+                                    },
+                                    {
+                                        "Expr": {
+                                            "ColumnName": "n_regionkey",
+                                            "OpType": "Column"
+                                        },
+                                        "OpType": "Target"
+                                    },
+                                    {
+                                        "Expr": {
+                                            "ColumnName": "n_comment",
+                                            "OpType": "Column"
+                                        },
+                                        "OpType": "Target"
+                                    }
+                                ],
+                                "Expr": {
+                                    "Relations": [
+                                        {
+                                            "JoinType": "INNER",
+                                            "JoinCondition": {
+                                                "LeftExpr": {
+                                                    "Qualifier": "n",
+                                                    "ColumnName": "n_regionkey",
+                                                    "OpType": "Column"
+                                                },
+                                                "RightExpr": {
+                                                    "Qualifier": "r",
+                                                    "ColumnName": "r_regionkey",
+                                                    "OpType": "Column"
+                                                },
+                                                "OpType": "Equals"
+                                            },
+                                            "IsNatural": false,
+                                            "LeftExpr": {
+                                                "TableName": "nation",
+                                                "TableAlias": "n",
+                                                "OpType": "Relation"
+                                            },
+                                            "RightExpr": {
+                                                "TableName": "region",
+                                                "TableAlias": "r",
+                                                "OpType": "Relation"
+                                            },
+                                            "OpType": "Join"
+                                        }
+                                    ],
+                                    "OpType": "RelationList"
+                                },
+                                "OpType": "Projection"
+                            },
+                            "TableName": "t",
+                            "OpType": "TablePrimaryTableSubQuery"
+                        },
+                        "RightExpr": {
+                            "TableName": "supplier",
+                            "TableAlias": "s",
+                            "OpType": "Relation"
+                        },
+                        "OpType": "Join"
+                    },
+                    "RightExpr": {
+                        "TableName": "partsupp",
+                        "TableAlias": "ps",
+                        "OpType": "Relation"
+                    },
+                    "OpType": "Join"
+                }
+            ],
+            "OpType": "RelationList"
+        },
+        "OpType": "Filter"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual1.sql
new file mode 100644
index 0000000..9a04dc5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual1.sql
@@ -0,0 +1,20 @@
+select
+	s.s_acctbal,
+	s.s_name,
+	n.n_name,
+	p.p_partkey,
+	p.p_mfgr,
+	s.s_address,
+	s.s_phone,
+	s.s_comment
+from nation n
+join region r on (n.n_regionkey = r.r_regionkey)
+join supplier s on (s.s_nationkey = n.n_nationkey)
+join partsupp ps on (s.s_suppkey = ps.ps_suppkey)
+join part p on (p.p_partkey = ps.ps_partkey)
+where n.n_regionkey = ps.ps_suppkey
+order by
+  s.s_acctbal,
+  s.s_name,
+  n.n_name,
+  p.p_partkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual2.sql
new file mode 100644
index 0000000..4a40651
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual2.sql
@@ -0,0 +1,8 @@
+select t.n_nationkey, t.name, t.n_regionkey, t.n_comment
+from (
+  select n_nationkey, n_name as name, n_regionkey, n_comment
+  from nation n
+  join region r on (n.n_regionkey = r.r_regionkey)
+) t
+join supplier s on (s.s_nationkey = t.n_nationkey)
+where t.name = 'MOROCCO';

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual3.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual3.sql
new file mode 100644
index 0000000..b34e9de
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual3.sql
@@ -0,0 +1,9 @@
+select t.n_nationkey, t.n_name, t.n_regionkey, t.n_comment, ps.ps_availqty, s.s_suppkey
+from (
+  select n_nationkey, n_name, n_regionkey, n_comment
+  from nation n
+  join region r on (n.n_regionkey = r.r_regionkey)
+) t
+join supplier s on (s.s_nationkey = t.n_nationkey)
+join partsupp ps on (s.s_suppkey = ps.ps_suppkey)
+where t.n_name in ('ARGENTINA','ETHIOPIA', 'MOROCCO');

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual4.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual4.sql
new file mode 100644
index 0000000..4519de7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual4.sql
@@ -0,0 +1,10 @@
+select t.n_nationkey, t.n_name, t.n_regionkey, t.n_comment, ps.ps_availqty, s.s_suppkey
+from (
+  select n_nationkey, n_name, n_regionkey, n_comment
+  from nation n
+  join region r on (n.n_regionkey = r.r_regionkey)
+) t
+join supplier s on (s.s_nationkey = t.n_nationkey)
+join partsupp ps on (s.s_suppkey = ps.ps_suppkey)
+where t.n_name in ('ARGENTINA','ETHIOPIA', 'MOROCCO')
+and t.n_nationkey > s.s_suppkey ;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinTypes.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinTypes.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinTypes.sql
new file mode 100644
index 0000000..ffb23ce
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinTypes.sql
@@ -0,0 +1,4 @@
+select * FROM
+customer c
+right outer join (select n_nationkey from nation) n on n.n_nationkey = c.c_custkey
+join region r on r.r_regionkey = c.c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithOrPredicates.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithOrPredicates.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithOrPredicates.sql
new file mode 100644
index 0000000..b388233
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testJoinWithOrPredicates.sql
@@ -0,0 +1,6 @@
+select
+  n1.n_nationkey,
+  n1.n_name,
+  n2.n_name
+from nation n1, nation n2 where n1.n_name = n2.n_name and (n1.n_nationkey in (1, 2) or n2.n_nationkey in (2))
+order by n1.n_nationkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoin1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoin1.sql
new file mode 100644
index 0000000..08a68e8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoin1.sql
@@ -0,0 +1,9 @@
+select
+  c_custkey,
+  orders.o_orderkey,
+  orders.o_orderstatus,
+  orders.o_orderdate
+from
+  customer left outer join orders on c_custkey = o_orderkey
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr1.sql
new file mode 100644
index 0000000..f5b0ba7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr1.sql
@@ -0,0 +1,9 @@
+select
+  c_custkey,
+  orders.o_orderkey,
+  'val' as val
+from
+  customer left outer join orders on c_custkey = o_orderkey
+order by
+  c_custkey,
+  o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr2.sql
new file mode 100644
index 0000000..7333d54
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr2.sql
@@ -0,0 +1,9 @@
+select
+  c_custkey,
+  o.o_orderkey,
+  'val' as val
+from
+  customer left outer join (select * from orders) o on c_custkey = o.o_orderkey
+order by
+  c_custkey,
+  o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr3.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr3.sql
new file mode 100644
index 0000000..f79b18b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr3.sql
@@ -0,0 +1,17 @@
+select
+  a.c_custkey,
+  123::INT8 as const_val,
+  b.min_name
+from
+  customer a
+left outer join (
+  select
+    c_custkey,
+    min(c_name) as min_name
+    from customer
+  group by
+    c_custkey)
+  b
+on a.c_custkey = b.c_custkey
+order by
+  a.c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr4.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr4.sql
new file mode 100644
index 0000000..9e3838d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr4.sql
@@ -0,0 +1,6 @@
+SELECT
+  l.l_orderkey,
+  o.o_orderkey,
+  '201405' as key1,
+  '5-LOW' as key2
+from lineitem l left outer join orders o on l.l_orderkey = o.o_orderkey and o_orderpriority = '5-LOW';

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr5.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr5.sql
new file mode 100644
index 0000000..720a004
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithConstantExpr5.sql
@@ -0,0 +1,9 @@
+SELECT
+  l.l_orderkey,
+  o.o_orderkey,
+  '201405' as key1,
+  '5-LOW' as key2
+from
+  lineitem l left outer join orders o on l.l_orderkey = o.o_orderkey
+WHERE
+  o_orderpriority = '5-LOW'

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..27ac8bc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable1.sql
@@ -0,0 +1,9 @@
+select
+  c_custkey,
+  empty_orders.o_orderkey,
+  empty_orders.o_orderstatus,
+  empty_orders.o_orderdate
+from
+  customer left outer join empty_orders on c_custkey = o_orderkey
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable2.sql
new file mode 100644
index 0000000..b0639ff
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable2.sql
@@ -0,0 +1,9 @@
+select
+  c_custkey,
+  sum(empty_orders.o_orderkey),
+  max(empty_orders.o_orderstatus),
+  max(empty_orders.o_orderdate)
+from
+  customer left outer join empty_orders on c_custkey = o_orderkey
+  group by c_custkey
+order by c_custkey ;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable3.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable3.sql
new file mode 100644
index 0000000..6a79e34
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable3.sql
@@ -0,0 +1,14 @@
+select count(*)
+from (
+  select
+    c_custkey,
+    sum(empty_orders.o_orderkey) as total1,
+    max(empty_orders.o_orderstatus) as total2,
+    max(empty_orders.o_orderdate) as total3
+  from
+    customer left outer join empty_orders on c_custkey = o_orderkey
+    group by c_custkey
+) t1
+group by
+  c_custkey
+order by c_custkey  ;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable4.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable4.sql
new file mode 100644
index 0000000..f4e9da6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable4.sql
@@ -0,0 +1,17 @@
+
+  select
+    max(c_custkey),
+    sum(orders.o_orderkey),
+    max(orders.o_orderstatus),
+    max(orders.o_orderdate)
+  from
+    customer left outer join orders on c_custkey = o_orderkey
+  union all
+  select
+    max(c_custkey),
+    sum(empty_orders.o_orderkey),
+    max(empty_orders.o_orderstatus),
+    max(empty_orders.o_orderdate)
+  from
+    customer left outer join empty_orders on c_custkey = o_orderkey
+;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable5.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable5.sql
new file mode 100644
index 0000000..d4ef649
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithEmptyTable5.sql
@@ -0,0 +1,11 @@
+select
+  l_linenumber,
+  sum(empty_orders.o_orderkey),
+  max(empty_orders.o_orderstatus),
+  max(empty_orders.o_orderdate),
+  avg(l_quantity),
+  sum(l_quantity)
+from
+  lineitem left outer join empty_orders on l_orderkey = o_orderkey
+  group by l_linenumber
+order by l_linenumber ;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull1.sql
new file mode 100644
index 0000000..5698a74
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull1.sql
@@ -0,0 +1,10 @@
+select
+  c_custkey,
+  orders.o_orderkey,
+  coalesce(orders.o_orderstatus, 'N/A'),
+  orders.o_orderdate
+from
+  customer left outer join orders on c_custkey = o_orderkey
+where o_orderkey is null
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull2.sql
new file mode 100644
index 0000000..000ab68
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull2.sql
@@ -0,0 +1,11 @@
+select
+  c_custkey,
+  orders.o_orderkey,
+  coalesce(orders.o_orderstatus, 'N/A'),
+  orders.o_orderdate
+from
+  customer left outer join orders on c_custkey = o_orderkey
+where orders.o_orderdate is not null
+and orders.o_orderdate like '1996%'
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull3.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull3.sql
new file mode 100644
index 0000000..32a7750
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithNull3.sql
@@ -0,0 +1,10 @@
+select
+  c_custkey,
+  orders.o_orderkey,
+  coalesce(orders.o_orderstatus, 'N/A'),
+  orders.o_orderdate
+from
+  customer left outer join orders on c_custkey = o_orderkey
+where orders.o_orderkey = 100
+order by
+  c_custkey, o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithThetaJoinConditionInWhere.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithThetaJoinConditionInWhere.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithThetaJoinConditionInWhere.sql
new file mode 100644
index 0000000..f9160c5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testLeftOuterJoinWithThetaJoinConditionInWhere.sql
@@ -0,0 +1,3 @@
+select * from region a left outer join customer b
+on a.r_regionkey = b.c_custkey
+where a.r_name < b.c_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testNaturalJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testNaturalJoin.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testNaturalJoin.sql
new file mode 100644
index 0000000..fcbdcdc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testNaturalJoin.sql
@@ -0,0 +1,3 @@
+select n1.n_name, n2.n_name
+from nation n1 natural join nation n2
+order by n2.n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testOuterJoinAndCaseWhen1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testOuterJoinAndCaseWhen1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testOuterJoinAndCaseWhen1.sql
new file mode 100644
index 0000000..2071e65
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testOuterJoinAndCaseWhen1.sql
@@ -0,0 +1,12 @@
+select
+  a.id,
+  a.name,
+  b.id as id2,
+  b.name as name2,
+  case when b.name is null then '9991231' else b.name end as c1,
+  case when c.name is null then '9991231' else c.name end as c2
+from
+  testOuterJoinAndCaseWhen1 a left outer join testOuterJoinAndCaseWhen2 b on a.id = b.id left outer join testOuterJoinAndCaseWhen1 c on b.id = c.id
+order by
+  a.id,
+  a.name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoin1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoin1.sql
new file mode 100644
index 0000000..ba4c713
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoin1.sql
@@ -0,0 +1,8 @@
+select
+  c_custkey,
+  orders.o_orderkey
+from
+  orders right outer join customer on c_custkey = o_orderkey
+order by
+  c_custkey,
+  orders.o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithEmptyTable1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..651a3cf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithEmptyTable1.sql
@@ -0,0 +1,8 @@
+select
+  c_custkey,
+  empty_orders.o_orderkey
+from
+  empty_orders right outer join customer on c_custkey = o_orderkey
+order by
+  c_custkey,
+  empty_orders.o_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithThetaJoinConditionInWhere.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithThetaJoinConditionInWhere.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithThetaJoinConditionInWhere.sql
new file mode 100644
index 0000000..10d9918
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testRightOuterJoinWithThetaJoinConditionInWhere.sql
@@ -0,0 +1,3 @@
+select * from region a right outer join customer b
+on a.r_regionkey = b.c_custkey
+where a.r_name < b.c_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testTPCHQ2Join.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testTPCHQ2Join.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testTPCHQ2Join.sql
new file mode 100644
index 0000000..9b7b5b9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testTPCHQ2Join.sql
@@ -0,0 +1,25 @@
+select
+	s_acctbal,
+	s_name,
+	n_name,
+	p_partkey,
+	p_mfgr,
+	s_address,
+	s_phone,
+	s_comment
+from
+	part,
+	supplier,
+	partsupp,
+	nation,
+	region
+where
+	p_partkey = ps_partkey
+	and s_suppkey = ps_suppkey
+	and s_nationkey = n_nationkey
+	and n_regionkey = r_regionkey
+order by
+  s_acctbal,
+  s_name,
+  n_name,
+  p_partkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin1.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin1.sql
new file mode 100644
index 0000000..575456f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin1.sql
@@ -0,0 +1,11 @@
+select
+  n_name,
+  r_name,
+  n_regionkey,
+  r_regionkey
+from
+  nation,
+  region
+where
+  n_regionkey = r_regionkey
+order by n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin2.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin2.sql
new file mode 100644
index 0000000..efc07b3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin2.sql
@@ -0,0 +1,9 @@
+select
+  n_name,
+  r_name
+from
+  nation,
+  region
+where
+  n_regionkey = r_regionkey
+order by n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin3.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin3.sql
new file mode 100644
index 0000000..04fd25b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin3.sql
@@ -0,0 +1,10 @@
+select
+  n_name,
+  r_name,
+  n_nationkey + 1 as p1,
+  r_regionkey + 1 as p2
+from
+  nation, region
+where
+  n_regionkey = r_regionkey
+order by n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin4.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin4.sql
new file mode 100644
index 0000000..777de8a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin4.sql
@@ -0,0 +1,9 @@
+select
+  n_name,
+  r_name,
+  n_nationkey + r_regionkey
+from
+  nation, region
+where
+  n_regionkey = r_regionkey
+order by n_name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin5.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin5.sql
new file mode 100644
index 0000000..3494007
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin5.sql
@@ -0,0 +1,15 @@
+select
+	s_acctbal,
+	s_name,
+	p_partkey
+from
+	part,
+	supplier,
+	partsupp
+where
+	p_partkey = ps_partkey and
+	s_suppkey = ps_suppkey
+order by
+  s_acctbal,
+  s_name,
+  p_partkey;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin6.sql b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin6.sql
new file mode 100644
index 0000000..62d3b79
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinQuery/testWhereClauseJoin6.sql
@@ -0,0 +1,19 @@
+select
+	s_acctbal,
+	s_name,
+	p_partkey,
+	n_name
+from
+	part,
+	supplier,
+	partsupp,
+	nation
+where
+	p_partkey = ps_partkey and
+	s_suppkey = ps_suppkey and
+	s_nationkey = n_nationkey
+order by
+  s_acctbal,
+  s_name,
+  p_partkey,
+  n_name;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestLogicalPlanner/window1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestLogicalPlanner/window1.sql b/tajo-core-tests/src/test/resources/queries/TestLogicalPlanner/window1.sql
new file mode 100644
index 0000000..9d30145
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestLogicalPlanner/window1.sql
@@ -0,0 +1,5 @@
+ SELECT
+  l_orderkey,
+  sum(l_partkey) over()
+FROM
+  lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/table1_ddl.sql
new file mode 100644
index 0000000..b4cc87e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/table1_ddl.sql
@@ -0,0 +1,4 @@
+-- It is used in TestNetTypes
+
+create external table IF NOT EXISTS table1 (id int, name text, score float, type text, addr inet4) using text
+with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/table2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/table2_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/table2_ddl.sql
new file mode 100644
index 0000000..40f0464
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/table2_ddl.sql
@@ -0,0 +1,4 @@
+-- It is used in TestNetTypes
+
+create external table IF NOT EXISTS table2 (id int, name text, score float, type text, addr inet4) using text
+with ('text.delimiter'='|', 'text.null'='NULL') location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby.sql
new file mode 100644
index 0000000..27353a9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby.sql
@@ -0,0 +1,8 @@
+select
+  name, addr, count(1)
+from
+  table1
+group by
+  name, addr
+order by
+  name, addr;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby2.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby2.sql
new file mode 100644
index 0000000..6c3c357
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testGroupby2.sql
@@ -0,0 +1,9 @@
+select
+  addr,
+  count(*)
+from
+  table1
+group by
+  addr
+order by
+  addr;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/testJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/testJoin.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testJoin.sql
new file mode 100644
index 0000000..22c97d5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testJoin.sql
@@ -0,0 +1 @@
+select t1.*,t2.* from table1 as t1, table2 as t2 where t1.addr = t2.addr order by t1.id, t1.name,t2. name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSelect.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSelect.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSelect.sql
new file mode 100644
index 0000000..1b28f06
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSelect.sql
@@ -0,0 +1 @@
+select name, addr from table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort.sql
new file mode 100644
index 0000000..2999a02
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort.sql
@@ -0,0 +1 @@
+select * from table1 order by addr;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort2.sql b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort2.sql
new file mode 100644
index 0000000..b613d4a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestNetTypes/testSort2.sql
@@ -0,0 +1 @@
+select addr from table2 order by addr;
\ No newline at end of file


[35/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestHBaseTable.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestHBaseTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestHBaseTable.java
new file mode 100644
index 0000000..4ff5e3e
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestHBaseTable.java
@@ -0,0 +1,1408 @@
+/**
+ * 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.query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.*;
+import org.apache.hadoop.hbase.filter.Filter;
+import org.apache.hadoop.hbase.filter.InclusiveStopFilter;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.expr.*;
+import org.apache.tajo.plan.logical.ScanNode;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.storage.Tablespace;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.storage.fragment.Fragment;
+import org.apache.tajo.storage.hbase.*;
+import org.apache.tajo.util.Bytes;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.TUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URI;
+import java.sql.ResultSet;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestHBaseTable extends QueryTestCaseBase {
+  private static final Log LOG = LogFactory.getLog(TestHBaseTable.class);
+
+  private static String tableSpaceUri;
+  private static String hostName,zkPort;
+
+  @BeforeClass
+  public static void beforeClass() throws IOException {
+    try {
+      testingCluster.getHBaseUtil().startHBaseCluster();
+      hostName = InetAddress.getLocalHost().getHostName();
+      zkPort = testingCluster.getHBaseUtil().getConf().get(HConstants.ZOOKEEPER_CLIENT_PORT);
+      assertNotNull(hostName);
+      assertNotNull(zkPort);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+
+    tableSpaceUri = "hbase:zk://" + hostName + ":" + zkPort;
+    HBaseTablespace hBaseTablespace = new HBaseTablespace("cluster1", URI.create(tableSpaceUri));
+    hBaseTablespace.init(new TajoConf(testingCluster.getHBaseUtil().getConf()));
+    TablespaceManager.addTableSpaceForTest(hBaseTablespace);
+  }
+
+  @AfterClass
+  public static void afterClass() {
+    try {
+      testingCluster.getHBaseUtil().stopHBaseCluster();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void testVerifyCreateHBaseTableRequiredMeta() throws Exception {
+    try {
+      executeString("CREATE TABLE hbase_mapped_table1 (col1 text, col2 text) TABLESPACE cluster1 USING hbase").close();
+      fail("hbase table must have 'table' meta");
+    } catch (TajoException e) {
+      assertEquals(e.getErrorCode(), ResultCode.MISSING_TABLE_PROPERTY);
+    }
+
+    try {
+      executeString("CREATE TABLE hbase_mapped_table1 (col1 text, col2 text) TABLESPACE cluster1 " +
+          "USING hbase " +
+          "WITH ('table'='hbase_table')").close();
+
+      fail("hbase table must have 'columns' meta");
+    } catch (TajoException e) {
+      assertEquals(e.getErrorCode(), ResultCode.MISSING_TABLE_PROPERTY);
+    }
+  }
+
+  @Test
+  public void testCreateHBaseTable() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table1 (col1 text, col2 text, col3 text, col4 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col2:a,col3:,col2:b')").close();
+
+    assertTableExists("hbase_mapped_table1");
+
+    HTableDescriptor hTableDesc = testingCluster.getHBaseUtil().getTableDescriptor("hbase_table");
+    assertNotNull(hTableDesc);
+    assertEquals("hbase_table", hTableDesc.getNameAsString());
+
+    HColumnDescriptor[] hColumns = hTableDesc.getColumnFamilies();
+    // col1 is mapped to rowkey
+    assertEquals(2, hColumns.length);
+    assertEquals("col2", hColumns[0].getNameAsString());
+    assertEquals("col3", hColumns[1].getNameAsString());
+
+    executeString("DROP TABLE hbase_mapped_table1 PURGE").close();
+
+    HBaseAdmin hAdmin =  new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+    try {
+      assertFalse(hAdmin.tableExists("hbase_table"));
+    } finally {
+      hAdmin.close();
+    }
+  }
+
+  @Test
+  public void testCreateNotExistsExternalHBaseTable() throws Exception {
+    String sql = String.format(
+        "CREATE EXTERNAL TABLE external_hbase_mapped_table1 (col1 text, col2 text, col3 text, col4 text) " +
+        "USING hbase WITH ('table'='external_hbase_table', 'columns'=':key,col2:a,col3:,col2:b') " +
+            "LOCATION '%s/external_hbase_table'", tableSpaceUri);
+    try {
+      executeString(sql).close();
+      fail("External table should be a existed table.");
+    } catch (Throwable e) {
+      assertTrue(e.getMessage().indexOf("External table should be a existed table.") >= 0);
+    }
+  }
+
+  @Test
+  public void testCreateRowFieldWithNonText() throws Exception {
+    try {
+      executeString("CREATE TABLE hbase_mapped_table2 (rk1 int4, rk2 text, col3 text, col4 text) " +
+          "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'='0:key#b,1:key,col3:,col2:b', " +
+          "'hbase.rowkey.delimiter'='_')").close();
+      fail("Key field type should be TEXT type");
+    } catch (Exception e) {
+      assertTrue(e.getMessage().indexOf("Key field type should be TEXT type") >= 0);
+    }
+  }
+
+  @Test
+  public void testCreateExternalHBaseTable() throws Exception {
+    HTableDescriptor hTableDesc = new HTableDescriptor(TableName.valueOf("external_hbase_table_not_purge"));
+    hTableDesc.addFamily(new HColumnDescriptor("col1"));
+    hTableDesc.addFamily(new HColumnDescriptor("col2"));
+    hTableDesc.addFamily(new HColumnDescriptor("col3"));
+    testingCluster.getHBaseUtil().createTable(hTableDesc);
+
+    String sql = String.format(
+        "CREATE EXTERNAL TABLE external_hbase_mapped_table (rk text, col1 text, col2 text, col3 text) " +
+        "USING hbase WITH ('table'='external_hbase_table_not_purge', 'columns'=':key,col1:a,col2:,col3:b') " +
+        "LOCATION '%s/external_hbase_table'", tableSpaceUri);
+    executeString(sql).close();
+
+    assertTableExists("external_hbase_mapped_table");
+
+    executeString("DROP TABLE external_hbase_mapped_table").close();
+
+    HBaseAdmin hAdmin =  new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+    try {
+      assertTrue(hAdmin.tableExists("external_hbase_table_not_purge"));
+      hAdmin.disableTable("external_hbase_table_not_purge");
+      hAdmin.deleteTable("external_hbase_table_not_purge");
+    } finally {
+      hAdmin.close();
+    }
+  }
+
+  @Test
+  public void testSimpleSelectQuery() throws Exception {
+    HTableDescriptor hTableDesc = new HTableDescriptor(TableName.valueOf("external_hbase_table"));
+    hTableDesc.addFamily(new HColumnDescriptor("col1"));
+    hTableDesc.addFamily(new HColumnDescriptor("col2"));
+    hTableDesc.addFamily(new HColumnDescriptor("col3"));
+    testingCluster.getHBaseUtil().createTable(hTableDesc);
+
+    String sql = String.format(
+        "CREATE EXTERNAL TABLE external_hbase_mapped_table (rk text, col1 text, col2 text, col3 text) " +
+        "USING hbase WITH ('table'='external_hbase_table', 'columns'=':key,col1:a,col2:,col3:b') " +
+        "LOCATION '%s/external_hbase_table'", tableSpaceUri);
+    executeString(sql).close();
+
+    assertTableExists("external_hbase_mapped_table");
+
+    HBaseTablespace space = (HBaseTablespace) TablespaceManager.getByName("cluster1").get();
+    HConnection hconn = space.getConnection();
+    HTableInterface htable = hconn.getTable("external_hbase_table");
+
+    try {
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put(String.valueOf(i).getBytes());
+        put.add("col1".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        put.add("col1".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        put.add("col2".getBytes(), "k1".getBytes(), ("k1-" + i).getBytes());
+        put.add("col2".getBytes(), "k2".getBytes(), ("k2-" + i).getBytes());
+        put.add("col3".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        htable.put(put);
+      }
+
+      ResultSet res = executeString("select * from external_hbase_mapped_table where rk > '20'");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE external_hbase_mapped_table PURGE").close();
+      htable.close();
+    }
+  }
+
+  @Test
+  public void testBinaryMappedQuery() throws Exception {
+    HTableDescriptor hTableDesc = new HTableDescriptor(TableName.valueOf("external_hbase_table"));
+    hTableDesc.addFamily(new HColumnDescriptor("col1"));
+    hTableDesc.addFamily(new HColumnDescriptor("col2"));
+    hTableDesc.addFamily(new HColumnDescriptor("col3"));
+    testingCluster.getHBaseUtil().createTable(hTableDesc);
+
+    String sql = String.format(
+        "CREATE EXTERNAL TABLE external_hbase_mapped_table (rk int8, col1 text, col2 text, col3 int4)\n " +
+        "USING hbase WITH ('table'='external_hbase_table', 'columns'=':key#b,col1:a,col2:,col3:b#b') " +
+        "LOCATION '%s/external_hbase_table'", tableSpaceUri);
+    executeString(sql).close();
+
+    assertTableExists("external_hbase_mapped_table");
+
+    HBaseTablespace space = (HBaseTablespace) TablespaceManager.getByName("cluster1").get();
+    HConnection hconn = space.getConnection();
+    HTableInterface htable = hconn.getTable("external_hbase_table");
+
+    try {
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put(Bytes.toBytes((long) i));
+        put.add("col1".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        put.add("col1".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        put.add("col2".getBytes(), "k1".getBytes(), ("k1-" + i).getBytes());
+        put.add("col2".getBytes(), "k2".getBytes(), ("k2-" + i).getBytes());
+        put.add("col3".getBytes(), "b".getBytes(), Bytes.toBytes(i));
+        htable.put(put);
+      }
+
+      ResultSet res = executeString("select * from external_hbase_mapped_table where rk > 20");
+      assertResultSet(res);
+      res.close();
+
+      //Projection
+      res = executeString("select col3, col2, rk from external_hbase_mapped_table where rk > 95");
+
+      String expected = "col3,col2,rk\n" +
+          "-------------------------------\n" +
+          "96,{\"k1\":\"k1-96\", \"k2\":\"k2-96\"},96\n" +
+          "97,{\"k1\":\"k1-97\", \"k2\":\"k2-97\"},97\n" +
+          "98,{\"k1\":\"k1-98\", \"k2\":\"k2-98\"},98\n" +
+          "99,{\"k1\":\"k1-99\", \"k2\":\"k2-99\"},99\n";
+
+      assertEquals(expected, resultSetToString(res));
+      res.close();
+
+    } finally {
+      executeString("DROP TABLE external_hbase_mapped_table PURGE").close();
+      htable.close();
+    }
+  }
+
+  @Test
+  public void testColumnKeyValueSelectQuery() throws Exception {
+    HTableDescriptor hTableDesc = new HTableDescriptor(TableName.valueOf("external_hbase_table"));
+    hTableDesc.addFamily(new HColumnDescriptor("col2"));
+    hTableDesc.addFamily(new HColumnDescriptor("col3"));
+    testingCluster.getHBaseUtil().createTable(hTableDesc);
+
+    String sql = String.format(
+        "CREATE EXTERNAL TABLE external_hbase_mapped_table (rk1 text, col2_key text, col2_value text, col3 text) " +
+        "USING hbase WITH ('table'='external_hbase_table', 'columns'=':key,col2:key:,col2:value:,col3:', " +
+        "'hbase.rowkey.delimiter'='_') LOCATION '%s/external_hbase_table'", tableSpaceUri);
+    executeString(sql).close();
+
+    assertTableExists("external_hbase_mapped_table");
+
+    HBaseTablespace space = (HBaseTablespace) TablespaceManager.getByName("cluster1").get();
+    HConnection hconn = space.getConnection();
+    HTableInterface htable = hconn.getTable("external_hbase_table");
+
+    try {
+      for (int i = 0; i < 10; i++) {
+        Put put = new Put(Bytes.toBytes("rk-" + i));
+        for (int j = 0; j < 5; j++) {
+          put.add("col2".getBytes(), ("key-" + j).getBytes(), Bytes.toBytes("value-" + j));
+        }
+        put.add("col3".getBytes(), "".getBytes(), ("col3-value-" + i).getBytes());
+        htable.put(put);
+      }
+
+      ResultSet res = executeString("select * from external_hbase_mapped_table where rk1 >= 'rk-0'");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE external_hbase_mapped_table PURGE").close();
+      htable.close();
+    }
+  }
+
+  @Test
+  public void testRowFieldSelectQuery() throws Exception {
+    HTableDescriptor hTableDesc = new HTableDescriptor(TableName.valueOf("external_hbase_table"));
+    hTableDesc.addFamily(new HColumnDescriptor("col3"));
+    testingCluster.getHBaseUtil().createTable(hTableDesc);
+
+    String sql = String.format(
+        "CREATE EXTERNAL TABLE external_hbase_mapped_table (rk1 text, rk2 text, col3 text) " +
+        "USING hbase WITH ('table'='external_hbase_table', 'columns'='0:key,1:key,col3:a', " +
+        "'hbase.rowkey.delimiter'='_') LOCATION '%s/external_hbase_table'", tableSpaceUri);
+    executeString(sql).close();
+
+    assertTableExists("external_hbase_mapped_table");
+
+    HBaseTablespace space = (HBaseTablespace) TablespaceManager.getByName("cluster1").get();
+    HConnection hconn = space.getConnection();
+    HTableInterface htable = hconn.getTable("external_hbase_table");
+
+    try {
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put(("field1-" + i + "_field2-" + i).getBytes());
+        put.add("col3".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        htable.put(put);
+      }
+
+      ResultSet res = executeString("select * from external_hbase_mapped_table where rk1 > 'field1-20'");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE external_hbase_mapped_table PURGE").close();
+      htable.close();
+    }
+  }
+
+  @Test
+  public void testIndexPredication() throws Exception {
+    String sql =
+        "CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text, col3 text) " +
+        "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:,col3:b', " +
+        "'hbase.split.rowkeys'='010,040,060,080') ";
+    executeString(sql).close();
+
+
+    assertTableExists("hbase_mapped_table");
+    HBaseAdmin hAdmin = new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+    hAdmin.tableExists("hbase_table");
+
+    HTable htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+    try {
+      org.apache.hadoop.hbase.util.Pair<byte[][], byte[][]> keys = htable.getStartEndKeys();
+      assertEquals(5, keys.getFirst().length);
+
+      DecimalFormat df = new DecimalFormat("000");
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put(String.valueOf(df.format(i)).getBytes());
+        put.add("col1".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        put.add("col1".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        put.add("col2".getBytes(), "k1".getBytes(), ("k1-" + i).getBytes());
+        put.add("col2".getBytes(), "k2".getBytes(), ("k2-" + i).getBytes());
+        put.add("col3".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        htable.put(put);
+      }
+      assertIndexPredication(false);
+
+      ResultSet res = executeString("select * from hbase_mapped_table where rk >= '020' and rk <= '055'");
+      assertResultSet(res);
+      res.close();
+
+      res = executeString("select * from hbase_mapped_table where rk = '021'");
+      String expected = "rk,col1,col2,col3\n" +
+          "-------------------------------\n" +
+          "021,a-21,{\"k1\":\"k1-21\", \"k2\":\"k2-21\"},b-21\n";
+
+      assertEquals(expected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+      htable.close();
+      hAdmin.close();
+    }
+  }
+
+  @Test
+  public void testCompositeRowIndexPredication() throws Exception {
+
+    executeString("CREATE TABLE hbase_mapped_table (rk text, rk2 text, col1 text, col2 text, col3 text) " +
+        "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'='0:key,1:key,col1:a,col2:,col3:b', " +
+        "'hbase.split.rowkeys'='010,040,060,080', " +
+        "'hbase.rowkey.delimiter'='_')").close();
+
+    assertTableExists("hbase_mapped_table");
+    HBaseAdmin hAdmin = new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+    hAdmin.tableExists("hbase_table");
+
+    HTable htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+    try {
+      org.apache.hadoop.hbase.util.Pair<byte[][], byte[][]> keys = htable.getStartEndKeys();
+      assertEquals(5, keys.getFirst().length);
+
+      DecimalFormat df = new DecimalFormat("000");
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put((df.format(i) + "_" + df.format(i)).getBytes());
+        put.add("col1".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        put.add("col1".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        put.add("col2".getBytes(), "k1".getBytes(), ("k1-" + i).getBytes());
+        put.add("col2".getBytes(), "k2".getBytes(), ("k2-" + i).getBytes());
+        put.add("col3".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        htable.put(put);
+      }
+
+      Scan scan = new Scan();
+      scan.setStartRow("021".getBytes());
+      scan.setStopRow(("021_" + new String(new char[]{Character.MAX_VALUE})).getBytes());
+      Filter filter = new InclusiveStopFilter(scan.getStopRow());
+      scan.setFilter(filter);
+
+      ResultScanner scanner = htable.getScanner(scan);
+      Result result = scanner.next();
+      assertNotNull(result);
+      assertEquals("021_021", new String(result.getRow()));
+      scanner.close();
+
+      assertIndexPredication(true);
+
+      ResultSet res = executeString("select * from hbase_mapped_table where rk = '021'");
+      String expected = "rk,rk2,col1,col2,col3\n" +
+          "-------------------------------\n" +
+          "021,021,a-21,{\"k1\":\"k1-21\", \"k2\":\"k2-21\"},b-21\n";
+
+      assertEquals(expected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+      htable.close();
+      hAdmin.close();
+    }
+  }
+
+  private void assertIndexPredication(boolean isCompositeRowKey) throws Exception {
+    String postFix = isCompositeRowKey ? "_" + new String(new char[]{Character.MAX_VALUE}) : "";
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    ScanNode scanNode = new ScanNode(1);
+
+    // where rk = '021'
+    EvalNode evalNodeEq = new BinaryEval(EvalType.EQUAL, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("021")));
+    scanNode.setQual(evalNodeEq);
+    Tablespace tablespace = TablespaceManager.getByName("cluster1").get();
+    List<Fragment> fragments = tablespace.getSplits("hbase_mapped_table", tableDesc, scanNode);
+    assertEquals(1, fragments.size());
+    assertEquals("021", new String(((HBaseFragment)fragments.get(0)).getStartRow()));
+    assertEquals("021" + postFix, new String(((HBaseFragment)fragments.get(0)).getStopRow()));
+
+    // where rk >= '020' and rk <= '055'
+    EvalNode evalNode1 = new BinaryEval(EvalType.GEQ, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("020")));
+    EvalNode evalNode2 = new BinaryEval(EvalType.LEQ, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("055")));
+    EvalNode evalNodeA = new BinaryEval(EvalType.AND, evalNode1, evalNode2);
+    scanNode.setQual(evalNodeA);
+
+    fragments = tablespace.getSplits("hbase_mapped_table", tableDesc, scanNode);
+    assertEquals(2, fragments.size());
+    HBaseFragment fragment1 = (HBaseFragment) fragments.get(0);
+    assertEquals("020", new String(fragment1.getStartRow()));
+    assertEquals("040", new String(fragment1.getStopRow()));
+
+    HBaseFragment fragment2 = (HBaseFragment) fragments.get(1);
+    assertEquals("040", new String(fragment2.getStartRow()));
+    assertEquals("055" + postFix, new String(fragment2.getStopRow()));
+
+    // where (rk >= '020' and rk <= '055') or rk = '075'
+    EvalNode evalNode3 = new BinaryEval(EvalType.EQUAL, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("075")));
+    EvalNode evalNodeB = new BinaryEval(EvalType.OR, evalNodeA, evalNode3);
+    scanNode.setQual(evalNodeB);
+    fragments = tablespace.getSplits("hbase_mapped_table", tableDesc, scanNode);
+    assertEquals(3, fragments.size());
+    fragment1 = (HBaseFragment) fragments.get(0);
+    assertEquals("020", new String(fragment1.getStartRow()));
+    assertEquals("040", new String(fragment1.getStopRow()));
+
+    fragment2 = (HBaseFragment) fragments.get(1);
+    assertEquals("040", new String(fragment2.getStartRow()));
+    assertEquals("055" + postFix, new String(fragment2.getStopRow()));
+
+    HBaseFragment fragment3 = (HBaseFragment) fragments.get(2);
+    assertEquals("075", new String(fragment3.getStartRow()));
+    assertEquals("075" + postFix, new String(fragment3.getStopRow()));
+
+
+    // where (rk >= '020' and rk <= '055') or (rk >= '072' and rk <= '078')
+    EvalNode evalNode4 = new BinaryEval(EvalType.GEQ, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("072")));
+    EvalNode evalNode5 = new BinaryEval(EvalType.LEQ, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("078")));
+    EvalNode evalNodeC = new BinaryEval(EvalType.AND, evalNode4, evalNode5);
+    EvalNode evalNodeD = new BinaryEval(EvalType.OR, evalNodeA, evalNodeC);
+    scanNode.setQual(evalNodeD);
+    fragments = tablespace.getSplits("hbase_mapped_table", tableDesc, scanNode);
+    assertEquals(3, fragments.size());
+
+    fragment1 = (HBaseFragment) fragments.get(0);
+    assertEquals("020", new String(fragment1.getStartRow()));
+    assertEquals("040", new String(fragment1.getStopRow()));
+
+    fragment2 = (HBaseFragment) fragments.get(1);
+    assertEquals("040", new String(fragment2.getStartRow()));
+    assertEquals("055" + postFix, new String(fragment2.getStopRow()));
+
+    fragment3 = (HBaseFragment) fragments.get(2);
+    assertEquals("072", new String(fragment3.getStartRow()));
+    assertEquals("078" + postFix, new String(fragment3.getStopRow()));
+
+    // where (rk >= '020' and rk <= '055') or (rk >= '057' and rk <= '059')
+    evalNode4 = new BinaryEval(EvalType.GEQ, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("057")));
+    evalNode5 = new BinaryEval(EvalType.LEQ, new FieldEval(tableDesc.getLogicalSchema().getColumn("rk")),
+        new ConstEval(new TextDatum("059")));
+    evalNodeC = new BinaryEval(EvalType.AND, evalNode4, evalNode5);
+    evalNodeD = new BinaryEval(EvalType.OR, evalNodeA, evalNodeC);
+    scanNode.setQual(evalNodeD);
+    fragments = tablespace.getSplits("hbase_mapped_table", tableDesc, scanNode);
+    assertEquals(2, fragments.size());
+
+    fragment1 = (HBaseFragment) fragments.get(0);
+    assertEquals("020", new String(fragment1.getStartRow()));
+    assertEquals("040", new String(fragment1.getStopRow()));
+
+    fragment2 = (HBaseFragment) fragments.get(1);
+    assertEquals("040", new String(fragment2.getStartRow()));
+    assertEquals("059" + postFix, new String(fragment2.getStopRow()));
+  }
+
+  @Test
+  public void testNonForwardQuery() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text, col3 int) " +
+        "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:,col3:#b', " +
+        "'hbase.split.rowkeys'='010,040,060,080')").close();
+
+    assertTableExists("hbase_mapped_table");
+    HBaseAdmin hAdmin =  new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+    HTable htable = null;
+    try {
+      hAdmin.tableExists("hbase_table");
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+      org.apache.hadoop.hbase.util.Pair<byte[][], byte[][]> keys = htable.getStartEndKeys();
+      assertEquals(5, keys.getFirst().length);
+
+      DecimalFormat df = new DecimalFormat("000");
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put(String.valueOf(df.format(i)).getBytes());
+        put.add("col1".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        put.add("col1".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        put.add("col2".getBytes(), "k1".getBytes(), ("k1-" + i).getBytes());
+        put.add("col2".getBytes(), "k2".getBytes(), ("k2-" + i).getBytes());
+        put.add("col3".getBytes(), "".getBytes(), Bytes.toBytes(i));
+        htable.put(put);
+      }
+
+      ResultSet res = executeString("select * from hbase_mapped_table");
+      assertResultSet(res);
+      res.close();
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+      hAdmin.close();
+      if (htable == null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testJoin() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text, col3 int8) " +
+        "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:,col3:b#b', " +
+        "'hbase.split.rowkeys'='010,040,060,080')").close();
+
+    assertTableExists("hbase_mapped_table");
+    HBaseAdmin hAdmin =  new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+    HTable htable = null;
+    try {
+      hAdmin.tableExists("hbase_table");
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+      org.apache.hadoop.hbase.util.Pair<byte[][], byte[][]> keys = htable.getStartEndKeys();
+      assertEquals(5, keys.getFirst().length);
+
+      DecimalFormat df = new DecimalFormat("000");
+      for (int i = 0; i < 100; i++) {
+        Put put = new Put(String.valueOf(df.format(i)).getBytes());
+        put.add("col1".getBytes(), "a".getBytes(), ("a-" + i).getBytes());
+        put.add("col1".getBytes(), "b".getBytes(), ("b-" + i).getBytes());
+        put.add("col2".getBytes(), "k1".getBytes(), ("k1-" + i).getBytes());
+        put.add("col2".getBytes(), "k2".getBytes(), ("k2-" + i).getBytes());
+        put.add("col3".getBytes(), "b".getBytes(), Bytes.toBytes((long) i));
+        htable.put(put);
+      }
+
+      ResultSet res = executeString("select a.rk, a.col1, a.col2, a.col3, b.l_orderkey, b.l_linestatus " +
+          "from hbase_mapped_table a " +
+          "join default.lineitem b on a.col3 = b.l_orderkey");
+      assertResultSet(res);
+      res.close();
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+      hAdmin.close();
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertInto() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text, col3 int4) " +
+        "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:,col3:b#b')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    executeString("insert into hbase_mapped_table " +
+        "select l_orderkey::text, l_shipdate, l_returnflag, l_suppkey from default.lineitem ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scan.addFamily(Bytes.toBytes("col2"));
+      scan.addFamily(Bytes.toBytes("col3"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1"), Bytes.toBytes("col2"), Bytes.toBytes("col3")},
+          new byte[][]{null, Bytes.toBytes("a"), null, Bytes.toBytes("b")},
+          new boolean[]{false, false, false, true}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertValues1() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text, col3 int4) " +
+        "TABLESPACE cluster1 USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:,col3:b#b')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    executeString("insert into hbase_mapped_table select 'aaa', 'a12', 'a34', 1").close();
+    executeString("insert into hbase_mapped_table select 'bbb', 'b12', 'b34', 2").close();
+    executeString("insert into hbase_mapped_table select 'ccc', 'c12', 'c34', 3").close();
+    executeString("insert into hbase_mapped_table select 'ddd', 'd12', 'd34', 4").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scan.addFamily(Bytes.toBytes("col2"));
+      scan.addFamily(Bytes.toBytes("col3"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1"), Bytes.toBytes("col2"), Bytes.toBytes("col3")},
+          new byte[][]{null, Bytes.toBytes("a"), null, Bytes.toBytes("b")},
+          new boolean[]{false, false, false, true}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoMultiRegion() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk text, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a', " +
+        "'hbase.split.rowkeys'='010,040,060,080')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.TEXT);
+    schema.addColumn("name", Type.TEXT);
+    List<String> datas = new ArrayList<String>();
+    DecimalFormat df = new DecimalFormat("000");
+    for (int i = 99; i >= 0; i--) {
+      datas.add(df.format(i) + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString("insert into hbase_mapped_table " +
+        "select id, name from base_table ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1")},
+          new byte[][]{null, Bytes.toBytes("a")},
+          new boolean[]{false, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoMultiRegion2() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk text, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a', " +
+        "'hbase.split.rowkeys'='1,2,3,4,5,6,7,8,9')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.TEXT);
+    schema.addColumn("name", Type.TEXT);
+    List<String> datas = new ArrayList<String>();
+    for (int i = 99; i >= 0; i--) {
+      datas.add(i + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString("insert into hbase_mapped_table " +
+        "select id, name from base_table ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1")},
+          new byte[][]{null, Bytes.toBytes("a")},
+          new boolean[]{false, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoMultiRegionWithSplitFile() throws Exception {
+    String splitFilePath = currentDatasetPath + "/splits.data";
+
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk text, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a', " +
+        "'hbase.split.rowkeys.file'='" + splitFilePath + "')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.TEXT);
+    schema.addColumn("name", Type.TEXT);
+    List<String> datas = new ArrayList<String>();
+    DecimalFormat df = new DecimalFormat("000");
+    for (int i = 99; i >= 0; i--) {
+      datas.add(df.format(i) + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString("insert into hbase_mapped_table " +
+        "select id, name from base_table ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1")},
+          new byte[][]{null, Bytes.toBytes("a")},
+          new boolean[]{false, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoMultiRegionMultiRowFields() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk1 text, rk2 text, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'='0:key,1:key,col1:a', " +
+        "'hbase.split.rowkeys'='001,002,003,004,005,006,007,008,009', " +
+        "'hbase.rowkey.delimiter'='_')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id1", Type.TEXT);
+    schema.addColumn("id2", Type.TEXT);
+    schema.addColumn("name", Type.TEXT);
+    DecimalFormat df = new DecimalFormat("000");
+    List<String> datas = new ArrayList<String>();
+    for (int i = 99; i >= 0; i--) {
+      datas.add(df.format(i) + "|" + (i + 100) + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString("insert into hbase_mapped_table " +
+        "select id1, id2, name from base_table ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, null, Bytes.toBytes("col1")},
+          new byte[][]{null, null, Bytes.toBytes("a")},
+          new boolean[]{false, false, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoBinaryMultiRegion() throws Exception {
+    executeString("CREATE TABLE hbase_mapped_table (rk int4, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key#b,col1:a', " +
+        "'hbase.split.rowkeys'='1,2,3,4,5,6,7,8,9')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4);
+    schema.addColumn("name", Type.TEXT);
+    List<String> datas = new ArrayList<String>();
+    for (int i = 99; i >= 0; i--) {
+      datas.add(i + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString("insert into hbase_mapped_table " +
+        "select id, name from base_table ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1")},
+          new byte[][]{null, Bytes.toBytes("a")},
+          new boolean[]{true, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoColumnKeyValue() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk text, col2_key text, col2_value text, col3 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col2:key:,col2:value:,col3:', " +
+        "'hbase.rowkey.delimiter'='_')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("rk", Type.TEXT);
+    schema.addColumn("col2_key", Type.TEXT);
+    schema.addColumn("col2_value", Type.TEXT);
+    schema.addColumn("col3", Type.TEXT);
+    List<String> datas = new ArrayList<String>();
+    for (int i = 20; i >= 0; i--) {
+      for (int j = 0; j < 3; j++) {
+        datas.add(i + "|ck-" + j + "|value-" + j + "|col3-" + i);
+      }
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString("insert into hbase_mapped_table " +
+        "select rk, col2_key, col2_value, col3 from base_table ").close();
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col2"));
+      scan.addFamily(Bytes.toBytes("col3"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col2"), Bytes.toBytes("col3")},
+          new byte[][]{null, null, null},
+          new boolean[]{false, false, false}, tableDesc.getSchema()));
+
+      ResultSet res = executeString("select * from hbase_mapped_table");
+
+      String expected = "rk,col2_key,col2_value,col3\n" +
+          "-------------------------------\n" +
+          "0,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-0\n" +
+          "1,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-1\n" +
+          "10,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-10\n" +
+          "11,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-11\n" +
+          "12,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-12\n" +
+          "13,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-13\n" +
+          "14,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-14\n" +
+          "15,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-15\n" +
+          "16,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-16\n" +
+          "17,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-17\n" +
+          "18,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-18\n" +
+          "19,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-19\n" +
+          "2,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-2\n" +
+          "20,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-20\n" +
+          "3,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-3\n" +
+          "4,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-4\n" +
+          "5,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-5\n" +
+          "6,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-6\n" +
+          "7,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-7\n" +
+          "8,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-8\n" +
+          "9,[\"ck-0\", \"ck-1\", \"ck-2\"],[\"value-0\", \"value-1\", \"value-2\"],col3-9\n";
+
+      assertEquals(expected, resultSetToString(res));
+      res.close();
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoDifferentType() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk text, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a', " +
+        "'hbase.split.rowkeys'='1,2,3,4,5,6,7,8,9')").close();
+
+    assertTableExists("hbase_mapped_table");
+
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4);
+    schema.addColumn("name", Type.TEXT);
+    List<String> datas = new ArrayList<String>();
+    for (int i = 99; i >= 0; i--) {
+      datas.add(i + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    try {
+      executeString("insert into hbase_mapped_table " +
+          "select id, name from base_table ").close();
+      fail("If inserting data type different with target table data type, should throw exception");
+    } catch (TajoException e) {
+      assertEquals(ResultCode.DATATYPE_MISMATCH, e.getErrorCode());
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+    }
+  }
+
+  @Test
+  public void testInsertIntoRowField() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk1 text, rk2 text, col1 text, col2 text, col3 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'='0:key,1:key,col1:a,col2:,col3:b', " +
+        "'hbase.rowkey.delimiter'='_')").close();
+
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    executeString("insert into hbase_mapped_table " +
+        "select l_orderkey::text, l_partkey::text, l_shipdate, l_returnflag, l_suppkey::text from default.lineitem ");
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scan.addFamily(Bytes.toBytes("col2"));
+      scan.addFamily(Bytes.toBytes("col3"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1"), Bytes.toBytes("col2"), Bytes.toBytes("col3")},
+          new byte[][]{null, Bytes.toBytes("a"), Bytes.toBytes(""), Bytes.toBytes("b")},
+          new boolean[]{false, false, false, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testCTAS() throws Exception {
+    // create test table
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.TEXT);
+    schema.addColumn("name", Type.TEXT);
+    List<String> datas = new ArrayList<>();
+    DecimalFormat df = new DecimalFormat("000");
+    for (int i = 99; i >= 0; i--) {
+      datas.add(df.format(i) + "|value" + i);
+    }
+    TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+        schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk text, col1 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a', " +
+        "'hbase.split.rowkeys'='010,040,060,080') as" +
+        " select id, name from base_table"
+    ).close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scanner = htable.getScanner(scan);
+
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1")},
+          new byte[][]{null, Bytes.toBytes("a")},
+          new boolean[]{false, false}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+
+      // TODO - rollback should support its corresponding hbase table
+      HBaseAdmin hAdmin = new HBaseAdmin(testingCluster.getHBaseUtil().getConf());
+      if (hAdmin.tableExists("hbase_table")) {
+        hAdmin.disableTable("hbase_table");
+        hAdmin.deleteTable("hbase_table");
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoUsingPut() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text, col3 int4) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:,col3:b#b')").close();
+
+    assertTableExists("hbase_mapped_table");
+    TableDesc tableDesc = catalog.getTableDesc(getCurrentDatabase(), "hbase_mapped_table");
+
+    Map<String, String> sessions = new HashMap<>();
+    sessions.put(HBaseStorageConstants.INSERT_PUT_MODE, "true");
+    client.updateSessionVariables(sessions);
+
+    HTable htable = null;
+    ResultScanner scanner = null;
+    try {
+      executeString(
+          "insert into hbase_mapped_table " +
+          "select l_orderkey::text, l_shipdate, l_returnflag, l_suppkey from default.lineitem"
+      ).close();
+
+      htable = new HTable(testingCluster.getHBaseUtil().getConf(), "hbase_table");
+
+      Scan scan = new Scan();
+      scan.addFamily(Bytes.toBytes("col1"));
+      scan.addFamily(Bytes.toBytes("col2"));
+      scan.addFamily(Bytes.toBytes("col3"));
+      scanner = htable.getScanner(scan);
+
+      // result is dirrerent with testInsertInto because l_orderkey is not unique.
+      assertStrings(resultSetToString(scanner,
+          new byte[][]{null, Bytes.toBytes("col1"), Bytes.toBytes("col2"), Bytes.toBytes("col3")},
+          new byte[][]{null, Bytes.toBytes("a"), null, Bytes.toBytes("b")},
+          new boolean[]{false, false, false, true}, tableDesc.getSchema()));
+
+    } finally {
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+
+      client.unsetSessionVariables(TUtil.newList(HBaseStorageConstants.INSERT_PUT_MODE));
+
+      if (scanner != null) {
+        scanner.close();
+      }
+
+      if (htable != null) {
+        htable.close();
+      }
+    }
+  }
+
+  @Test
+  public void testInsertIntoLocation() throws Exception {
+    executeString(
+        "CREATE TABLE hbase_mapped_table (rk text, col1 text, col2 text) TABLESPACE cluster1 " +
+        "USING hbase WITH ('table'='hbase_table', 'columns'=':key,col1:a,col2:', " +
+        "'hbase.split.rowkeys'='010,040,060,080')").close();
+
+    assertTableExists("hbase_mapped_table");
+
+    try {
+      // create test table
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+      tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+      Schema schema = new Schema();
+      schema.addColumn("id", Type.TEXT);
+      schema.addColumn("name", Type.TEXT);
+      schema.addColumn("comment", Type.TEXT);
+      List<String> datas = new ArrayList<>();
+      DecimalFormat df = new DecimalFormat("000");
+      for (int i = 99; i >= 0; i--) {
+        datas.add(df.format(i) + "|value" + i + "|comment-" + i);
+      }
+      TajoTestingCluster.createTable(getCurrentDatabase() + ".base_table",
+          schema, tableOptions, datas.toArray(new String[]{}), 2);
+
+      executeString("insert into location '/tmp/hfile_test' " +
+          "select id, name, comment from base_table ").close();
+
+      FileSystem fs = testingCluster.getDefaultFileSystem();
+      Path path = new Path("/tmp/hfile_test");
+      assertTrue(fs.exists(path));
+
+      FileStatus[] files = fs.listStatus(path);
+      assertNotNull(files);
+      assertEquals(2, files.length);
+
+      int index = 0;
+      for (FileStatus eachFile: files) {
+        assertEquals("/tmp/hfile_test/part-01-00000" + index + "-00" + index, eachFile.getPath().toUri().getPath());
+        for (FileStatus subFile: fs.listStatus(eachFile.getPath())) {
+          assertTrue(subFile.isFile());
+          assertTrue(subFile.getLen() > 0);
+        }
+        index++;
+      }
+    } finally {
+      executeString("DROP TABLE base_table PURGE").close();
+      executeString("DROP TABLE hbase_mapped_table PURGE").close();
+    }
+  }
+
+  private String resultSetToString(ResultScanner scanner, byte[][] cfNames, byte[][] qualifiers,
+                                   boolean [] binaries, Schema schema) throws Exception {
+    StringBuilder sb = new StringBuilder();
+    Result result = null;
+    while ( (result = scanner.next()) != null ) {
+      if (binaries[0]) {
+        sb.append(HBaseBinarySerializerDeserializer.deserialize(schema.getColumn(0), result.getRow()).asChar());
+      } else {
+        sb.append(new String(result.getRow()));
+      }
+
+      for (int i = 0; i < cfNames.length; i++) {
+        if (cfNames[i] == null) {
+          //rowkey
+          continue;
+        }
+        if (qualifiers[i] == null) {
+          Map<byte[], byte[]> values = result.getFamilyMap(cfNames[i]);
+          if (values == null) {
+            sb.append(", null");
+          } else {
+            sb.append(", {");
+            String delim = "";
+            for (Map.Entry<byte[], byte[]> valueEntry: values.entrySet()) {
+              byte[] keyBytes = valueEntry.getKey();
+              byte[] valueBytes = valueEntry.getValue();
+
+              if (binaries[i]) {
+                sb.append(delim).append("\"").append(keyBytes == null ? "" : Bytes.toLong(keyBytes)).append("\"");
+                sb.append(": \"").append(HBaseBinarySerializerDeserializer.deserialize(schema.getColumn(i), valueBytes)).append("\"");
+              } else {
+                sb.append(delim).append("\"").append(keyBytes == null ? "" : new String(keyBytes)).append("\"");
+                sb.append(": \"").append(HBaseTextSerializerDeserializer.deserialize(schema.getColumn(i), valueBytes)).append("\"");
+              }
+              delim = ", ";
+            }
+            sb.append("}");
+          }
+        } else {
+          byte[] value = result.getValue(cfNames[i], qualifiers[i]);
+          if (value == null) {
+            sb.append(", null");
+          } else {
+            if (binaries[i]) {
+              sb.append(", ").append(HBaseBinarySerializerDeserializer.deserialize(schema.getColumn(i), value));
+            } else {
+              sb.append(", ").append(HBaseTextSerializerDeserializer.deserialize(schema.getColumn(i), value));
+            }
+          }
+        }
+      }
+      sb.append("\n");
+    }
+
+    return sb.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInSubquery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInSubquery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInSubquery.java
new file mode 100644
index 0000000..fe465f1
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInSubquery.java
@@ -0,0 +1,177 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.TajoRuntimeException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+public class TestInSubquery extends TestJoinQuery {
+
+  public TestInSubquery(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testInSubQuery2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testNestedInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testInSubQueryWithOtherConditions() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testMultipleInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testInSubQueryWithJoin() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testInSubQueryWithTableSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testNotInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testMultipleNotInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testNestedNotInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testInAndNotInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testNestedInAndNotInSubQuery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testNestedInSubQuery2() throws Exception {
+    // select c_name from customer
+    // where c_nationkey in (
+    //    select n_nationkey from nation where n_name like 'C%' and n_regionkey in (
+    //    select count(*)-1 from region where r_regionkey > 0 and r_regionkey < 3))
+    runSimpleTests();
+  }
+
+  @Test()
+  public final void testCorrelatedSubQuery() throws Exception {
+    // Use try-catch clause to verify the exact error message
+    try {
+      executeString("select * from nation where n_regionkey in (select r_regionkey from region where n_name > r_name)");
+      fail("Correlated subquery must raise the UnimplementedException.");
+    } catch (TajoRuntimeException e) {
+      assertEquals(ResultCode.NOT_IMPLEMENTED, e.getErrorCode());
+    }
+  }
+
+  @Test
+  @Option(withExplain = false, withExplainGlobal = false, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testSameKeyNameOfOuterAndInnerQueries() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testWithAsteriskAndJoin() throws Exception {
+    // select * from lineitem, orders where l_orderkey = o_orderkey and l_partkey in
+    // (select l_partkey from lineitem where l_linenumber in (1, 3, 5, 7, 9))
+    runSimpleTests();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestIndexScan.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestIndexScan.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestIndexScan.java
new file mode 100644
index 0000000..a255c6d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestIndexScan.java
@@ -0,0 +1,145 @@
+/*
+ * 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.query;
+
+import com.google.protobuf.ServiceException;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.exception.NoSuchSessionVariableException;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+@Category(IntegrationTest.class)
+public class TestIndexScan extends QueryTestCaseBase {
+
+  public TestIndexScan() throws ServiceException, SQLException, NoSuchSessionVariableException {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+    Map<String,String> sessionVars = new HashMap<String, String>();
+    sessionVars.put(SessionVars.INDEX_ENABLED.keyname(), "true");
+    sessionVars.put(SessionVars.INDEX_SELECTIVITY_THRESHOLD.keyname(), "0.01f");
+    client.updateSessionVariables(sessionVars);
+  }
+
+  @Test
+  public final void testOnSortedNonUniqueKeys() throws Exception {
+    executeString("create index l_orderkey_idx on lineitem (l_orderkey)");
+    try {
+      ResultSet res = executeString("select * from lineitem where l_orderkey = 1;");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index l_orderkey_idx");
+    }
+  }
+
+  @Test
+  public final void testOnUnsortedTextKeys() throws Exception {
+    executeString("create index l_shipdate_idx on lineitem (l_shipdate)");
+    try {
+      ResultSet res = executeString("select l_orderkey, l_shipdate, l_comment from lineitem where l_shipdate = '1997-01-28';");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index l_shipdate_idx");
+    }
+  }
+
+  @Test
+  public final void testOnMultipleKeys() throws Exception {
+    executeString("create index multikey_idx on lineitem (l_shipdate asc null last, l_tax desc null first, l_shipmode, l_linenumber desc null last)");
+    try {
+      ResultSet res = executeString("select l_orderkey, l_shipdate, l_comment from lineitem " +
+          "where l_shipdate = '1997-01-28' and l_tax = 0.05 and l_shipmode = 'RAIL' and l_linenumber = 1;");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index multikey_idx");
+    }
+  }
+
+  @Test
+  public final void testOnMultipleKeys2() throws Exception {
+    executeString("create index multikey_idx on lineitem (l_shipdate asc null last, l_tax desc null first)");
+    try {
+      ResultSet res = executeString("select l_orderkey, l_shipdate, l_comment from lineitem " +
+          "where l_shipdate = '1997-01-28' and l_tax = 0.05 and l_shipmode = 'RAIL' and l_linenumber = 1;");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index multikey_idx");
+    }
+  }
+
+  @Test
+  public final void testOnMultipleExprs() throws Exception {
+    executeString("create index l_orderkey_100_l_linenumber_10_idx on lineitem (l_orderkey*100-l_linenumber*10 asc null first);");
+    try {
+      ResultSet res = executeString("select l_orderkey, l_linenumber from lineitem where l_orderkey*100-l_linenumber*10 = 280");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index l_orderkey_100_l_linenumber_10_idx");
+    }
+  }
+
+  @Test
+  public final void testWithGroupBy() throws Exception {
+    executeString("create index l_shipdate_idx on lineitem (l_shipdate)");
+    try {
+      ResultSet res = executeString("select l_shipdate, count(*) from lineitem where l_shipdate = '1997-01-28' group by l_shipdate;");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index l_shipdate_idx");
+    }
+  }
+
+  @Test
+  public final void testWithSort() throws Exception {
+    executeString("create index l_orderkey_idx on lineitem (l_orderkey)");
+    try {
+      ResultSet res = executeString("select l_shipdate from lineitem where l_orderkey = 1 order by l_shipdate;");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index l_orderkey_idx");
+    }
+  }
+
+  @Test
+  public final void testWithJoin() throws Exception {
+    executeString("create index l_orderkey_idx on lineitem (l_orderkey)");
+    executeString("create index o_orderkey_idx on orders (o_orderkey)");
+    try {
+      ResultSet res = executeString("select l_shipdate, o_orderstatus from lineitem, orders where l_orderkey = o_orderkey and l_orderkey = 1 and o_orderkey = 1;");
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("drop index l_orderkey_idx");
+      executeString("drop index o_orderkey_idx");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java
new file mode 100644
index 0000000..88b3548
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinQuery.java
@@ -0,0 +1,335 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+public class TestInnerJoinQuery extends TestJoinQuery {
+
+  public TestInnerJoinQuery(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select n_name, r_name, n_regionkey, r_regionkey from nation, region order by n_name, r_name"),
+      // testCrossJoinWithAsterisk
+      @QuerySpec("select region.*, customer.* from region, customer"),
+      @QuerySpec("select region.*, customer.* from customer, region"),
+      @QuerySpec("select * from customer, region"),
+      @QuerySpec("select length(r_comment) as len, *, c_custkey*10 from customer, region order by len,r_regionkey,r_name")
+  })
+  public final void testCrossJoin() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest()
+  public final void testCrossJoinWithThetaJoinConditionInWhere() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testInnerJoinWithThetaJoinConditionInWhere() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testWhereClauseJoin1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testWhereClauseJoin2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testWhereClauseJoin3() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testWhereClauseJoin4() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testWhereClauseJoin5() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testWhereClauseJoin6() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testTPCHQ2Join() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinWithMultipleJoinQual1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testJoinCoReferredEvals1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testJoinCoReferredEvalsWithSameExprs1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testJoinCoReferredEvalsWithSameExprs2() throws Exception {
+    // including grouping operator
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testInnerJoinAndCaseWhen() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testInnerJoinWithEmptyTable() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testCrossJoinWithEmptyTable1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(prepare = {
+      "CREATE DATABASE JOINS",
+      "CREATE TABLE JOINS.part_ as SELECT * FROM part",
+      "CREATE TABLE JOINS.supplier_ as SELECT * FROM supplier"
+  }, cleanup = {
+      "DROP TABLE JOINS.part_ PURGE",
+      "DROP TABLE JOINS.supplier_ PURGE",
+      "DROP DATABASE JOINS"
+  })
+  public final void testJoinOnMultipleDatabases() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  public final void testJoinWithJson() throws Exception {
+    // select length(r_comment) as len, *, c_custkey*10 from customer, region order by len,r_regionkey,r_name
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testJoinOnMultipleDatabasesWithJson() throws Exception {
+    executeString("CREATE DATABASE JOINS");
+    assertDatabaseExists("joins");
+    executeString("CREATE TABLE JOINS.part_ as SELECT * FROM part");
+    assertTableExists("joins.part_");
+    executeString("CREATE TABLE JOINS.supplier_ as SELECT * FROM supplier");
+    assertTableExists("joins.supplier_");
+
+    try {
+      ResultSet res = executeJsonQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE JOINS.part_ PURGE");
+      executeString("DROP TABLE JOINS.supplier_ PURGE");
+      executeString("DROP DATABASE JOINS");
+    }
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinAsterisk() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testDifferentTypesJoinCondition() throws Exception {
+    // select * from table20 t3 join table21 t4 on t3.id = t4.id;
+    executeDDL("table1_int8_ddl.sql", "table1", "table20");
+    executeDDL("table1_int4_ddl.sql", "table1", "table21");
+    try {
+      runSimpleTests();
+    } finally {
+      executeString("DROP TABLE table20");
+      executeString("DROP TABLE table21");
+    }
+  }
+
+  @Test
+  @SimpleTest
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  public void testComplexJoinCondition1() throws Exception {
+    // select n1.n_nationkey, n1.n_name, n2.n_name  from nation n1 join nation n2 on n1.n_name = upper(n2.n_name);
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinCondition2() throws Exception {
+    // select n1.n_nationkey, n1.n_name, upper(n2.n_name) name from nation n1 join nation n2
+    // on n1.n_name = upper(n2.n_name);
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinCondition3() throws Exception {
+    // select n1.n_nationkey, n1.n_name, n2.n_name from nation n1 join nation n2 on lower(n1.n_name) = lower(n2.n_name);
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinCondition4() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinWithOrPredicates() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testNaturalJoin() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testCrossJoinAndCaseWhen() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testCrossJoinWithAsterisk1() throws Exception {
+    // select region.*, customer.* from region, customer;
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testCrossJoinWithAsterisk2() throws Exception {
+    // select region.*, customer.* from customer, region;
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testCrossJoinWithAsterisk3() throws Exception {
+    // select * from customer, region
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testCrossJoinWithAsterisk4() throws Exception {
+    // select length(r_regionkey), *, c_custkey*10 from customer, region
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testBroadcastTwoPartJoin() throws Exception {
+    runSimpleTests();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java
new file mode 100644
index 0000000..6c9546e
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestInnerJoinWithSubQuery.java
@@ -0,0 +1,132 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+public class TestInnerJoinWithSubQuery extends TestJoinQuery {
+
+  public TestInnerJoinWithSubQuery(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinWithMultipleJoinQual2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinWithMultipleJoinQual3() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinWithMultipleJoinQual4() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  public final void testJoinWithJson2() throws Exception {
+    /*
+    select t.n_nationkey, t.n_name, t.n_regionkey, t.n_comment, ps.ps_availqty, s.s_suppkey
+    from (
+      select n_nationkey, n_name, n_regionkey, n_comment
+      from nation n
+      join region r on (n.n_regionkey = r.r_regionkey)
+    ) t
+    join supplier s on (s.s_nationkey = t.n_nationkey)
+    join partsupp ps on (s.s_suppkey = ps.ps_suppkey)
+    where t.n_name in ('ARGENTINA','ETHIOPIA', 'MOROCCO');
+     */
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinCondition5() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinCondition6() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testComplexJoinCondition7() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testBroadcastSubquery() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testBroadcastSubquery2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testThetaJoinKeyPairs() throws Exception {
+    runSimpleTests();
+  }
+}


[22/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLead1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLead1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLead1.sql
new file mode 100644
index 0000000..1c6cc20
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLead1.sql
@@ -0,0 +1,18 @@
+SELECT
+  lead(l_shipmode, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_lead,
+  lead(l_linenumber, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_lead,
+  lead(l_suppkey_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_lead,
+  lead(l_shipdate_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipdate_lead,
+  lead(l_commitdate_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as commitdate_lead,
+  lead(l_extendedprice, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_lead,
+  lead(l_discount_t, 1) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_lead,
+  l_orderkey
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithDefault.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithDefault.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithDefault.sql
new file mode 100644
index 0000000..792d47f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithDefault.sql
@@ -0,0 +1,18 @@
+SELECT
+  lead(l_shipmode, 1, 'default') over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_lead,
+  lead(l_linenumber, 1, 100) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_lead,
+  lead(l_suppkey_t, 1, 1000::int8) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_lead,
+  lead(l_shipdate_t, 1, '15-01-01'::date) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipdate_lead,
+  lead(l_commitdate_t, 1, '15-01-01 12:00:00'::timestamp) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as commitdate_lead,
+  lead(l_extendedprice, 1, 1.234::float8) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_lead,
+  lead(l_discount_t, 1, 0.11::float4) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_lead,
+  l_orderkey
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithNoArgs.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithNoArgs.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithNoArgs.sql
new file mode 100644
index 0000000..7f5f940
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testLeadWithNoArgs.sql
@@ -0,0 +1,18 @@
+SELECT
+  lead(l_shipmode) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipmode_lead,
+  lead(l_linenumber) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_lead,
+  lead(l_suppkey_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_lead,
+  lead(l_shipdate_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as shipdate_lead,
+  lead(l_commitdate_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as commitdate_lead,
+  lead(l_extendedprice) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_lead,
+  lead(l_discount_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_lead,
+  l_orderkey
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber1.sql
new file mode 100644
index 0000000..14a5128
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber1.sql
@@ -0,0 +1,5 @@
+SELECT
+  l_orderkey,
+  row_number() OVER () as row_num
+FROM
+  LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber2.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber2.sql
new file mode 100644
index 0000000..2e45120
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber2.sql
@@ -0,0 +1,5 @@
+SELECT
+  l_orderkey,
+  row_number() OVER (PARTITION BY L_ORDERKEY) as row_num
+FROM
+  LINEITEM
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber3.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber3.sql
new file mode 100644
index 0000000..44594c7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testRowNumber3.sql
@@ -0,0 +1,7 @@
+SELECT
+  l_orderkey,
+  row_number() OVER (PARTITION BY L_ORDERKEY) as row_num,
+  l_discount,
+  avg(l_discount) OVER (PARTITION BY L_ORDERKEY) as average
+FROM
+  LINEITEM
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevPop1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevPop1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevPop1.sql
new file mode 100644
index 0000000..013c8af
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevPop1.sql
@@ -0,0 +1,14 @@
+SELECT
+  STDDEV_POP(l_linenumber) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_stddev_pop,
+  STDDEV_POP(l_suppkey_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_stddev_pop,
+  STDDEV_POP(l_extendedprice) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_stddev_pop,
+  STDDEV_POP(l_discount_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_stddev_pop
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevSamp1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevSamp1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevSamp1.sql
new file mode 100644
index 0000000..4bb5d5c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testStdDevSamp1.sql
@@ -0,0 +1,14 @@
+SELECT
+  STDDEV_SAMP(l_linenumber) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as linenumber_stddev_samp,
+  STDDEV_SAMP(l_suppkey_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as suppkey_stddev_samp,
+  STDDEV_SAMP(l_extendedprice) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as extendedprice_stddev_samp,
+  STDDEV_SAMP(l_discount_t) over (PARTITION BY L_ORDERKEY order by l_shipmode ) as discount_stddev_samp
+FROM
+(
+  SELECT
+    l_orderkey,l_partkey,l_suppkey::INT8 as l_suppkey_t,l_linenumber,l_quantity,
+    l_extendedprice,l_discount::FLOAT4 as l_discount_t,l_tax,l_returnflag,l_linestatus,
+    l_shipdate::DATE as l_shipdate_t,l_commitdate::TIMESTAMP as l_commitdate_t,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+  FROM
+    LINEITEM
+) xx
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow1.sql
new file mode 100644
index 0000000..8e6d083
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow1.sql
@@ -0,0 +1 @@
+SELECT sum(l_quantity) OVER () FROM LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow2.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow2.sql
new file mode 100644
index 0000000..baa92f6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow2.sql
@@ -0,0 +1 @@
+SELECT l_orderkey, l_quantity, sum(l_quantity) OVER () FROM LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow3.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow3.sql
new file mode 100644
index 0000000..e4b92f0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow3.sql
@@ -0,0 +1 @@
+SELECT l_orderkey, l_quantity, sum(l_quantity) OVER (PARTITION BY l_orderkey) FROM LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow4.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow4.sql
new file mode 100644
index 0000000..d32c63a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow4.sql
@@ -0,0 +1 @@
+SELECT l_orderkey, l_discount, sum(l_discount) OVER (PARTITION BY l_orderkey), sum(l_quantity) OVER (PARTITION BY l_orderkey) FROM LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow5.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow5.sql
new file mode 100644
index 0000000..7f31991
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow5.sql
@@ -0,0 +1 @@
+SELECT l_orderkey, sum(l_discount) OVER (PARTITION BY l_orderkey), l_discount, sum(l_quantity) OVER (PARTITION BY l_orderkey) FROM LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow6.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow6.sql
new file mode 100644
index 0000000..c1e4a84
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow6.sql
@@ -0,0 +1 @@
+SELECT l_orderkey, l_discount, row_number() OVER (PARTITION BY l_orderkey) r1 , sum(l_discount) OVER (PARTITION BY l_orderkey) r2 FROM LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow7.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow7.sql
new file mode 100644
index 0000000..2caf0db
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow7.sql
@@ -0,0 +1 @@
+select l_orderkey, l_quantity, rank() over (partition by l_orderkey) as r from lineitem
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow8.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow8.sql
new file mode 100644
index 0000000..4611bee
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindow8.sql
@@ -0,0 +1,7 @@
+select
+  l_orderkey,
+  l_quantity,
+  rank() over (partition by l_orderkey) as r,
+  5 as const_val
+from
+  lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowBeforeLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowBeforeLimit.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowBeforeLimit.sql
new file mode 100644
index 0000000..c4d7fa6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowBeforeLimit.sql
@@ -0,0 +1,6 @@
+select
+  r_name,
+  rank() over (order by r_regionkey) as ran
+from
+  region
+limit 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation1.sql
new file mode 100644
index 0000000..7afdae2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation1.sql
@@ -0,0 +1,4 @@
+select
+  row_number() over (order by count(*) desc) row_num
+from
+  lineitem
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation2.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation2.sql
new file mode 100644
index 0000000..1d77ca1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation2.sql
@@ -0,0 +1,7 @@
+select
+  l_orderkey,
+  row_number() over (partition by l_orderkey order by count(*) desc) row_num
+from
+  lineitem
+group by
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation3.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation3.sql
new file mode 100644
index 0000000..f3d3703
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation3.sql
@@ -0,0 +1,5 @@
+select
+  count(*) as cnt,
+  row_number() over (order by count(*) desc) row_num
+from
+  lineitem
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation4.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation4.sql
new file mode 100644
index 0000000..af695ba
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation4.sql
@@ -0,0 +1,8 @@
+select
+  l_orderkey,
+  count(*) as cnt,
+  row_number() over (order by count(*) desc) row_num
+from
+  lineitem
+group by
+  l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation5.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation5.sql
new file mode 100644
index 0000000..2764ae9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation5.sql
@@ -0,0 +1,9 @@
+select
+  l_orderkey,
+  count(*) as cnt,
+  row_number() over (partition by l_orderkey order by count(*) desc)
+  row_num
+from
+  lineitem
+group by
+  l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation6.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation6.sql
new file mode 100644
index 0000000..1a9d46b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithAggregation6.sql
@@ -0,0 +1,10 @@
+select
+  l_orderkey,
+  count(*) as cnt,
+  row_number() over (order by count(*) desc) row_num
+from
+  lineitem
+group by
+  l_orderkey
+order by
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy1.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy1.sql
new file mode 100644
index 0000000..d047bbd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy1.sql
@@ -0,0 +1,6 @@
+SELECT
+  l_orderkey,
+  l_discount,
+  rank() OVER (ORDER BY l_discount) r1
+FROM
+  LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy2.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy2.sql
new file mode 100644
index 0000000..7e6b339
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy2.sql
@@ -0,0 +1,6 @@
+SELECT
+  l_orderkey,
+  l_partkey,
+  rank() OVER (PARTITION BY L_ORDERKEY ORDER BY l_partkey) r1
+FROM
+  LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy3.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy3.sql
new file mode 100644
index 0000000..5fc7317
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy3.sql
@@ -0,0 +1,6 @@
+SELECT
+  l_orderkey,
+  l_partkey,
+  rank() OVER (PARTITION BY L_ORDERKEY ORDER BY l_partkey desc) r1
+FROM
+  LINEITEM
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy4.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy4.sql
new file mode 100644
index 0000000..26cfaa7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy4.sql
@@ -0,0 +1,7 @@
+SELECT
+  l_orderkey,
+  l_partkey,
+  rank() OVER (ORDER BY l_orderkey) r1,
+  rank() OVER(ORDER BY l_partkey desc) r2
+FROM
+  LINEITEM;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy5.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy5.sql
new file mode 100644
index 0000000..2dc87af
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithOrderBy5.sql
@@ -0,0 +1,9 @@
+SELECT
+  l_orderkey,
+  l_partkey,
+  rank() OVER (ORDER BY l_orderkey) r1,
+  rank() OVER(ORDER BY l_partkey desc) r2
+FROM
+  LINEITEM
+where
+  l_partkey > 0 and l_partkey < 100;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery.sql
new file mode 100644
index 0000000..5fa6d00
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery.sql
@@ -0,0 +1,14 @@
+select
+  r_name,
+  c,
+  rank() over (order by r_regionkey) as ran
+from (
+  select
+    r_name,
+    r_regionkey,
+    count(*) as c
+  from
+    region
+  group by
+    r_name, r_regionkey
+) a;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery2.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery2.sql
new file mode 100644
index 0000000..87520fb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery2.sql
@@ -0,0 +1,15 @@
+select
+  r_name,
+  c,
+  rank() over (partition by r_regionkey order by r_regionkey) as ran
+from (
+  select
+    r_name,
+    r_regionkey,
+    count(*) as c
+  from
+    region
+  group by
+    r_name, r_regionkey
+) a
+limit 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery3.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery3.sql
new file mode 100644
index 0000000..10d8863
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery3.sql
@@ -0,0 +1,14 @@
+select
+  a.r_name,
+  a.r_regionkey,
+  row_number() over (partition by a.r_name order by a.cnt desc) mk
+from (
+  select
+    r_name,
+    r_regionkey,
+    count(*) cnt
+  from
+    default.region
+  group by
+    r_name, r_regionkey
+) a;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery4.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery4.sql
new file mode 100644
index 0000000..fe32eb1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery4.sql
@@ -0,0 +1,14 @@
+select
+  a.r_name,
+  a.r_regionkey,
+  row_number() over (partition by a.r_regionkey order by a.cnt desc) mk
+from (
+  select
+    r_name,
+    r_regionkey,
+    count(*) cnt
+  from
+    default.region
+  group by
+    r_name, r_regionkey
+) a;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery5.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery5.sql
new file mode 100644
index 0000000..2db397b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery5.sql
@@ -0,0 +1,11 @@
+select
+  *
+from (
+  select
+    r_name,
+    rank() over (order by r_regionkey) as ran
+  from
+    region
+) a
+where
+  ran >= 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery6.sql b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery6.sql
new file mode 100644
index 0000000..8678fe6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestWindowQuery/testWindowWithSubQuery6.sql
@@ -0,0 +1,9 @@
+select
+  *
+from (
+  select
+    r_name,
+    rank() over (order by r_regionkey) as ran from region
+) a
+where
+  r_name LIKE 'ASIA'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_1.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_1.sql
new file mode 100644
index 0000000..0f91b68
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_1.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 ADD PARTITION (col1 = 1 , col2 = 2)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_2.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_2.sql
new file mode 100644
index 0000000..ee4df75
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_2.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 ADD PARTITION (col1 = 1 , col2 = 2) LOCATION 'hdfs://xxx.com/warehouse/table1/col1=1/col2=2'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_3.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_3.sql
new file mode 100644
index 0000000..79d1426
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_3.sql
@@ -0,0 +1,2 @@
+ALTER TABLE table1 ADD PARTITION (col1 = '2015' , col2 = '01', col3 = '11' )
+LOCATION 'hdfs://xxx.com/warehouse/table1/col1=2015/col2=01/col3=11'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_4.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_4.sql
new file mode 100644
index 0000000..bc22a14
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_4.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 ADD PARTITION (col1 = 'TAJO' )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_5.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_5.sql
new file mode 100644
index 0000000..127d999
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_add_partition_5.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 ADD IF NOT EXISTS PARTITION (col1 = 'TAJO' )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_1.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_1.sql
new file mode 100644
index 0000000..6e2ad7c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_1.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 DROP PARTITION (col1 = 1 , col2 = 2)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_2.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_2.sql
new file mode 100644
index 0000000..5752710
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_2.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 DROP PARTITION (col1 = '2015' , col2 = '01', col3 = '11' )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_3.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_3.sql
new file mode 100644
index 0000000..8a1a6a5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_3.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 DROP PARTITION (col1 = 'TAJO' ) PURGE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_4.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_4.sql
new file mode 100644
index 0000000..44c7977
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_drop_partition_4.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 DROP IF EXISTS PARTITION (col1 = 'TAJO' ) PURGE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_1.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_1.sql
new file mode 100644
index 0000000..ac7aa4d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_1.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 SET PROPERTY 'timezone' = 'GMT-7'

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_2.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_2.sql
new file mode 100644
index 0000000..77df213
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_2.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 SET PROPERTY 'text.delimiter' = '&'

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_3.sql b/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_3.sql
new file mode 100644
index 0000000..6230a34
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/alter_table_set_property_3.sql
@@ -0,0 +1 @@
+ALTER TABLE table1 SET PROPERTY 'compression.type'='RECORD','compression.codec'='org.apache.hadoop.io.compress.SnappyCodec'

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/asterisk_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/asterisk_1.sql b/tajo-core-tests/src/test/resources/queries/default/asterisk_1.sql
new file mode 100644
index 0000000..2bbe245
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/asterisk_1.sql
@@ -0,0 +1 @@
+select * from people
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/asterisk_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/asterisk_2.sql b/tajo-core-tests/src/test/resources/queries/default/asterisk_2.sql
new file mode 100644
index 0000000..d646044
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/asterisk_2.sql
@@ -0,0 +1 @@
+select p.*, s.* from people cross join students
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/asterisk_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/asterisk_3.sql b/tajo-core-tests/src/test/resources/queries/default/asterisk_3.sql
new file mode 100644
index 0000000..1566230
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/asterisk_3.sql
@@ -0,0 +1 @@
+select * from people cross join students
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/asterisk_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/asterisk_4.sql b/tajo-core-tests/src/test/resources/queries/default/asterisk_4.sql
new file mode 100644
index 0000000..22faf44
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/asterisk_4.sql
@@ -0,0 +1 @@
+select age-10, *, length(name) from people
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_partitioned_table_as_select.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_partitioned_table_as_select.sql b/tajo-core-tests/src/test/resources/queries/default/create_partitioned_table_as_select.sql
new file mode 100644
index 0000000..b2d7dce
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_partitioned_table_as_select.sql
@@ -0,0 +1,17 @@
+CREATE TABLE sales (
+  col1 int,
+  col2 int)
+PARTITION BY COLUMN (col3 int, col4 float, col5 text) AS
+
+SELECT
+  col1,
+  col2,
+  col3,
+  col4,
+  col5
+FROM
+  sales_src
+WHERE
+  col1 > 16
+
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_1.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_1.hiveql b/tajo-core-tests/src/test/resources/queries/default/create_table_1.hiveql
new file mode 100644
index 0000000..c4dcc74
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_1.hiveql
@@ -0,0 +1 @@
+create table name (name string, age int)

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_1.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_1.sql
new file mode 100644
index 0000000..8875b0e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_1.sql
@@ -0,0 +1 @@
+create table name (name text, age int)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_10.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_10.sql
new file mode 100644
index 0000000..43314fa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_10.sql
@@ -0,0 +1 @@
+create external table table1 (name text, age int, earn bigint, score float) using csv location '/tmp/data'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_11.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_11.hiveql b/tajo-core-tests/src/test/resources/queries/default/create_table_11.hiveql
new file mode 100644
index 0000000..014bcbe
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_11.hiveql
@@ -0,0 +1,3 @@
+create external table table1 (name string, age int)
+STORED as rcfile
+location '/user/hive/table1'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_11.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_11.sql
new file mode 100644
index 0000000..d6ca3ae
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_11.sql
@@ -0,0 +1,3 @@
+create external table table1 (name text, age int)
+using rcfile
+location '/user/hive/table1'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_12.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_12.hiveql b/tajo-core-tests/src/test/resources/queries/default/create_table_12.hiveql
new file mode 100644
index 0000000..e74d3e3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_12.hiveql
@@ -0,0 +1,4 @@
+create external table table1  (name string, age int)
+ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
+STORED as  textfile
+location '/user/hive/table1'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_12.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_12.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_12.sql
new file mode 100644
index 0000000..99e7b8d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_12.sql
@@ -0,0 +1,3 @@
+create external table table1 (name text, age int)
+USING text WITH ('text.delimiter'='|')
+location '/user/hive/table1'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_2.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_2.hiveql b/tajo-core-tests/src/test/resources/queries/default/create_table_2.hiveql
new file mode 100644
index 0000000..a5cf55d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_2.hiveql
@@ -0,0 +1 @@
+create table name (name string, age int) STORED as  rcfile
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_2.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_2.sql
new file mode 100644
index 0000000..4580e82
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_2.sql
@@ -0,0 +1 @@
+create table name (name text, age int) using rcfile
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_3.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_3.sql
new file mode 100644
index 0000000..5ab2af2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_3.sql
@@ -0,0 +1 @@
+create table name (name text, age int) using rcfile with ('rcfile.buffer'=4096)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_4.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_4.sql
new file mode 100644
index 0000000..fe4d580
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_4.sql
@@ -0,0 +1 @@
+create table name as select * from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_5.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_5.sql
new file mode 100644
index 0000000..b22b841
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_5.sql
@@ -0,0 +1 @@
+create table name (name text, age int) as select * from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_6.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_6.sql
new file mode 100644
index 0000000..27e06f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_6.sql
@@ -0,0 +1 @@
+create table name (name text, age int) using rcfile as select * from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_7.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_7.sql
new file mode 100644
index 0000000..5c9bf35
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_7.sql
@@ -0,0 +1 @@
+create table name (name text, age int) using rcfile with ('rcfile.buffer'= 4096) as select * from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_8.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_8.sql
new file mode 100644
index 0000000..d6c2ae6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_8.sql
@@ -0,0 +1,48 @@
+create table widetable (
+  col0 bit,
+  col1 BIT(10),
+  col2 bit varying,
+  col3 bit VARYING(10),
+  col4 tinyint,
+  col5 smallInt,
+  col6 integer,
+  col7 biginT,
+  col8 real,
+  col9 float,
+  col10 float(53),
+  col11 double,
+  col12 doublE precision,
+  col13 numeric,
+  col14 numeric(10),
+  col15 numeric(10,2),
+  col16 decimal,
+  col17 decimal(10),
+  col18 decimal(10,2),
+  col19 char,
+  col20 character,
+  col21 chaR(10),
+  col22 character(10),
+  col23 varchar,
+  col24 character varying,
+  col25 varchar(255),
+  col26 character varying (255),
+  col27 nchar,
+  col28 nchar(255),
+  col29 national character,
+  col30 national character(255),
+  col31 nvarchar,
+  col32 nvarchar(255),
+  col33 natIonal character varying,
+  col34 national character varying (255),
+  col35 date,
+  col36 time,
+  col37 timetz,
+  col38 time With time zone,
+  col39 timesTamptz,
+  col40 timestamp with time zone,
+  col41 binary,
+  col42 binary(10),
+  col43 varbinary(10),
+  col44 binary Varying(10),
+  col45 blOb
+) as select * from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_9.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_9.sql
new file mode 100644
index 0000000..49e1e3c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_9.sql
@@ -0,0 +1 @@
+create table widetable (col1 float(10), col2 float) as select * from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_like_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_like_1.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_like_1.sql
new file mode 100644
index 0000000..73f2f46
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_like_1.sql
@@ -0,0 +1 @@
+create table new_table like orig_name;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_column.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_column.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_column.sql
new file mode 100644
index 0000000..397e7ac
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_column.sql
@@ -0,0 +1,4 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY COLUMN (col3 int, col4 float, col5 text);
+
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_1.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_1.sql
new file mode 100644
index 0000000..f13225a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_1.sql
@@ -0,0 +1,3 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY HASH (col1)
+PARTITIONS 2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_2.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_2.sql
new file mode 100644
index 0000000..c8fe3c5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_hash_2.sql
@@ -0,0 +1,7 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY HASH (col1)
+(
+  PARTITION part1,
+  PARTITION part2,
+  PARTITION part3
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_list.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_list.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_list.sql
new file mode 100644
index 0000000..9461e01
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_list.sql
@@ -0,0 +1,8 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY LIST (col1)
+ (
+  PARTITION col1 VALUES ('Seoul', '서울'),
+  PARTITION col2 VALUES ('Busan', '부산')
+ );
+
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_range.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_range.sql b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_range.sql
new file mode 100644
index 0000000..65c4fdd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/create_table_partition_by_range.sql
@@ -0,0 +1,9 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY RANGE (col1)
+ (
+  PARTITION col1 VALUES LESS THAN (2),
+  PARTITION col1 VALUES LESS THAN (5),
+  PARTITION col1 VALUES LESS THAN (MAXVALUE)
+ );
+
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/drop_table.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/drop_table.sql b/tajo-core-tests/src/test/resources/queries/default/drop_table.sql
new file mode 100644
index 0000000..0e52112
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/drop_table.sql
@@ -0,0 +1 @@
+drop table abc
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/exists_predicate_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/exists_predicate_1.sql b/tajo-core-tests/src/test/resources/queries/default/exists_predicate_1.sql
new file mode 100644
index 0000000..0b10799
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/exists_predicate_1.sql
@@ -0,0 +1 @@
+select c1,c2,c3 from table1 where exists (select c4 from table2 where c4 = table1.c1);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/exists_predicate_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/exists_predicate_2.sql b/tajo-core-tests/src/test/resources/queries/default/exists_predicate_2.sql
new file mode 100644
index 0000000..f4f82f9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/exists_predicate_2.sql
@@ -0,0 +1 @@
+select c1,c2,c3 from table1 where not exists (select c4 from table2 where c4 = table1.c1);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/groupby_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/groupby_1.sql b/tajo-core-tests/src/test/resources/queries/default/groupby_1.sql
new file mode 100644
index 0000000..85dbe21
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/groupby_1.sql
@@ -0,0 +1 @@
+select col0, col1, col2, col3, sum(col4) as total, avg(col5) from base group by col0, cube (col1, col2), rollup(col3) having total > 100
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/groupby_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/groupby_2.sql b/tajo-core-tests/src/test/resources/queries/default/groupby_2.sql
new file mode 100644
index 0000000..031cab2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/groupby_2.sql
@@ -0,0 +1 @@
+select col0, col1, col2, col3, sum(col4) as total, avg(col5) from base group by col0, cube (col1, col2), col3 having total > 100
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/groupby_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/groupby_3.sql b/tajo-core-tests/src/test/resources/queries/default/groupby_3.sql
new file mode 100644
index 0000000..469e8b2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/groupby_3.sql
@@ -0,0 +1 @@
+select col0, col1, col2, col3, sum(col4) as total, avg(col5) from base group by col0, col3, cube (col1, col2) having total > 100
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/groupby_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/groupby_4.sql b/tajo-core-tests/src/test/resources/queries/default/groupby_4.sql
new file mode 100644
index 0000000..749c6d9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/groupby_4.sql
@@ -0,0 +1 @@
+select trim(name), count(1) from table1 group by trim(name)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/groupby_5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/groupby_5.sql b/tajo-core-tests/src/test/resources/queries/default/groupby_5.sql
new file mode 100644
index 0000000..f654ef6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/groupby_5.sql
@@ -0,0 +1 @@
+select id, name, count(*), sum(id), avg(age) from people group by id, name
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/in_subquery_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/in_subquery_1.sql b/tajo-core-tests/src/test/resources/queries/default/in_subquery_1.sql
new file mode 100644
index 0000000..2a16a8d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/in_subquery_1.sql
@@ -0,0 +1 @@
+select c1,c2,c3 from table1 where c1 in (select c4 from table2);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/in_subquery_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/in_subquery_2.sql b/tajo-core-tests/src/test/resources/queries/default/in_subquery_2.sql
new file mode 100644
index 0000000..64c8034
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/in_subquery_2.sql
@@ -0,0 +1 @@
+select c1,c2,c3 from table1 where c1 not in (select c4 from table2);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_into_select_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_into_select_1.sql b/tajo-core-tests/src/test/resources/queries/default/insert_into_select_1.sql
new file mode 100644
index 0000000..d3291f5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_into_select_1.sql
@@ -0,0 +1 @@
+insert into table1 select col1, col2, sum(col3) from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_into_select_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_into_select_2.sql b/tajo-core-tests/src/test/resources/queries/default/insert_into_select_2.sql
new file mode 100644
index 0000000..2928b11
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_into_select_2.sql
@@ -0,0 +1 @@
+insert into location 'file:/tmp/data' select col1, col2, sum(col3) from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_into_select_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_into_select_3.sql b/tajo-core-tests/src/test/resources/queries/default/insert_into_select_3.sql
new file mode 100644
index 0000000..b7718dc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_into_select_3.sql
@@ -0,0 +1 @@
+insert into table1 (col1, col2, col3) select col1, col2, sum(col3) as total from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_1.sql b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_1.sql
new file mode 100644
index 0000000..84992bc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_1.sql
@@ -0,0 +1 @@
+insert overwrite into table1 select col1, col2, sum(col3) from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.hiveql b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.hiveql
new file mode 100644
index 0000000..b99863e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.hiveql
@@ -0,0 +1 @@
+INSERT OVERWRITE DIRECTORY  'file:/tmp/data' select col1, col2, sum(col3) from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.sql b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.sql
new file mode 100644
index 0000000..1c4227b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_2.sql
@@ -0,0 +1 @@
+insert overwrite into location 'file:/tmp/data' select col1, col2, sum(col3) from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_3.sql b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_3.sql
new file mode 100644
index 0000000..bfacc01
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/insert_overwrite_into_select_3.sql
@@ -0,0 +1 @@
+insert overwrite into table1 (col1, col2, col3) select col1, col2, sum(col3) as total from table2 group by col1, col2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_1.sql b/tajo-core-tests/src/test/resources/queries/default/join_1.sql
new file mode 100644
index 0000000..ad27795
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_1.sql
@@ -0,0 +1 @@
+select name, addr from people natural join student natural join professor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_10.sql b/tajo-core-tests/src/test/resources/queries/default/join_10.sql
new file mode 100644
index 0000000..c9056cc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_10.sql
@@ -0,0 +1 @@
+select * from a cross join b, c, d, e
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_11.sql b/tajo-core-tests/src/test/resources/queries/default/join_11.sql
new file mode 100644
index 0000000..25daeb0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_11.sql
@@ -0,0 +1 @@
+select * from x, y, (select * from a, b, c WHERE something) as ss where somethingelse
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_12.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_12.sql b/tajo-core-tests/src/test/resources/queries/default/join_12.sql
new file mode 100644
index 0000000..02a0b8e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_12.sql
@@ -0,0 +1 @@
+select name, addr from people join student join professor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_13.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_13.sql b/tajo-core-tests/src/test/resources/queries/default/join_13.sql
new file mode 100644
index 0000000..9c56bc0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_13.sql
@@ -0,0 +1,13 @@
+select * 
+from table1 
+cross join table2 
+join table3 on table1.id = table3.id 
+inner join table4 on table1.id = table4.id 
+left outer join table5 on table1.id = table5.id 
+right outer join table6 on table1.id = table6.id 
+full outer join table7 on table1.id = table7.id 
+join table8 
+inner join table9 
+left outer join table10 
+right outer join table11 
+full outer join table12
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_14.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_14.sql b/tajo-core-tests/src/test/resources/queries/default/join_14.sql
new file mode 100644
index 0000000..21c7099
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_14.sql
@@ -0,0 +1 @@
+select * from a cross join b cross join c cross join d cross join e
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_15.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_15.hiveql b/tajo-core-tests/src/test/resources/queries/default/join_15.hiveql
new file mode 100644
index 0000000..28e9a02
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_15.hiveql
@@ -0,0 +1 @@
+select  * from x join y join (select * from a join b  on a.age = b.age join c on a.sex = c.sex) ss
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_15.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_15.sql b/tajo-core-tests/src/test/resources/queries/default/join_15.sql
new file mode 100644
index 0000000..8e41142
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_15.sql
@@ -0,0 +1 @@
+select  * from x join y join (select * from a join b  on a.age = b.age join c on a.sex = c.sex) as ss
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_2.sql b/tajo-core-tests/src/test/resources/queries/default/join_2.sql
new file mode 100644
index 0000000..03056ac
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_2.sql
@@ -0,0 +1 @@
+select name, addr from people inner join student on people.name = student.name
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_3.sql b/tajo-core-tests/src/test/resources/queries/default/join_3.sql
new file mode 100644
index 0000000..22281fe
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_3.sql
@@ -0,0 +1 @@
+select name, addr from people inner join student using (id, name)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_4.sql b/tajo-core-tests/src/test/resources/queries/default/join_4.sql
new file mode 100644
index 0000000..7e572de
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_4.sql
@@ -0,0 +1 @@
+select name, addr from people join student using (id, name)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_5.sql b/tajo-core-tests/src/test/resources/queries/default/join_5.sql
new file mode 100644
index 0000000..79c69e3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_5.sql
@@ -0,0 +1 @@
+select name, addr from people cross join student
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_6.sql b/tajo-core-tests/src/test/resources/queries/default/join_6.sql
new file mode 100644
index 0000000..10aafa9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_6.sql
@@ -0,0 +1 @@
+select name, addr from people left outer join student on people.name = student.name
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_7.sql b/tajo-core-tests/src/test/resources/queries/default/join_7.sql
new file mode 100644
index 0000000..402b82f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_7.sql
@@ -0,0 +1 @@
+select name, addr from people right outer join student on people.name = student.name
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_8.sql b/tajo-core-tests/src/test/resources/queries/default/join_8.sql
new file mode 100644
index 0000000..f413478
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_8.sql
@@ -0,0 +1,13 @@
+select *
+  from table1
+  cross join table2
+  join table3 on table1.id = table3.id
+  inner join table4 on table1.id = table4.id
+  left outer join table5 on table1.id = table5.id
+  right outer join table6 on table1.id = table6.id
+  full outer join table7 on table1.id = table7.id
+  natural join table8
+  natural inner join table9
+  natural left outer join table10
+  natural right outer join table11
+  natural full outer join table12
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/join_9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/join_9.sql b/tajo-core-tests/src/test/resources/queries/default/join_9.sql
new file mode 100644
index 0000000..6f0ae0d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/join_9.sql
@@ -0,0 +1,5 @@
+select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment, ps_supplycost
+  from region join nation on n_regionkey = r_regionkey and r_name = 'EUROPE'
+  join supplier on s_nationekey = n_nationkey
+  join partsupp on s_suppkey = ps_ps_suppkey
+  join part on p_partkey = ps_partkey and p_type like '%BRASS' and p_size = 15
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_1.sql b/tajo-core-tests/src/test/resources/queries/default/select_1.sql
new file mode 100644
index 0000000..7196f0c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_1.sql
@@ -0,0 +1 @@
+select id, name, age, gender from people
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_10.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_10.hiveql b/tajo-core-tests/src/test/resources/queries/default/select_10.hiveql
new file mode 100644
index 0000000..f03fdc0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_10.hiveql
@@ -0,0 +1,5 @@
+select B.*
+from (
+  select A.member_id, A.member_name
+  from table1 A
+) B

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_10.sql b/tajo-core-tests/src/test/resources/queries/default/select_10.sql
new file mode 100644
index 0000000..a3557a1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_10.sql
@@ -0,0 +1,5 @@
+select B.*
+from (
+  select A.member_id, A.member_name
+  from table1 AS A
+) B

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_11.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_11.hiveql b/tajo-core-tests/src/test/resources/queries/default/select_11.hiveql
new file mode 100644
index 0000000..3bb82e9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_11.hiveql
@@ -0,0 +1,4 @@
+select A.member_id, A.member_name
+from table1 A
+where A.member_id between '10000' and '20000'
+and A.age between 30 and 50
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_11.sql b/tajo-core-tests/src/test/resources/queries/default/select_11.sql
new file mode 100644
index 0000000..8984a4d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_11.sql
@@ -0,0 +1,6 @@
+select A.member_id, A.member_name
+from table1 AS A
+where A.member_id >= '10000'
+and A.member_id <= '20000'
+and A.age >= 30
+and A.age <= 50
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_12.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_12.hiveql b/tajo-core-tests/src/test/resources/queries/default/select_12.hiveql
new file mode 100644
index 0000000..3ea5008
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_12.hiveql
@@ -0,0 +1,3 @@
+SELECT name, salary
+FROM  employees
+limit 10

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_13.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_13.hiveql b/tajo-core-tests/src/test/resources/queries/default/select_13.hiveql
new file mode 100644
index 0000000..e9f7592
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_13.hiveql
@@ -0,0 +1,2 @@
+select A.*
+from table1 A
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_13.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_13.sql b/tajo-core-tests/src/test/resources/queries/default/select_13.sql
new file mode 100644
index 0000000..19410ea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_13.sql
@@ -0,0 +1,2 @@
+select A.*
+from table1  A
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_14.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_14.sql b/tajo-core-tests/src/test/resources/queries/default/select_14.sql
new file mode 100644
index 0000000..27c9a5a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_14.sql
@@ -0,0 +1,2 @@
+select *
+from table1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_15.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_15.hiveql b/tajo-core-tests/src/test/resources/queries/default/select_15.hiveql
new file mode 100644
index 0000000..37c1c83
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_15.hiveql
@@ -0,0 +1 @@
+select id,  cast(point as string) as point, cast(score as int) as score from table1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_15.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_15.sql b/tajo-core-tests/src/test/resources/queries/default/select_15.sql
new file mode 100644
index 0000000..7c942b1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_15.sql
@@ -0,0 +1 @@
+select id,  point::text as point, score::INT4 as score from table1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_2.sql b/tajo-core-tests/src/test/resources/queries/default/select_2.sql
new file mode 100644
index 0000000..0727705
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_2.sql
@@ -0,0 +1 @@
+select id, name, age, gender from people as p, students as s
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_3.sql b/tajo-core-tests/src/test/resources/queries/default/select_3.sql
new file mode 100644
index 0000000..2e8f43a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_3.sql
@@ -0,0 +1 @@
+select name, addr, sum(score) from students group by name, addr
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_4.sql b/tajo-core-tests/src/test/resources/queries/default/select_4.sql
new file mode 100644
index 0000000..6c19a45
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_4.sql
@@ -0,0 +1 @@
+select name, addr, age from people where age > 30
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_5.sql b/tajo-core-tests/src/test/resources/queries/default/select_5.sql
new file mode 100644
index 0000000..d9234e0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_5.sql
@@ -0,0 +1 @@
+select name as n, func(score, 3+4, 3>4) as total, 3+4 as id from people where age = 30
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_6.sql b/tajo-core-tests/src/test/resources/queries/default/select_6.sql
new file mode 100644
index 0000000..965aa08
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_6.sql
@@ -0,0 +1 @@
+select ipv4:src_ip from test
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_7.sql b/tajo-core-tests/src/test/resources/queries/default/select_7.sql
new file mode 100644
index 0000000..d54276b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_7.sql
@@ -0,0 +1 @@
+select distinct id, name, age, gender from people
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_8.sql b/tajo-core-tests/src/test/resources/queries/default/select_8.sql
new file mode 100644
index 0000000..13f6842
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_8.sql
@@ -0,0 +1 @@
+select all id, name, age, gender from people
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_9.hiveql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_9.hiveql b/tajo-core-tests/src/test/resources/queries/default/select_9.hiveql
new file mode 100644
index 0000000..96e6042
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_9.hiveql
@@ -0,0 +1,4 @@
+SELECT A.*
+FROM table1 A
+WHERE A.member_name is not null
+and A.post_code is null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/select_9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/select_9.sql b/tajo-core-tests/src/test/resources/queries/default/select_9.sql
new file mode 100644
index 0000000..8f99ca3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/select_9.sql
@@ -0,0 +1,4 @@
+SELECT A.*
+FROM table1 AS A
+WHERE A.member_name is not null
+and A.post_code is null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/set_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/set_1.sql b/tajo-core-tests/src/test/resources/queries/default/set_1.sql
new file mode 100644
index 0000000..88600fc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/set_1.sql
@@ -0,0 +1 @@
+select c1,c2,c3 from table1 union select c4,c5,c6 from table2 union all select c7, c8 from table3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/set_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/set_2.sql b/tajo-core-tests/src/test/resources/queries/default/set_2.sql
new file mode 100644
index 0000000..0eb5670
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/set_2.sql
@@ -0,0 +1 @@
+select a,b,c from table1 union distinct select a,b,c from table2 except all select a,b,c from table3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/default/set_3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/default/set_3.sql b/tajo-core-tests/src/test/resources/queries/default/set_3.sql
new file mode 100644
index 0000000..eebfbcb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/default/set_3.sql
@@ -0,0 +1 @@
+select a,b,c from table1 intersect select a,b,c from table2 intersect all select a,b,c from table3
\ No newline at end of file


[11/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort.plan
new file mode 100644
index 0000000..21e765d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..4250b5c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4)
+  => out schema: {(1) default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(2) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(1) default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(1) default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.result
new file mode 100644
index 0000000..774f3a8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvals1.result
@@ -0,0 +1,27 @@
+r_regionkey,n_regionkey,plus
+-------------------------------
+0,0,0
+0,0,0
+0,0,0
+0,0,0
+0,0,0
+1,1,2
+1,1,2
+1,1,2
+1,1,2
+1,1,2
+2,2,4
+2,2,4
+2,2,4
+2,2,4
+2,2,4
+3,3,6
+3,3,6
+3,3,6
+3,3,6
+3,3,6
+4,4,8
+4,4,8
+4,4,8
+4,4,8
+4,4,8

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash.plan
new file mode 100644
index 0000000..a8f9f8b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash.plan
@@ -0,0 +1,88 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      JOIN(7)(INNER)
+        => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+        => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+         SCAN(0) on default.region
+           => filter: default.region.r_regionkey (INT4) > 0
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+           => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+     => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(0) on default.region
+        => filter: default.region.r_regionkey (INT4) > 0
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..936e4fc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Hash_NoBroadcast.plan
@@ -0,0 +1,115 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      JOIN(7)(INNER)
+        => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+        => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+         SCAN(0) on default.region
+           => filter: default.region.r_regionkey (INT4) > 0
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+           => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+  => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => filter: default.region.r_regionkey (INT4) > 0
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+     => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(1) default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort.plan
new file mode 100644
index 0000000..a8f9f8b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort.plan
@@ -0,0 +1,88 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      JOIN(7)(INNER)
+        => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+        => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+         SCAN(0) on default.region
+           => filter: default.region.r_regionkey (INT4) > 0
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+           => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+     => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(0) on default.region
+        => filter: default.region.r_regionkey (INT4) > 0
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..936e4fc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.Sort_NoBroadcast.plan
@@ -0,0 +1,115 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      JOIN(7)(INNER)
+        => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+        => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+         SCAN(0) on default.region
+           => filter: default.region.r_regionkey (INT4) > 0
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+           => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+  => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => filter: default.region.r_regionkey (INT4) > 0
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as plus1
+     => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(1) default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4)
+  => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), v1 (INT4)}
+  => in  schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+   SORT(3)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+        => in schema: {(5) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.result
new file mode 100644
index 0000000..e437085
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs1.result
@@ -0,0 +1,22 @@
+v1,n_regionkey,r_regionkey,plus1,plus2,result
+-------------------------------
+2,1,1,2,2,1
+3,1,1,2,2,1
+4,1,1,2,2,1
+8,4,4,8,8,4
+9,3,3,6,6,3
+10,2,2,4,4,2
+10,3,3,6,6,3
+11,2,2,4,4,2
+14,2,2,4,4,2
+14,4,4,8,8,4
+15,4,4,8,8,4
+17,4,4,8,8,4
+18,1,1,2,2,1
+20,2,2,4,4,2
+22,3,3,6,6,3
+23,2,2,4,4,2
+24,4,4,8,8,4
+25,1,1,2,2,1
+25,3,3,6,6,3
+26,3,3,6,6,3

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash.plan
new file mode 100644
index 0000000..d6252ea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash.plan
@@ -0,0 +1,119 @@
+explain
+-------------------------------
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+        => exprs: (sum(?plus (INT4)))
+        => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+        => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+         JOIN(8)(INNER)
+           => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+           => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+           => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+           => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+            SCAN(0) on default.region
+              => filter: default.region.r_regionkey (INT4) > 0
+              => target list: default.region.r_regionkey (INT4)
+              => out schema: {(1) default.region.r_regionkey (INT4)}
+              => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+              => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+4: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+GROUP_BY(12)(?plus,n_regionkey,r_regionkey,result,v1)
+  => exprs: (sum(?plus (INT4)))
+  => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)
+  => out schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+  => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+   JOIN(8)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+     => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(0) on default.region
+        => filter: default.region.r_regionkey (INT4) > 0
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+SORT(14)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+     => exprs: (sum(?sum_3 (INT8)))
+     => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+     => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+     => in schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+      SCAN(13) on eb_0000000000000_0000_000003
+        => out schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+        => in schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000004
+
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(15) on eb_0000000000000_0000_000004
+        => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..f3a2084
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Hash_NoBroadcast.plan
@@ -0,0 +1,146 @@
+explain
+-------------------------------
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+        => exprs: (sum(?plus (INT4)))
+        => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+        => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+         JOIN(8)(INNER)
+           => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+           => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+           => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+           => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+            SCAN(0) on default.region
+              => filter: default.region.r_regionkey (INT4) > 0
+              => target list: default.region.r_regionkey (INT4)
+              => out schema: {(1) default.region.r_regionkey (INT4)}
+              => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+              => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+            |-eb_0000000000000_0000_000002
+            |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+  => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => filter: default.region.r_regionkey (INT4) > 0
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+GROUP_BY(12)(?plus,n_regionkey,r_regionkey,result,v1)
+  => exprs: (sum(?plus (INT4)))
+  => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)
+  => out schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+  => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+   JOIN(8)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+     => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(11) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(1) default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+SORT(14)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+     => exprs: (sum(?sum_3 (INT8)))
+     => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+     => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+     => in schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+      SCAN(13) on eb_0000000000000_0000_000003
+        => out schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+        => in schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000004
+
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(15) on eb_0000000000000_0000_000004
+        => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort.plan
new file mode 100644
index 0000000..d6252ea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort.plan
@@ -0,0 +1,119 @@
+explain
+-------------------------------
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+        => exprs: (sum(?plus (INT4)))
+        => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+        => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+         JOIN(8)(INNER)
+           => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+           => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+           => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+           => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+            SCAN(0) on default.region
+              => filter: default.region.r_regionkey (INT4) > 0
+              => target list: default.region.r_regionkey (INT4)
+              => out schema: {(1) default.region.r_regionkey (INT4)}
+              => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+              => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+4: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+GROUP_BY(12)(?plus,n_regionkey,r_regionkey,result,v1)
+  => exprs: (sum(?plus (INT4)))
+  => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)
+  => out schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+  => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+   JOIN(8)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+     => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(0) on default.region
+        => filter: default.region.r_regionkey (INT4) > 0
+        => target list: default.region.r_regionkey (INT4)
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+SORT(14)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+     => exprs: (sum(?sum_3 (INT8)))
+     => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+     => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+     => in schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+      SCAN(13) on eb_0000000000000_0000_000003
+        => out schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+        => in schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000004
+
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(15) on eb_0000000000000_0000_000004
+        => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..f3a2084
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.Sort_NoBroadcast.plan
@@ -0,0 +1,146 @@
+explain
+-------------------------------
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+        => exprs: (sum(?plus (INT4)))
+        => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+        => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+         JOIN(8)(INNER)
+           => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+           => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+           => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+           => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+            SCAN(0) on default.region
+              => filter: default.region.r_regionkey (INT4) > 0
+              => target list: default.region.r_regionkey (INT4)
+              => out schema: {(1) default.region.r_regionkey (INT4)}
+              => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+              => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+            |-eb_0000000000000_0000_000002
+            |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4), default.nation.n_regionkey (INT4) + default.nation.n_nationkey (INT4) as v1
+  => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => filter: default.region.r_regionkey (INT4) > 0
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+GROUP_BY(12)(?plus,n_regionkey,r_regionkey,result,v1)
+  => exprs: (sum(?plus (INT4)))
+  => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)
+  => out schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+  => in schema:{(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+   JOIN(8)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) / 2 as result, default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4), default.region.r_regionkey (INT4) + default.nation.n_regionkey (INT4) as ?plus
+     => out schema: {(5) ?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4)}
+     => in schema: {(3) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), v1 (INT4)}
+      SCAN(11) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.region.r_regionkey (INT4)}
+        => in schema: {(1) default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+        => in schema: {(2) default.nation.n_regionkey (INT4), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=HASH_SHUFFLE, key=?plus (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), result (INT4), v1 (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+SORT(14)
+  => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   GROUP_BY(3)(v1,n_regionkey,r_regionkey,?plus,result)
+     => exprs: (sum(?sum_3 (INT8)))
+     => target list: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4) as plus1, result (INT4), total (INT8)
+     => out schema:{(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+     => in schema:{(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+      SCAN(13) on eb_0000000000000_0000_000003
+        => out schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+        => in schema: {(6) v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), ?plus (INT4), result (INT4), ?sum_3 (INT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 4 => 5 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), v1 (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000004
+
+PROJECTION(5)
+  => Targets: v1 (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus1 (INT4) as plus2, result (INT4), total (INT8)
+  => out schema: {(7) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), plus2 (INT4), result (INT4), total (INT8), v1 (INT4)}
+  => in  schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+   SORT(4)
+     => Sort Keys: v1 (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+      SCAN(15) on eb_0000000000000_0000_000004
+        => out schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+        => in schema: {(6) default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), plus1 (INT4), result (INT4), total (INT8), v1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.result
new file mode 100644
index 0000000..3a3ff3e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinCoReferredEvalsWithSameExprs2.result
@@ -0,0 +1,22 @@
+v1,n_regionkey,r_regionkey,plus1,plus2,result,total
+-------------------------------
+2,1,1,2,2,1,2
+3,1,1,2,2,1,2
+4,1,1,2,2,1,2
+8,4,4,8,8,4,8
+9,3,3,6,6,3,6
+10,2,2,4,4,2,4
+10,3,3,6,6,3,6
+11,2,2,4,4,2,4
+14,2,2,4,4,2,4
+14,4,4,8,8,4,8
+15,4,4,8,8,4,8
+17,4,4,8,8,4,8
+18,1,1,2,2,1,2
+20,2,2,4,4,2,4
+22,3,3,6,6,3,6
+23,2,2,4,4,2,4
+24,4,4,8,8,4,8
+25,1,1,2,2,1,2
+25,3,3,6,6,3,6
+26,3,3,6,6,3,6


[18/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash.plan
new file mode 100644
index 0000000..1d0e9ff
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..feec5d9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+  => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(1) name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort.plan
new file mode 100644
index 0000000..1d0e9ff
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..feec5d9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+  => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(1) name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.result
new file mode 100644
index 0000000..9244a0b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition4.result
@@ -0,0 +1,29 @@
+n_nationkey,name1,name2
+-------------------------------
+0,ALGE,ALGE
+1,ARGE,ARGE
+2,BRAZ,BRAZ
+3,CANA,CANA
+4,EGYP,EGYP
+5,ETHI,ETHI
+6,FRAN,FRAN
+7,GERM,GERM
+8,INDI,INDI
+9,INDO,INDO
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+12,JAPA,JAPA
+13,JORD,JORD
+14,KENY,KENY
+15,MORO,MORO
+16,MOZA,MOZA
+17,PERU,PERU
+18,CHIN,CHIN
+19,ROMA,ROMA
+20,SAUD,SAUD
+21,VIET,VIET
+22,RUSS,RUSS
+23,UNIT,UNIT
+23,UNIT,UNIT
+24,UNIT,UNIT
+24,UNIT,UNIT

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash.plan
new file mode 100644
index 0000000..0fb22b3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..4278681
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Hash_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+SORT(10)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort.plan
new file mode 100644
index 0000000..0fb22b3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..4278681
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.Sort_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+SORT(10)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.region.r_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.nation.n_name (TEXT) (asc),default.region.r_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.result
new file mode 100644
index 0000000..7d5a2f5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.1.result
@@ -0,0 +1,127 @@
+n_name,r_name,n_regionkey,r_regionkey
+-------------------------------
+ALGERIA,AFRICA,0,0
+ALGERIA,AMERICA,0,1
+ALGERIA,ASIA,0,2
+ALGERIA,EUROPE,0,3
+ALGERIA,MIDDLE EAST,0,4
+ARGENTINA,AFRICA,1,0
+ARGENTINA,AMERICA,1,1
+ARGENTINA,ASIA,1,2
+ARGENTINA,EUROPE,1,3
+ARGENTINA,MIDDLE EAST,1,4
+BRAZIL,AFRICA,1,0
+BRAZIL,AMERICA,1,1
+BRAZIL,ASIA,1,2
+BRAZIL,EUROPE,1,3
+BRAZIL,MIDDLE EAST,1,4
+CANADA,AFRICA,1,0
+CANADA,AMERICA,1,1
+CANADA,ASIA,1,2
+CANADA,EUROPE,1,3
+CANADA,MIDDLE EAST,1,4
+CHINA,AFRICA,2,0
+CHINA,AMERICA,2,1
+CHINA,ASIA,2,2
+CHINA,EUROPE,2,3
+CHINA,MIDDLE EAST,2,4
+EGYPT,AFRICA,4,0
+EGYPT,AMERICA,4,1
+EGYPT,ASIA,4,2
+EGYPT,EUROPE,4,3
+EGYPT,MIDDLE EAST,4,4
+ETHIOPIA,AFRICA,0,0
+ETHIOPIA,AMERICA,0,1
+ETHIOPIA,ASIA,0,2
+ETHIOPIA,EUROPE,0,3
+ETHIOPIA,MIDDLE EAST,0,4
+FRANCE,AFRICA,3,0
+FRANCE,AMERICA,3,1
+FRANCE,ASIA,3,2
+FRANCE,EUROPE,3,3
+FRANCE,MIDDLE EAST,3,4
+GERMANY,AFRICA,3,0
+GERMANY,AMERICA,3,1
+GERMANY,ASIA,3,2
+GERMANY,EUROPE,3,3
+GERMANY,MIDDLE EAST,3,4
+INDIA,AFRICA,2,0
+INDIA,AMERICA,2,1
+INDIA,ASIA,2,2
+INDIA,EUROPE,2,3
+INDIA,MIDDLE EAST,2,4
+INDONESIA,AFRICA,2,0
+INDONESIA,AMERICA,2,1
+INDONESIA,ASIA,2,2
+INDONESIA,EUROPE,2,3
+INDONESIA,MIDDLE EAST,2,4
+IRAN,AFRICA,4,0
+IRAN,AMERICA,4,1
+IRAN,ASIA,4,2
+IRAN,EUROPE,4,3
+IRAN,MIDDLE EAST,4,4
+IRAQ,AFRICA,4,0
+IRAQ,AMERICA,4,1
+IRAQ,ASIA,4,2
+IRAQ,EUROPE,4,3
+IRAQ,MIDDLE EAST,4,4
+JAPAN,AFRICA,2,0
+JAPAN,AMERICA,2,1
+JAPAN,ASIA,2,2
+JAPAN,EUROPE,2,3
+JAPAN,MIDDLE EAST,2,4
+JORDAN,AFRICA,4,0
+JORDAN,AMERICA,4,1
+JORDAN,ASIA,4,2
+JORDAN,EUROPE,4,3
+JORDAN,MIDDLE EAST,4,4
+KENYA,AFRICA,0,0
+KENYA,AMERICA,0,1
+KENYA,ASIA,0,2
+KENYA,EUROPE,0,3
+KENYA,MIDDLE EAST,0,4
+MOROCCO,AFRICA,0,0
+MOROCCO,AMERICA,0,1
+MOROCCO,ASIA,0,2
+MOROCCO,EUROPE,0,3
+MOROCCO,MIDDLE EAST,0,4
+MOZAMBIQUE,AFRICA,0,0
+MOZAMBIQUE,AMERICA,0,1
+MOZAMBIQUE,ASIA,0,2
+MOZAMBIQUE,EUROPE,0,3
+MOZAMBIQUE,MIDDLE EAST,0,4
+PERU,AFRICA,1,0
+PERU,AMERICA,1,1
+PERU,ASIA,1,2
+PERU,EUROPE,1,3
+PERU,MIDDLE EAST,1,4
+ROMANIA,AFRICA,3,0
+ROMANIA,AMERICA,3,1
+ROMANIA,ASIA,3,2
+ROMANIA,EUROPE,3,3
+ROMANIA,MIDDLE EAST,3,4
+RUSSIA,AFRICA,3,0
+RUSSIA,AMERICA,3,1
+RUSSIA,ASIA,3,2
+RUSSIA,EUROPE,3,3
+RUSSIA,MIDDLE EAST,3,4
+SAUDI ARABIA,AFRICA,4,0
+SAUDI ARABIA,AMERICA,4,1
+SAUDI ARABIA,ASIA,4,2
+SAUDI ARABIA,EUROPE,4,3
+SAUDI ARABIA,MIDDLE EAST,4,4
+UNITED KINGDOM,AFRICA,3,0
+UNITED KINGDOM,AMERICA,3,1
+UNITED KINGDOM,ASIA,3,2
+UNITED KINGDOM,EUROPE,3,3
+UNITED KINGDOM,MIDDLE EAST,3,4
+UNITED STATES,AFRICA,1,0
+UNITED STATES,AMERICA,1,1
+UNITED STATES,ASIA,1,2
+UNITED STATES,EUROPE,1,3
+UNITED STATES,MIDDLE EAST,1,4
+VIETNAM,AFRICA,2,0
+VIETNAM,AMERICA,2,1
+VIETNAM,ASIA,2,2
+VIETNAM,EUROPE,2,3
+VIETNAM,MIDDLE EAST,2,4

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash.plan
new file mode 100644
index 0000000..8bc07bf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash.plan
@@ -0,0 +1,51 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..5d0de2f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Hash_NoBroadcast.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort.plan
new file mode 100644
index 0000000..8bc07bf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort.plan
@@ -0,0 +1,51 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..5d0de2f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.Sort_NoBroadcast.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(0) on default.region
+     => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(1) on default.customer
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+JOIN(5)(CROSS)
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+     => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.result
new file mode 100644
index 0000000..304b867
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoin.2.result
@@ -0,0 +1,27 @@
+r_regionkey,r_name,r_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+1,AMERICA,hs use ironic, even requests. s,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+1,AMERICA,hs use ironic, even requests. s,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+1,AMERICA,hs use ironic, even requests. s,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+1,AMERICA,hs use ironic, even requests. s,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+1,AMERICA,hs use ironic, even requests. s,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+2,ASIA,ges. thinly even pinto beans ca,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+2,ASIA,ges. thinly even pinto beans ca,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+2,ASIA,ges. thinly even pinto beans ca,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+2,ASIA,ges. thinly even pinto beans ca,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+2,ASIA,ges. thinly even pinto beans ca,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+3,EUROPE,ly final courts cajole furiously final excuse,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+3,EUROPE,ly final courts cajole furiously final excuse,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+3,EUROPE,ly final courts cajole furiously final excuse,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,EUROPE,ly final courts cajole furiously final excuse,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+3,EUROPE,ly final courts cajole furiously final excuse,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor


[19/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..fc5e3e3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+        => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+         SCAN(3) on default.customer
+           => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+           => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+           => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+         SCAN(4) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+           => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(2) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+           => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(1) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+            SCAN(0) on default.lineitem
+              => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+              => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+              => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+
+SCAN(0) on default.lineitem
+  => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+  => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+  => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.orders.o_orderkey (INT4), num=32)
+
+SCAN(1) on default.orders
+  => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+  => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+  => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.orders.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+  => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+  => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+  => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+     => in schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+     => in schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(2) on default.part
+  => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+  => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+SCAN(4) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.customer.c_nationkey (INT4), num=32)
+
+SCAN(3) on default.customer
+  => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+  => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.orders.o_custkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+  => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+  => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+  => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+     => in schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+     => in schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.customer.c_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+  => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+  => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+  => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+     => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.orders.o_custkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.result
new file mode 100644
index 0000000..1fb0cdf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.result
@@ -0,0 +1,7 @@
+l_orderkey,p_name,n_name
+-------------------------------
+1,goldenrod lavender spring chocolate lace,ARGENTINA
+1,goldenrod lavender spring chocolate lace,ARGENTINA
+2,blush thistle blue yellow saddle,EGYPT
+3,blush thistle blue yellow saddle,JORDAN
+3,spring green yellow purple cornsilk,JORDAN

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash.plan
new file mode 100644
index 0000000..ae3d2c2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..7705f67
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?upper_1 (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+  => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+  => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?upper_1 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort.plan
new file mode 100644
index 0000000..ae3d2c2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..7705f67
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?upper_1 (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_name (TEXT), upper(default.n2.n_name (TEXT)) as ?upper_1
+  => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+  => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?upper_1 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = ?upper_1 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(4) ?upper_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(2) ?upper_1 (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.result
new file mode 100644
index 0000000..0cdaae4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition1.result
@@ -0,0 +1,27 @@
+n_nationkey,n_name,n_name
+-------------------------------
+0,ALGERIA,ALGERIA
+1,ARGENTINA,ARGENTINA
+2,BRAZIL,BRAZIL
+3,CANADA,CANADA
+4,EGYPT,EGYPT
+5,ETHIOPIA,ETHIOPIA
+6,FRANCE,FRANCE
+7,GERMANY,GERMANY
+8,INDIA,INDIA
+9,INDONESIA,INDONESIA
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+12,JAPAN,JAPAN
+13,JORDAN,JORDAN
+14,KENYA,KENYA
+15,MOROCCO,MOROCCO
+16,MOZAMBIQUE,MOZAMBIQUE
+17,PERU,PERU
+18,CHINA,CHINA
+19,ROMANIA,ROMANIA
+20,SAUDI ARABIA,SAUDI ARABIA
+21,VIETNAM,VIETNAM
+22,RUSSIA,RUSSIA
+23,UNITED KINGDOM,UNITED KINGDOM
+24,UNITED STATES,UNITED STATES

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash.plan
new file mode 100644
index 0000000..9f69697
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: upper(default.n2.n_name (TEXT)) as name
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: upper(default.n2.n_name (TEXT)) as name
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..53b6430
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: upper(default.n2.n_name (TEXT)) as name
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: upper(default.n2.n_name (TEXT)) as name
+  => out schema: {(1) name (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+  => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(1) name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort.plan
new file mode 100644
index 0000000..9f69697
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: upper(default.n2.n_name (TEXT)) as name
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: upper(default.n2.n_name (TEXT)) as name
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..53b6430
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: upper(default.n2.n_name (TEXT)) as name
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: upper(default.n2.n_name (TEXT)) as name
+  => out schema: {(1) name (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+  => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_name (TEXT) = name (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(1) name (TEXT)}
+        => in schema: {(1) name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.result
new file mode 100644
index 0000000..59fa1db
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition2.result
@@ -0,0 +1,27 @@
+n_nationkey,n_name,name
+-------------------------------
+0,ALGERIA,ALGERIA
+1,ARGENTINA,ARGENTINA
+2,BRAZIL,BRAZIL
+3,CANADA,CANADA
+4,EGYPT,EGYPT
+5,ETHIOPIA,ETHIOPIA
+6,FRANCE,FRANCE
+7,GERMANY,GERMANY
+8,INDIA,INDIA
+9,INDONESIA,INDONESIA
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+12,JAPAN,JAPAN
+13,JORDAN,JORDAN
+14,KENYA,KENYA
+15,MOROCCO,MOROCCO
+16,MOZAMBIQUE,MOZAMBIQUE
+17,PERU,PERU
+18,CHINA,CHINA
+19,ROMANIA,ROMANIA
+20,SAUDI ARABIA,SAUDI ARABIA
+21,VIETNAM,VIETNAM
+22,RUSSIA,RUSSIA
+23,UNITED KINGDOM,UNITED KINGDOM
+24,UNITED STATES,UNITED STATES

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash.plan
new file mode 100644
index 0000000..2f639c2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..3f3e632
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?lower_2 (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+  => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?lower_1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+  => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?lower_2 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?lower_1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort.plan
new file mode 100644
index 0000000..2f639c2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..3f3e632
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?lower_2 (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_name (TEXT), lower(default.n2.n_name (TEXT)) as ?lower_2
+  => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?lower_1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), lower(default.n1.n_name (TEXT)) as ?lower_1
+  => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?lower_2 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?lower_1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: ?lower_1 (TEXT) = ?lower_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?lower_1 (TEXT), ?lower_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(3) ?lower_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+        => in schema: {(2) ?lower_2 (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.result
new file mode 100644
index 0000000..0cdaae4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testComplexJoinCondition3.result
@@ -0,0 +1,27 @@
+n_nationkey,n_name,n_name
+-------------------------------
+0,ALGERIA,ALGERIA
+1,ARGENTINA,ARGENTINA
+2,BRAZIL,BRAZIL
+3,CANADA,CANADA
+4,EGYPT,EGYPT
+5,ETHIOPIA,ETHIOPIA
+6,FRANCE,FRANCE
+7,GERMANY,GERMANY
+8,INDIA,INDIA
+9,INDONESIA,INDONESIA
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+12,JAPAN,JAPAN
+13,JORDAN,JORDAN
+14,KENYA,KENYA
+15,MOROCCO,MOROCCO
+16,MOZAMBIQUE,MOZAMBIQUE
+17,PERU,PERU
+18,CHINA,CHINA
+19,ROMANIA,ROMANIA
+20,SAUDI ARABIA,SAUDI ARABIA
+21,VIETNAM,VIETNAM
+22,RUSSIA,RUSSIA
+23,UNITED KINGDOM,UNITED KINGDOM
+24,UNITED STATES,UNITED STATES


[37/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterMergeJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterMergeJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterMergeJoinExec.java
new file mode 100644
index 0000000..9a5a85f
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterMergeJoinExec.java
@@ -0,0 +1,531 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.Appender;
+import org.apache.tajo.storage.FileTablespace;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.storage.VTuple;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.*;
+
+public class TestRightOuterMergeJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestRightOuterMergeJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+  private QueryContext defaultContext;
+
+
+  private TableDesc dep3;
+  private TableDesc dep4;
+  private TableDesc job3;
+  private TableDesc emp3;
+  private TableDesc phone3;
+
+  private final String DEP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep3");
+  private final String DEP4_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep4");
+  private final String JOB3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "job3");
+  private final String EMP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "emp3");
+  private final String PHONE3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "phone3");
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    //----------------- dep3 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    Schema dep3Schema = new Schema();
+    dep3Schema.addColumn("dep_id", Type.INT4);
+    dep3Schema.addColumn("dep_name", Type.TEXT);
+    dep3Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep3Path = new Path(testDir, "dep3.csv");
+    Appender appender1 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(dep3Meta, dep3Schema, dep3Path);
+    appender1.init();
+    VTuple tuple = new VTuple(dep3Schema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createText("dept_" + i),
+          DatumFactory.createInt4(1000 + i) });
+      appender1.addTuple(tuple);
+    }
+
+    appender1.flush();
+    appender1.close();
+    dep3 = CatalogUtil.newTableDesc(DEP3_NAME, dep3Schema, dep3Meta, dep3Path);
+    catalog.createTable(dep3);
+
+
+    //----------------- dep4 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    // 10     | dep_10    | 1010
+    Schema dep4Schema = new Schema();
+    dep4Schema.addColumn("dep_id", Type.INT4);
+    dep4Schema.addColumn("dep_name", Type.TEXT);
+    dep4Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep4Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep4Path = new Path(testDir, "dep4.csv");
+    Appender appender4 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(dep4Meta, dep4Schema, dep4Path);
+    appender4.init();
+    VTuple tuple4 = new VTuple(dep4Schema.size());
+    for (int i = 0; i < 11; i++) {
+      tuple4.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createText("dept_" + i),
+          DatumFactory.createInt4(1000 + i) });
+      appender4.addTuple(tuple4);
+    }
+
+    appender4.flush();
+    appender4.close();
+    dep4 = CatalogUtil.newTableDesc(DEP4_NAME, dep4Schema, dep4Meta, dep4Path);
+    catalog.createTable(dep4);
+
+
+
+    //----------------- job3 ------------------------------
+    //  job_id  | job_title
+    // ----------------------
+    //   101    |  job_101
+    //   102    |  job_102
+    //   103    |  job_103
+
+    Schema job3Schema = new Schema();
+    job3Schema.addColumn("job_id", Type.INT4);
+    job3Schema.addColumn("job_title", Type.TEXT);
+
+
+    TableMeta job3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path job3Path = new Path(testDir, "job3.csv");
+    Appender appender2 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(job3Meta, job3Schema, job3Path);
+    appender2.init();
+    VTuple tuple2 = new VTuple(job3Schema.size());
+    for (int i = 1; i < 4; i++) {
+      int x = 100 + i;
+      tuple2.put(new Datum[] { DatumFactory.createInt4(100 + i),
+          DatumFactory.createText("job_" + x) });
+      appender2.addTuple(tuple2);
+    }
+
+    appender2.flush();
+    appender2.close();
+    job3 = CatalogUtil.newTableDesc(JOB3_NAME, job3Schema, job3Meta, job3Path);
+    catalog.createTable(job3);
+
+
+
+    //---------------------emp3 --------------------
+    // emp_id  | first_name | last_name | dep_id | salary | job_id
+    // ------------------------------------------------------------
+    //  11     |  fn_11     |  ln_11    |  1     | 123    | 101
+    //  13     |  fn_13     |  ln_13    |  3     | 369    | 103
+    //  15     |  fn_15     |  ln_15    |  5     | 615    | null
+    //  17     |  fn_17     |  ln_17    |  7     | 861    | null
+    //  19     |  fn_19     |  ln_19    |  9     | 1107   | null
+    //  21     |  fn_21     |  ln_21    |  1     | 123    | 101
+    //  23     |  fn_23     |  ln_23    |  3     | 369    | 103
+
+    Schema emp3Schema = new Schema();
+    emp3Schema.addColumn("emp_id", Type.INT4);
+    emp3Schema.addColumn("first_name", Type.TEXT);
+    emp3Schema.addColumn("last_name", Type.TEXT);
+    emp3Schema.addColumn("dep_id", Type.INT4);
+    emp3Schema.addColumn("salary", Type.FLOAT4);
+    emp3Schema.addColumn("job_id", Type.INT4);
+
+
+    TableMeta emp3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path emp3Path = new Path(testDir, "emp3.csv");
+    Appender appender3 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(emp3Meta, emp3Schema, emp3Path);
+    appender3.init();
+    VTuple tuple3 = new VTuple(emp3Schema.size());
+
+    for (int i = 1; i < 4; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+
+      int y = 20 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(20 + i),
+          DatumFactory.createText("firstname_" + y),
+          DatumFactory.createText("lastname_" + y),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+    }
+
+    for (int i = 5; i < 10; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createNullDatum() });
+      appender3.addTuple(tuple3);
+    }
+
+    appender3.flush();
+    appender3.close();
+    emp3 = CatalogUtil.newTableDesc(EMP3_NAME, emp3Schema, emp3Meta, emp3Path);
+    catalog.createTable(emp3);
+
+    //---------------------phone3 --------------------
+    // emp_id  | phone_number
+    // -----------------------------------------------
+    // this table is empty, no rows
+
+    Schema phone3Schema = new Schema();
+    phone3Schema.addColumn("emp_id", Type.INT4);
+    phone3Schema.addColumn("phone_number", Type.TEXT);
+
+
+    TableMeta phone3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path phone3Path = new Path(testDir, "phone3.csv");
+    Appender appender5 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(phone3Meta, phone3Schema, phone3Path);
+    appender5.init();
+
+    appender5.flush();
+    appender5.close();
+    phone3 = CatalogUtil.newTableDesc(PHONE3_NAME, phone3Schema, phone3Meta, phone3Path);
+    catalog.createTable(phone3);
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      // [0] no nulls
+      "select dep3.dep_id, dep_name, emp_id, salary from emp3 right outer join dep3 on dep3.dep_id = emp3.dep_id",
+      // [1] nulls on the left operand
+      "select job3.job_id, job_title, emp_id, salary from emp3 right outer join job3 on job3.job_id=emp3.job_id",
+      // [2] nulls on the right side
+      "select job3.job_id, job_title, emp_id, salary from job3 right outer join emp3 on job3.job_id=emp3.job_id",
+      // [3] no nulls, right continues after left
+      "select dep4.dep_id, dep_name, emp_id, salary from emp3 right outer join dep4 on dep4.dep_id = emp3.dep_id",
+      // [4] one operand is empty
+      "select emp3.emp_id, first_name, phone_number from emp3 right outer join phone3 on emp3.emp_id = phone3.emp_id",
+      // [5] one operand is empty
+      "select phone_number, emp3.emp_id, first_name from phone3 right outer join emp3 on emp3.emp_id = phone3.emp_id"
+  };
+
+  @Test
+  public final void testRightOuterMergeJoin0() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] dep3Frags = FileTablespace.splitNG(conf, DEP3_NAME, dep3.getMeta(), new Path(dep3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, dep3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testRightOuterMergeJoin0");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof RightOuterMergeJoinExec);
+
+    int count = 0;
+    exec.init();
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(12, count);
+  }
+
+
+  @Test
+  public final void testRightOuter_MergeJoin1() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] job3Frags =
+        FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testRightOuterMergeJoin1");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof RightOuterMergeJoinExec);
+
+    int count = 0;
+    exec.init();
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(5, count);
+  }
+
+  @Test
+  public final void testRightOuterMergeJoin2() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[2]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] job3Frags =
+        FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testRightOuterMergeJoin2");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof RightOuterMergeJoinExec);
+
+    int count = 0;
+    exec.init();
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(7, count);
+  }
+
+
+  @Test
+  public final void testRightOuter_MergeJoin3() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[3]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] dep4Frags =
+        FileTablespace.splitNG(conf, DEP4_NAME, dep4.getMeta(), new Path(dep4.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, dep4Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testRightOuter_MergeJoin3");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof RightOuterMergeJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(13, count);
+  }
+
+  @Test
+  public final void testRightOuter_MergeJoin4() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[4]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] phone3Frags =
+        FileTablespace.splitNG(conf, PHONE3_NAME, phone3.getMeta(), new Path(phone3.getUri()),
+            Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, phone3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testRightOuter_MergeJoin4");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof RightOuterMergeJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(0, count);
+  }
+
+  @Test
+  public final void testRightOuterMergeJoin5() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[5]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] phone3Frags = FileTablespace.splitNG(conf, PHONE3_NAME, phone3.getMeta(), new Path(phone3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(phone3Frags,emp3Frags);
+
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testRightOuterMergeJoin5");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof RightOuterMergeJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    exec.close();
+    assertEquals(7, count);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortExec.java
new file mode 100644
index 0000000..81cb945
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortExec.java
@@ -0,0 +1,179 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.RangePartitionAlgorithm;
+import org.apache.tajo.engine.planner.UniformRangePartition;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Random;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestSortExec {
+  private static TajoConf conf;
+  private static final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestPhysicalPlanner";
+  private static TajoTestingCluster util;
+  private static CatalogService catalog;
+  private static SQLAnalyzer analyzer;
+  private static LogicalPlanner planner;
+  private static LogicalOptimizer optimizer;
+  private static FileTablespace sm;
+  private static Path workDir;
+  private static Path tablePath;
+  private static TableMeta employeeMeta;
+  private static QueryContext queryContext;
+
+  private static Random rnd = new Random(System.currentTimeMillis());
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+    util = TpchTestBase.getInstance().getTestingCluster();
+    catalog = util.getMaster().getCatalog();
+    workDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    sm = TablespaceManager.getLocalFs();
+
+    Schema schema = new Schema();
+    schema.addColumn("managerid", Type.INT4);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    employeeMeta = CatalogUtil.newTableMeta("TEXT");
+
+    tablePath = StorageUtil.concatPath(workDir, "employee", "table1");
+    sm.getFileSystem().mkdirs(tablePath.getParent());
+
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, schema, tablePath);
+    appender.init();
+    VTuple tuple = new VTuple(schema.size());
+    for (int i = 0; i < 100; i++) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(rnd.nextInt(5)),
+          DatumFactory.createInt4(rnd.nextInt(10)),
+          DatumFactory.createText("dept_" + rnd.nextInt(10))});
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+
+    TableDesc desc = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "employee"), schema, employeeMeta,
+        tablePath.toUri());
+    catalog.createTable(desc);
+
+    queryContext = new QueryContext(conf);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(conf, catalog);
+  }
+
+  public static String[] QUERIES = {
+      "select managerId, empId, deptName from employee order by managerId, empId desc" };
+
+  @Test
+  public final void testNext() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employeeMeta, tablePath, Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestSortExec");
+    TaskAttemptContext ctx = new TaskAttemptContext(queryContext,
+        LocalTajoTestingUtility
+        .newTaskAttemptId(), new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    Tuple tuple;
+    Datum preVal = null;
+    Datum curVal;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      curVal = tuple.asDatum(0);
+      if (preVal != null) {
+        assertTrue(preVal.lessThanEqual(curVal).asBool());
+      }
+
+      preVal = curVal;
+    }
+    exec.close();
+  }
+
+  @Test
+  /**
+   * TODO - Now, in FSM branch, TestUniformRangePartition is ported to Java.
+   * So, this test is located in here.
+   * Later it should be moved TestUniformPartitions.
+   */
+  public void testTAJO_946() {
+    Schema schema = new Schema();
+    schema.addColumn("l_orderkey", Type.INT8);
+    SortSpec [] sortSpecs = PlannerUtil.schemaToSortSpecs(schema);
+
+    VTuple s = new VTuple(1);
+    s.put(0, DatumFactory.createInt8(0));
+    VTuple e = new VTuple(1);
+    e.put(0, DatumFactory.createInt8(6000000000l));
+    TupleRange expected = new TupleRange(sortSpecs, s, e);
+    RangePartitionAlgorithm partitioner
+        = new UniformRangePartition(expected, sortSpecs, true);
+    TupleRange [] ranges = partitioner.partition(967);
+
+    TupleRange prev = null;
+    for (TupleRange r : ranges) {
+      if (prev == null) {
+        prev = r;
+      } else {
+        assertTrue(prev.compareTo(r) < 0);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortIntersectExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortIntersectExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortIntersectExec.java
new file mode 100644
index 0000000..7289472
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestSortIntersectExec.java
@@ -0,0 +1,293 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.SortNode;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+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.assertTrue;
+
+public class TestSortIntersectExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestSortIntersectExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private LogicalOptimizer optimizer;
+  private Path testDir;
+
+  private TableDesc employee1;
+  private TableDesc employee2;
+
+  private int[] leftNum = new int[] {1, 2, 3, 3, 9, 9, 3, 0, 3};
+  private int[] rightNum = new int[] {3, 7, 3, 5};
+  private int[] answerAllNum = new int[] {3, 3}; // this should be set as leftNum intersect all rightNum + order by
+  private int[] answerDistinctNum = new int[] {3}; // this should be set as leftNum intersect rightNum + order by
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema employeeSchema1 = new Schema();
+    employeeSchema1.addColumn("managerid", TajoDataTypes.Type.INT4);
+    employeeSchema1.addColumn("empid", TajoDataTypes.Type.INT4);
+    employeeSchema1.addColumn("memid", TajoDataTypes.Type.INT4);
+    employeeSchema1.addColumn("deptname", TajoDataTypes.Type.TEXT);
+
+    TableMeta employeeMeta1 = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath1 = new Path(testDir, "employee1.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs()).
+        getAppender(employeeMeta1, employeeSchema1, employeePath1);
+    appender.init();
+    Tuple tuple = new VTuple(employeeSchema1.size());
+
+    for (int i : leftNum) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), // empid [0-8]
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+    employee1 = CatalogUtil.newTableDesc("default.employee1", employeeSchema1, employeeMeta1, employeePath1);
+    catalog.createTable(employee1);
+
+    Schema employeeSchema2 = new Schema();
+    employeeSchema2.addColumn("managerid", TajoDataTypes.Type.INT4);
+    employeeSchema2.addColumn("empid", TajoDataTypes.Type.INT4);
+    employeeSchema2.addColumn("memid", TajoDataTypes.Type.INT4);
+    employeeSchema2.addColumn("deptname", TajoDataTypes.Type.TEXT);
+
+    TableMeta employeeMeta2 = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath2 = new Path(testDir, "employee2.csv");
+    Appender appender2 = ((FileTablespace) TablespaceManager.getLocalFs()).
+        getAppender(employeeMeta2, employeeSchema2, employeePath2);
+    appender2.init();
+    Tuple tuple2 = new VTuple(employeeSchema2.size());
+
+    for (int i : rightNum) {
+      tuple2.put(new Datum[]{
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), // empid [1-9]
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i)});
+      appender2.addTuple(tuple2);
+    }
+
+    appender2.flush();
+    appender2.close();
+    employee2 = CatalogUtil.newTableDesc("default.employee2", employeeSchema2, employeeMeta2, employeePath2);
+    catalog.createTable(employee2);
+
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(conf, catalog);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+
+  // relation descriptions
+  // employee1 (managerid, empid, memid, deptname)
+  // employee2 (managerid, empid, memid, deptname)
+
+  String[] QUERIES = {
+      "select * from employee1 as e1, employee2 as e2 where e1.empId = e2.empId"
+  };
+
+  @Test
+  public final void testSortIntersectAll() throws IOException, TajoException {
+    FileFragment[] empFrags1 = ((FileTablespace) TablespaceManager.getLocalFs()).
+        splitNG(conf, "default.e1", employee1.getMeta(),
+            new Path(employee1.getUri()), Integer.MAX_VALUE);
+    FileFragment[] empFrags2 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .splitNG(conf, "default.e2", employee2.getMeta(),
+            new Path(employee2.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(empFrags1, empFrags2);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testSortIntersectAll");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    // replace an equal join with sort intersect all .
+    if (exec instanceof MergeJoinExec) {
+      MergeJoinExec join = (MergeJoinExec) exec;
+      exec = new SortIntersectExec(ctx, join.getLeftChild(), join.getRightChild(), false);
+    } else if (exec instanceof HashJoinExec) {
+      // we need to sort the results from both left and right children
+      HashJoinExec join = (HashJoinExec) exec;
+      SortSpec[] sortSpecsLeft = PlannerUtil.schemaToSortSpecs(join.getLeftChild().getSchema());
+      SortSpec[] sortSpecsRight = PlannerUtil.schemaToSortSpecs(join.getRightChild().getSchema());
+
+      SortNode leftSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
+      leftSortNode.setSortSpecs(sortSpecsLeft);
+      leftSortNode.setInSchema(join.getLeftChild().getSchema());
+      leftSortNode.setOutSchema(join.getLeftChild().getSchema());
+      ExternalSortExec leftSort = new ExternalSortExec(ctx, leftSortNode, join.getLeftChild());
+
+      SortNode rightSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
+      rightSortNode.setSortSpecs(sortSpecsRight);
+      rightSortNode.setInSchema(join.getRightChild().getSchema());
+      rightSortNode.setOutSchema(join.getRightChild().getSchema());
+      ExternalSortExec rightSort = new ExternalSortExec(ctx, rightSortNode, join.getRightChild());
+
+      exec = new SortIntersectExec(ctx, leftSort, rightSort, false);
+    }
+
+    Tuple tuple;
+    int count = 0;
+    int i = 0;
+    exec.init();
+
+    while ((tuple = exec.next()) != null) {
+      count++;
+      int answer = answerAllNum[i];
+      assertTrue(answer == tuple.asDatum(0).asInt4());
+      assertTrue(answer == tuple.asDatum(1).asInt4());
+      assertTrue(10 + answer == tuple.asDatum(2).asInt4());
+      assertTrue(("dept_" + answer).equals(tuple.asDatum(3).asChars()));
+
+      i++;
+    }
+    exec.close();
+    assertEquals(answerAllNum.length , count);
+  }
+
+  @Test
+  public final void testSortIntersect() throws IOException, TajoException {
+    FileFragment[] empFrags1 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .splitNG(conf, "default.e1", employee1.getMeta(),
+            new Path(employee1.getUri()), Integer.MAX_VALUE);
+    FileFragment[] empFrags2 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .splitNG(conf, "default.e2", employee2.getMeta(),
+        new Path(employee2.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(empFrags1, empFrags2);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testSortIntersect");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    // replace an equal join with sort intersect all .
+    if (exec instanceof MergeJoinExec) {
+      MergeJoinExec join = (MergeJoinExec) exec;
+      exec = new SortIntersectExec(ctx, join.getLeftChild(), join.getRightChild(), true);
+    } else if (exec instanceof HashJoinExec) {
+      // we need to sort the results from both left and right children
+      HashJoinExec join = (HashJoinExec) exec;
+      SortSpec[] sortSpecsLeft = PlannerUtil.schemaToSortSpecs(join.getLeftChild().getSchema());
+      SortSpec[] sortSpecsRight = PlannerUtil.schemaToSortSpecs(join.getRightChild().getSchema());
+
+      SortNode leftSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
+      leftSortNode.setSortSpecs(sortSpecsLeft);
+      leftSortNode.setInSchema(join.getLeftChild().getSchema());
+      leftSortNode.setOutSchema(join.getLeftChild().getSchema());
+      ExternalSortExec leftSort = new ExternalSortExec(ctx, leftSortNode, join.getLeftChild());
+
+      SortNode rightSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
+      rightSortNode.setSortSpecs(sortSpecsRight);
+      rightSortNode.setInSchema(join.getRightChild().getSchema());
+      rightSortNode.setOutSchema(join.getRightChild().getSchema());
+      ExternalSortExec rightSort = new ExternalSortExec(ctx, rightSortNode, join.getRightChild());
+
+      exec = new SortIntersectExec(ctx, leftSort, rightSort, true);
+    }
+
+    Tuple tuple;
+    int count = 0;
+    int i = 0;
+    exec.init();
+
+    while ((tuple = exec.next()) != null) {
+      count++;
+      int answer = answerDistinctNum[i];
+      assertTrue(answer == tuple.asDatum(0).asInt4());
+      assertTrue(answer == tuple.asDatum(1).asInt4());
+      assertTrue(10 + answer == tuple.asDatum(2).asInt4());
+      assertTrue(("dept_" + answer).equals(tuple.asDatum(3).asChars()));
+
+      i++;
+    }
+    exec.close();
+    assertEquals(answerDistinctNum.length , count);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestTupleSorter.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestTupleSorter.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestTupleSorter.java
new file mode 100644
index 0000000..4061b25
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestTupleSorter.java
@@ -0,0 +1,127 @@
+/**
+ * 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.planner.physical;
+
+import com.google.common.collect.Iterators;
+import com.google.common.primitives.Ints;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.SortSpec;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.storage.BaseTupleComparator;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class TestTupleSorter {
+
+  private static final Log LOG = LogFactory.getLog(TestTupleSorter.class);
+
+  private static final Random rnd = new Random(-1);
+
+  @Test
+  public final void testSortBench() {
+    final int MAX_SORT_KEY = 3;
+    final int ITERATION = 10;
+    final int LENGTH = 1000000;
+    final int SAMPLING = 100;
+
+    Tuple[] tuples = new Tuple[LENGTH];
+    for (int i = 0; i < LENGTH; i++) {
+      Datum[] datums = new Datum[]{
+          DatumFactory.createInt4(rnd.nextInt(Short.MAX_VALUE)),
+          DatumFactory.createInt4(rnd.nextInt()),
+          DatumFactory.createText("dept_" + rnd.nextInt()),
+          DatumFactory.createBool(rnd.nextBoolean()),
+          DatumFactory.createInt8(rnd.nextLong()),
+          DatumFactory.createInterval(rnd.nextInt(), rnd.nextLong())};
+      tuples[i] = new VTuple(datums);
+    }
+
+    Column col0 = new Column("col0", Type.INT2);
+    Column col1 = new Column("col1", Type.INT4);
+    Column col2 = new Column("col2", Type.TEXT);
+    Column col3 = new Column("col3", Type.BOOLEAN);
+    Column col4 = new Column("col4", Type.INT8);
+    Column col5 = new Column("col5", Type.INTERVAL);
+
+    Schema schema = new Schema(new Column[] {col0, col1, col2, col3, col4, col5});
+
+    long[] time1 = new long[ITERATION];
+    long[] time2 = new long[ITERATION];
+    for(int iteration = 0; iteration < ITERATION; iteration++) {
+      TupleList target = new TupleList(tuples.length);
+      target.addAll(Arrays.asList(Arrays.copyOf(tuples, tuples.length)));
+      Set<Integer> keys = new TreeSet<Integer>();
+      for (int i = 0; i < MAX_SORT_KEY; i++) {
+        keys.add(rnd.nextInt(schema.size()));
+      }
+      int[] keyIndices = Ints.toArray(keys);
+      SortSpec[] sortKeys = new SortSpec[keyIndices.length];
+      for (int i = 0; i < keyIndices.length; i++) {
+        sortKeys[i] = new SortSpec(schema.getColumn(keyIndices[i]), rnd.nextBoolean(), rnd.nextBoolean());
+      }
+
+      long start = System.currentTimeMillis();
+      VectorizedSorter sorter = new VectorizedSorter(target, sortKeys, keyIndices);
+      Iterator<Tuple> iterator = sorter.sort().iterator();
+
+      String[] result1 = new String[SAMPLING];
+      for (int i = 0; i < result1.length; i++) {
+        Tuple tuple = Iterators.get(iterator, LENGTH / result1.length - 1);
+        StringBuilder builder = new StringBuilder();
+        for (int keyIndex : keyIndices) {
+          builder.append(tuple.getText(keyIndex));
+        }
+        result1[i] = builder.toString();
+      }
+      time1[iteration] = System.currentTimeMillis() - start;
+
+      BaseTupleComparator comparator = new BaseTupleComparator(schema, sortKeys);
+
+      start = System.currentTimeMillis();
+      Collections.sort(target, comparator);
+      iterator = target.iterator();
+
+      String[] result2 = new String[SAMPLING];
+      for (int i = 0; i < result2.length; i++) {
+        Tuple tuple = Iterators.get(iterator, LENGTH / result2.length - 1);
+        StringBuilder builder = new StringBuilder();
+        for (int keyIndex : keyIndices) {
+          builder.append(tuple.getText(keyIndex));
+        }
+        result2[i] = builder.toString();
+      }
+      time2[iteration] = System.currentTimeMillis() - start;
+
+      LOG.info("Sort on keys " + Arrays.toString(keyIndices) +
+          ": Vectorized " + time1[iteration]+ " msec, Original " + time2[iteration] + " msec");
+
+      assertArrayEquals(result1, result2);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
new file mode 100644
index 0000000..8339ea7
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
@@ -0,0 +1,114 @@
+/**
+ * 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.query;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestAlterTable extends QueryTestCaseBase {
+  @Test
+  public final void testAlterTableName() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC");
+    assertTableExists(createdNames.get(0));
+    executeDDL("alter_table_rename_table_ddl.sql", null);
+    assertTableExists("DEF");
+  }
+
+  @Test
+  public final void testAlterTableColumnName() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "XYZ");
+    executeDDL("alter_table_rename_column_ddl.sql", null);
+    assertColumnExists(createdNames.get(0), "renum");
+  }
+
+  @Test
+  public final void testAlterTableAddNewColumn() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "EFG");
+    executeDDL("alter_table_add_new_column_ddl.sql", null);
+    assertColumnExists(createdNames.get(0),"cool");
+  }
+
+  @Test
+  public final void testAlterTableSetProperty() throws Exception {
+    executeDDL("table2_ddl.sql", "table2.tbl", "ALTX");
+    ResultSet before_res = executeQuery();
+    assertResultSet(before_res, "before_set_property_delimiter.result");
+    cleanupQuery(before_res);
+
+    executeDDL("alter_table_set_property_delimiter.sql", null);
+
+    ResultSet after_res = executeQuery();
+    assertResultSet(after_res, "after_set_property_delimiter.result");
+    cleanupQuery(after_res);
+  }
+
+  @Test
+  public final void testAlterTableAddPartition() throws Exception {
+    executeDDL("create_partitioned_table.sql", null);
+
+    String tableName = CatalogUtil.buildFQName("TestAlterTable", "partitioned_table");
+    assertTrue(catalog.existsTable(tableName));
+
+    TableDesc retrieved = catalog.getTableDesc(tableName);
+    assertEquals(retrieved.getName(), tableName);
+    assertEquals(retrieved.getPartitionMethod().getPartitionType(), CatalogProtos.PartitionType.COLUMN);
+    assertEquals(retrieved.getPartitionMethod().getExpressionSchema().getAllColumns().size(), 2);
+    assertEquals(retrieved.getPartitionMethod().getExpressionSchema().getColumn(0).getSimpleName(), "col3");
+    assertEquals(retrieved.getPartitionMethod().getExpressionSchema().getColumn(1).getSimpleName(), "col4");
+
+    executeDDL("alter_table_add_partition1.sql", null);
+    executeDDL("alter_table_add_partition2.sql", null);
+
+    List<CatalogProtos.PartitionDescProto> partitions = catalog.getPartitions("TestAlterTable", "partitioned_table");
+    assertNotNull(partitions);
+    assertEquals(partitions.size(), 1);
+    assertEquals(partitions.get(0).getPartitionName(), "col3=1/col4=2");
+    assertEquals(partitions.get(0).getPartitionKeysList().get(0).getColumnName(), "col3");
+    assertEquals(partitions.get(0).getPartitionKeysList().get(0).getPartitionValue(), "1");
+    assertEquals(partitions.get(0).getPartitionKeysList().get(1).getColumnName(), "col4");
+    assertEquals(partitions.get(0).getPartitionKeysList().get(1).getPartitionValue(), "2");
+
+    assertNotNull(partitions.get(0).getPath());
+    Path partitionPath = new Path(partitions.get(0).getPath());
+    FileSystem fs = partitionPath.getFileSystem(conf);
+    assertTrue(fs.exists(partitionPath));
+    assertTrue(partitionPath.toString().indexOf("col3=1/col4=2") > 0);
+
+    executeDDL("alter_table_drop_partition1.sql", null);
+    executeDDL("alter_table_drop_partition2.sql", null);
+
+    partitions = catalog.getPartitions("TestAlterTable", "partitioned_table");
+    assertNotNull(partitions);
+    assertEquals(partitions.size(), 0);
+    assertFalse(fs.exists(partitionPath));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTablespace.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTablespace.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTablespace.java
new file mode 100644
index 0000000..8509b07
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTablespace.java
@@ -0,0 +1,59 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestAlterTablespace extends QueryTestCaseBase {
+
+  @Test
+  public final void testAlterLocation() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      //////////////////////////////////////////////////////////////////////////////
+      // Create two table spaces
+      //////////////////////////////////////////////////////////////////////////////
+
+      assertFalse(catalog.existTablespace("space1"));
+      catalog.createTablespace("space1", "hdfs://xxx.com/warehouse");
+      assertTrue(catalog.existTablespace("space1"));
+
+      // pre verification
+      CatalogProtos.TablespaceProto space1 = catalog.getTablespace("space1");
+      assertEquals("space1", space1.getSpaceName());
+      assertEquals("hdfs://xxx.com/warehouse", space1.getUri());
+
+      executeString("ALTER TABLESPACE space1 LOCATION 'hdfs://yyy.com/warehouse';");
+
+      // Verify ALTER TABLESPACE space1
+      space1 = catalog.getTablespace("space1");
+      assertEquals("space1", space1.getSpaceName());
+      assertEquals("hdfs://yyy.com/warehouse", space1.getUri());
+
+      catalog.dropTablespace("space1");
+      assertFalse(catalog.existTablespace("space1"));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
new file mode 100644
index 0000000..f327c85
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
@@ -0,0 +1,281 @@
+/**
+ * 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.query;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.partition.PartitionMethodDesc;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.util.Map;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.catalog.CatalogUtil.buildFQName;
+import static org.junit.Assert.*;
+
+
+/**
+ * Test CREATE TABLE AS SELECT statements
+ */
+@Category(IntegrationTest.class)
+public class TestCTASQuery extends QueryTestCaseBase {
+
+  public TestCTASQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testCtasWithoutTableDefinition() throws Exception {
+    ResultSet res = executeQuery();
+    res.close();
+
+    String tableName = CatalogUtil.normalizeIdentifier("testCtasWithoutTableDefinition");
+    CatalogService catalog = testBase.getTestingCluster().getMaster().getCatalog();
+    String qualifiedTableName = buildFQName(DEFAULT_DATABASE_NAME, tableName);
+    TableDesc desc = catalog.getTableDesc(qualifiedTableName);
+    assertTrue(catalog.existsTable(qualifiedTableName));
+
+    assertTrue(desc.getSchema().contains("default.testctaswithouttabledefinition.col1"));
+    PartitionMethodDesc partitionDesc = desc.getPartitionMethod();
+    assertEquals(partitionDesc.getPartitionType(), CatalogProtos.PartitionType.COLUMN);
+    assertEquals("key", partitionDesc.getExpressionSchema().getRootColumns().get(0).getSimpleName());
+
+    FileSystem fs = FileSystem.get(testBase.getTestingCluster().getConfiguration());
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(path));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=17.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=36.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=49.0")));
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    ResultSet res2 = executeFile("check1.sql");
+
+    Map<Double, int []> resultRows1 = Maps.newHashMap();
+    resultRows1.put(45.0d, new int[]{3, 2});
+    resultRows1.put(38.0d, new int[]{2, 2});
+
+    int i = 0;
+    while(res2.next()) {
+      assertEquals(resultRows1.get(res2.getDouble(3))[0], res2.getInt(1));
+      assertEquals(resultRows1.get(res2.getDouble(3))[1], res2.getInt(2));
+      i++;
+    }
+    res2.close();
+    assertEquals(2, i);
+  }
+
+  @Test
+  public final void testCtasWithColumnedPartition() throws Exception {
+    ResultSet res = executeQuery();
+    res.close();
+
+    String tableName = CatalogUtil.normalizeIdentifier("testCtasWithColumnedPartition");
+
+    TajoTestingCluster cluster = testBase.getTestingCluster();
+    CatalogService catalog = cluster.getMaster().getCatalog();
+    TableDesc desc = catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName);
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName));
+    PartitionMethodDesc partitionDesc = desc.getPartitionMethod();
+    assertEquals(partitionDesc.getPartitionType(), CatalogProtos.PartitionType.COLUMN);
+    assertEquals("key", partitionDesc.getExpressionSchema().getRootColumns().get(0).getSimpleName());
+
+    FileSystem fs = FileSystem.get(cluster.getConfiguration());
+    Path path = new Path(desc.getUri());
+    assertTrue(fs.isDirectory(path));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=17.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=36.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=38.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=45.0")));
+    assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=49.0")));
+    if (!cluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, desc.getStats().getNumRows().intValue());
+    }
+
+    ResultSet res2 = executeFile("check2.sql");
+
+    Map<Double, int []> resultRows1 = Maps.newHashMap();
+    resultRows1.put(45.0d, new int[]{3, 2});
+    resultRows1.put(38.0d, new int[]{2, 2});
+
+    int i = 0;
+    while(res2.next()) {
+      assertEquals(resultRows1.get(res2.getDouble(3))[0], res2.getInt(1));
+      assertEquals(resultRows1.get(res2.getDouble(3))[1], res2.getInt(2));
+      i++;
+    }
+    res2.close();
+    assertEquals(2, i);
+  }
+
+  @Test
+  public final void testCtasWithGroupby() throws Exception {
+    ResultSet res = executeFile("CtasWithGroupby.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    assertResultSet(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithOrderby() throws Exception {
+    ResultSet res = executeFile("CtasWithOrderby.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    assertResultSet(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithLimit() throws Exception {
+    ResultSet res = executeFile("CtasWithLimit.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    assertResultSet(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithUnion() throws Exception {
+    ResultSet res = executeFile("CtasWithUnion.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    resultSetToString(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithMultipleUnions() throws Exception {
+    ResultSet res = executeFile("CtasWithMultipleUnions.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    String actual = resultSetToString(res2);
+    res2.close();
+
+    String expected = "c_custkey,c_nationkey\n" +
+        "-------------------------------\n" +
+        "1,15\n" +
+        "2,13\n" +
+        "3,1\n" +
+        "4,4\n" +
+        "5,3\n" +
+        "1,15\n" +
+        "2,13\n" +
+        "3,1\n" +
+        "4,4\n" +
+        "5,3\n";
+
+    assertEquals(expected, actual);
+
+    TableDesc desc = client.getTableDesc(CatalogUtil.normalizeIdentifier(res2.getMetaData().getTableName(1)));
+    assertNotNull(desc);
+  }
+
+  @Test
+  public final void testCtasWithStoreType() throws Exception {
+    ResultSet res = executeFile("CtasWithStoreType.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    resultSetToString(res2);
+    res2.close();
+
+    TableDesc desc =  client.getTableDesc(CatalogUtil.normalizeIdentifier(res2.getMetaData().getTableName(1)));
+    assertNotNull(desc);
+    assertTrue("RCFILE".equalsIgnoreCase(desc.getMeta().getStoreType()));
+  }
+
+  @Test
+  public final void testCtasWithTextFile() throws Exception {
+    ResultSet res = executeFile("CtasWithTextFile.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    resultSetToString(res2);
+    res2.close();
+
+    TableDesc desc =  client.getTableDesc(CatalogUtil.normalizeIdentifier(res2.getMetaData().getTableName(1)));
+    assertNotNull(desc);
+    assertTrue("TEXT".equalsIgnoreCase(desc.getMeta().getStoreType()));
+  }
+
+  @Test
+  public final void testCtasWithOptions() throws Exception {
+    ResultSet res = executeFile("CtasWithOptions.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    resultSetToString(res2);
+    res2.close();
+
+    TableDesc desc =  client.getTableDesc(CatalogUtil.normalizeIdentifier(res2.getMetaData().getTableName(1)));
+    assertNotNull(desc);
+    assertTrue("TEXT".equalsIgnoreCase(desc.getMeta().getStoreType()));
+
+
+    KeyValueSet options = desc.getMeta().getOptions();
+    assertNotNull(options);
+    assertEquals(StringEscapeUtils.escapeJava("\u0001"), options.get(StorageConstants.TEXT_DELIMITER));
+  }
+
+  @Test
+  public final void testCtasWithManagedTable() throws Exception {
+    ResultSet res = executeFile("CtasWithManagedTable.sql");
+    res.close();
+
+    if (testingCluster.isHiveCatalogStoreRunning()) {
+      assertTrue(client.existTable("managed_table1"));
+
+      TableDesc desc =  client.getTableDesc("managed_table1");
+
+      assertNotNull(desc);
+      assertEquals("managed_table1", new Path(desc.getUri()).getName());
+    } else {
+      assertFalse(client.existTable("managed_Table1"));
+      assertTrue(client.existTable("MANAGED_TABLE1"));
+
+      TableDesc desc =  client.getTableDesc("MANAGED_TABLE1");
+
+      assertNotNull(desc);
+      assertEquals("MANAGED_TABLE1", new Path(desc.getUri()).getName());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCaseByCases.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCaseByCases.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCaseByCases.java
new file mode 100644
index 0000000..bcf00f8
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCaseByCases.java
@@ -0,0 +1,183 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.junit.Test;
+
+import java.sql.ResultSet;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestCaseByCases extends QueryTestCaseBase {
+
+  public TestCaseByCases() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testTAJO415Case() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO418Case() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  /**
+   * It's an unit test to reproduce TAJO-619 (https://issues.apache.org/jira/browse/TAJO-619).
+   */
+  @Test
+  public final void testTAJO619Case() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO718Case() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO739Case() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO880Case1() throws Exception {
+    //TAJO-880: NULL in CASE clause occurs Exception.
+    ResultSet res = executeString(
+        "select case when l_returnflag != 'R' then l_orderkey else null end from lineitem"
+    );
+
+    String expected =
+        "?casewhen\n" +
+        "-------------------------------\n" +
+        "1\n" +
+        "1\n" +
+        "2\n" +
+        "null\n" +
+        "null\n";
+
+    assertEquals(expected, resultSetToString(res));
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO880Case2() throws Exception {
+    //TAJO-880: NULL in CASE clause occurs Exception.
+    ResultSet res = executeString(
+        "select case when l_returnflag != 'R' then null else l_orderkey end from lineitem"
+    );
+
+    String expected =
+        "?casewhen\n" +
+        "-------------------------------\n" +
+        "null\n" +
+        "null\n" +
+        "null\n" +
+        "3\n" +
+        "3\n";
+
+    assertEquals(expected, resultSetToString(res));
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO880Case3() throws Exception {
+    //TAJO-880: NULL in CASE clause occurs Exception.
+    ResultSet res = executeString(
+        "select case " +
+            "when l_orderkey = 1 then null " +
+            "when l_orderkey = 2 then l_orderkey " +
+            "else null end " +
+        "from lineitem"
+    );
+
+    String expected =
+        "?casewhen\n" +
+            "-------------------------------\n" +
+            "null\n" +
+            "null\n" +
+            "2\n" +
+            "null\n" +
+            "null\n";
+
+    assertEquals(expected, resultSetToString(res));
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO914Case1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO914Case2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO914Case3() throws Exception {
+    executeString("CREATE TABLE T3 (l_orderkey bigint, col1 text);").close();
+    ResultSet res = executeQuery();
+    res.close();
+
+    res = executeString("select * from T3;");
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO914Case4() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO917Case1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTAJO1224Case1() throws Exception {
+    executeString("CREATE TABLE TAJO1224 USING JSON AS SELECT * FROM LINEITEM").close();
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateDatabase.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateDatabase.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateDatabase.java
new file mode 100644
index 0000000..453c174
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateDatabase.java
@@ -0,0 +1,75 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+
+@Category(IntegrationTest.class)
+public class TestCreateDatabase extends QueryTestCaseBase {
+
+  @Test
+  public final void testCreateAndDropDatabase() throws Exception {
+    String databaseName = CatalogUtil.normalizeIdentifier("testCreateAndDropDatabase");
+
+    ResultSet res = null;
+    try {
+      res = executeString("CREATE DATABASE testCreateAndDropDatabase;");
+      assertDatabaseExists(databaseName);
+      executeString("DROP DATABASE testCreateAndDropDatabase;");
+      assertDatabaseNotExists(databaseName);
+    } finally {
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testCreateIfNotExists() throws Exception {
+    String databaseName = CatalogUtil.normalizeIdentifier("testCreateIfNotExists");
+
+    assertDatabaseNotExists(databaseName);
+    executeString("CREATE DATABASE " + databaseName + ";").close();
+    assertDatabaseExists(databaseName);
+
+    executeString("CREATE DATABASE IF NOT EXISTS " + databaseName + ";").close();
+    assertDatabaseExists(databaseName);
+
+    executeString("DROP DATABASE " + databaseName + ";").close();
+    assertDatabaseNotExists(databaseName);
+  }
+
+  @Test
+  public final void testDropIfExists() throws Exception {
+    String databaseName = CatalogUtil.normalizeIdentifier("testDropIfExists");
+    assertDatabaseNotExists(databaseName);
+    executeString("CREATE DATABASE " + databaseName + ";").close();
+    assertDatabaseExists(databaseName);
+
+    executeString("DROP DATABASE " + databaseName + ";").close();
+    assertDatabaseNotExists(databaseName);
+
+    executeString("DROP DATABASE IF EXISTS " + databaseName + ";");
+    assertDatabaseNotExists(databaseName);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateIndex.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateIndex.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateIndex.java
new file mode 100644
index 0000000..81df04a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestCreateIndex.java
@@ -0,0 +1,112 @@
+/*
+ * 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.query;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestCreateIndex extends QueryTestCaseBase {
+
+  public TestCreateIndex() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  private static void assertIndexNotExist(String databaseName, String indexName) throws IOException {
+    Path indexPath = new Path(conf.getVar(ConfVars.WAREHOUSE_DIR), databaseName + "/" + indexName);
+    FileSystem fs = indexPath.getFileSystem(conf);
+    if (fs.exists(indexPath)) {
+      fs.deleteOnExit(indexPath);
+      assertFalse("Index is not deleted from the file system.", true);
+    }
+  }
+
+  @Test
+  public final void testCreateIndex() throws Exception {
+    executeQuery();
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_idx"));
+    assertTrue(catalog.existIndexByColumnNames(getCurrentDatabase(), "lineitem", new String[]{"l_orderkey"}));
+    executeString("drop index l_orderkey_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_idx"));
+    assertIndexNotExist(getCurrentDatabase(), "l_orderkey_idx");
+  }
+
+  @Test
+  public final void testCreateIndexOnMultiAttrs() throws Exception {
+    executeQuery();
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_partkey_idx"));
+    assertTrue(catalog.existIndexByColumnNames(getCurrentDatabase(), "lineitem", new String[]{"l_orderkey", "l_partkey"}));
+    executeString("drop index l_orderkey_partkey_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_partkey_idx"));
+    assertIndexNotExist(getCurrentDatabase(), "l_orderkey_partkey_idx");
+  }
+
+  @Test
+  public final void testCreateIndexWithCondition() throws Exception {
+    executeQuery();
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_partkey_lt10_idx"));
+    assertTrue(catalog.existIndexByColumnNames(getCurrentDatabase(), "lineitem", new String[]{"l_orderkey", "l_partkey"}));
+    executeString("drop index l_orderkey_partkey_lt10_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_partkey_lt10_idx"));
+    assertIndexNotExist(getCurrentDatabase(), "l_orderkey_partkey_lt10_idx");
+  }
+
+  @Test
+  public final void testCreateIndexOnExpression() throws Exception {
+    executeQuery();
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_100_lt10_idx"));
+    executeString("drop index l_orderkey_100_lt10_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_100_lt10_idx"));
+    assertIndexNotExist(getCurrentDatabase(), "l_orderkey_100_lt10_idx");
+  }
+
+  @Test
+  public final void testCreateIndexOnMultiExprs() throws Exception {
+    executeQuery();
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_100_l_linenumber_10_lt10_idx"));
+    executeString("drop index l_orderkey_100_l_linenumber_10_lt10_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_100_l_linenumber_10_lt10_idx"));
+    assertIndexNotExist(getCurrentDatabase(), "l_orderkey_100_l_linenumber_10_lt10_idx");
+  }
+
+  @Test
+  public final void testCreateIndexOnLocation() throws Exception {
+    executeQuery();
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_idx"));
+    assertTrue(catalog.existIndexByColumnNames(getCurrentDatabase(), "lineitem", new String[]{"l_orderkey"}));
+    catalog.dropIndex(getCurrentDatabase(), "l_orderkey_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_idx"));
+    executeString("create index l_orderkey_idx on lineitem (l_orderkey asc null first) location '/tajo/warehouse/default/l_orderkey_idx';");
+    assertTrue(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_idx"));
+    assertTrue(catalog.existIndexByColumnNames(getCurrentDatabase(), "lineitem", new String[]{"l_orderkey"}));
+    executeString("drop index l_orderkey_idx");
+    assertFalse(catalog.existIndexByName(getCurrentDatabase(), "l_orderkey_idx"));
+    assertIndexNotExist(getCurrentDatabase(), "l_orderkey_idx");
+  }
+}


[50/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 0b705e8..2cd18eb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,9 @@ Release 0.11.0 - unreleased
 
   IMPROVEMENT
 
+    TAJO-1761: Separate an integration unit test kit into an independent 
+    module. (hyunsik)
+
     TAJO-680: Improve the IN operator to support sub queries. (jihoon)
 
     TAJO-1751: Reduce the client connection timeout. (jinho)

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 296830a..69eaebf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,8 @@
     <module>tajo-thirdparty/asm</module>
     <module>tajo-cli</module>
     <module>tajo-metrics</module>
+    <module>tajo-core-tests</module>
+    <module>tajo-cluster-tests</module>
   </modules>
 
   <build>

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/pom.xml b/tajo-cluster-tests/pom.xml
new file mode 100644
index 0000000..20c43bd
--- /dev/null
+++ b/tajo-cluster-tests/pom.xml
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tajo-project</artifactId>
+    <groupId>org.apache.tajo</groupId>
+    <version>0.11.0-SNAPSHOT</version>
+    <relativePath>../tajo-project</relativePath>
+  </parent>
+  <artifactId>tajo-cluster-tests</artifactId>
+  <packaging>jar</packaging>
+  <name>Tajo Cluster Tests</name>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <excludes>
+            <exclude>derby.log</exclude>
+            <exclude>benchmark/**</exclude>
+            <exclude>src/test/tpch/**</exclude>
+            <exclude>src/test/resources/dataset/**</exclude>
+            <exclude>src/test/resources/queries/**</exclude>
+            <exclude>src/test/resources/results/**</exclude>
+            <exclude>src/main/resources/META-INF/services/*</exclude>
+            <exclude>src/main/resources/webapps/static/js/*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemProperties>
+            <tajo.test>TRUE</tajo.test>
+          </systemProperties>
+          <argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=152m -Dfile.encoding=UTF-8</argLine>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-deploy-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.1</version>
+        <configuration>
+          <excludes>
+            <exclude>LICENSE</exclude>
+          </excludes>
+          <archive>
+            <addMavenDescriptor>false</addMavenDescriptor>
+          </archive>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <includeScope>runtime</includeScope>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>false</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-algebra</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-plan</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-catalog-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-storage-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-storage-hdfs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-storage-hbase</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-pullserver</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-rpc-protobuf</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-thirdparty-asm</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-ws-rs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-metrics</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-el</groupId>
+          <artifactId>commons-el</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-runtime</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-compiler</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.mortbay.jetty</groupId>
+          <artifactId>jsp-2.1-jetty</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-el</groupId>
+          <artifactId>commons-el</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-runtime</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>tomcat</groupId>
+          <artifactId>jasper-compiler</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.mortbay.jetty</groupId>
+          <artifactId>jsp-2.1-jetty</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey.jersey-test-framework</groupId>
+          <artifactId>jersey-test-framework-grizzly2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-server-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-server</artifactId>
+      <version>${hbase.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-server</artifactId>
+      <version>${hbase.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-hadoop-compat</artifactId>
+      <version>${hbase.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-hadoop2-compat</artifactId>
+      <version>${hbase.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>jdk.tools</artifactId>
+          <groupId>jdk.tools</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/BackendTestingUtil.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/BackendTestingUtil.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/BackendTestingUtil.java
new file mode 100644
index 0000000..3bfd34d
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/BackendTestingUtil.java
@@ -0,0 +1,71 @@
+/**
+ * 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;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.storage.*;
+
+import java.io.IOException;
+
+public class BackendTestingUtil {
+  public final static Schema mockupSchema;
+  public final static TableMeta mockupMeta;
+
+  static {
+    mockupSchema = new Schema();
+    mockupSchema.addColumn("deptname", Type.TEXT);
+    mockupSchema.addColumn("score", Type.INT4);
+    mockupMeta = CatalogUtil.newTableMeta("TEXT");
+  }
+
+  public static void writeTmpTable(TajoConf conf, Path tablePath)
+      throws IOException {
+    FileTablespace sm = TablespaceManager.getDefault();
+    Appender appender;
+
+    Path filePath = new Path(tablePath, "table.csv");
+    FileSystem fs = filePath.getFileSystem(conf);
+    if (fs.exists(tablePath)) {
+      fs.delete(tablePath, true);
+    }
+    fs.mkdirs(tablePath);
+
+    appender = sm.getAppender(mockupMeta, mockupSchema, filePath);
+    appender.init();
+
+    int deptSize = 10000;
+    int tupleNum = 100;
+    Tuple tuple;
+    for (int i = 0; i < tupleNum; i++) {
+      tuple = new VTuple(2);
+      String key = "test" + (i % deptSize);
+      tuple.put(0, DatumFactory.createText(key));
+      tuple.put(1, DatumFactory.createInt4(i + 1));
+      appender.addTuple(tuple);
+    }
+    appender.close();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/HBaseTestClusterUtil.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/HBaseTestClusterUtil.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/HBaseTestClusterUtil.java
new file mode 100644
index 0000000..0072e97
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/HBaseTestClusterUtil.java
@@ -0,0 +1,184 @@
+/**
+ * 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;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.*;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.master.ServerManager;
+import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
+import org.apache.tajo.util.Bytes;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.apache.hadoop.hbase.HConstants.REPLICATION_ENABLE_KEY;
+
+public class HBaseTestClusterUtil {
+  private static final Log LOG = LogFactory.getLog(HBaseTestClusterUtil.class);
+  private Configuration conf;
+  private MiniHBaseCluster hbaseCluster;
+  private MiniZooKeeperCluster zkCluster;
+  private File testBaseDir;
+  public HBaseTestClusterUtil(Configuration conf, File testBaseDir) {
+    this.conf = conf;
+    this.testBaseDir = testBaseDir;
+  }
+  /**
+   * Returns the path to the default root dir the minicluster uses.
+   * Note: this does not cause the root dir to be created.
+   * @return Fully qualified path for the default hbase root dir
+   * @throws java.io.IOException
+   */
+  public Path getDefaultRootDirPath() throws IOException {
+    FileSystem fs = FileSystem.get(this.conf);
+    return new Path(fs.makeQualified(fs.getHomeDirectory()),"hbase");
+  }
+
+  /**
+   * Creates an hbase rootdir in user home directory.  Also creates hbase
+   * version file.  Normally you won't make use of this method.  Root hbasedir
+   * is created for you as part of mini cluster startup.  You'd only use this
+   * method if you were doing manual operation.
+   * @return Fully qualified path to hbase root dir
+   * @throws java.io.IOException
+   */
+  public Path createRootDir() throws IOException {
+    FileSystem fs = FileSystem.get(this.conf);
+    Path hbaseRootdir = getDefaultRootDirPath();
+    FSUtils.setRootDir(this.conf, hbaseRootdir);
+    fs.mkdirs(hbaseRootdir);
+    FSUtils.setVersion(fs, hbaseRootdir);
+    return hbaseRootdir;
+  }
+
+  public void stopHBaseCluster() throws IOException {
+    if (hbaseCluster != null) {
+      LOG.info("MiniHBaseCluster stopped");
+      hbaseCluster.shutdown();
+      hbaseCluster.waitUntilShutDown();
+      hbaseCluster = null;
+    }
+  }
+
+  public void startHBaseCluster() throws Exception {
+    if (zkCluster == null) {
+      startMiniZKCluster();
+    }
+    if (hbaseCluster != null) {
+      return;
+    }
+
+    System.setProperty("HBASE_ZNODE_FILE", testBaseDir + "/hbase_znode_file");
+    if (conf.getInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, -1) == -1) {
+      conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, 1);
+    }
+    if (conf.getInt(ServerManager.WAIT_ON_REGIONSERVERS_MAXTOSTART, -1) == -1) {
+      conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MAXTOSTART, 1);
+    }
+    conf.setBoolean(HConstants.REPLICATION_ENABLE_KEY, false);
+    createRootDir();
+
+    Configuration c = HBaseConfiguration.create(this.conf);
+    // randomize hbase info port
+    c.setInt(HConstants.MASTER_INFO_PORT, 0);
+
+    hbaseCluster = new MiniHBaseCluster(c, 1);
+
+    // Don't leave here till we've done a successful scan of the hbase:meta
+    HTable t = new HTable(c, TableName.META_TABLE_NAME);
+    ResultScanner s = t.getScanner(new Scan());
+    while (s.next() != null) {
+      continue;
+    }
+    s.close();
+    t.close();
+    LOG.info("MiniHBaseCluster started");
+
+  }
+
+  /**
+   * Start a mini ZK cluster. If the property "test.hbase.zookeeper.property.clientPort" is set
+   *  the port mentionned is used as the default port for ZooKeeper.
+   */
+  public MiniZooKeeperCluster startMiniZKCluster()
+      throws Exception {
+    File zkDataPath = new File(testBaseDir, "zk");
+    if (this.zkCluster != null) {
+      throw new IOException("Cluster already running at " + zkDataPath);
+    }
+    this.zkCluster = new MiniZooKeeperCluster(conf);
+    final int defPort = this.conf.getInt("test.hbase.zookeeper.property.clientPort", 0);
+    if (defPort > 0){
+      // If there is a port in the config file, we use it.
+      this.zkCluster.setDefaultClientPort(defPort);
+    }
+    int clientPort =  this.zkCluster.startup(zkDataPath, 1);
+    this.conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, Integer.toString(clientPort));
+    LOG.info("MiniZooKeeperCluster started");
+
+    return this.zkCluster;
+  }
+
+  public void stopZooKeeperCluster() throws IOException {
+    if (zkCluster != null) {
+      LOG.info("MiniZooKeeperCluster stopped");
+      zkCluster.shutdown();
+      zkCluster = null;
+    }
+  }
+
+  public Configuration getConf() {
+    return conf;
+  }
+
+  public MiniZooKeeperCluster getMiniZooKeeperCluster() {
+    return zkCluster;
+  }
+
+  public MiniHBaseCluster getMiniHBaseCluster() {
+    return hbaseCluster;
+  }
+
+  public HTableDescriptor getTableDescriptor(String tableName) throws IOException {
+    HBaseAdmin admin = new HBaseAdmin(conf);
+    try {
+      return admin.getTableDescriptor(Bytes.toBytes(tableName));
+    } finally {
+      admin.close();
+    }
+  }
+
+  public void createTable(HTableDescriptor hTableDesc) throws IOException {
+    HBaseAdmin admin = new HBaseAdmin(conf);
+    try {
+      admin.createTable(hTableDesc);
+    } finally {
+      admin.close();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/IntegrationTest.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/IntegrationTest.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/IntegrationTest.java
new file mode 100644
index 0000000..755b90a
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/IntegrationTest.java
@@ -0,0 +1,22 @@
+/**
+ * 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;
+
+public interface IntegrationTest {
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
new file mode 100644
index 0000000..f084138
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
@@ -0,0 +1,169 @@
+/**
+ * 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;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.tajo.benchmark.TPCH;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.session.Session;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.FileUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.TajoIdUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.sql.ResultSet;
+import java.util.UUID;
+
+public class LocalTajoTestingUtility {
+  private static final Log LOG = LogFactory.getLog(LocalTajoTestingUtility.class);
+
+  private TajoTestingCluster util;
+  private TajoConf conf;
+  private TajoClient client;
+
+  private static UserGroupInformation dummyUserInfo;
+
+  static {
+    try {
+      dummyUserInfo = UserGroupInformation.getCurrentUser();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private static int taskAttemptId;
+
+  public static TaskAttemptId newTaskAttemptId() {
+    return QueryIdFactory.newTaskAttemptId(
+        QueryIdFactory.newTaskId(new MasterPlan(newQueryId(), null, null).newExecutionBlockId()), taskAttemptId++);
+  }
+  public static TaskAttemptId newTaskAttemptId(MasterPlan plan) {
+    return QueryIdFactory.newTaskAttemptId(QueryIdFactory.newTaskId(plan.newExecutionBlockId()), 0);
+  }
+
+  public static Session createDummySession() {
+    return new Session(UUID.randomUUID().toString(), dummyUserInfo.getUserName(), TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  public static QueryContext createDummyContext(TajoConf conf) {
+    QueryContext context = new QueryContext(conf, createDummySession());
+    context.putAll(CommonTestingUtil.getSessionVarsForTest().getAllKeyValus());
+    return context;
+  }
+
+  /**
+   * for test
+   * @return The generated QueryId
+   */
+  public synchronized static QueryId newQueryId() {
+    return QueryIdFactory.newQueryId(TajoIdUtils.MASTER_ID_FORMAT.format(0));
+  }
+
+  public void setup(String[] names,
+                    String[] tablepaths,
+                    Schema[] schemas,
+                    KeyValueSet option) throws Exception {
+    LOG.info("===================================================");
+    LOG.info("Starting Test Cluster.");
+    LOG.info("===================================================");
+
+    util = new TajoTestingCluster();
+    util.startMiniCluster(1);
+    conf = util.getConfiguration();
+    client = util.newTajoClient();
+
+    FileSystem fs = util.getDefaultFileSystem();
+    Path rootDir = TajoConf.getWarehouseDir(conf);
+    fs.mkdirs(rootDir);
+    for (int i = 0; i < tablepaths.length; i++) {
+      Path localPath = new Path(tablepaths[i]);
+      Path tablePath = new Path(rootDir, names[i]);
+      fs.mkdirs(tablePath);
+      Path dfsPath = new Path(tablePath, localPath.getName());
+      fs.copyFromLocalFile(localPath, dfsPath);
+      TableMeta meta = CatalogUtil.newTableMeta("TEXT", option);
+
+      // Add fake table statistic data to tables.
+      // It gives more various situations to unit tests.
+      TableStats stats = new TableStats();
+      stats.setNumBytes(TPCH.tableVolumes.get(names[i]));
+      TableDesc tableDesc = new TableDesc(
+          CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, names[i]), schemas[i], meta,
+          tablePath.toUri());
+      tableDesc.setStats(stats);
+      util.getMaster().getCatalog().createTable(tableDesc);
+    }
+
+    LOG.info("===================================================");
+    LOG.info("Test Cluster ready and test table created.");
+    LOG.info("===================================================");
+
+  }
+
+  public TajoTestingCluster getTestingCluster() {
+    return util;
+  }
+
+  public ResultSet execute(String query) throws TajoException {
+    return client.executeQueryAndGetResult(query);
+  }
+
+  public void shutdown() throws IOException {
+    if(client != null) {
+      client.close();
+    }
+    if(util != null) {
+      util.shutdownMiniCluster();
+    }
+  }
+
+  public static Path getResourcePath(String path, String suffix) {
+    URL resultBaseURL = ClassLoader.getSystemResource(path);
+    return new Path(resultBaseURL.toString(), suffix);
+  }
+
+  public static Path getResultPath(Class clazz, String fileName) {
+    return new Path (getResourcePath("results", clazz.getSimpleName()), fileName);
+  }
+
+  public static String getResultText(Class clazz, String fileName) throws IOException {
+    FileSystem localFS = FileSystem.getLocal(new Configuration());
+    Path path = getResultPath(clazz, fileName);
+    Preconditions.checkState(localFS.exists(path) && localFS.isFile(path));
+    return FileUtil.readTextFile(new File(path.toUri()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/NamedTest.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/NamedTest.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/NamedTest.java
new file mode 100644
index 0000000..f2c1bb7
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/NamedTest.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NamedTest {
+  String value();
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-cluster-tests/src/test/java/org/apache/tajo/QueryTestCaseBase.java
----------------------------------------------------------------------
diff --git a/tajo-cluster-tests/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-cluster-tests/src/test/java/org/apache/tajo/QueryTestCaseBase.java
new file mode 100644
index 0000000..c3c9b52
--- /dev/null
+++ b/tajo-cluster-tests/src/test/java/org/apache/tajo/QueryTestCaseBase.java
@@ -0,0 +1,1030 @@
+/**
+ * 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;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.algebra.*;
+import org.apache.tajo.annotation.Nullable;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.exception.UndefinedTableException;
+import org.apache.tajo.cli.tsql.ParsedResult;
+import org.apache.tajo.cli.tsql.SimpleParser;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.master.GlobalEngine;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.verifier.LogicalPlanVerifier;
+import org.apache.tajo.plan.verifier.PreLogicalPlanVerifier;
+import org.apache.tajo.plan.verifier.VerificationState;
+import org.apache.tajo.storage.StorageUtil;
+import org.apache.tajo.util.FileUtil;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.*;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * (Note that this class is not thread safe. Do not execute maven test in any parallel mode.)
+ * <br />
+ * <code>QueryTestCaseBase</code> provides useful methods to easily execute queries and verify their results.
+ *
+ * This class basically uses four resource directories:
+ * <ul>
+ *   <li>src/test/resources/dataset - contains a set of data files. It contains sub directories, each of which
+ *   corresponds each test class. All data files in each sub directory can be used in the corresponding test class.</li>
+ *
+ *   <li>src/test/resources/queries - This is the query directory. It contains sub directories, each of which
+ *   corresponds each test class. All query files in each sub directory can be used in the corresponding test
+ *   class.</li>
+ *
+ *   <li>src/test/resources/results - This is the result directory. It contains sub directories, each of which
+ *   corresponds each test class. All result files in each sub directory can be used in the corresponding test class.
+ *   </li>
+ * </ul>
+ *
+ * For example, if you create a test class named <code>TestJoinQuery</code>, you should create a pair of query and
+ * result set directories as follows:
+ *
+ * <pre>
+ *   src-|
+ *       |- resources
+ *             |- dataset
+ *             |     |- TestJoinQuery
+ *             |              |- table1.tbl
+ *             |              |- table2.tbl
+ *             |
+ *             |- queries
+ *             |     |- TestJoinQuery
+ *             |              |- TestInnerJoin.sql
+ *             |              |- table1_ddl.sql
+ *             |              |- table2_ddl.sql
+ *             |
+ *             |- results
+ *                   |- TestJoinQuery
+ *                            |- TestInnerJoin.result
+ * </pre>
+ *
+ * <code>QueryTestCaseBase</code> basically provides the following methods:
+ * <ul>
+ *  <li><code>{@link #executeQuery()}</code> - executes a corresponding query and returns an ResultSet instance</li>
+ *  <li><code>{@link #executeFile(String)}</code> - executes a given query file included in the corresponding query
+ *  file in the current class's query directory</li>
+ *  <li><code>assertResultSet()</code> - check if the query result is equivalent to the expected result included
+ *  in the corresponding result file in the current class's result directory.</li>
+ *  <li><code>cleanQuery()</code> - clean up all resources</li>
+ *  <li><code>executeDDL()</code> - execute a DDL query like create or drop table.</li>
+ * </ul>
+ *
+ * In order to make use of the above methods, query files and results file must be as follows:
+ * <ul>
+ *  <li>Each query file must be located on the subdirectory whose structure must be src/resources/queries/${ClassName},
+ *  where ${ClassName} indicates an actual test class's simple name.</li>
+ *  <li>Each result file must be located on the subdirectory whose structure must be src/resources/results/${ClassName},
+ *  where ${ClassName} indicates an actual test class's simple name.</li>
+ * </ul>
+ *
+ * Especially, {@link #executeQuery() and {@link #assertResultSet(java.sql.ResultSet)} methods automatically finds
+ * a query file to be executed and a result to be compared, which are corresponding to the running class and method.
+ * For them, query and result files additionally must be follows as:
+ * <ul>
+ *  <li>Each result file must have the file extension '.result'</li>
+ *  <li>Each query file must have the file extension '.sql'.</li>
+ * </ul>
+ */
+public class QueryTestCaseBase {
+  private static final Log LOG = LogFactory.getLog(QueryTestCaseBase.class);
+  protected static final TpchTestBase testBase;
+  protected static final TajoTestingCluster testingCluster;
+  protected static TajoConf conf;
+  protected static TajoClient client;
+  protected static final CatalogService catalog;
+  protected static final SQLAnalyzer sqlParser;
+  protected static PreLogicalPlanVerifier verifier;
+  protected static LogicalPlanner planner;
+  protected static LogicalOptimizer optimizer;
+  protected static LogicalPlanVerifier postVerifier;
+
+  /** the base path of dataset directories */
+  protected static final Path datasetBasePath;
+  /** the base path of query directories */
+  protected static final Path queryBasePath;
+  /** the base path of result directories */
+  protected static final Path resultBasePath;
+
+  static {
+    testBase = TpchTestBase.getInstance();
+    testingCluster = testBase.getTestingCluster();
+    conf = testBase.getTestingCluster().getConfiguration();
+    catalog = testBase.getTestingCluster().getMaster().getCatalog();
+    URL datasetBaseURL = ClassLoader.getSystemResource("dataset");
+    datasetBasePath = new Path(datasetBaseURL.toString());
+    URL queryBaseURL = ClassLoader.getSystemResource("queries");
+    queryBasePath = new Path(queryBaseURL.toString());
+    URL resultBaseURL = ClassLoader.getSystemResource("results");
+    resultBasePath = new Path(resultBaseURL.toString());
+
+    GlobalEngine engine = testingCluster.getMaster().getContext().getGlobalEngine();
+    sqlParser = engine.getAnalyzer();
+    verifier = engine.getPreLogicalPlanVerifier();
+    planner = engine.getLogicalPlanner();
+    optimizer = engine.getLogicalOptimizer();
+    postVerifier = engine.getLogicalPlanVerifier();
+  }
+
+  /** It transiently contains created tables for the running test class. */
+  private static String currentDatabase;
+  private static Set<String> createdTableGlobalSet = new HashSet<String>();
+  // queries and results directory corresponding to subclass class.
+  protected Path currentQueryPath;
+  protected Path namedQueryPath;
+  protected Path currentResultPath;
+  protected Path currentDatasetPath;
+  protected Path namedDatasetPath;
+
+  protected FileSystem currentResultFS;
+
+  protected final String testParameter;
+
+  // for getting a method name
+  @Rule public TestName name = new TestName();
+
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    conf = testBase.getTestingCluster().getConfiguration();
+    client = testBase.getTestingCluster().newTajoClient();
+  }
+
+  @AfterClass
+  public static void tearDownClass() throws Exception {
+    for (String tableName : createdTableGlobalSet) {
+      client.updateQuery("DROP TABLE IF EXISTS " + CatalogUtil.denormalizeIdentifier(tableName));
+    }
+    createdTableGlobalSet.clear();
+
+    // if the current database is "default", shouldn't drop it.
+    if (!currentDatabase.equals(TajoConstants.DEFAULT_DATABASE_NAME)) {
+      for (String tableName : catalog.getAllTableNames(currentDatabase)) {
+        client.updateQuery("DROP TABLE IF EXISTS " + tableName);
+      }
+
+      client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME);
+      client.dropDatabase(currentDatabase);
+    }
+    client.close();
+  }
+
+  @Before
+  public void printTestName() {
+    /* protect a travis stalled build */
+    System.out.println("Run: " + name.getMethodName() +
+        " Used memory: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())
+        / (1024 * 1024)) + " MBytes, Active Threads:" + Thread.activeCount());
+  }
+
+  public QueryTestCaseBase() {
+    // hive 0.12 does not support quoted identifier.
+    // So, we use lower case database names when Tajo uses HiveCatalogStore.
+    if (testingCluster.isHiveCatalogStoreRunning()) {
+      this.currentDatabase = getClass().getSimpleName().toLowerCase();
+    } else {
+      this.currentDatabase = getClass().getSimpleName();
+    }
+    testParameter = null;
+    init();
+  }
+
+  public QueryTestCaseBase(String currentDatabase) {
+    this(currentDatabase, null);
+  }
+
+  public QueryTestCaseBase(String currentDatabase, String testParameter) {
+    this.currentDatabase = currentDatabase;
+    this.testParameter = testParameter;
+    init();
+  }
+
+  private void init() {
+    String className = getClass().getSimpleName();
+    currentQueryPath = new Path(queryBasePath, className);
+    currentResultPath = new Path(resultBasePath, className);
+    currentDatasetPath = new Path(datasetBasePath, className);
+    NamedTest namedTest = getClass().getAnnotation(NamedTest.class);
+    if (namedTest != null) {
+      namedQueryPath = new Path(queryBasePath, namedTest.value());
+      namedDatasetPath = new Path(datasetBasePath, namedTest.value());
+    }
+
+    try {
+      // if the current database is "default", we don't need create it because it is already prepated at startup time.
+      if (!currentDatabase.equals(TajoConstants.DEFAULT_DATABASE_NAME)) {
+        client.updateQuery("CREATE DATABASE IF NOT EXISTS " + CatalogUtil.denormalizeIdentifier(currentDatabase));
+      }
+      client.selectDatabase(currentDatabase);
+      currentResultFS = currentResultPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+    testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$TEST_BROADCAST_JOIN_ENABLED.varname, "false");
+  }
+
+  protected TajoClient getClient() {
+    return client;
+  }
+
+  public String getCurrentDatabase() {
+    return currentDatabase;
+  }
+
+  private static VerificationState verify(String query) throws TajoException {
+
+    VerificationState state = new VerificationState();
+    QueryContext context = LocalTajoTestingUtility.createDummyContext(conf);
+
+    Expr expr = sqlParser.parse(query);
+
+    verifier.verify(context, state, expr);
+
+    if (state.getErrors().size() > 0) {
+      return state;
+    }
+    LogicalPlan plan = planner.createPlan(context, expr);
+    optimizer.optimize(plan);
+    postVerifier.verify(state, plan);
+
+    return state;
+  }
+
+  public void assertValidSQL(String query) throws IOException {
+    VerificationState state = null;
+    try {
+      state = verify(query);
+      if (state.getErrors().size() > 0) {
+        fail(state.getErrors().get(0).getMessage());
+      }
+    } catch (TajoException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void assertValidSQLFromFile(String fileName) throws IOException {
+    Path queryFilePath = getQueryFilePath(fileName);
+    String query = FileUtil.readTextFile(new File(queryFilePath.toUri()));
+    assertValidSQL(query);
+  }
+
+  public void assertInvalidSQL(String query) throws IOException {
+    VerificationState state = null;
+    try {
+      state = verify(query);
+
+      if (state.getErrors().size() == 0) {
+        fail(PreLogicalPlanVerifier.class.getSimpleName() + " cannot catch any verification error: " + query);
+      }
+
+    } catch (TajoException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void assertInvalidSQLFromFile(String fileName) throws IOException {
+    Path queryFilePath = getQueryFilePath(fileName);
+    String query = FileUtil.readTextFile(new File(queryFilePath.toUri()));
+    assertInvalidSQL(query);
+  }
+
+  public void assertPlanError(String fileName) throws IOException {
+    Path queryFilePath = getQueryFilePath(fileName);
+    String query = FileUtil.readTextFile(new File(queryFilePath.toUri()));
+    try {
+      verify(query);
+    } catch (TajoException e) {
+      return;
+    }
+    fail("Cannot catch any planning error from: " + query);
+  }
+
+  protected ResultSet executeString(String sql) throws TajoException {
+    return client.executeQueryAndGetResult(sql);
+  }
+
+  /**
+   * It executes the query file and compare the result against the the result file.
+   *
+   * @throws Exception
+   */
+  public void assertQuery() throws Exception {
+    ResultSet res = null;
+    try {
+      res = executeQuery();
+      assertResultSet(res);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  /**
+   * It executes a given query statement and verifies the result against the the result file.
+   *
+   * @param query A query statement
+   * @throws Exception
+   */
+  public void assertQueryStr(String query) throws Exception {
+    ResultSet res = null;
+    try {
+      res = executeString(query);
+      assertResultSet(res);
+    } finally {
+      if (res != null) {
+        res.close();
+      }
+    }
+  }
+
+  /**
+   * Execute a query contained in the file located in src/test/resources/results/<i>ClassName</i>/<i>MethodName</i>.
+   * <i>ClassName</i> and <i>MethodName</i> will be replaced by actual executed class and methods.
+   *
+   * @return ResultSet of query execution.
+   */
+  public ResultSet executeQuery() throws Exception {
+    return executeFile(getMethodName() + ".sql");
+  }
+
+  private volatile Description current;
+
+  @Rule
+  public TestRule watcher = new TestWatcher() {
+    @Override
+    protected void starting(Description description) {
+      QueryTestCaseBase.this.current = description;
+    }
+  };
+
+  @Target({ElementType.METHOD})
+  @Retention(RetentionPolicy.RUNTIME)
+  protected @interface SimpleTest {
+    String[] prepare() default {};
+    QuerySpec[] queries() default {};
+    String[] cleanup() default {};
+  }
+
+  @Target({ElementType.METHOD})
+  @Retention(RetentionPolicy.RUNTIME)
+  protected @interface QuerySpec {
+    String value();
+    boolean override() default false;
+    Option option() default @Option;
+  }
+
+  @Target({ElementType.METHOD})
+  @Retention(RetentionPolicy.RUNTIME)
+  protected @interface Option {
+    boolean withExplain() default false;
+    boolean withExplainGlobal() default false;
+    boolean parameterized() default false;
+    boolean sort() default false;
+  }
+
+  private static class DummyQuerySpec implements QuerySpec {
+    private final String value;
+    private final Option option;
+    public DummyQuerySpec(String value, Option option) {
+      this.value = value;
+      this.option = option;
+    }
+    public Class<? extends Annotation> annotationType() { return QuerySpec.class; }
+    public String value() { return value; }
+    public boolean override() { return option != null; }
+    public Option option() { return option; }
+  }
+
+  private static class DummyOption implements Option {
+    private final boolean explain;
+    private final boolean withExplainGlobal;
+    private final boolean parameterized;
+    private final boolean sort;
+    public DummyOption(boolean explain, boolean withExplainGlobal, boolean parameterized, boolean sort) {
+      this.explain = explain;
+      this.withExplainGlobal = withExplainGlobal;
+      this.parameterized = parameterized;
+      this.sort = sort;
+    }
+    public Class<? extends Annotation> annotationType() { return Option.class; }
+    public boolean withExplain() { return explain;}
+    public boolean withExplainGlobal() { return withExplainGlobal;}
+    public boolean parameterized() { return parameterized;}
+    public boolean sort() { return sort;}
+  }
+
+  protected void runSimpleTests() throws Exception {
+    String methodName = getMethodName();
+    Method method = current.getTestClass().getMethod(methodName);
+    SimpleTest annotation = method.getAnnotation(SimpleTest.class);
+    if (annotation == null) {
+      throw new IllegalStateException("Cannot find test annotation");
+    }
+
+    List<String> prepares = new ArrayList<>(Arrays.asList(annotation.prepare()));
+    QuerySpec[] queries = annotation.queries();
+    Option defaultOption = method.getAnnotation(Option.class);
+    if (defaultOption == null) {
+      defaultOption = new DummyOption(false, false, false, false);
+    }
+
+    boolean fromFile = false;
+    if (queries.length == 0) {
+      Path queryFilePath = getQueryFilePath(getMethodName() + ".sql");
+      List<ParsedResult> parsedResults = SimpleParser.parseScript(FileUtil.readTextFile(new File(queryFilePath.toUri())));
+      int i = 0;
+      for (; i < parsedResults.size() - 1; i++) {
+        prepares.add(parsedResults.get(i).getStatement());
+      }
+      queries = new QuerySpec[] {new DummyQuerySpec(parsedResults.get(i).getHistoryStatement(), null)};
+      fromFile = true;  // do not append query index to result file
+    }
+    
+    try {
+      for (String prepare : prepares) {
+        client.executeQueryAndGetResult(prepare).close();
+      }
+      for (int i = 0; i < queries.length; i++) {
+        QuerySpec spec = queries[i];
+        Option option = spec.override() ? spec.option() : defaultOption;
+        String prefix = "";
+        testingCluster.getConfiguration().set(TajoConf.ConfVars.$TEST_PLAN_SHAPE_FIX_ENABLED.varname, "true");
+        if (option.withExplain()) {// Enable this option to fix the shape of the generated plans.
+          prefix += resultSetToString(executeString("explain " + spec.value()));
+        }
+        if (option.withExplainGlobal()) {
+          // Enable this option to fix the shape of the generated plans.
+          prefix += resultSetToString(executeString("explain global " + spec.value()));
+        }
+
+        // plan test
+        if (prefix.length() > 0) {
+          String planResultName = methodName + (fromFile ? "" : "" + (i + 1)) +
+              ((option.parameterized() && testParameter != null) ? "" + testParameter : "") + ".plan";
+          Path resultPath = StorageUtil.concatPath(currentResultPath, planResultName);
+          if (currentResultFS.exists(resultPath)) {
+            assertEquals("Plan Verification for: " + (i + 1) + " th test",
+                FileUtil.readTextFromStream(currentResultFS.open(resultPath)), prefix);
+          } else if (prefix.length() > 0) {
+            // If there is no result file expected, create gold files for new tests.
+            FileUtil.writeTextToStream(prefix, currentResultFS.create(resultPath));
+            LOG.info("New test output for " + current.getDisplayName() + " is written to " + resultPath);
+            // should be copied to src directory
+          }
+        }
+
+        testingCluster.getConfiguration().set(TajoConf.ConfVars.$TEST_PLAN_SHAPE_FIX_ENABLED.varname, "false");
+        ResultSet result = client.executeQueryAndGetResult(spec.value());
+
+        // result test
+        String fileName = methodName + (fromFile ? "" : "" + (i + 1)) + ".result";
+        Path resultPath = StorageUtil.concatPath(currentResultPath, fileName);
+        if (currentResultFS.exists(resultPath)) {
+          assertEquals("Result Verification for: " + (i + 1) + " th test",
+              FileUtil.readTextFromStream(currentResultFS.open(resultPath)), resultSetToString(result, option.sort()));
+        } else if (!isNull(result)) {
+          // If there is no result file expected, create gold files for new tests.
+          FileUtil.writeTextToStream(resultSetToString(result, option.sort()), currentResultFS.create(resultPath));
+          LOG.info("New test output for " + current.getDisplayName() + " is written to " + resultPath);
+          // should be copied to src directory
+        }
+        result.close();
+      }
+    } finally {
+      for (String cleanup : annotation.cleanup()) {
+        try {
+          client.executeQueryAndGetResult(cleanup).close();
+        } catch (SQLException e) {
+          // ignore
+        }
+      }
+    }
+  }
+
+  private boolean isNull(ResultSet result) throws SQLException {
+    return result.getMetaData().getColumnCount() == 0;
+  }
+
+  protected String getMethodName() {
+    String methodName = name.getMethodName();
+    // In the case of parameter execution name's pattern is methodName[0]
+    if (methodName.endsWith("]")) {
+      methodName = methodName.substring(0, methodName.length() - 3);
+    }
+    return methodName;
+  }
+
+  public ResultSet executeJsonQuery() throws Exception {
+    return executeJsonFile(getMethodName() + ".json");
+  }
+
+  /**
+   * Execute a query contained in the given named file. This methods tries to find the given file within the directory
+   * src/test/resources/results/<i>ClassName</i>.
+   *
+   * @param queryFileName The file name to be used to execute a query.
+   * @return ResultSet of query execution.
+   */
+  public ResultSet executeFile(String queryFileName) throws Exception {
+    Path queryFilePath = getQueryFilePath(queryFileName);
+
+    List<ParsedResult> parsedResults = SimpleParser.parseScript(FileUtil.readTextFile(new File(queryFilePath.toUri())));
+    if (parsedResults.size() > 1) {
+      assertNotNull("This script \"" + queryFileName + "\" includes two or more queries");
+    }
+
+    int idx = 0;
+    for (; idx < parsedResults.size() - 1; idx++) {
+      client.executeQueryAndGetResult(parsedResults.get(idx).getHistoryStatement()).close();
+    }
+
+    ResultSet result = client.executeQueryAndGetResult(parsedResults.get(idx).getHistoryStatement());
+    assertNotNull("Query succeeded test", result);
+    return result;
+  }
+
+  public ResultSet executeJsonFile(String jsonFileName) throws Exception {
+    Path queryFilePath = getQueryFilePath(jsonFileName);
+
+    ResultSet result = client.executeJsonQueryAndGetResult(FileUtil.readTextFile(new File(queryFilePath.toUri())));
+    assertNotNull("Query succeeded test", result);
+    return result;
+  }
+
+  /**
+   * Assert the equivalence between the expected result and an actual query result.
+   * If it isn't it throws an AssertionError.
+   *
+   * @param result Query result to be compared.
+   */
+  public final void assertResultSet(ResultSet result) throws IOException {
+    assertResultSet("Result Verification", result, getMethodName() + ".result");
+  }
+
+  /**
+   * Assert the equivalence between the expected result and an actual query result.
+   * If it isn't it throws an AssertionError.
+   *
+   * @param result Query result to be compared.
+   * @param resultFileName The file name containing the result to be compared
+   */
+  public final void assertResultSet(ResultSet result, String resultFileName) throws IOException {
+    assertResultSet("Result Verification", result, resultFileName);
+  }
+
+  /**
+   * Assert the equivalence between the expected result and an actual query result.
+   * If it isn't it throws an AssertionError with the given message.
+   *
+   * @param message message The message to printed if the assertion is failed.
+   * @param result Query result to be compared.
+   */
+  public final void assertResultSet(String message, ResultSet result, String resultFileName) throws IOException {
+    Path resultFile = getResultFile(resultFileName);
+    try {
+      verifyResultText(message, result, resultFile);
+    } catch (SQLException e) {
+      throw new IOException(e);
+    }
+  }
+
+  public final void assertStrings(String actual) throws IOException {
+    assertStrings(actual, getMethodName() + ".result");
+  }
+
+  public final void assertStrings(String actual, String resultFileName) throws IOException {
+    assertStrings("Result Verification", actual, resultFileName);
+  }
+
+  public final void assertStrings(String message, String actual, String resultFileName) throws IOException {
+    Path resultFile = getResultFile(resultFileName);
+    String expectedResult = FileUtil.readTextFile(new File(resultFile.toUri()));
+    assertEquals(message, expectedResult, actual);
+  }
+
+  /**
+   * Release all resources
+   *
+   * @param resultSet ResultSet
+   */
+  public final void cleanupQuery(ResultSet resultSet) throws IOException {
+    if (resultSet == null) {
+      return;
+    }
+    try {
+      resultSet.close();
+    } catch (SQLException e) {
+      throw new IOException(e);
+    }
+  }
+
+  /**
+   * Assert that the database exists.
+   * @param databaseName The database name to be checked. This name is case sensitive.
+   */
+  public void assertDatabaseExists(String databaseName) throws SQLException {
+    assertTrue(client.existDatabase(databaseName));
+  }
+
+  /**
+   * Assert that the database does not exists.
+   * @param databaseName The database name to be checked. This name is case sensitive.
+   */
+  public void assertDatabaseNotExists(String databaseName) {
+    assertTrue(!client.existDatabase(databaseName));
+  }
+
+  /**
+   * Assert that the table exists.
+   *
+   * @param tableName The table name to be checked. This name is case sensitive.
+   * @throws ServiceException
+   */
+  public void assertTableExists(String tableName) {
+    assertTrue(client.existTable(tableName));
+  }
+
+  /**
+   * Assert that the table does not exist.
+   *
+   * @param tableName The table name to be checked. This name is case sensitive.
+   */
+  public void assertTableNotExists(String tableName) {
+    assertTrue(!client.existTable(tableName));
+  }
+
+  public void assertColumnExists(String tableName,String columnName) throws UndefinedTableException {
+    TableDesc tableDesc = getTableDesc(tableName);
+    assertTrue(tableDesc.getSchema().containsByName(columnName));
+  }
+
+  private TableDesc getTableDesc(String tableName) throws UndefinedTableException {
+    return client.getTableDesc(tableName);
+  }
+
+  public void assertTablePropertyEquals(String tableName, String key, String expectedValue)
+      throws UndefinedTableException {
+
+    TableDesc tableDesc = getTableDesc(tableName);
+    assertEquals(expectedValue, tableDesc.getMeta().getOption(key));
+  }
+
+  public String resultSetToString(ResultSet resultSet) throws SQLException {
+    return resultSetToString(resultSet, false);
+  }
+
+  /**
+   * It transforms a ResultSet instance to rows represented as strings.
+   *
+   * @param resultSet ResultSet that contains a query result
+   * @return String
+   * @throws SQLException
+   */
+  public String resultSetToString(ResultSet resultSet, boolean sort) throws SQLException {
+    StringBuilder sb = new StringBuilder();
+    ResultSetMetaData rsmd = resultSet.getMetaData();
+    int numOfColumns = rsmd.getColumnCount();
+
+    for (int i = 1; i <= numOfColumns; i++) {
+      if (i > 1) sb.append(",");
+      String columnName = rsmd.getColumnName(i);
+      sb.append(columnName);
+    }
+    sb.append("\n-------------------------------\n");
+
+    List<String> results = new ArrayList<String>();
+    while (resultSet.next()) {
+      StringBuilder line = new StringBuilder();
+      for (int i = 1; i <= numOfColumns; i++) {
+        if (i > 1) line.append(",");
+        String columnValue = resultSet.getString(i);
+        if (resultSet.wasNull()) {
+          columnValue = "null";
+        }
+        line.append(columnValue);
+      }
+      results.add(line.toString());
+    }
+    if (sort) {
+      Collections.sort(results);
+    }
+    for (String line : results) {
+      sb.append(line).append('\n');
+    }
+    return sb.toString();
+  }
+
+  private void verifyResultText(String message, ResultSet res, Path resultFile) throws SQLException, IOException {
+    String actualResult = resultSetToString(res);
+    String expectedResult = FileUtil.readTextFile(new File(resultFile.toUri()));
+    assertEquals(message, expectedResult.trim(), actualResult.trim());
+  }
+
+  private Path getQueryFilePath(String fileName) throws IOException {
+    Path queryFilePath = StorageUtil.concatPath(currentQueryPath, fileName);
+    FileSystem fs = currentQueryPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+    if (!fs.exists(queryFilePath)) {
+      if (namedQueryPath != null) {
+        queryFilePath = StorageUtil.concatPath(namedQueryPath, fileName);
+        fs = namedQueryPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+        if (!fs.exists(queryFilePath)) {
+          throw new IOException("Cannot find " + fileName + " at " + currentQueryPath + " and " + namedQueryPath);
+        }
+      } else {
+        throw new IOException("Cannot find " + fileName + " at " + currentQueryPath);
+      }
+    }
+    return queryFilePath;
+  }
+
+  protected String getResultContents(String fileName) throws IOException {
+    Path resultFile = getResultFile(getMethodName() + ".result");
+    return FileUtil.readTextFile(new File(resultFile.toUri()));
+  }
+
+  protected Path getResultFile(String fileName) throws IOException {
+    Path resultPath = StorageUtil.concatPath(currentResultPath, fileName);
+    FileSystem fs = currentResultPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+    assertTrue(resultPath.toString() + " existence check", fs.exists(resultPath));
+    return resultPath;
+  }
+
+  private Path getDataSetFile(String fileName) throws IOException {
+    Path dataFilePath = StorageUtil.concatPath(currentDatasetPath, fileName);
+    FileSystem fs = currentDatasetPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+    if (!fs.exists(dataFilePath)) {
+      if (namedDatasetPath != null) {
+        dataFilePath = StorageUtil.concatPath(namedDatasetPath, fileName);
+        fs = namedDatasetPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+        if (!fs.exists(dataFilePath)) {
+          throw new IOException("Cannot find " + fileName + " at " + currentQueryPath + " and " + namedQueryPath);
+        }
+      } else {
+        throw new IOException("Cannot find " + fileName + " at " + currentQueryPath + " and " + namedQueryPath);
+      }
+    }
+    return dataFilePath;
+  }
+
+  public List<String> executeDDL(String ddlFileName, @Nullable String [] args) throws Exception {
+    return executeDDL(ddlFileName, null, true, args);
+  }
+
+  /**
+   *
+   * Execute a data definition language (DDL) template. A general SQL DDL statement can be included in this file. But,
+   * for user-specified table name or exact external table path, you must use some format string to indicate them.
+   * The format string will be replaced by the corresponding arguments.
+   *
+   * The below is predefined format strings:
+   * <ul>
+   *   <li>${table.path} - It is replaced by the absolute file path that <code>dataFileName</code> points. </li>
+   *   <li>${i} - It is replaced by the corresponding element of <code>args</code>. For example, ${0} and ${1} are
+   *   replaced by the first and second elements of <code>args</code> respectively</li>. It uses zero-based index.
+   * </ul>
+   *
+   * Example ddl
+   * <pre>
+   *   CREATE EXTERNAL TABLE ${0} (
+   *     t_timestamp  TIMESTAMP,
+   *     t_date    DATE
+   *   ) USING TEXT LOCATION ${table.path}
+   * </pre>
+   *
+   * @param ddlFileName A file name, containing a data definition statement.
+   * @param dataFileName A file name, containing data rows, which columns have to be separated by vertical bar '|'.
+   *                     This file name is used for replacing some format string indicating an external table location.
+   * @param args A list of arguments, each of which is used to replace corresponding variable which has a form of ${i}.
+   * @return The table names created
+   */
+  public List<String> executeDDL(String ddlFileName, @Nullable String dataFileName, @Nullable String ... args)
+      throws Exception {
+
+    return executeDDL(ddlFileName, dataFileName, true, args);
+  }
+
+  private List<String> executeDDL(String ddlFileName, @Nullable String dataFileName, boolean isLocalTable,
+                                  @Nullable String[] args) throws Exception {
+
+    Path ddlFilePath = getQueryFilePath(ddlFileName);
+
+    String template = FileUtil.readTextFile(new File(ddlFilePath.toUri()));
+    String dataFilePath = null;
+    if (dataFileName != null) {
+      dataFilePath = getDataSetFile(dataFileName).toString();
+    }
+    String compiled = compileTemplate(template, dataFilePath, args);
+
+    List<ParsedResult> parsedResults = SimpleParser.parseScript(compiled);
+    List<String> createdTableNames = new ArrayList<String>();
+
+    for (ParsedResult parsedResult : parsedResults) {
+      // parse a statement
+      Expr expr = sqlParser.parse(parsedResult.getHistoryStatement());
+      assertNotNull(ddlFilePath + " cannot be parsed", expr);
+
+      if (expr.getType() == OpType.CreateTable) {
+        CreateTable createTable = (CreateTable) expr;
+        String tableName = createTable.getTableName();
+        assertTrue("Table [" + tableName + "] creation is failed.", client.updateQuery(parsedResult.getHistoryStatement()));
+
+        TableDesc createdTable = client.getTableDesc(tableName);
+        String createdTableName = createdTable.getName();
+
+        assertTrue("table '" + createdTableName + "' creation check", client.existTable(createdTableName));
+        if (isLocalTable) {
+          createdTableGlobalSet.add(createdTableName);
+          createdTableNames.add(tableName);
+        }
+      } else if (expr.getType() == OpType.DropTable) {
+        DropTable dropTable = (DropTable) expr;
+        String tableName = dropTable.getTableName();
+        assertTrue("table '" + tableName + "' existence check",
+            client.existTable(CatalogUtil.buildFQName(currentDatabase, tableName)));
+        assertTrue("table drop is failed.", client.updateQuery(parsedResult.getHistoryStatement()));
+        assertFalse("table '" + tableName + "' dropped check",
+            client.existTable(CatalogUtil.buildFQName(currentDatabase, tableName)));
+        if (isLocalTable) {
+          createdTableGlobalSet.remove(tableName);
+        }
+      } else if (expr.getType() == OpType.AlterTable) {
+        AlterTable alterTable = (AlterTable) expr;
+        String tableName = alterTable.getTableName();
+        assertTrue("table '" + tableName + "' existence check", client.existTable(tableName));
+        client.updateQuery(compiled);
+        if (isLocalTable) {
+          createdTableGlobalSet.remove(tableName);
+        }
+      } else if (expr.getType() == OpType.CreateIndex) {
+        // TODO: index existence check
+        client.executeQuery(compiled);
+      } else {
+        assertTrue(ddlFilePath + " is not a Create or Drop Table statement", false);
+      }
+    }
+
+    return createdTableNames;
+  }
+
+  /**
+   * Replace format strings by a given parameters.
+   *
+   * @param template
+   * @param dataFileName The data file name to replace <code>${table.path}</code>
+   * @param args The list argument to replace each corresponding format string ${i}. ${i} uses zero-based index.
+   * @return A string compiled
+   */
+  private String compileTemplate(String template, @Nullable String dataFileName, @Nullable String ... args) {
+    String result;
+    if (dataFileName != null) {
+      result = template.replace("${table.path}", "\'" + dataFileName + "'");
+    } else {
+      result = template;
+    }
+
+    if (args != null) {
+      for (int i = 0; i < args.length; i++) {
+        result = result.replace("${" + i + "}", args[i]);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Reads data file from Test Cluster's HDFS
+   * @param path data parent path
+   * @return data file's contents
+   * @throws Exception
+   */
+  public String getTableFileContents(Path path) throws Exception {
+    FileSystem fs = path.getFileSystem(conf);
+
+    FileStatus[] files = fs.listStatus(path);
+
+    if (files == null || files.length == 0) {
+      return "";
+    }
+
+    StringBuilder sb = new StringBuilder();
+    byte[] buf = new byte[1024];
+
+    for (FileStatus file: files) {
+      if (file.isDirectory()) {
+        sb.append(getTableFileContents(file.getPath()));
+        continue;
+      }
+
+      InputStream in = fs.open(file.getPath());
+      try {
+        while (true) {
+          int readBytes = in.read(buf);
+          if (readBytes <= 0) {
+            break;
+          }
+
+          sb.append(new String(buf, 0, readBytes));
+        }
+      } finally {
+        in.close();
+      }
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Reads data file from Test Cluster's HDFS
+   * @param tableName
+   * @return data file's contents
+   * @throws Exception
+   */
+  public String getTableFileContents(String tableName) throws Exception {
+    TableDesc tableDesc = testingCluster.getMaster().getCatalog().getTableDesc(getCurrentDatabase(), tableName);
+    if (tableDesc == null) {
+      return null;
+    }
+
+    Path path = new Path(tableDesc.getUri());
+    return getTableFileContents(path);
+  }
+
+  public List<Path> listTableFiles(String tableName) throws Exception {
+    TableDesc tableDesc = testingCluster.getMaster().getCatalog().getTableDesc(getCurrentDatabase(), tableName);
+    if (tableDesc == null) {
+      return null;
+    }
+
+    Path path = new Path(tableDesc.getUri());
+    FileSystem fs = path.getFileSystem(conf);
+
+    return listFiles(fs, path);
+  }
+
+  private List<Path> listFiles(FileSystem fs, Path path) throws Exception {
+    List<Path> result = new ArrayList<Path>();
+    FileStatus[] files = fs.listStatus(path);
+    if (files == null || files.length == 0) {
+      return result;
+    }
+
+    for (FileStatus eachFile: files) {
+      if (eachFile.isDirectory()) {
+        result.addAll(listFiles(fs, eachFile.getPath()));
+      } else {
+        result.add(eachFile.getPath());
+      }
+    }
+    return result;
+  }
+}


[39/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterMergeJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterMergeJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterMergeJoinExec.java
new file mode 100644
index 0000000..ec2aa04
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestFullOuterMergeJoinExec.java
@@ -0,0 +1,537 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.catalog.*;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.Appender;
+import org.apache.tajo.storage.FileTablespace;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.storage.VTuple;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.*;
+
+public class TestFullOuterMergeJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestFullOuterMergeJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+  private QueryContext defaultContext;
+
+  private TableDesc dep3;
+  private TableDesc dep4;
+  private TableDesc job3;
+  private TableDesc emp3;
+  private TableDesc phone3;
+
+  private final String DEP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep3");
+  private final String DEP4_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep4");
+  private final String JOB3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "job3");
+  private final String EMP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "emp3");
+  private final String PHONE3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "phone3");
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(TajoConstants.DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+
+    conf = util.getConfiguration();
+
+    //----------------- dep3 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    Schema dep3Schema = new Schema();
+    dep3Schema.addColumn("dep_id", Type.INT4);
+    dep3Schema.addColumn("dep_name", Type.TEXT);
+    dep3Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep3Path = new Path(testDir, "dep3.csv");
+    Appender appender1 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(dep3Meta, dep3Schema, dep3Path);
+    appender1.init();
+    VTuple tuple = new VTuple(dep3Schema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createText("dept_" + i),
+          DatumFactory.createInt4(1000 + i) });
+      appender1.addTuple(tuple);
+    }
+
+    appender1.flush();
+    appender1.close();
+    dep3 = CatalogUtil.newTableDesc(DEP3_NAME, dep3Schema, dep3Meta, dep3Path);
+    catalog.createTable(dep3);
+
+
+    //----------------- dep4 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    // 10     | dep_10    | 1010
+    Schema dep4Schema = new Schema();
+    dep4Schema.addColumn("dep_id", Type.INT4);
+    dep4Schema.addColumn("dep_name", Type.TEXT);
+    dep4Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep4Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep4Path = new Path(testDir, "dep4.csv");
+    Appender appender4 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(dep4Meta, dep4Schema, dep4Path);
+    appender4.init();
+    VTuple tuple4 = new VTuple(dep4Schema.size());
+    for (int i = 0; i < 11; i++) {
+      tuple4.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createText("dept_" + i),
+          DatumFactory.createInt4(1000 + i) });
+      appender4.addTuple(tuple4);
+    }
+
+    appender4.flush();
+    appender4.close();
+    dep4 = CatalogUtil.newTableDesc(DEP4_NAME, dep4Schema, dep4Meta, dep4Path);
+    catalog.createTable(dep4);
+
+
+
+    //----------------- job3 ------------------------------
+    //  job_id  | job_title
+    // ----------------------
+    //   101    |  job_101
+    //   102    |  job_102
+    //   103    |  job_103
+
+    Schema job3Schema = new Schema();
+    job3Schema.addColumn("job_id", Type.INT4);
+    job3Schema.addColumn("job_title", Type.TEXT);
+
+
+    TableMeta job3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path job3Path = new Path(testDir, "job3.csv");
+    Appender appender2 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(job3Meta, job3Schema, job3Path);
+    appender2.init();
+    VTuple tuple2 = new VTuple(job3Schema.size());
+    for (int i = 1; i < 4; i++) {
+      int x = 100 + i;
+      tuple2.put(new Datum[] { DatumFactory.createInt4(100 + i),
+          DatumFactory.createText("job_" + x) });
+      appender2.addTuple(tuple2);
+    }
+
+    appender2.flush();
+    appender2.close();
+    job3 = CatalogUtil.newTableDesc(JOB3_NAME, job3Schema, job3Meta, job3Path);
+    catalog.createTable(job3);
+
+
+
+    //---------------------emp3 --------------------
+    // emp_id  | first_name | last_name | dep_id | salary | job_id
+    // ------------------------------------------------------------
+    //  11     |  fn_11     |  ln_11    |  1     | 123    | 101
+    //  13     |  fn_13     |  ln_13    |  3     | 369    | 103
+    //  15     |  fn_15     |  ln_15    |  5     | 615    | null
+    //  17     |  fn_17     |  ln_17    |  7     | 861    | null
+    //  19     |  fn_19     |  ln_19    |  9     | 1107   | null
+    //  21     |  fn_21     |  ln_21    |  1     | 123    | 101
+    //  23     |  fn_23     |  ln_23    |  3     | 369    | 103
+
+    Schema emp3Schema = new Schema();
+    emp3Schema.addColumn("emp_id", Type.INT4);
+    emp3Schema.addColumn("first_name", Type.TEXT);
+    emp3Schema.addColumn("last_name", Type.TEXT);
+    emp3Schema.addColumn("dep_id", Type.INT4);
+    emp3Schema.addColumn("salary", Type.FLOAT4);
+    emp3Schema.addColumn("job_id", Type.INT4);
+
+
+    TableMeta emp3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path emp3Path = new Path(testDir, "emp3.csv");
+    Appender appender3 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(emp3Meta, emp3Schema, emp3Path);
+    appender3.init();
+    VTuple tuple3 = new VTuple(emp3Schema.size());
+
+    for (int i = 1; i < 4; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+
+      int y = 20 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(20 + i),
+          DatumFactory.createText("firstname_" + y),
+          DatumFactory.createText("lastname_" + y),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+    }
+
+    for (int i = 5; i < 10; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createNullDatum() });
+      appender3.addTuple(tuple3);
+    }
+
+    appender3.flush();
+    appender3.close();
+    emp3 = CatalogUtil.newTableDesc(EMP3_NAME, emp3Schema, emp3Meta, emp3Path);
+    catalog.createTable(emp3);
+
+    //---------------------phone3 --------------------
+    // emp_id  | phone_number
+    // -----------------------------------------------
+    // this table is empty, no rows
+
+    Schema phone3Schema = new Schema();
+    phone3Schema.addColumn("emp_id", Type.INT4);
+    phone3Schema.addColumn("phone_number", Type.TEXT);
+
+
+    TableMeta phone3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path phone3Path = new Path(testDir, "phone3.csv");
+    Appender appender5 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(phone3Meta, phone3Schema, phone3Path);
+    appender5.init();
+    appender5.flush();
+    appender5.close();
+    phone3 = CatalogUtil.newTableDesc(PHONE3_NAME, phone3Schema, phone3Meta, phone3Path);
+    catalog.createTable(phone3);
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      // [0] no nulls
+      "select dep3.dep_id, dep_name, emp_id, salary from emp3 full outer join dep3 on dep3.dep_id = emp3.dep_id",
+      // [1] nulls on the left operand
+      "select job3.job_id, job_title, emp_id, salary from emp3 full outer join job3 on job3.job_id=emp3.job_id",
+      // [2] nulls on the right side
+      "select job3.job_id, job_title, emp_id, salary from job3 full outer join emp3 on job3.job_id=emp3.job_id",
+      // [3] no nulls, right continues after left
+      "select dep4.dep_id, dep_name, emp_id, salary from emp3 full outer join dep4 on dep4.dep_id = emp3.dep_id",
+      // [4] one operand is empty
+      "select emp3.emp_id, first_name, phone_number from emp3 full outer join phone3 on emp3.emp_id = phone3.emp_id",
+      // [5] one operand is empty
+      "select emp3.emp_id, first_name, phone_number from phone3 full outer join emp3 on emp3.emp_id = phone3.emp_id",
+  };
+
+  @Test
+  public final void testFullOuterMergeJoin0() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] dep3Frags =
+        FileTablespace.splitNG(conf, DEP3_NAME, dep3.getMeta(), new Path(dep3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, dep3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testFullOuterMergeJoin0");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof MergeFullOuterJoinExec);
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(12, count);
+  }
+
+
+  @Test
+  public final void testFullOuterMergeJoin1() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] job3Frags =
+        FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testFullOuterMergeJoin1");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof MergeFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(8, count);
+  }
+
+  @Test
+  public final void testFullOuterMergeJoin2() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[2]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] job3Frags =
+        FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testFullOuterMergeJoin2");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof MergeFullOuterJoinExec);
+
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(8, count);
+  }
+
+  @Test
+  public final void testFullOuterMergeJoin3() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[3]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] dep4Frags =
+        FileTablespace.splitNG(conf, DEP4_NAME, dep4.getMeta(), new Path(dep4.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, dep4Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testFullOuterMergeJoin3");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+
+    // if it chose the hash join WITH REVERSED ORDER, convert to merge join exec
+    assertTrue(proj.getChild() instanceof MergeFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(13, count);
+  }
+
+
+  @Test
+  public final void testFullOuterMergeJoin4() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[4]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] phone3Frags =
+        FileTablespace.splitNG(conf, PHONE3_NAME, phone3.getMeta(), new Path(phone3.getUri()),
+            Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(emp3Frags, phone3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testFullOuterMergeJoin4");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof MergeFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(7, count);
+  }
+
+
+  @Test
+  public final void testFullOuterMergeJoin5() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[5]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] emp3Frags =
+        FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] phone3Frags =
+        FileTablespace.splitNG(conf, PHONE3_NAME, phone3.getMeta(), new Path(phone3.getUri()),
+            Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(phone3Frags,emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testFullOuterMergeJoin5");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof MergeFullOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    assertNull(exec.next());
+    exec.close();
+    assertEquals(7, count);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashAntiJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashAntiJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashAntiJoinExec.java
new file mode 100644
index 0000000..b9ba2de
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashAntiJoinExec.java
@@ -0,0 +1,215 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+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.assertTrue;
+
+public class TestHashAntiJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestHashJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private LogicalOptimizer optimizer;
+  private Path testDir;
+  private QueryContext queryContext;
+
+  private TableDesc employee;
+  private TableDesc people;
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema employeeSchema = new Schema();
+    employeeSchema.addColumn("managerid", Type.INT4);
+    employeeSchema.addColumn("empid", Type.INT4);
+    employeeSchema.addColumn("memid", Type.INT4);
+    employeeSchema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, employeeSchema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(employeeSchema.size());
+
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), // empid [0-9]
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+    employee = CatalogUtil.newTableDesc("default.employee", employeeSchema, employeeMeta, employeePath);
+    catalog.createTable(employee);
+
+    Schema peopleSchema = new Schema();
+    peopleSchema.addColumn("empid", Type.INT4);
+    peopleSchema.addColumn("fk_memid", Type.INT4);
+    peopleSchema.addColumn("name", Type.TEXT);
+    peopleSchema.addColumn("age", Type.INT4);
+    TableMeta peopleMeta = CatalogUtil.newTableMeta("TEXT");
+    Path peoplePath = new Path(testDir, "people.csv");
+    appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(peopleMeta, peopleSchema, peoplePath);
+    appender.init();
+    tuple = new VTuple(peopleSchema.size());
+    for (int i = 1; i < 10; i += 2) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(i), // empid [1, 3, 5, 7, 9]
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(30 + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+
+    queryContext = new QueryContext(conf);
+    people = CatalogUtil.newTableDesc("default.people", peopleSchema, peopleMeta, peoplePath);
+    catalog.createTable(people);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(conf, catalog);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+
+  // relation descriptions
+  // employee (managerid, empid, memid, deptname)
+  // people (empid, fk_memid, name, age)
+
+  String[] QUERIES = {
+      "select managerId, e.empId, deptName, e.memId from employee as e, people as p where e.empId = p.empId"
+  };
+
+  @Test
+  public final void testHashAntiJoin() throws IOException, TajoException {
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testHashAntiJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(queryContext,
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    // replace an equal join with an hash anti join.
+    if (exec instanceof MergeJoinExec) {
+      MergeJoinExec join = (MergeJoinExec) exec;
+      ExternalSortExec sortLeftChild = (ExternalSortExec) join.getLeftChild();
+      ExternalSortExec sortRightChild = (ExternalSortExec) join.getRightChild();
+      SeqScanExec scanLeftChild = sortLeftChild.getChild();
+      SeqScanExec scanRightChild = sortRightChild.getChild();
+
+      // 'people' should be outer table. So, the below code guarantees that people becomes the outer table.
+      if (scanLeftChild.getTableName().equals("default.people")) {
+        exec = new HashLeftAntiJoinExec(ctx, join.getPlan(), scanRightChild, scanLeftChild);
+      } else {
+        exec = new HashLeftAntiJoinExec(ctx, join.getPlan(), scanLeftChild, scanRightChild);
+      }
+    } else if (exec instanceof HashJoinExec) {
+      HashJoinExec join = (HashJoinExec) exec;
+      SeqScanExec scanLeftChild = (SeqScanExec) join.getLeftChild();
+
+      // 'people' should be outer table. So, the below code guarantees that people becomes the outer table.
+      if (scanLeftChild.getTableName().equals("default.people")) {
+        exec = new HashLeftAntiJoinExec(ctx, join.getPlan(), join.getRightChild(), join.getLeftChild());
+      } else {
+        exec = new HashLeftAntiJoinExec(ctx, join.getPlan(), join.getLeftChild(), join.getRightChild());
+      }
+    }
+
+    Tuple tuple;
+    int count = 0;
+    int i = 0;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      count++;
+      assertTrue(i == tuple.getInt4(0));
+      assertTrue(i == tuple.getInt4(1)); // expected empid [0, 2, 4, 6, 8]
+      assertTrue(("dept_" + i).equals(tuple.getText(2)));
+      assertTrue(10 + i == tuple.getInt4(3));
+
+      i += 2;
+    }
+    exec.close();
+    assertEquals(5 , count); // the expected result : [0, 2, 4, 6, 8]
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashJoinExec.java
new file mode 100644
index 0000000..4550db9
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashJoinExec.java
@@ -0,0 +1,281 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.*;
+
+public class TestHashJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestHashJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+  private QueryContext defaultContext;
+
+  private TableDesc employee;
+  private TableDesc people;
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(TajoConstants.DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema employeeSchema = new Schema();
+    employeeSchema.addColumn("managerid", Type.INT4);
+    employeeSchema.addColumn("empid", Type.INT4);
+    employeeSchema.addColumn("memid", Type.INT4);
+    employeeSchema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, employeeSchema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(employeeSchema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+    employee = CatalogUtil.newTableDesc("default.employee", employeeSchema, employeeMeta, employeePath);
+    catalog.createTable(employee);
+
+    Schema peopleSchema = new Schema();
+    peopleSchema.addColumn("empid", Type.INT4);
+    peopleSchema.addColumn("fk_memid", Type.INT4);
+    peopleSchema.addColumn("name", Type.TEXT);
+    peopleSchema.addColumn("age", Type.INT4);
+    TableMeta peopleMeta = CatalogUtil.newTableMeta("TEXT");
+    Path peoplePath = new Path(testDir, "people.csv");
+    appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(peopleMeta, peopleSchema, peoplePath);
+    appender.init();
+    tuple = new VTuple(peopleSchema.size());
+    for (int i = 1; i < 10; i += 2) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(30 + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+
+    people = CatalogUtil.newTableDesc("default.people", peopleSchema, peopleMeta, peoplePath);
+    catalog.createTable(people);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      "select managerId, e.empId, deptName, e.memId from employee as e inner join " +
+          "people as p on e.empId = p.empId and e.memId = p.fk_memId"
+  };
+
+  @Test
+  public final void testHashInnerJoin() throws IOException, TajoException {
+
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testHashInnerJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashJoinExec);
+
+    Tuple tuple;
+    int count = 0;
+    int i = 1;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      count++;
+      assertTrue(i == tuple.getInt4(0));
+      assertTrue(i == tuple.getInt4(1));
+      assertTrue(("dept_" + i).equals(tuple.getText(2)));
+      assertTrue(10 + i == tuple.getInt4(3));
+
+      i += 2;
+    }
+    exec.close();
+    assertEquals(10 / 2, count);
+  }
+
+  @Test
+  public final void testCheckIfInMemoryInnerJoinIsPossible() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testHashInnerJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    ctx.getQueryContext().setLong(SessionVars.HASH_JOIN_SIZE_LIMIT.keyname(), 100l);
+    PhysicalPlannerImpl phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashJoinExec);
+    HashJoinExec joinExec = proj.getChild();
+
+    assertCheckInnerJoinRelatedFunctions(ctx, phyPlanner, joinNode, joinExec);
+  }
+
+  /**
+   * It checks inner-join related functions. It will return TRUE if left relations is smaller than right relations.
+   *
+   * The below unit tests will work according to which side is smaller. In this unit tests, we use two tables: p and e.
+   * The table p is 75 bytes, and the table e is 140 bytes. Since we cannot expect that which side is smaller,
+   * we use some boolean variable <code>leftSmaller</code> to indicate which side is small.
+   */
+  private static boolean assertCheckInnerJoinRelatedFunctions(TaskAttemptContext ctx,
+                                                       PhysicalPlannerImpl phyPlanner,
+                                                       JoinNode joinNode, BinaryPhysicalExec joinExec) throws
+      IOException {
+
+    String [] left = PlannerUtil.getRelationLineage(joinNode.getLeftChild());
+    String [] right = PlannerUtil.getRelationLineage(joinNode.getRightChild());
+
+    boolean leftSmaller;
+    if (left[0].equals("default.p")) {
+      leftSmaller = true;
+    } else {
+      leftSmaller = false;
+    }
+
+    long leftSize = phyPlanner.estimateSizeRecursive(ctx, left);
+    long rightSize = phyPlanner.estimateSizeRecursive(ctx, right);
+
+    // The table p is 75 bytes, and the table e is 140 bytes.
+    if (leftSmaller) { // if left one is smaller
+      assertEquals(75, leftSize);
+      assertEquals(140, rightSize);
+    } else { // if right one is smaller
+      assertEquals(140, leftSize);
+      assertEquals(75, rightSize);
+    }
+
+    if (leftSmaller) {
+      PhysicalExec [] ordered = phyPlanner.switchJoinSidesIfNecessary(ctx, joinNode, joinExec.getLeftChild(),
+          joinExec.getRightChild());
+      assertEquals(ordered[0], joinExec.getLeftChild());
+      assertEquals(ordered[1], joinExec.getRightChild());
+
+      assertEquals("default.p", left[0]);
+      assertEquals("default.e", right[0]);
+    } else {
+      PhysicalExec [] ordered = phyPlanner.switchJoinSidesIfNecessary(ctx, joinNode, joinExec.getLeftChild(),
+          joinExec.getRightChild());
+      assertEquals(ordered[1], joinExec.getLeftChild());
+      assertEquals(ordered[0], joinExec.getRightChild());
+
+      assertEquals("default.e", left[0]);
+      assertEquals("default.p", right[0]);
+    }
+
+    if (leftSmaller) {
+      assertTrue(phyPlanner.checkIfInMemoryInnerJoinIsPossible(ctx, joinNode.getLeftChild(), true));
+      assertFalse(phyPlanner.checkIfInMemoryInnerJoinIsPossible(ctx, joinNode.getRightChild(), false));
+    } else {
+      assertFalse(phyPlanner.checkIfInMemoryInnerJoinIsPossible(ctx, joinNode.getLeftChild(), true));
+      assertTrue(phyPlanner.checkIfInMemoryInnerJoinIsPossible(ctx, joinNode.getRightChild(), false));
+    }
+
+    return leftSmaller;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashPartitioner.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashPartitioner.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashPartitioner.java
new file mode 100644
index 0000000..1146e85
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashPartitioner.java
@@ -0,0 +1,117 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestHashPartitioner {
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public final void testGetPartition() {   
+    VTuple tuple1 = new VTuple(3);
+    tuple1.put(new Datum[] {
+        DatumFactory.createInt4(1),
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(3)
+    });
+    VTuple tuple2 = new VTuple(3);
+    tuple2.put(new Datum[] {
+        DatumFactory.createInt4(1),
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(4)
+    });
+    VTuple tuple3 = new VTuple(3);
+    tuple3.put(new Datum[] {
+        DatumFactory.createInt4(1),
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(5)
+    });
+    VTuple tuple4 = new VTuple(3);
+    tuple4.put(new Datum[] {
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(3)
+    });
+    VTuple tuple5 = new VTuple(3);
+    tuple5.put(new Datum[] {
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(2),
+        DatumFactory.createInt4(4)
+    });
+    
+    int [] partKeys = {0,1};
+    Partitioner p = new HashPartitioner(partKeys, 2);
+    
+    int part1 = p.getPartition(tuple1);
+    assertEquals(part1, p.getPartition(tuple2));
+    assertEquals(part1, p.getPartition(tuple3));
+    
+    int part2 = p.getPartition(tuple4);
+    assertEquals(part2, p.getPartition(tuple5));    
+  }
+
+  @Test
+  public final void testGetPartition2() {
+    // https://issues.apache.org/jira/browse/TAJO-976
+    Random rand = new Random();
+    String[][] data = new String[1000][];
+
+    for (int i = 0; i < 1000; i++) {
+      data[i] = new String[]{ String.valueOf(rand.nextInt(1000)), String.valueOf(rand.nextInt(1000)), String.valueOf(rand.nextInt(1000))};
+    }
+
+    int[] testNumPartitions = new int[]{31, 62, 124, 32, 63, 125};
+    for (int index = 0; index <  testNumPartitions.length; index++) {
+      Partitioner p = new HashPartitioner(new int[]{0, 1, 2}, testNumPartitions[index]);
+
+      Set<Integer> ids = new TreeSet<Integer>();
+      for (int i = 0; i < data.length; i++) {
+        Tuple tuple = new VTuple(
+            new Datum[]{new TextDatum(data[i][0]), new TextDatum(data[i][1]), new TextDatum(data[i][2])});
+
+        ids.add(p.getPartition(tuple));
+      }
+
+      // The number of partitions isn't exactly matched.
+      assertTrue(ids.size() + 5 >= testNumPartitions[index]);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashSemiJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashSemiJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashSemiJoinExec.java
new file mode 100644
index 0000000..0d996de
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestHashSemiJoinExec.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.engine.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+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.assertTrue;
+
+public class TestHashSemiJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestHashJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private LogicalOptimizer optimizer;
+  private Path testDir;
+  private QueryContext queryContext;
+
+  private TableDesc employee;
+  private TableDesc people;
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema employeeSchema = new Schema();
+    employeeSchema.addColumn("managerid", Type.INT4);
+    employeeSchema.addColumn("empid", Type.INT4);
+    employeeSchema.addColumn("memid", Type.INT4);
+    employeeSchema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, employeeSchema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(employeeSchema.size());
+
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), // empid [0-9]
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+    employee = CatalogUtil.newTableDesc("default.employee", employeeSchema, employeeMeta, employeePath);
+    catalog.createTable(employee);
+
+    Schema peopleSchema = new Schema();
+    peopleSchema.addColumn("empid", Type.INT4);
+    peopleSchema.addColumn("fk_memid", Type.INT4);
+    peopleSchema.addColumn("name", Type.TEXT);
+    peopleSchema.addColumn("age", Type.INT4);
+    TableMeta peopleMeta = CatalogUtil.newTableMeta("TEXT");
+    Path peoplePath = new Path(testDir, "people.csv");
+    appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(peopleMeta, peopleSchema, peoplePath);
+    appender.init();
+    tuple = new VTuple(peopleSchema.size());
+    // make 27 tuples
+    for (int i = 1; i < 10; i += 2) {
+      // make three duplicated tuples for each tuples
+      for (int j = 0; j < 3; j++) {
+        tuple.put(new Datum[] {
+            DatumFactory.createInt4(i), // empid [1, 3, 5, 7, 9]
+            DatumFactory.createInt4(10 + i),
+            DatumFactory.createText("name_" + i),
+            DatumFactory.createInt4(30 + i) });
+        appender.addTuple(tuple);
+      }
+    }
+
+    appender.flush();
+    appender.close();
+
+    queryContext = new QueryContext(conf);
+    people = CatalogUtil.newTableDesc("default.people", peopleSchema, peopleMeta, peoplePath);
+    catalog.createTable(people);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(conf, catalog);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+
+  // relation descriptions
+  // employee (managerid, empid, memid, deptname)
+  // people (empid, fk_memid, name, age)
+
+  String[] QUERIES = {
+      "select managerId, e.empId, deptName, e.memId from employee as e, people as p where e.empId = p.empId"
+  };
+
+  @Test
+  public final void testHashSemiJoin() throws IOException, TajoException {
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testHashSemiJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(queryContext,
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    // replace an equal join with an hash anti join.
+    if (exec instanceof MergeJoinExec) {
+      MergeJoinExec join = (MergeJoinExec) exec;
+      ExternalSortExec sortLeftChild = (ExternalSortExec) join.getLeftChild();
+      ExternalSortExec sortRightChild = (ExternalSortExec) join.getRightChild();
+      SeqScanExec scanLeftChild = sortLeftChild.getChild();
+      SeqScanExec scanRightChild = sortRightChild.getChild();
+
+      // 'people' should be outer table. So, the below code guarantees that people becomes the outer table.
+      if (scanLeftChild.getTableName().equals("default.people")) {
+        exec = new HashLeftSemiJoinExec(ctx, join.getPlan(), scanRightChild, scanLeftChild);
+      } else {
+        exec = new HashLeftSemiJoinExec(ctx, join.getPlan(), scanLeftChild, scanRightChild);
+      }
+    } else if (exec instanceof HashJoinExec) {
+      HashJoinExec join = (HashJoinExec) exec;
+      SeqScanExec scanLeftChild = (SeqScanExec) join.getLeftChild();
+
+      // 'people' should be outer table. So, the below code guarantees that people becomes the outer table.
+      if (scanLeftChild.getTableName().equals("default.people")) {
+        exec = new HashLeftSemiJoinExec(ctx, join.getPlan(), join.getRightChild(), join.getLeftChild());
+      } else {
+        exec = new HashLeftSemiJoinExec(ctx, join.getPlan(), join.getLeftChild(), join.getRightChild());
+      }
+    }
+
+    Tuple tuple;
+    int count = 0;
+    int i = 1;
+    exec.init();
+    // expect result without duplicated tuples.
+    while ((tuple = exec.next()) != null) {
+      count++;
+      assertTrue(i == tuple.getInt4(0));
+      assertTrue(i == tuple.getInt4(1));
+      assertTrue(("dept_" + i).equals(tuple.getText(2)));
+      assertTrue(10 + i == tuple.getInt4(3));
+
+      i += 2;
+    }
+    exec.close();
+    assertEquals(5 , count); // the expected result: [1, 3, 5, 7, 9]
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestLeftOuterHashJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestLeftOuterHashJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestLeftOuterHashJoinExec.java
new file mode 100644
index 0000000..76e38e4
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestLeftOuterHashJoinExec.java
@@ -0,0 +1,440 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestLeftOuterHashJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestLeftOuterHashJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+  private QueryContext defaultContext;
+
+  private TableDesc dep3;
+  private TableDesc job3;
+  private TableDesc emp3;
+  private TableDesc phone3;
+
+  private final String DEP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep3");
+  private final String JOB3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "job3");
+  private final String EMP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "emp3");
+  private final String PHONE3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "phone3");
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    //----------------- dep3 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    Schema dep3Schema = new Schema();
+    dep3Schema.addColumn("dep_id", Type.INT4);
+    dep3Schema.addColumn("dep_name", Type.TEXT);
+    dep3Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep3Path = new Path(testDir, "dep3.csv");
+    Appender appender1 = ((FileTablespace) TablespaceManager.getLocalFs()).getAppender(dep3Meta, dep3Schema, dep3Path);
+    appender1.init();
+    VTuple tuple = new VTuple(dep3Schema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+                    DatumFactory.createText("dept_" + i),
+                    DatumFactory.createInt4(1000 + i) });
+      appender1.addTuple(tuple);
+    }
+
+    appender1.flush();
+    appender1.close();
+    dep3 = CatalogUtil.newTableDesc(DEP3_NAME, dep3Schema, dep3Meta, dep3Path);
+    catalog.createTable(dep3);
+
+    //----------------- job3 ------------------------------
+    //  job_id  | job_title
+    // ----------------------
+    //   101    |  job_101
+    //   102    |  job_102
+    //   103    |  job_103
+
+    Schema job3Schema = new Schema();
+    job3Schema.addColumn("job_id", Type.INT4);
+    job3Schema.addColumn("job_title", Type.TEXT);
+
+
+    TableMeta job3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path job3Path = new Path(testDir, "job3.csv");
+    Appender appender2 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(job3Meta, job3Schema, job3Path);
+    appender2.init();
+    VTuple tuple2 = new VTuple(job3Schema.size());
+    for (int i = 1; i < 4; i++) {
+      int x = 100 + i;
+      tuple2.put(new Datum[] { DatumFactory.createInt4(100 + i),
+                    DatumFactory.createText("job_" + x) });
+      appender2.addTuple(tuple2);
+    }
+
+    appender2.flush();
+    appender2.close();
+    job3 = CatalogUtil.newTableDesc(JOB3_NAME, job3Schema, job3Meta, job3Path);
+    catalog.createTable(job3);
+
+
+
+    //---------------------emp3 --------------------
+    // emp_id  | first_name | last_name | dep_id | salary | job_id
+    // ------------------------------------------------------------
+    //  11     |  fn_11     |  ln_11    |  1     | 123    | 101
+    //  13     |  fn_13     |  ln_13    |  3     | 369    | 103
+    //  15     |  fn_15     |  ln_15    |  5     | 615    | null
+    //  17     |  fn_17     |  ln_17    |  7     | 861    | null
+    //  19     |  fn_19     |  ln_19    |  9     | 1107   | null
+    //  21     |  fn_21     |  ln_21    |  1     | 123    | 101
+    //  23     |  fn_23     |  ln_23    |  3     | 369    | 103
+
+    Schema emp3Schema = new Schema();
+    emp3Schema.addColumn("emp_id", Type.INT4);
+    emp3Schema.addColumn("first_name", Type.TEXT);
+    emp3Schema.addColumn("last_name", Type.TEXT);
+    emp3Schema.addColumn("dep_id", Type.INT4);
+    emp3Schema.addColumn("salary", Type.FLOAT4);
+    emp3Schema.addColumn("job_id", Type.INT4);
+
+
+    TableMeta emp3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path emp3Path = new Path(testDir, "emp3.csv");
+    Appender appender3 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(emp3Meta, emp3Schema, emp3Path);
+    appender3.init();
+    VTuple tuple3 = new VTuple(emp3Schema.size());
+
+    for (int i = 1; i < 4; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+
+      int y = 20 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(20 + i),
+          DatumFactory.createText("firstname_" + y),
+          DatumFactory.createText("lastname_" + y),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+    }
+
+    for (int i = 5; i < 10; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createNullDatum() });
+      appender3.addTuple(tuple3);
+    }
+
+    appender3.flush();
+    appender3.close();
+    emp3 = CatalogUtil.newTableDesc(EMP3_NAME, emp3Schema, emp3Meta, emp3Path);
+    catalog.createTable(emp3);
+
+    //---------------------phone3 --------------------
+    // emp_id  | phone_number
+    // -----------------------------------------------
+    // this table is empty, no rows
+
+    Schema phone3Schema = new Schema();
+    phone3Schema.addColumn("emp_id", Type.INT4);
+    phone3Schema.addColumn("phone_number", Type.TEXT);
+
+
+    TableMeta phone3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path phone3Path = new Path(testDir, "phone3.csv");
+    Appender appender5 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(phone3Meta, phone3Schema, phone3Path);
+    appender5.init();
+    
+    appender5.flush();
+    appender5.close();
+    phone3 = CatalogUtil.newTableDesc(PHONE3_NAME, phone3Schema, phone3Meta, phone3Path);
+    catalog.createTable(phone3);
+
+
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      // [0] no nulls
+      "select dep3.dep_id, dep_name, emp_id, salary from dep3 left outer join emp3 on dep3.dep_id = emp3.dep_id",
+      // [1] nulls on the right operand
+      "select job3.job_id, job_title, emp_id, salary from job3 left outer join emp3 on job3.job_id=emp3.job_id",
+      // [2] nulls on the left side
+      "select job3.job_id, job_title, emp_id, salary from emp3 left outer join job3 on job3.job_id=emp3.job_id",
+      // [3] one operand is empty
+      "select emp3.emp_id, first_name, phone_number from emp3 left outer join phone3 on emp3.emp_id = phone3.emp_id",
+      // [4] one operand is empty
+      "select phone_number, emp3.emp_id, first_name from phone3 left outer join emp3 on emp3.emp_id = phone3.emp_id"
+  };
+
+  @Test
+  public final void testLeftOuterHashJoinExec0() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+    JoinNode joinNode = PlannerUtil.findTopNode(plan, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.IN_MEMORY_HASH_JOIN);
+
+    FileFragment[] dep3Frags = FileTablespace.splitNG(conf, DEP3_NAME, dep3.getMeta(),
+        new Path(dep3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(),
+        new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(dep3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestLeftOuterHashJoinExec0");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof HashLeftOuterJoinExec);
+
+    int count = 0;
+    exec.init();
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    exec.close();
+    assertEquals(12, count);
+  }
+
+
+  @Test
+  public final void testLeftOuter_HashJoinExec1() throws IOException, TajoException {
+    FileFragment[] job3Frags = FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(),
+        new Path(job3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(),
+        new Path(emp3.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestLeftOuter_HashJoinExec1");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    Tuple tuple;
+    int count = 0;
+    int i = 1;
+    exec.init();
+
+    while ((tuple = exec.next()) != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    exec.close();
+    assertEquals(5, count);
+  }
+
+    @Test
+  public final void testLeftOuter_HashJoinExec2() throws IOException, TajoException {
+    
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(),
+        new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] job3Frags = FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(),
+        new Path(job3.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(emp3Frags, job3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + 
+        "/TestLeftOuter_HashJoinExec2");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[2]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    Tuple tuple;
+    int count = 0;
+    int i = 1;
+    exec.init();
+
+    while ((tuple = exec.next()) != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    exec.close();
+    assertEquals(7, count);
+  }
+
+
+   @Test
+  public final void testLeftOuter_HashJoinExec3() throws IOException, TajoException {
+    
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(),
+        new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] phone3Frags = FileTablespace.splitNG(conf, PHONE3_NAME, phone3.getMeta(),
+        new Path(phone3.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(emp3Frags, phone3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestLeftOuter_HashJoinExec3");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[3]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    Tuple tuple;
+    int count = 0;
+    int i = 1;
+    exec.init();
+
+    while ((tuple = exec.next()) != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    exec.close();
+    assertEquals(7, count);
+  }
+
+  
+   @Test
+  public final void testLeftOuter_HashJoinExec4() throws IOException, TajoException {
+    
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, "default.emp3", emp3.getMeta(),
+        new Path(emp3.getUri()), Integer.MAX_VALUE);
+    FileFragment[] phone3Frags = FileTablespace.splitNG(conf, "default.phone3", phone3.getMeta(),
+        new Path(phone3.getUri()), Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(phone3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestLeftOuter_HashJoinExec4");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[4]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    int count = 0;
+    exec.init();
+
+    while (exec.next() != null) {
+      //TODO check contents
+      count = count + 1;
+    }
+    exec.close();
+    assertEquals(0, count);
+  }
+  
+
+
+}
+ //--camelia

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestMergeJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestMergeJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestMergeJoinExec.java
new file mode 100644
index 0000000..2c26cc2
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestMergeJoinExec.java
@@ -0,0 +1,197 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.catalog.*;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.JoinNode;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.JoinEnforce.JoinAlgorithm;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestMergeJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestMergeJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+
+  private TableDesc employee;
+  private TableDesc people;
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    Path testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(TajoConstants.DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema employeeSchema = new Schema();
+    employeeSchema.addColumn("managerid", Type.INT4);
+    employeeSchema.addColumn("empid", Type.INT4);
+    employeeSchema.addColumn("memid", Type.INT4);
+    employeeSchema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, employeeSchema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(employeeSchema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+    for (int i = 11; i < 20; i+=2) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i), DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+    employee = CatalogUtil.newTableDesc("default.employee", employeeSchema, employeeMeta, employeePath);
+    catalog.createTable(employee);
+
+    Schema peopleSchema = new Schema();
+    peopleSchema.addColumn("empid", Type.INT4);
+    peopleSchema.addColumn("fk_memid", Type.INT4);
+    peopleSchema.addColumn("name", Type.TEXT);
+    peopleSchema.addColumn("age", Type.INT4);
+    TableMeta peopleMeta = CatalogUtil.newTableMeta("TEXT");
+    Path peoplePath = new Path(testDir, "people.csv");
+    appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(peopleMeta, peopleSchema, peoplePath);
+    appender.init();
+    tuple = new VTuple(peopleSchema.size());
+    for (int i = 1; i < 10; i += 2) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(30 + i) });
+      appender.addTuple(tuple);
+    }
+    for (int i = 10; i < 20; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(30 + i) });
+      appender.addTuple(tuple);
+    }
+
+    appender.flush();
+    appender.close();
+
+    people = CatalogUtil.newTableDesc("default.people", peopleSchema, peopleMeta, peoplePath);
+    catalog.createTable(people);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      "select managerId, e.empId, deptName, e.memId from employee as e inner join " +
+          "people as p on e.empId = p.empId and e.memId = p.fk_memId"
+  };
+
+  @Test
+  public final void testMergeInnerJoin() throws IOException, TajoException {
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    LogicalNode root = plan.getRootBlock().getRoot();
+
+    JoinNode joinNode = PlannerUtil.findTopNode(root, NodeType.JOIN);
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceJoinAlgorithm(joinNode.getPID(), JoinAlgorithm.MERGE_JOIN);
+
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(), new Path(employee.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(), new Path(people.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testMergeInnerJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, root);
+    ProjectionExec proj = (ProjectionExec) exec;
+    assertTrue(proj.getChild() instanceof MergeJoinExec);
+
+    Tuple tuple;
+    int count = 0;
+    int i = 1;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      count++;
+      assertTrue(i == tuple.getInt4(0));
+      assertTrue(i == tuple.getInt4(1));
+      assertTrue(("dept_" + i).equals(tuple.getText(2)));
+      assertTrue((10 + i) == tuple.getInt4(3));
+
+      i += 2;
+    }
+    exec.close();
+    assertEquals(10, count); // expected 10 * 5
+  }
+}


[26/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation7.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation7.sql
new file mode 100644
index 0000000..75b3eea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation7.sql
@@ -0,0 +1,6 @@
+select
+    count(*),
+    count(distinct c_nationkey),
+    count(distinct c_mktsegment)
+from
+    customer
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation8.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation8.sql
new file mode 100644
index 0000000..0553d06
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation8.sql
@@ -0,0 +1,9 @@
+select
+  sum(distinct l_orderkey),
+  l_linenumber, l_returnflag, l_linestatus, l_shipdate,
+  count(distinct l_partkey),
+  sum(l_orderkey)
+from
+  lineitem
+group by
+  l_linenumber, l_returnflag, l_linestatus, l_shipdate;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase3.sql
new file mode 100644
index 0000000..925cadd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase3.sql
@@ -0,0 +1,8 @@
+select
+  col1,
+  count(distinct col2) as cnt1,
+  count(distinct case when col3 is not null then col2 else null end) as cnt2
+from
+  table10
+group by
+  col1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase4.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase4.sql
new file mode 100644
index 0000000..5941c19
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationCaseByCase4.sql
@@ -0,0 +1,7 @@
+select
+  col1,
+  count(distinct col2) as cnt
+from
+  testDistinctAggregationCaseByCase4
+group by
+  col1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithHaving1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithHaving1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithHaving1.sql
new file mode 100644
index 0000000..8fc33ae
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithHaving1.sql
@@ -0,0 +1 @@
+select l_linenumber, count(*), count(distinct l_orderkey), sum(distinct l_orderkey) from lineitem group by l_linenumber having sum(distinct l_orderkey) = 6;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithUnion1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithUnion1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithUnion1.sql
new file mode 100644
index 0000000..a14f982
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregationWithUnion1.sql
@@ -0,0 +1,21 @@
+select
+  sum(distinct l_orderkey),
+  l_linenumber,
+  count(distinct l_orderkey),
+  count(*) as total
+from
+  (
+    select
+      *
+    from
+      lineitem
+
+    union all
+
+    select
+      *
+    from
+      lineitem
+  ) t1
+group by
+  l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case1.sql
new file mode 100644
index 0000000..4f01904
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case1.sql
@@ -0,0 +1,7 @@
+select
+    sum(l_quantity) as quantity,
+    count(distinct l_suppkey) suppkey,
+    l_returnflag
+from
+    lineitem
+group by l_returnflag
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case10.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case10.sql
new file mode 100644
index 0000000..6ab7c25
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case10.sql
@@ -0,0 +1,5 @@
+select sum(cnt1), sum(sum2)
+from (
+  select o_orderdate, count(distinct o_orderpriority), count(distinct o_orderkey) cnt1, sum(o_totalprice) sum2
+  from orders group by o_orderdate
+) a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case2.sql
new file mode 100644
index 0000000..10f1970
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case2.sql
@@ -0,0 +1,8 @@
+select
+    sum(l_quantity) as quantity,
+    count(distinct l_partkey) as partkey,
+    count(distinct l_suppkey) as suppkey,
+    l_returnflag
+from
+    lineitem
+group by l_returnflag
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case3.sql
new file mode 100644
index 0000000..e585d42
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case3.sql
@@ -0,0 +1,9 @@
+select
+    sum(l_quantity) as quantity,
+    count(distinct l_partkey) as partkey,
+    count(distinct l_suppkey),
+    max(l_quantity),
+    l_returnflag
+from
+    lineitem
+group by l_returnflag
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case4.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case4.sql
new file mode 100644
index 0000000..e8f05de
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case4.sql
@@ -0,0 +1,10 @@
+select
+    l_orderkey,
+    sum(l_quantity) as quantity,
+    count(distinct l_partkey) as partkey,
+    count(distinct l_suppkey),
+    max(l_quantity),
+    l_returnflag
+from
+    lineitem
+group by l_returnflag, l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case5.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case5.sql
new file mode 100644
index 0000000..9a4d4eb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case5.sql
@@ -0,0 +1,10 @@
+select
+    l_orderkey,
+    sum(l_quantity) as quantity,
+    count(distinct l_partkey) as partkey,
+    count(distinct l_suppkey),
+    max(l_quantity),
+    l_returnflag
+from
+    (select * from lineitem) as litem
+group by l_returnflag, l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case6.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case6.sql
new file mode 100644
index 0000000..0a30fe3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case6.sql
@@ -0,0 +1,12 @@
+select * from (
+select
+    l_orderkey,
+    sum(l_quantity) as quantity,
+    count(distinct l_partkey) as partkey,
+    count(distinct l_suppkey),
+    max(l_quantity),
+    l_returnflag
+from
+    lineitem
+group by l_returnflag, l_orderkey
+) a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case7.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case7.sql
new file mode 100644
index 0000000..e08c829
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case7.sql
@@ -0,0 +1,9 @@
+select
+    count(distinct l_orderkey),
+    sum(l_quantity) as quantity,
+    count(distinct l_partkey) as partkey,
+    count(distinct l_suppkey),
+    max(l_quantity)
+from
+    lineitem
+group by l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case8.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case8.sql
new file mode 100644
index 0000000..ed8e363
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case8.sql
@@ -0,0 +1,10 @@
+select
+    lineitem.l_orderkey as l_orderkey,
+    lineitem.l_partkey as l_partkey,
+    count(distinct lineitem.l_partkey) as cnt1,
+    count(distinct lineitem.l_suppkey) as cnt2,
+    sum(lineitem.l_quantity) as sum1
+from
+    lineitem
+group by
+    lineitem.l_orderkey, lineitem.l_partkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case9.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case9.sql
new file mode 100644
index 0000000..6265599
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctAggregation_case9.sql
@@ -0,0 +1,11 @@
+select
+    lineitem.l_orderkey as l_orderkey,
+    count(distinct lineitem.l_partkey) as cnt1,
+    sum(lineitem.l_quantity + lineitem.l_linenumber)/count(distinct lineitem.l_suppkey) as value2,
+    lineitem.l_partkey as l_partkey,
+    avg(lineitem.l_quantity) as avg1,
+    count(distinct lineitem.l_suppkey) as cnt2
+from
+    lineitem
+group by
+    lineitem.l_orderkey, lineitem.l_partkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctPythonUdafWithUnion1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctPythonUdafWithUnion1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctPythonUdafWithUnion1.sql
new file mode 100644
index 0000000..73e9579
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testDistinctPythonUdafWithUnion1.sql
@@ -0,0 +1,21 @@
+select
+  sum(distinct l_orderkey),
+  l_linenumber,
+  count(distinct l_orderkey),
+  countpy() as total
+from
+  (
+    select
+      *
+    from
+      lineitem
+
+    union
+
+    select
+      *
+    from
+      lineitem
+  ) t1
+group by
+  l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy.sql
new file mode 100644
index 0000000..1c6751a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy.sql
@@ -0,0 +1 @@
+select count(1) as unique_key from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy2.sql
new file mode 100644
index 0000000..7aeab38
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy2.sql
@@ -0,0 +1 @@
+select count(1) as unique_key from lineitem group by l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy3.sql
new file mode 100644
index 0000000..1e97435
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy3.sql
@@ -0,0 +1 @@
+select l_orderkey as gkey from lineitem group by gkey order by gkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy4.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy4.sql
new file mode 100644
index 0000000..4f2c63a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy4.sql
@@ -0,0 +1,9 @@
+select
+  l_orderkey as gkey,
+  count(1) as unique_key
+from
+  lineitem
+group by
+  lineitem.l_orderkey
+order by
+  gkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy5.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy5.sql
new file mode 100644
index 0000000..96ea13b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupBy5.sql
@@ -0,0 +1 @@
+select l_orderkey as gkey, '00' as const_val from lineitem group by lineitem.l_orderkey order by gkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested1.sql
new file mode 100644
index 0000000..0ebeaab
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested1.sql
@@ -0,0 +1,8 @@
+select
+  l_orderkey + l_partkey as unique_key
+from
+  lineitem
+group by
+  l_orderkey + l_partkey
+order by
+  unique_key;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested2.sql
new file mode 100644
index 0000000..eb86ce0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByNested2.sql
@@ -0,0 +1,10 @@
+select * from (
+select
+  sum(l_orderkey) + sum(l_partkey) as total
+from
+  lineitem
+group by
+  l_orderkey + l_partkey
+) t1
+order by
+  total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys1.sql
new file mode 100644
index 0000000..52541aa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys1.sql
@@ -0,0 +1 @@
+select 123 as key, count(1) as total from lineitem group by key order by key, total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys2.sql
new file mode 100644
index 0000000..5a2892d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys2.sql
@@ -0,0 +1 @@
+select l_partkey as a, timestamp '2014-07-07 04:28:31.561' as b, '##' as c, count(*) d from lineitem group by a, b, c order by l_partkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys3.sql
new file mode 100644
index 0000000..568009d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys3.sql
@@ -0,0 +1,8 @@
+select
+  timestamp '2014-07-07 04:28:31.561' as b,
+  '##' as c,
+  count(*) d
+from
+  lineitem
+group by
+  b, c;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys4.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys4.sql
new file mode 100644
index 0000000..4de4dda
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys4.sql
@@ -0,0 +1,12 @@
+select
+  'day',
+  l_orderkey,
+  count(*) as sum
+from
+  lineitem
+group by
+  'day',
+  l_orderkey
+order by
+  'day',
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys5.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys5.sql
new file mode 100644
index 0000000..4132d37
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithConstantKeys5.sql
@@ -0,0 +1,13 @@
+select
+  'day',
+  'day' as key,
+  l_orderkey,
+  count(*) as sum
+from
+  lineitem
+group by
+  'day',
+  l_orderkey
+order by
+  'day',
+  l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys1.sql
new file mode 100644
index 0000000..4dbc2ce
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys1.sql
@@ -0,0 +1 @@
+select upper(lower(l_orderkey::text)) as key, count(1) as total from lineitem group by key order by upper(lower(l_orderkey::text)), total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys2.sql
new file mode 100644
index 0000000..c98c121
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithExpressionKeys2.sql
@@ -0,0 +1 @@
+select upper(lower(l_orderkey::text)) as key, count(1) as total from lineitem group by upper(lower(l_orderkey::text)) order by upper(lower(l_orderkey::text)), total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData1.sql
new file mode 100644
index 0000000..af089df
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData1.sql
@@ -0,0 +1 @@
+select count(1) as unique_key from lineitem where l_orderkey = 1000;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData10.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData10.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData10.sql
new file mode 100644
index 0000000..98546db
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData10.sql
@@ -0,0 +1,3 @@
+select count(distinct l_linenumber) as unique_key, count(distinct l_returnflag || l_linestatus) flag
+from lineitem
+where l_orderkey = 1000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData11.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData11.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData11.sql
new file mode 100644
index 0000000..3fae412
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData11.sql
@@ -0,0 +1,5 @@
+select l_orderkey, count(distinct l_linenumber) as unique_key
+, count(distinct l_returnflag || l_linestatus) flag
+from lineitem
+where l_orderkey = 1000
+group by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData12.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData12.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData12.sql
new file mode 100644
index 0000000..3a94d82
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData12.sql
@@ -0,0 +1,29 @@
+select
+	s.s_acctbal,
+	s.s_name,
+	n.t_name,
+	p.p_partkey,
+	p.p_mfgr,
+	s.s_address,
+	s.s_phone,
+	s.s_comment
+from (
+   select n_name as t_name, n_nationkey as t_nationkey
+    , n_regionkey as t_regionkey
+    , count(distinct n_comment) as cnt
+    , count(distinct n_nationkey / n_regionkey) as diff
+   from nation
+   where n_nationkey > 10000
+   group by n_name, n_nationkey, n_regionkey, n_regionkey
+) n
+join region r on (n.t_regionkey = r.r_regionkey)
+join supplier s on (s.s_nationkey = n.t_nationkey)
+join partsupp ps on (s.s_suppkey = ps.ps_suppkey)
+join part p on (p.p_partkey = ps.ps_partkey)
+where n.t_regionkey = ps.ps_suppkey
+and n.cnt > 0
+order by
+  s.s_acctbal,
+  s.s_name,
+  n.t_name,
+  p.p_partkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData2.sql
new file mode 100644
index 0000000..84351af
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData2.sql
@@ -0,0 +1 @@
+select count(1) as unique_key, max(l_orderkey) as max_key from lineitem where l_orderkey = 1000;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData3.sql
new file mode 100644
index 0000000..c6c23c6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData3.sql
@@ -0,0 +1,3 @@
+select max(l_orderkey) as maximum, count(l_linenumber) as unique_key
+from lineitem
+where l_orderkey = 1000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData4.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData4.sql
new file mode 100644
index 0000000..ee345f9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData4.sql
@@ -0,0 +1,3 @@
+select max(l_orderkey) as maximum, count(distinct l_linenumber) as unique_key
+from lineitem
+where l_orderkey = 1000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData5.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData5.sql
new file mode 100644
index 0000000..105817f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData5.sql
@@ -0,0 +1 @@
+select count(1) as unique_key from testGroupByWithNullData5;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData6.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData6.sql
new file mode 100644
index 0000000..0e87731
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData6.sql
@@ -0,0 +1 @@
+select count(distinct age) as unique_key, max(point) as maximum from testGroupByWithNullData6;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData7.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData7.sql
new file mode 100644
index 0000000..1127bee
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData7.sql
@@ -0,0 +1 @@
+select max(point) as maximum, count(distinct age) as unique_key from testGroupByWithNullData7 where age > 100;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData8.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData8.sql
new file mode 100644
index 0000000..74c83fc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData8.sql
@@ -0,0 +1 @@
+select max(point) as maximum, count(age) as unique_key from testGroupByWithNullData8;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData9.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData9.sql
new file mode 100644
index 0000000..56fb65c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithNullData9.sql
@@ -0,0 +1,4 @@
+select l_orderkey, count(distinct l_linenumber) as unique_key
+from lineitem
+where l_orderkey = 1000
+group by l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameConstantKeys1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameConstantKeys1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameConstantKeys1.sql
new file mode 100644
index 0000000..c8c3db7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameConstantKeys1.sql
@@ -0,0 +1 @@
+select l_partkey as a, '##' as b, '##' as c, count(*) d from lineitem group by a, b, c order by a;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs1.sql
new file mode 100644
index 0000000..a04745e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs1.sql
@@ -0,0 +1,8 @@
+select
+  sum(l_orderkey) + sum(l_orderkey) as total
+from
+  lineitem
+group by
+  l_orderkey + l_partkey
+order by
+  l_orderkey + l_partkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs2.sql
new file mode 100644
index 0000000..074e252
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupByWithSameExprs2.sql
@@ -0,0 +1,8 @@
+select
+  sum(l_orderkey) as total1 , sum(l_orderkey) as total2
+from
+  lineitem
+group by
+  l_orderkey + l_partkey
+order by
+  total1, total2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithJson.json b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithJson.json
new file mode 100644
index 0000000..072cf9b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithJson.json
@@ -0,0 +1,127 @@
+// select l_orderkey, avg(l_partkey) total, sum(l_linenumber) as num from lineitem group by l_orderkey
+// having total >= 2 or num = 3;
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "Expr": {
+                "ColumnName": "l_orderkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "AliasName": "total",
+            "Expr": {
+                "IsDistinct": false,
+                "Signature": "avg",
+                "FuncParams": [
+                    {
+                        "ColumnName": "l_partkey",
+                        "OpType": "Column"
+                    }
+                ],
+                "OpType": "GeneralSetFunction"
+            },
+            "OpType": "Target"
+        },
+        {
+            "AliasName": "num",
+            "Expr": {
+                "IsDistinct": false,
+                "Signature": "sum",
+                "FuncParams": [
+                    {
+                        "ColumnName": "l_linenumber",
+                        "OpType": "Column"
+                    }
+                ],
+                "OpType": "GeneralSetFunction"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "SortSpecs": [
+            {
+                "SortKey": {
+                    "ColumnName": "l_orderkey",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "total",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            },
+            {
+                "SortKey": {
+                    "ColumnName": "num",
+                    "OpType": "Column"
+                },
+                "IsAsc": true,
+                "IsNullFirst": false
+            }
+        ],
+        "Expr": {
+            "HavingCondition": {
+                "LeftExpr": {
+                    "LeftExpr": {
+                        "ColumnName": "total",
+                        "OpType": "Column"
+                    },
+                    "RightExpr": {
+                        "Value": "2",
+                        "ValueType": "Unsigned_Integer",
+                        "OpType": "Literal"
+                    },
+                    "OpType": "GreaterThanOrEquals"
+                },
+                "RightExpr": {
+                    "LeftExpr": {
+                        "ColumnName": "num",
+                        "OpType": "Column"
+                    },
+                    "RightExpr": {
+                        "Value": "3",
+                        "ValueType": "Unsigned_Integer",
+                        "OpType": "Literal"
+                    },
+                    "OpType": "Equals"
+                },
+                "OpType": "Or"
+            },
+            "Expr": {
+                "Groups": [
+                    {
+                        "GroupType": "OrdinaryGroup",
+                        "Dimensions": [
+                            {
+                                "ColumnName": "l_orderkey",
+                                "OpType": "Column"
+                            }
+                        ]
+                    }
+                ],
+                "Expr": {
+                    "Relations": [
+                        {
+                            "TableName": "lineitem",
+                            "OpType": "Relation"
+                        }
+                    ],
+                    "OpType": "RelationList"
+                },
+                "OpType": "Aggregation"
+            },
+            "OpType": "Having"
+        },
+        "OpType": "Sort"
+    },
+    "OpType": "Projection"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit1.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit1.sql
new file mode 100644
index 0000000..06d96af
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit1.sql
@@ -0,0 +1 @@
+select sum(l_linenumber) from lineitem limit 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit2.sql
new file mode 100644
index 0000000..1ddb171
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit2.sql
@@ -0,0 +1 @@
+select sum(l_linenumber) from lineitem limit 10;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit3.sql
new file mode 100644
index 0000000..fd1e5fb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithLimit3.sql
@@ -0,0 +1 @@
+select l_orderkey, sum(l_linenumber) from lineitem group by l_orderkey order by l_orderkey limit 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc.sql
new file mode 100644
index 0000000..8100f11
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc.sql
@@ -0,0 +1 @@
+select count(*) from nation where add_py(n_nationkey, 1) > 2 group by n_regionkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc2.sql
new file mode 100644
index 0000000..bcfce13
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testGroupbyWithPythonFunc2.sql
@@ -0,0 +1 @@
+select n_regionkey, count(*) as cnt from nation group by n_regionkey having percent(cnt, 25) > 10
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithAggFunction.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithAggFunction.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithAggFunction.sql
new file mode 100644
index 0000000..9103ffc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithAggFunction.sql
@@ -0,0 +1 @@
+select l_orderkey, avg(l_partkey) total, sum(l_linenumber) as num from lineitem group by l_orderkey having avg(l_partkey) = 2.5 or num = 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithNamedTarget.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithNamedTarget.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithNamedTarget.sql
new file mode 100644
index 0000000..87a784f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testHavingWithNamedTarget.sql
@@ -0,0 +1,13 @@
+select
+  l_orderkey,
+  avg(l_partkey) total,
+  sum(l_linenumber) as num
+from
+  lineitem
+group by
+  l_orderkey
+having
+  total >= 2 or num = 3
+order by
+  l_orderkey,
+  total;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf.sql
new file mode 100644
index 0000000..e29816b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf.sql
@@ -0,0 +1 @@
+select avgpy(n_nationkey), avg(n_nationkey), countpy() from nation;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf2.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf2.sql
new file mode 100644
index 0000000..b08ff1e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf2.sql
@@ -0,0 +1 @@
+select countpy(), count(*) from lineitem group by l_linenumber
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf3.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf3.sql
new file mode 100644
index 0000000..406442f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdaf3.sql
@@ -0,0 +1 @@
+select avgpy(o_totalprice), countpy(), avg(o_totalprice), count(*) from orders group by o_custkey, o_orderdate
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithHaving.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithHaving.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithHaving.sql
new file mode 100644
index 0000000..b7769b7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithHaving.sql
@@ -0,0 +1,3 @@
+select l_orderkey, avgpy(l_partkey) total, sum(l_linenumber) as num from lineitem
+group by l_orderkey
+having avgpy(l_partkey) = 2.5 or num = 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithNullData.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithNullData.sql b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithNullData.sql
new file mode 100644
index 0000000..56fb65c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestGroupByQuery/testPythonUdafWithNullData.sql
@@ -0,0 +1,4 @@
+select l_orderkey, count(distinct l_linenumber) as unique_key
+from lineitem
+where l_orderkey = 1000
+group by l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInAndNotInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInAndNotInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInAndNotInSubQuery.sql
new file mode 100644
index 0000000..8ef5077
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInAndNotInSubQuery.sql
@@ -0,0 +1,3 @@
+select n_name from nation
+where n_regionkey in (select r_regionkey from region)
+  and n_nationkey not in (select s_nationkey from supplier)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery.sql
new file mode 100644
index 0000000..48928a1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery.sql
@@ -0,0 +1 @@
+select n_name from nation where n_regionkey in (select r_regionkey from region)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery2.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery2.sql
new file mode 100644
index 0000000..eff1e7b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQuery2.sql
@@ -0,0 +1,2 @@
+select n_name from nation
+where n_nationkey in (select count(*) from region)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithJoin.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithJoin.sql
new file mode 100644
index 0000000..178b601
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithJoin.sql
@@ -0,0 +1,2 @@
+select n_name from nation, supplier
+where n_regionkey in (select r_regionkey from region) and n_nationkey = s_nationkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithOtherConditions.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithOtherConditions.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithOtherConditions.sql
new file mode 100644
index 0000000..47a23fa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithOtherConditions.sql
@@ -0,0 +1,2 @@
+select n_name from nation where n_regionkey in (
+  select r_regionkey from region) and n_nationkey > 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithTableSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithTableSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithTableSubQuery.sql
new file mode 100644
index 0000000..8645df1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testInSubQueryWithTableSubQuery.sql
@@ -0,0 +1,2 @@
+select n_name from (select * from nation where n_nationkey > 1 and n_nationkey < 10) as T
+where n_regionkey in (select r_regionkey from region where r_regionkey > 1 and r_regionkey < 3);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleInSubQuery.sql
new file mode 100644
index 0000000..b93041f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleInSubQuery.sql
@@ -0,0 +1,5 @@
+select n_name from nation
+where
+  n_regionkey in (select r_regionkey from region)
+  and
+  n_nationkey in (select s_nationkey from supplier)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleNotInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleNotInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleNotInSubQuery.sql
new file mode 100644
index 0000000..bd85ded
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testMultipleNotInSubQuery.sql
@@ -0,0 +1,3 @@
+select n_name from nation
+where n_nationkey not in (select r_regionkey from region)
+  and n_nationkey not in (select s_nationkey from supplier)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInAndNotInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInAndNotInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInAndNotInSubQuery.sql
new file mode 100644
index 0000000..8e4c6ba
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInAndNotInSubQuery.sql
@@ -0,0 +1,5 @@
+select c_name from customer
+  where c_nationkey in (
+    select n_nationkey from nation where n_name like 'C%' and n_regionkey
+    not in (
+      select count(*) from region where r_regionkey > 0 and r_regionkey < 3))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery.sql
new file mode 100644
index 0000000..902dfd7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery.sql
@@ -0,0 +1,4 @@
+select c_name from customer
+where c_nationkey in (
+  select n_nationkey from nation where n_name like 'C%' and n_regionkey in (
+    select r_regionkey from region where r_regionkey > 0 and r_regionkey < 3))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery2.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery2.sql
new file mode 100644
index 0000000..4965ec2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedInSubQuery2.sql
@@ -0,0 +1,4 @@
+select c_name from customer
+  where c_nationkey in (
+    select n_nationkey from nation where n_name like 'C%' and n_regionkey in (
+    select count(*) - 1 from region where r_regionkey > 0 and r_regionkey < 3))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedNotInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedNotInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedNotInSubQuery.sql
new file mode 100644
index 0000000..a2cea67
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNestedNotInSubQuery.sql
@@ -0,0 +1,4 @@
+select c_name from customer
+where c_nationkey not in (
+  select n_nationkey from nation where n_name like 'C%' and n_regionkey not in (
+    select r_regionkey from region where r_regionkey > 0 and r_regionkey < 3))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNotInSubQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNotInSubQuery.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNotInSubQuery.sql
new file mode 100644
index 0000000..cb05624
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testNotInSubQuery.sql
@@ -0,0 +1 @@
+select n_name from nation where n_nationkey not in (select r_regionkey from region)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.sql
new file mode 100644
index 0000000..c8d3bf4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.sql
@@ -0,0 +1,22 @@
+select
+  n_regionkey, count(*)
+from
+  customer, lineitem, orders, supplier, nation
+where
+  l_orderkey = o_orderkey and
+  c_custkey = o_custkey and
+  l_linenumber = s_suppkey and
+  l_partkey in (
+    select
+      l_partkey
+    from
+      lineitem
+    where
+      l_linenumber in (1, 3, 5, 7, 9)
+  ) and
+  n_nationkey = c_nationkey
+group by
+  n_regionkey
+order by
+  n_regionkey
+limit 100;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInSubquery/testWithAsteriskAndJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInSubquery/testWithAsteriskAndJoin.sql b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testWithAsteriskAndJoin.sql
new file mode 100644
index 0000000..d5e2bfa
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInSubquery/testWithAsteriskAndJoin.sql
@@ -0,0 +1,7 @@
+select
+  *
+from
+  lineitem, orders
+where
+  l_orderkey = o_orderkey and
+  l_partkey in (select l_partkey from lineitem where l_linenumber in (1, 3, 5, 7, 9))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testBroadcastTwoPartJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testBroadcastTwoPartJoin.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testBroadcastTwoPartJoin.sql
new file mode 100644
index 0000000..36c53cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testBroadcastTwoPartJoin.sql
@@ -0,0 +1,19 @@
+select
+    l_orderkey,
+    p_name,
+    n_name
+from
+    lineitem,
+    orders,
+    part,
+    customer,
+    nation
+where
+    l_orderkey = o_orderkey
+    and l_partkey = p_partkey
+    and o_custkey = c_custkey
+    and c_nationkey = n_nationkey
+order by
+    l_orderkey,
+    p_name,
+    n_name

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinAndCaseWhen.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinAndCaseWhen.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinAndCaseWhen.sql
new file mode 100644
index 0000000..d058aba
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinAndCaseWhen.sql
@@ -0,0 +1,18 @@
+select
+  r_regionkey,
+  n_regionkey,
+  case
+    when r_regionkey = 1 then 'one'
+    when r_regionkey = 2 then 'two'
+    when r_regionkey = 3 then 'three'
+    when r_regionkey = 4 then 'four'
+    else 'zero'
+  end as cond
+from
+  region,
+  nation
+where
+  r_regionkey = n_regionkey
+order by
+  r_regionkey,
+  n_regionkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk1.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk1.sql
new file mode 100644
index 0000000..111a371
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk1.sql
@@ -0,0 +1 @@
+select region.*, customer.* from region, customer order by r_regionkey,r_name,c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk2.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk2.sql
new file mode 100644
index 0000000..ca1672e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk2.sql
@@ -0,0 +1 @@
+select region.*, customer.* from customer, region order by r_regionkey,r_name,c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk3.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk3.sql
new file mode 100644
index 0000000..fd44916
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk3.sql
@@ -0,0 +1 @@
+select * from customer, region order by c_custkey,c_name,r_regionkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk4.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk4.sql
new file mode 100644
index 0000000..fc5b1c3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinQuery/testCrossJoinWithAsterisk4.sql
@@ -0,0 +1 @@
+select length(r_comment) as len, *, c_custkey*10 from customer, region order by len,r_regionkey,r_name,c_custkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery.sql
new file mode 100644
index 0000000..88e1f72
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery.sql
@@ -0,0 +1,12 @@
+select
+    l_orderkey,
+    a.o_custkey,
+    p_name
+from
+    lineitem,
+    part,
+    (select o_orderkey, o_custkey from orders) a
+where
+    l_partkey = p_partkey
+    and l_orderkey = a.o_orderkey
+order by l_orderkey, o_custkey, p_name
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery2.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery2.sql
new file mode 100644
index 0000000..f3b0995
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testBroadcastSubquery2.sql
@@ -0,0 +1,19 @@
+select sum(b.l_quantity)
+from (
+      select a.l_orderkey, a.l_quantity, a.l_linenumber
+        from lineitem a
+        join part on a.l_partkey = p_partkey) b
+join orders c on c.o_orderkey = b.l_orderkey
+join (
+      select e.l_orderkey, avg(e.l_quantity) avg_quantity
+      from (
+          select d.l_orderkey, d.l_quantity
+            from lineitem d
+            join part on d.l_partkey = p_partkey
+      ) e
+      group by e.l_orderkey
+) f
+on c.o_orderkey = f.l_orderkey
+where
+  c.o_orderkey > 0 and
+  b.l_quantity > f.avg_quantity
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testThetaJoinKeyPairs.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testThetaJoinKeyPairs.sql b/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testThetaJoinKeyPairs.sql
new file mode 100644
index 0000000..802e2b0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInnerJoinWithSubQuery/testThetaJoinKeyPairs.sql
@@ -0,0 +1,20 @@
+select
+  n_nationkey, n_name, n_regionkey, t.cnt
+from
+  nation n
+  join
+  (
+    select
+      r_regionkey, count(*) as cnt
+    from
+      nation n
+      join
+      region r
+    on (n.n_regionkey = r.r_regionkey)
+    group by
+      r_regionkey
+  ) t
+on
+  (n.n_regionkey = t.r_regionkey) and n.n_nationkey > t.cnt
+order by
+  n_nationkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_csv_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_csv_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_csv_ddl.sql
new file mode 100644
index 0000000..729ca83
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_csv_ddl.sql
@@ -0,0 +1 @@
+create table full_table_csv as select * from default.lineitem
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_parquet_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_parquet_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_parquet_ddl.sql
new file mode 100644
index 0000000..1025b3b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/full_table_parquet_ddl.sql
@@ -0,0 +1 @@
+create table full_table_parquet using parquet as select * from default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/lineitem_year_month_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/lineitem_year_month_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/lineitem_year_month_ddl.sql
new file mode 100644
index 0000000..fb18ad8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/lineitem_year_month_ddl.sql
@@ -0,0 +1,18 @@
+create table lineitem_year_month (
+ l_orderkey bigint,
+ l_partkey bigint,
+ l_suppkey bigint,
+ l_linenumber int,
+ l_quantity float8,
+ l_extendedprice float8,
+ l_discount float8,
+ l_tax float8,
+ l_returnflag text,
+ l_linestatus text,
+ l_shipdate text,
+ l_commitdate text,
+ l_receiptdate text,
+ l_shipinstruct text,
+ l_shipmode text,
+ l_comment text
+) PARTITION BY COLUMN (year TEXT, MONTH TEXT);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/load_to_lineitem_year_month.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/load_to_lineitem_year_month.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/load_to_lineitem_year_month.sql
new file mode 100644
index 0000000..601af12
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/load_to_lineitem_year_month.sql
@@ -0,0 +1 @@
+INSERT INTO lineitem_year_month SELECT *, SUBSTR(l_shipdate, 1,4) as year, SUBSTR(l_shipdate, 6, 2) as month FROM default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/nation_diff_col_order.ddl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/nation_diff_col_order.ddl b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/nation_diff_col_order.ddl
new file mode 100644
index 0000000..6998304
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/nation_diff_col_order.ddl
@@ -0,0 +1 @@
+create table nation_diff (n_nationkey int8, n_name text, n_regionkey int8, n_comment text);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/table1_ddl.sql
new file mode 100644
index 0000000..b8333c4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/table1_ddl.sql
@@ -0,0 +1 @@
+create table table1 (col1 int4, col2 int4, col3 float8)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_ddl.sql
new file mode 100644
index 0000000..c02b080
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_ddl.sql
@@ -0,0 +1 @@
+create table test1 (col1 char(5));
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_nolength_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_nolength_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_nolength_ddl.sql
new file mode 100644
index 0000000..cbe3654
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/test1_nolength_ddl.sql
@@ -0,0 +1 @@
+create table test1 (col1 char);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertInto.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertInto.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertInto.sql
new file mode 100644
index 0000000..9656694
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertInto.sql
@@ -0,0 +1 @@
+insert into table1 select l_orderkey, l_partkey, l_quantity from default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeChar.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeChar.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeChar.sql
new file mode 100644
index 0000000..f7ec11c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeChar.sql
@@ -0,0 +1,4 @@
+insert into test1 select 'a';
+insert into test1 select 'abc';
+insert into test1 select 'abcde';
+select * from test1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeCharWithNoLength.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeCharWithNoLength.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeCharWithNoLength.sql
new file mode 100644
index 0000000..02a1d6c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertIntoSelectWithFixedSizeCharWithNoLength.sql
@@ -0,0 +1,2 @@
+insert into test1 select 'a';
+select * from test1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwrite.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwrite.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwrite.sql
new file mode 100644
index 0000000..db18c0e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwrite.sql
@@ -0,0 +1 @@
+insert overwrite into table1 select l_orderkey, l_partkey, l_quantity from default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocation.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocation.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocation.sql
new file mode 100644
index 0000000..28ac95c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocation.sql
@@ -0,0 +1 @@
+insert overwrite into location '/tajo-data/testInsertOverwriteCapitalTableName' select * from default.lineitem where l_orderkey = 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithCompression.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithCompression.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithCompression.sql
new file mode 100644
index 0000000..3582403
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithCompression.sql
@@ -0,0 +1 @@
+insert overwrite into location '/tajo-data/testInsertOverwriteLocationWithCompression' USING text WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec') select * from default.lineitem where l_orderkey = 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnion.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnion.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnion.sql
new file mode 100644
index 0000000..65bab10
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnion.sql
@@ -0,0 +1,4 @@
+insert overwrite into location '/tajo-data/testInsertOverwriteLocationWithUnion'
+select l_orderkey as col1, l_partkey as col2, l_quantity as col3 from default.lineitem
+union all
+select o_orderkey as col1, o_custkey as col2, o_totalprice as col3 from default.orders
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnionDifferenceAlias.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnionDifferenceAlias.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnionDifferenceAlias.sql
new file mode 100644
index 0000000..cbd7a94
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteLocationWithUnionDifferenceAlias.sql
@@ -0,0 +1,4 @@
+insert overwrite into location '/tajo-data/testInsertOverwriteLocationWithUnionDifferenceAlias'
+select l_orderkey as col1, l_partkey as col2, l_quantity as col3 from default.lineitem
+union all
+select o_orderkey as col4, o_custkey as col5, o_totalprice as col6 from default.orders
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteSmallerColumns.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteSmallerColumns.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteSmallerColumns.sql
new file mode 100644
index 0000000..ce3fc0d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteSmallerColumns.sql
@@ -0,0 +1 @@
+insert overwrite into table1 select l_orderkey from default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsterisk.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsterisk.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsterisk.sql
new file mode 100644
index 0000000..4856e18
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsterisk.sql
@@ -0,0 +1 @@
+insert overwrite into full_table_csv select * from default.lineitem where l_orderkey = 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsteriskAndMore.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsteriskAndMore.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsteriskAndMore.sql
new file mode 100644
index 0000000..07c904d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithAsteriskAndMore.sql
@@ -0,0 +1 @@
+select * from lineitem_year_month;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression.sql
new file mode 100644
index 0000000..8157c1d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression.sql
@@ -0,0 +1 @@
+insert overwrite into testInsertOverwriteWithCompression select  l_orderkey, l_partkey, l_quantity from default.lineitem where l_orderkey = 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression_ddl.sql
new file mode 100644
index 0000000..8e76b9e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithCompression_ddl.sql
@@ -0,0 +1,4 @@
+create table
+  testInsertOverwriteWithCompression (col1 int4, col2 int4, col3 float8)
+USING text
+WITH ('text.delimiter'='|','compression.codec'='org.apache.hadoop.io.compress.DeflateCodec');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithDatabase.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithDatabase.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithDatabase.sql
new file mode 100644
index 0000000..db18c0e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithDatabase.sql
@@ -0,0 +1 @@
+insert overwrite into table1 select l_orderkey, l_partkey, l_quantity from default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithTargetColumns.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithTargetColumns.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithTargetColumns.sql
new file mode 100644
index 0000000..67f9773
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithTargetColumns.sql
@@ -0,0 +1 @@
+insert overwrite into table1 (col1, col3) select l_orderkey, l_quantity from default.lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnion.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnion.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnion.sql
new file mode 100644
index 0000000..843d24c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnion.sql
@@ -0,0 +1,4 @@
+insert overwrite into table1
+select l_orderkey as col1, l_partkey as col2, l_quantity as col3 from default.lineitem
+union all
+select o_orderkey as col1, o_custkey as col2, o_totalprice as col3 from default.orders
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnionDifferentAlias.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnionDifferentAlias.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnionDifferentAlias.sql
new file mode 100644
index 0000000..1660eb5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertOverwriteWithUnionDifferentAlias.sql
@@ -0,0 +1,4 @@
+insert overwrite into table1
+select l_orderkey as col1, l_partkey as col2, l_quantity as col3 from default.lineitem
+union all
+select o_orderkey as col4, o_custkey as col5, o_totalprice as col6 from default.orders
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertWithDifferentColumnOrder.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertWithDifferentColumnOrder.sql b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertWithDifferentColumnOrder.sql
new file mode 100644
index 0000000..ad360f9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestInsertQuery/testInsertWithDifferentColumnOrder.sql
@@ -0,0 +1 @@
+insert overwrite into nation_diff (n_comment, n_name) select n_comment, n_name from default.nation;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/selfJoinOfPartitionedTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/selfJoinOfPartitionedTable.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/selfJoinOfPartitionedTable.sql
new file mode 100644
index 0000000..988c0e9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/selfJoinOfPartitionedTable.sql
@@ -0,0 +1,9 @@
+select
+  t1.c_nationkey,
+  t2.c_nationkey
+from
+  customer_parts t1, customer_parts t2
+where
+  t1.c_nationkey = t2.c_nationkey
+order by
+  t1.c_nationkey desc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testBroadcastPartitionTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testBroadcastPartitionTable.sql b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testBroadcastPartitionTable.sql
new file mode 100644
index 0000000..8d555a7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestJoinOnPartitionedTables/testBroadcastPartitionTable.sql
@@ -0,0 +1,16 @@
+select
+  c_custkey,
+  c_name,
+  c_nationkey,
+  n_nationkey,
+  o_orderkey
+from
+  customer_broad_parts,
+  nation_multifile,
+  orders
+where
+  c_nationkey = n_nationkey
+and
+  o_custkey = c_custkey
+order by
+  c_custkey;
\ No newline at end of file


[15/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort.plan
new file mode 100644
index 0000000..78b074a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..214097c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.Sort_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.result
new file mode 100644
index 0000000..304b867
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk1.result
@@ -0,0 +1,27 @@
+r_regionkey,r_name,r_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+1,AMERICA,hs use ironic, even requests. s,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+1,AMERICA,hs use ironic, even requests. s,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+1,AMERICA,hs use ironic, even requests. s,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+1,AMERICA,hs use ironic, even requests. s,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+1,AMERICA,hs use ironic, even requests. s,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+2,ASIA,ges. thinly even pinto beans ca,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+2,ASIA,ges. thinly even pinto beans ca,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+2,ASIA,ges. thinly even pinto beans ca,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+2,ASIA,ges. thinly even pinto beans ca,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+2,ASIA,ges. thinly even pinto beans ca,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+3,EUROPE,ly final courts cajole furiously final excuse,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+3,EUROPE,ly final courts cajole furiously final excuse,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+3,EUROPE,ly final courts cajole furiously final excuse,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,EUROPE,ly final courts cajole furiously final excuse,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+3,EUROPE,ly final courts cajole furiously final excuse,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash.plan
new file mode 100644
index 0000000..b4d8565
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..4a2b03d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Hash_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort.plan
new file mode 100644
index 0000000..b4d8565
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..4a2b03d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.Sort_NoBroadcast.plan
@@ -0,0 +1,103 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+  => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region
+  => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+SORT(10)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.region.r_name (TEXT) (asc),default.customer.c_custkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.result
new file mode 100644
index 0000000..304b867
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk2.result
@@ -0,0 +1,27 @@
+r_regionkey,r_name,r_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+1,AMERICA,hs use ironic, even requests. s,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+1,AMERICA,hs use ironic, even requests. s,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+1,AMERICA,hs use ironic, even requests. s,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+1,AMERICA,hs use ironic, even requests. s,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+1,AMERICA,hs use ironic, even requests. s,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+2,ASIA,ges. thinly even pinto beans ca,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+2,ASIA,ges. thinly even pinto beans ca,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+2,ASIA,ges. thinly even pinto beans ca,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+2,ASIA,ges. thinly even pinto beans ca,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+2,ASIA,ges. thinly even pinto beans ca,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+3,EUROPE,ly final courts cajole furiously final excuse,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+3,EUROPE,ly final courts cajole furiously final excuse,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+3,EUROPE,ly final courts cajole furiously final excuse,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,EUROPE,ly final courts cajole furiously final excuse,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+3,EUROPE,ly final courts cajole furiously final excuse,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash.plan
new file mode 100644
index 0000000..d1c32a0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithAsterisk3.Hash.plan
@@ -0,0 +1,76 @@
+explain
+-------------------------------
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(10)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   JOIN(6)(CROSS)
+     => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)
+        => out schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.customer.c_name (TEXT), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(2)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.customer.c_name (TEXT) (asc),default.region.r_regionkey (INT4) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(11) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT), default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================


[24/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin2.sql b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin2.sql
new file mode 100644
index 0000000..6c2d66a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin2.sql
@@ -0,0 +1,5 @@
+select a.l_orderkey, b.c_custkey, b.c_name, b.c_nationkey, d.n_name
+from lineitem a
+left outer join customer b on a.l_orderkey = b.c_custkey
+left outer join orders c on b.c_custkey = c.o_custkey
+left outer join nation d on a.l_orderkey = d.n_nationkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin3.sql b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin3.sql
new file mode 100644
index 0000000..ef6e490
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testLeftOuterJoin3.sql
@@ -0,0 +1,7 @@
+select a.c_custkey, a.c_name, a.c_nationkey, b.l_orderkey, c.o_orderdate, d.o_orderdate, e.n_name, f.p_name
+from customer a
+left outer join lineitem b on a.c_custkey = b.l_orderkey
+left outer join orders c on b.l_orderkey = c.o_orderkey
+left outer join orders d on a.c_custkey = d.o_orderkey
+left outer join nation e on d.o_orderkey = e.n_nationkey
+left outer join part f on f.p_partkey = d.o_orderkey

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength.sql b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength.sql
new file mode 100644
index 0000000..6ae6c09
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength.sql
@@ -0,0 +1,3 @@
+select * from customer a
+ left outer join nation_multifile b on a.c_nationkey = b.n_nationkey
+ where b.n_nationkey is null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength2.sql b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength2.sql
new file mode 100644
index 0000000..e6dfba7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestOuterJoinQuery/testMultipleBroadcastDataFileWithZeroLength2.sql
@@ -0,0 +1,5 @@
+select b.o_orderkey, b.o_orderdate, b.o_custkey, a.c_custkey, a.c_name, c.n_nationkey, c.n_name
+from customer a
+ left outer join orders b on a.c_custkey = b.o_custkey
+ left outer join nation_multifile c on a.c_nationkey = c.n_nationkey
+ where c.n_nationkey is not null
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_1.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_1.sql
new file mode 100644
index 0000000..7aa9439
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_1.sql
@@ -0,0 +1 @@
+select * from lineitem group by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_2.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_2.sql
new file mode 100644
index 0000000..90b31b2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/error_groupby_2.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem group by l_paerkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_casewhen_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_casewhen_1.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_casewhen_1.sql
new file mode 100644
index 0000000..57b369b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_casewhen_1.sql
@@ -0,0 +1,15 @@
+SELECT
+  CASE
+    WHEN PERIOD < 0 THEN 'N/A'
+    WHEN PERIOD <= INTERVAL '12h' THEN 'C0'
+    WHEN PERIOD <= INTERVAL '24h' THEN 'C1'
+    WHEN PERIOD <= INTERVAL '48h' THEN 'C2'
+    ELSE 'XX'
+  END AS P
+FROM (
+  SELECT
+    INTERVAL '12h' as PERIOD,
+    L_ORDERKEY
+  FROM
+    LINEITEM
+) T;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_limit_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_limit_1.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_limit_1.sql
new file mode 100644
index 0000000..65c72b1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_limit_1.sql
@@ -0,0 +1 @@
+select * from lineitem limit l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_store_format.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_store_format.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_store_format.sql
new file mode 100644
index 0000000..e5307d6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/invalid_store_format.sql
@@ -0,0 +1 @@
+create table table1 (name text, age int) using RAW;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_groupby_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_groupby_1.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_groupby_1.sql
new file mode 100644
index 0000000..90c2371
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_groupby_1.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem group by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_limit_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_limit_1.sql b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_limit_1.sql
new file mode 100644
index 0000000..79cf804
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestQueryValidation/valid_limit_1.sql
@@ -0,0 +1 @@
+select * from lineitem limit 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql
new file mode 100644
index 0000000..bdf76eb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql
@@ -0,0 +1 @@
+CREATE TABLE T1 (A TEXT, B INT4, C RECORD (D TEXT, E INT8), F FLOAT8);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql
new file mode 100644
index 0000000..0bfdc11
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql
@@ -0,0 +1 @@
+CREATE TABLE T1 (A TEXT, B INT4, C RECORD (D TEXT, E INT8, F RECORD (G INT1, H FLOAT4)), Z FLOAT8);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql
new file mode 100644
index 0000000..345531c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql
@@ -0,0 +1 @@
+SET CATALOG tajo;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql
new file mode 100644
index 0000000..d2ef283
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql
@@ -0,0 +1 @@
+SET CATALOG "Mixed Letter";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql
new file mode 100644
index 0000000..8efe696
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql
@@ -0,0 +1 @@
+SET SESSION ENABLE_SEQSCAN TO true;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql
new file mode 100644
index 0000000..458f1e5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql
@@ -0,0 +1 @@
+SET SESSION ENABLE_SEQSCAN TO false;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql
new file mode 100644
index 0000000..432d123
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql
@@ -0,0 +1 @@
+SET SESSION EXTSORT_BUFFER_SIZE TO 100;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql
new file mode 100644
index 0000000..a363702
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql
@@ -0,0 +1 @@
+SET SESSION EXTSORT_BUFFER_SIZE TO 50.7;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql
new file mode 100644
index 0000000..c9fcfc5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql
@@ -0,0 +1 @@
+SET SESSION EXTSORT_BUFFER_SIZE TO 'ABCD';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql
new file mode 100644
index 0000000..957232b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql
@@ -0,0 +1 @@
+SET SESSION EXTSORT_BUFFER_SIZE 'ABCD';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql
new file mode 100644
index 0000000..179428e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql
@@ -0,0 +1 @@
+SET SESSION EXTSORT_BUFFER_SIZE = 'ABCD';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql
new file mode 100644
index 0000000..a86d255
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql
@@ -0,0 +1 @@
+SET TIME ZONE 'PDT';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql
new file mode 100644
index 0000000..85dae0f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql
@@ -0,0 +1 @@
+SET TIME ZONE -7;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql
new file mode 100644
index 0000000..ef56b12
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql
@@ -0,0 +1 @@
+SET TIME ZONE DEFAULT;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window1.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window1.sql
new file mode 100644
index 0000000..52156b8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window1.sql
@@ -0,0 +1,5 @@
+ SELECT
+  dt,
+  sum(xy) over()
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window2.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window2.sql
new file mode 100644
index 0000000..60f1fbf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window2.sql
@@ -0,0 +1,5 @@
+ SELECT
+  dt,
+  sum(xy) over(partition by dt)
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window3.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window3.sql
new file mode 100644
index 0000000..01dd542
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window3.sql
@@ -0,0 +1,5 @@
+ SELECT
+  dt,
+  sum(xy) over(partition by round(dt))
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window4.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window4.sql
new file mode 100644
index 0000000..629d5e4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window4.sql
@@ -0,0 +1,5 @@
+ SELECT
+  dt,
+  sum(xy) over(order by dt)
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window5.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window5.sql
new file mode 100644
index 0000000..6338817
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window5.sql
@@ -0,0 +1,6 @@
+ SELECT
+  dt,
+  dt2,
+  sum(xy) over(partition by round(dt),dt2 order by ceil(dt) asc null last)
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window6.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window6.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window6.sql
new file mode 100644
index 0000000..1f1870e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window6.sql
@@ -0,0 +1,6 @@
+ SELECT
+  dt,
+  dt2,
+  sum(xy) over(partition by round(dt),dt2 order by ceil(dt) asc null last ROWS UNBOUNDED PRECEDING)
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window7.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window7.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window7.sql
new file mode 100644
index 0000000..6daa806
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window7.sql
@@ -0,0 +1,6 @@
+ SELECT
+  dt,
+  dt2,
+  row_number() over(partition by round(dt),dt2 order by ceil(dt) asc null last ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window8.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window8.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window8.sql
new file mode 100644
index 0000000..6f70690
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window8.sql
@@ -0,0 +1,6 @@
+ SELECT
+  dt,
+  dt2,
+  row_number() over(partition by round(dt),dt2 order by ceil(dt) asc null last ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
+FROM
+  sum_example;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window9.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window9.sql b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window9.sql
new file mode 100644
index 0000000..b289ebf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSQLAnalyzer/window9.sql
@@ -0,0 +1,9 @@
+ SELECT
+  dt,
+  dt2,
+  row_number() over(window1),
+  rank() over(window1)
+FROM
+  sum_example
+WINDOW
+  window1 AS (partition by round(dt),dt2 order by ceil(dt) asc null last ROWS BETWEEN 1 PRECEDING AND CURRENT ROW);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample0_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample0_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample0_ddl.sql
new file mode 100644
index 0000000..ed6aee1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample0_ddl.sql
@@ -0,0 +1 @@
+CREATE TABLE clone (title TEXT, name RECORD (first_name TEXT, last_name TEXT)) USING JSON;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample1_ddl.sql
new file mode 100644
index 0000000..9ba5f8c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample1_ddl.sql
@@ -0,0 +1,7 @@
+CREATE EXTERNAL TABLE ${0} (
+  title TEXT,
+  name RECORD (
+    first_name TEXT,
+    last_name TEXT
+  )
+) USING JSON LOCATION ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample2_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample2_ddl.sql
new file mode 100644
index 0000000..bc2d6e2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/sample2_ddl.sql
@@ -0,0 +1,23 @@
+CREATE EXTERNAL TABLE ${0} (
+  glossary RECORD (
+    title TEXT,
+    "GlossDiv" RECORD (
+      title TEXT,
+      "GlossList" RECORD (
+        "GlossEntry" RECORD (
+        "ID" TEXT,
+        "SortAs" TEXT,
+        "GlossTerm" TEXT,
+        "Acronym" TEXT,
+        "Abbrev" TEXT,
+        "GlossDef" RECORD (
+          para TEXT,
+          "GlossSeeAlso" TEXT
+        ),
+
+        "GlossSee" TEXT
+        )
+      )
+    )
+  )
+) USING JSON LOCATION ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsGroupbyKey1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsGroupbyKey1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsGroupbyKey1.sql
new file mode 100644
index 0000000..c19e69e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsGroupbyKey1.sql
@@ -0,0 +1,9 @@
+SELECT
+  user.name,
+  sum(retweet_count) as total_retweet
+FROM
+  tweets
+GROUP BY
+  user.name
+order by
+  user.name;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsJoinKey1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsJoinKey1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsJoinKey1.sql
new file mode 100644
index 0000000..336840e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testNestedFieldAsJoinKey1.sql
@@ -0,0 +1,7 @@
+SELECT
+  t1.user.id,
+  t1.user.name,
+  t2.user.id,
+  t2.user.name
+FROM
+  tweets t1 join tweets t2 ON t1.user.id = t2.user.id
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect0.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect0.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect0.sql
new file mode 100644
index 0000000..a594bcf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect0.sql
@@ -0,0 +1 @@
+SELECT title, name.first_name, name.last_name FROM sample1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect1.sql
new file mode 100644
index 0000000..b099e77
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect1.sql
@@ -0,0 +1 @@
+SELECT title, (name.first_name || ' ' || name.last_name) as full_name FROM sample1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect2.sql
new file mode 100644
index 0000000..9993a4e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect2.sql
@@ -0,0 +1,61 @@
+SELECT
+  coordinates,
+  favorited,
+  truncated,
+  created_at,
+  id_str,
+  in_reply_to_user_id_str,
+  contributors,
+  "text",
+  metadata.iso_language_code,
+  metadata.result_type,
+  retweet_count,
+  in_reply_to_status_id_str,
+  id,
+  geo,
+  retweeted,
+  in_reply_to_user_id,
+  place,
+  user.profile_sidebar_fill_color,
+  user.profile_sidebar_border_color,
+  user.profile_background_tile,
+  user.name,
+  user.profile_image_url,
+  user.created_at,
+  user.location,
+  user.follow_request_sent,
+  user.profile_link_color,
+  user.is_translator,
+  user.id_str,
+  user.default_profile,
+  user.contributors_enabled,
+  user.favourites_count,
+  user.url,
+  user.profile_image_url_https,
+  user.utc_offset,
+  user.id,
+  user.profile_use_background_image,
+  user.listed_count,
+  user.profile_text_color,
+  user.lang,
+  user.followers_count,
+  user.protected,
+  user.notifications,
+  user.profile_background_image_url_https,
+  user.profile_background_color,
+  user.verified,
+  user.geo_enabled,
+  user.time_zone,
+  user.description,
+  user.default_profile_image,
+  user.profile_background_image_url,
+  user.statuses_count,
+  user.friends_count,
+  user.following,
+  user.show_all_inline_media,
+  user.screen_name,
+  in_reply_to_screen_name,
+  source,
+  in_reply_to_status_id
+FROM
+  tweets;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect3.sql
new file mode 100644
index 0000000..dfc79e9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/testSelect3.sql
@@ -0,0 +1 @@
+select glossary.title, glossary."GlossDiv"."title" from sample5;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/tweets_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/tweets_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/tweets_ddl.sql
new file mode 100644
index 0000000..e750095
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectNestedRecord/tweets_ddl.sql
@@ -0,0 +1,74 @@
+CREATE EXTERNAL TABLE IF NOT EXISTS ${0} (
+  coordinates TEXT,
+  favorited BOOL,
+  truncated BOOL,
+  created_at TIMESTAMP,
+  id_str TEXT,
+  /*entrities RECORD ( -- when we support array, we should remove this comment.
+    urls ARRAY<TEXT>
+  )*/
+  in_reply_to_user_id_str TEXT,
+  contributors TEXT,
+  text TEXT,
+  metadata RECORD (
+    iso_language_code TEXT,
+    result_type TEXT
+  ),
+  retweet_count INTEGER,
+  in_reply_to_status_id_str TEXT,
+  id TEXT,
+  geo TEXT,
+  retweeted BOOL,
+  in_reply_to_user_id TEXT,
+  place TEXT,
+  user RECORD (
+    profile_sidebar_fill_color TEXT,
+    profile_sidebar_border_color TEXT,
+    profile_background_tile TEXT,
+    name TEXT,
+    profile_image_url TEXT,
+    created_at TIMESTAMP,
+    location TEXT,
+    follow_request_sent TEXT,
+    profile_link_color TEXT,
+    is_translator BOOL,
+    id_str TEXT,
+    /* -- when we support array, we should fill the following comments.
+    entities RECORD (
+      url RECORD (
+      ),
+      description RECORD (
+      )
+    ), */
+    default_profile BOOL,
+    contributors_enabled BOOL,
+    favourites_count INTEGER,
+    url TEXT,
+    profile_image_url_https TEXT,
+    utc_offset INTEGER,
+    id BIGINT,
+    profile_use_background_image BOOL,
+    listed_count INTEGER,
+    profile_text_color TEXT,
+    lang TEXT,
+    followers_count INTEGER,
+    protected BOOL,
+    notifications TEXT,
+    profile_background_image_url_https TEXT,
+    profile_background_color TEXT,
+    verified TEXT,
+    geo_enabled TEXT,
+    time_zone TEXT,
+    description TEXT,
+    default_profile_image TEXT,
+    profile_background_image_url TEXT,
+    statuses_count INTEGER,
+    friends_count INTEGER,
+    following TEXT,
+    show_all_inline_media BOOL,
+    screen_name TEXT
+  ),
+  in_reply_to_screen_name TEXT,
+  source TEXT,
+  in_reply_to_status_id TEXT
+) USING JSON LOCATION ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/customer_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/customer_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/customer_ddl.sql
new file mode 100644
index 0000000..ca43710
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/customer_ddl.sql
@@ -0,0 +1,9 @@
+CREATE TABLE customer_parts (
+  c_custkey    INT4,
+  c_name    TEXT,
+  c_address    TEXT,
+  c_phone    TEXT,
+  c_acctbal    FLOAT8,
+  c_mktsegment    TEXT,
+  c_comment    TEXT
+) PARTITION BY COLUMN (c_nationkey INT4);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_ddl.sql
new file mode 100644
index 0000000..d2c97c5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_ddl.sql
@@ -0,0 +1,4 @@
+CREATE EXTERNAL TABLE ${0} (
+  t_timestamp  TIMESTAMP,
+  t_date    DATE
+) USING TEXT LOCATION ${table.path}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_timezoned_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_timezoned_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_timezoned_ddl.sql
new file mode 100644
index 0000000..131e619
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/datetime_table_timezoned_ddl.sql
@@ -0,0 +1,4 @@
+CREATE EXTERNAL TABLE ${0} (
+  t_timestamp  TIMESTAMP,
+  t_date    DATE
+) USING TEXT WITH ('timezone' = 'GMT+9') LOCATION ${table.path}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/insert_into_customer.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/insert_into_customer.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/insert_into_customer.sql
new file mode 100644
index 0000000..8767ba4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/insert_into_customer.sql
@@ -0,0 +1,11 @@
+INSERT INTO customer_parts
+  SELECT
+    c_custkey,
+    c_name,
+    c_address,
+    c_phone,
+    c_acctbal,
+    c_mktsegment,
+    c_comment,
+    c_nationkey
+  FROM customer;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table1_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table1_ddl.sql
new file mode 100644
index 0000000..8309d11
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table1_ddl.sql
@@ -0,0 +1,3 @@
+create external table table1 (id int, name text, score float, type text) using text
+with ('text.delimiter'='||', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table2_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table2_ddl.sql
new file mode 100644
index 0000000..2fb821a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table2_ddl.sql
@@ -0,0 +1,3 @@
+create external table table2 (id int, name text, score float, type text) using text
+with ('text.delimiter'='ㅎ', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table3_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table3_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table3_ddl.sql
new file mode 100644
index 0000000..8309d11
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table3_ddl.sql
@@ -0,0 +1,3 @@
+create external table table1 (id int, name text, score float, type text) using text
+with ('text.delimiter'='||', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table4_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table4_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table4_ddl.sql
new file mode 100644
index 0000000..2fb821a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/multibytes_delimiter_table4_ddl.sql
@@ -0,0 +1,3 @@
+create external table table2 (id int, name text, score float, type text) using text
+with ('text.delimiter'='ㅎ', 'text.null'='NULL') location ${table.path};
+

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhen.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhen.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhen.sql
new file mode 100644
index 0000000..20e8190
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhen.sql
@@ -0,0 +1,11 @@
+select
+  r_regionkey,
+  case
+    when r_regionkey = 1 then 'one'
+    when r_regionkey = 2 then 'two'
+    when r_regionkey = 3 then 'three'
+    when r_regionkey = 4 then 'four'
+    else 'zero'
+  end as cond
+from
+  region;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenRound.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenRound.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenRound.sql
new file mode 100644
index 0000000..cee905a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenRound.sql
@@ -0,0 +1,8 @@
+select *
+  from (select n_nationkey as key,
+               case when n_nationkey > 6 then round((n_nationkey * 100 / 2.123) / (n_regionkey * 50 / 2.123), 2) else 100.0 end as val
+          from nation
+         where n_regionkey > 0
+           and n_nationkey > 0
+  ) a
+order by a.key
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenWithoutElse.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenWithoutElse.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenWithoutElse.sql
new file mode 100644
index 0000000..279d3fd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCaseWhenWithoutElse.sql
@@ -0,0 +1,10 @@
+select
+  r_regionkey,
+  case
+    when r_regionkey = 1 then 10 + r_regionkey
+    when r_regionkey = 2 then 10 + r_regionkey
+    when r_regionkey = 3 then 10 + r_regionkey
+    when r_regionkey = 4 then 10 + r_regionkey
+  end as cond
+from
+  region;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition1.sql
new file mode 100644
index 0000000..f47d21c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition1.sql
@@ -0,0 +1,7 @@
+SELECT
+  L_ORDERKEY,
+  L_PARTKEY
+FROM
+  LINEITEM
+WHERE
+  L_ORDERKEY > L_PARTKEY;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition2.sql
new file mode 100644
index 0000000..dd153d5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testColumnEqualityButNotJoinCondition2.sql
@@ -0,0 +1,7 @@
+SELECT
+  SUBSTR(L_ORDERKEY::TEXT,1,1),
+  SUBSTR(L_PARTKEY::TEXT,1,1)
+  FROM
+      LINEITEM
+  WHERE
+  SUBSTR(L_ORDERKEY::TEXT,1,1) = SUBSTR(L_PARTKEY::TEXT,1,1);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCreateAfterSelect.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCreateAfterSelect.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCreateAfterSelect.sql
new file mode 100644
index 0000000..2bc4be9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testCreateAfterSelect.sql
@@ -0,0 +1 @@
+create table orderkeys as select l_orderkey from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef1.sql
new file mode 100644
index 0000000..a483758
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef1.sql
@@ -0,0 +1 @@
+SELECT L_ORDERKEY FROM "TestSelectQuery"."LineItem";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef2.sql
new file mode 100644
index 0000000..6abc3f9
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef2.sql
@@ -0,0 +1 @@
+SELECT "LineItem".L_ORDERKEY FROM "TestSelectQuery"."LineItem";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef3.sql
new file mode 100644
index 0000000..3fded5f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testDatabaseRef3.sql
@@ -0,0 +1 @@
+SELECT "TestSelectQuery"."LineItem".L_ORDERKEY FROM "TestSelectQuery"."LineItem";
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testExplainSelect.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testExplainSelect.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testExplainSelect.sql
new file mode 100644
index 0000000..4d4f32c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testExplainSelect.sql
@@ -0,0 +1 @@
+explain select l_orderkey, l_partkey from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInClause.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInClause.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInClause.sql
new file mode 100644
index 0000000..406fd31
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInClause.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem where l_partkey in (2,3);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInStrClause.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInStrClause.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInStrClause.sql
new file mode 100644
index 0000000..8a4f426
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testInStrClause.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem where l_returnflag in ('R', 'S');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLikeClause.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLikeClause.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLikeClause.sql
new file mode 100644
index 0000000..b173aa1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLikeClause.sql
@@ -0,0 +1 @@
+SELECT n_name FROM nation WHERE n_name LIKE '%IA';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLimit.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLimit.sql
new file mode 100644
index 0000000..6e74de5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testLimit.sql
@@ -0,0 +1 @@
+select l_orderkey, l_suppkey from lineitem limit 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter1.sql
new file mode 100644
index 0000000..bd6b02d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter1.sql
@@ -0,0 +1 @@
+select * from table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter2.sql
new file mode 100644
index 0000000..66a69ec
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter2.sql
@@ -0,0 +1 @@
+select * from table2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter3.sql
new file mode 100644
index 0000000..bd6b02d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter3.sql
@@ -0,0 +1 @@
+select * from table1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter4.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter4.sql
new file mode 100644
index 0000000..66a69ec
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testMultiBytesDelimiter4.sql
@@ -0,0 +1 @@
+select * from table2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNestedPythonFunction.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNestedPythonFunction.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNestedPythonFunction.sql
new file mode 100644
index 0000000..02b2059
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNestedPythonFunction.sql
@@ -0,0 +1 @@
+select * from nation where add_py(n_regionkey, return_one()) < 2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonFromSelect1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonFromSelect1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonFromSelect1.sql
new file mode 100644
index 0000000..ca0ef7a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonFromSelect1.sql
@@ -0,0 +1 @@
+select upper('abc');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonQualifiedNames.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonQualifiedNames.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonQualifiedNames.sql
new file mode 100644
index 0000000..0c176b7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNonQualifiedNames.sql
@@ -0,0 +1 @@
+select l_orderkey, l_partkey from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotEqual.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotEqual.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotEqual.sql
new file mode 100644
index 0000000..ccd6a9f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotEqual.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem where l_orderkey != 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInClause.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInClause.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInClause.sql
new file mode 100644
index 0000000..1e9ea93
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInClause.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem where l_partkey not in (2,3);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInStrClause.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInStrClause.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInStrClause.sql
new file mode 100644
index 0000000..8e38750
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testNotInStrClause.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem where l_returnflag not in ('N', 'S');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testRealValueCompare.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testRealValueCompare.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testRealValueCompare.sql
new file mode 100644
index 0000000..589b51b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testRealValueCompare.sql
@@ -0,0 +1 @@
+select ps_supplycost from partsupp where ps_supplycost = 771.64;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect.sql
new file mode 100644
index 0000000..0c176b7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect.sql
@@ -0,0 +1 @@
+select l_orderkey, l_partkey from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect2.sql
new file mode 100644
index 0000000..3bc28da
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect2.sql
@@ -0,0 +1 @@
+select l_orderkey, l_partkey, l_orderkey + l_partkey as plus from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect3.sql
new file mode 100644
index 0000000..1c85f59
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelect3.sql
@@ -0,0 +1 @@
+select l_orderkey + l_partkey as plus from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterik.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterik.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterik.sql
new file mode 100644
index 0000000..cda515b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterik.sql
@@ -0,0 +1 @@
+select * from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql
new file mode 100644
index 0000000..cda515b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql
@@ -0,0 +1 @@
+select * from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql
new file mode 100644
index 0000000..71da1f1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql
@@ -0,0 +1 @@
+select * from lineitem where l_orderkey = 2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql
new file mode 100644
index 0000000..4d75b08
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql
@@ -0,0 +1 @@
+select * from lineitem where l_orderkey % 2 = 0;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk4.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk4.sql
new file mode 100644
index 0000000..71580c8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk4.sql
@@ -0,0 +1 @@
+select length(l_comment), l_extendedprice * l_discount, *, l_tax * 10 from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk5.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk5.sql
new file mode 100644
index 0000000..d538eb8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectAsterisk5.sql
@@ -0,0 +1 @@
+select * from (select l_orderkey, 1 from lineitem where l_orderkey % 2 = 0) t1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAlias1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAlias1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAlias1.sql
new file mode 100644
index 0000000..a9ce4a2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAlias1.sql
@@ -0,0 +1 @@
+select l_orderkey as col1, l_orderkey + 1 as col2 from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation1.sql
new file mode 100644
index 0000000..91170e3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation1.sql
@@ -0,0 +1 @@
+select (l_orderkey + l_orderkey) l_orderkey from lineitem where l_orderkey > 2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation2.sql
new file mode 100644
index 0000000..89f63fd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation2.sql
@@ -0,0 +1 @@
+select (-l_orderkey) as l_orderkey from lineitem order by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation3.sql
new file mode 100644
index 0000000..98336b7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectColumnAliasExistingInRelation3.sql
@@ -0,0 +1,19 @@
+SELECT l_orderkey FROM (
+
+-- actual test query
+  SELECT
+    T1.l_orderkey
+  FROM
+    LINEITEM
+  INNER JOIN (
+    SELECT
+      T1.l_orderkey
+    FROM (
+      SELECT
+        LINEITEM.l_orderkey AS l_orderkey
+      FROM
+        LINEITEM
+    ) T1
+  ) T1 ON LINEITEM.l_orderkey=T1.l_orderkey
+
+) A ORDER BY l_orderkey; -- for determinant query result
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectDistinct.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectDistinct.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectDistinct.sql
new file mode 100644
index 0000000..224e181
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectDistinct.sql
@@ -0,0 +1,7 @@
+select
+  l_orderkey, l_linenumber
+from (
+  select distinct l_orderkey, l_linenumber from lineitem
+) table1
+order by
+  l_orderkey, l_linenumber;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectOnSessionTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectOnSessionTable.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectOnSessionTable.sql
new file mode 100644
index 0000000..a953751
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectOnSessionTable.sql
@@ -0,0 +1 @@
+select * from information_schema.session where name = 'CURRENT_DATABASE';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectPythonFuncs.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectPythonFuncs.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectPythonFuncs.sql
new file mode 100644
index 0000000..5ae0d5e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectPythonFuncs.sql
@@ -0,0 +1,2 @@
+select helloworld(), add_py(n_nationkey, n_regionkey) as sum, concat_py(n_name) as concat
+from nation where n_nationkey < 5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases.sql
new file mode 100644
index 0000000..baf21ea
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases.sql
@@ -0,0 +1 @@
+select l_orderkey, '20130819' as date1, '20130819' as date2 from lineitem where l_orderkey > -1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases2.sql
new file mode 100644
index 0000000..fecabd5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases2.sql
@@ -0,0 +1 @@
+select l_orderkey, '20130819' as date1, '20130819' as date2, '20130819' as date3, '20130819' as date4 from lineitem where l_orderkey > -1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases3.sql
new file mode 100644
index 0000000..ec03a11
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameConstantsWithDifferentAliases3.sql
@@ -0,0 +1,10 @@
+select
+  l_orderkey,
+  '20130819' as date1,
+  '20130819',
+  '20130819',
+  '20130819'
+from
+  lineitem
+where
+  l_orderkey > -1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameExprsWithDifferentAliases.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameExprsWithDifferentAliases.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameExprsWithDifferentAliases.sql
new file mode 100644
index 0000000..52d2c1a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectSameExprsWithDifferentAliases.sql
@@ -0,0 +1 @@
+select l_orderkey, l_partkey + 1 as plus1, l_partkey + 1 as plus2 from lineitem where l_orderkey > -1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithJson.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithJson.json b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithJson.json
new file mode 100644
index 0000000..bf89ab5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithJson.json
@@ -0,0 +1,74 @@
+// select l_orderkey, l_partkey + 1 as plus1, l_partkey + 1 as plus2 from lineitem where l_orderkey > -1;
+{
+    "IsDistinct": false,
+    "Projections": [
+        {
+            "Expr": {
+                "ColumnName": "l_orderkey",
+                "OpType": "Column"
+            },
+            "OpType": "Target"
+        },
+        {
+            "AliasName": "plus1",
+            "Expr": {
+                "LeftExpr": {
+                    "ColumnName": "l_partkey",
+                    "OpType": "Column"
+                },
+                "RightExpr": {
+                    "Value": "1",
+                    "ValueType": "Unsigned_Integer",
+                    "OpType": "Literal"
+                },
+                "OpType": "Plus"
+            },
+            "OpType": "Target"
+        },
+        {
+            "AliasName": "plus2",
+            "Expr": {
+                "LeftExpr": {
+                    "ColumnName": "l_partkey",
+                    "OpType": "Column"
+                },
+                "RightExpr": {
+                    "Value": "1",
+                    "ValueType": "Unsigned_Integer",
+                    "OpType": "Literal"
+                },
+                "OpType": "Plus"
+            },
+            "OpType": "Target"
+        }
+    ],
+    "Expr": {
+        "SelectCondition": {
+            "LeftExpr": {
+                "ColumnName": "l_orderkey",
+                "OpType": "Column"
+            },
+            "RightExpr": {
+                "IsNegative": true,
+                "Expr": {
+                    "Value": "1",
+                    "ValueType": "Unsigned_Integer",
+                    "OpType": "Literal"
+                },
+                "OpType": "Sign"
+            },
+            "OpType": "GreaterThan"
+        },
+        "Expr": {
+            "Relations": [
+                {
+                    "TableName": "lineitem",
+                    "OpType": "Relation"
+                }
+            ],
+            "OpType": "RelationList"
+        },
+        "OpType": "Filter"
+    },
+    "OpType": "Projection"
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses1.sql
new file mode 100644
index 0000000..24f5e3b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses1.sql
@@ -0,0 +1 @@
+(select n_nationkey, n_name from nation where n_nationkey = 1);

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses2.sql
new file mode 100644
index 0000000..e707a8c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithParentheses2.sql
@@ -0,0 +1 @@
+(select n1.n_nationkey, n2.n_name from nation n1 join nation n2 on n1.n_nationkey = n2.n_nationkey where n1.n_nationkey = 1);

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithPredicateOnPythonFunc.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithPredicateOnPythonFunc.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithPredicateOnPythonFunc.sql
new file mode 100644
index 0000000..aa9feba
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSelectWithPredicateOnPythonFunc.sql
@@ -0,0 +1 @@
+select * from nation where add_py(n_regionkey,1) > 2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQuery.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQuery.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQuery.sql
new file mode 100644
index 0000000..cda515b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQuery.sql
@@ -0,0 +1 @@
+select * from lineitem;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimit.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimit.sql
new file mode 100644
index 0000000..79cf804
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimit.sql
@@ -0,0 +1 @@
+select * from lineitem limit 3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimitPartitionedTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimitPartitionedTable.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimitPartitionedTable.sql
new file mode 100644
index 0000000..42362b6
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSimpleQueryWithLimitPartitionedTable.sql
@@ -0,0 +1 @@
+select * from customer_parts limit 10;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testStringCompare.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testStringCompare.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testStringCompare.sql
new file mode 100644
index 0000000..7f4a672
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testStringCompare.sql
@@ -0,0 +1 @@
+select l_orderkey from lineitem where l_shipdate <= '1996-03-22';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumFloatOverflow.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumFloatOverflow.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumFloatOverflow.sql
new file mode 100644
index 0000000..9ec941a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumFloatOverflow.sql
@@ -0,0 +1 @@
+select sum(cast(L_EXTENDEDPRICE * 3.21506374375027E33 as FLOAT8)) from lineitem where l_quantity > 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumIntOverflow.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumIntOverflow.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumIntOverflow.sql
new file mode 100644
index 0000000..96421eb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testSumIntOverflow.sql
@@ -0,0 +1 @@
+select sum(cast(l_quantity * 25264513 as INT4)) from lineitem where l_quantity > 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable1.sql
new file mode 100644
index 0000000..38c9e90
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable1.sql
@@ -0,0 +1 @@
+SELECT * FROM timezoned1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable2.sql
new file mode 100644
index 0000000..1fd9e36
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable2.sql
@@ -0,0 +1,2 @@
+SET TIME ZONE 'GMT';
+SELECT * FROM timezoned2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable3.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable3.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable3.sql
new file mode 100644
index 0000000..32b9c3a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable3.sql
@@ -0,0 +1 @@
+SELECT * FROM timezoned3;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable4.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable4.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable4.sql
new file mode 100644
index 0000000..acd096b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable4.sql
@@ -0,0 +1,2 @@
+SET TIME ZONE 'GMT+9';
+SELECT * FROM timezoned4;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable5.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable5.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable5.sql
new file mode 100644
index 0000000..13894ce
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testTimezonedTable5.sql
@@ -0,0 +1,2 @@
+SET SESSION TIMEZONE = 'GMT+9';
+SELECT * FROM timezoned5;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond1.sql
new file mode 100644
index 0000000..cb44aed
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond1.sql
@@ -0,0 +1 @@
+select l_orderkey + l_partkey as plus from lineitem where plus = 4;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond2.sql
new file mode 100644
index 0000000..7fa0d18
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCond2.sql
@@ -0,0 +1,9 @@
+select *
+from (
+ select a.l_orderkey, count(*) as cnt, sum(l_extendedprice) as sum1
+  from lineitem a
+  group by a.l_orderkey
+  having sum1 > 70000
+) t
+where t.cnt > 1
+order by t.l_orderkey
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias1.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias1.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias1.sql
new file mode 100644
index 0000000..e758dfd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias1.sql
@@ -0,0 +1 @@
+select l_orderkey as orderkey, l_partkey from lineitem where orderkey = 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias2.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias2.sql b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias2.sql
new file mode 100644
index 0000000..566ea2d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSelectQuery/testWhereCondWithAlias2.sql
@@ -0,0 +1 @@
+select l_orderkey as orderkey from lineitem where l_orderkey = 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_asc_desc_keys.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_asc_desc_keys.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_asc_desc_keys.sql
new file mode 100644
index 0000000..936e5ed
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_asc_desc_keys.sql
@@ -0,0 +1 @@
+create external table table2 (col1 int8, col2 int8) using text with ('text.delimiter'=',') location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_date_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_date_ddl.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_date_ddl.sql
new file mode 100644
index 0000000..3ba63e0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/create_table_with_date_ddl.sql
@@ -0,0 +1,10 @@
+-- Sort Table
+-- It is used in TestSortQuery::testSortWithDate
+
+create external table testSortWithDate (
+  col1 timestamp,
+	col2 date,
+	col3 time
+) using text
+with ('text.delimiter'='|', 'text.null'='NULL')
+location ${table.path};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testAsterisk.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testAsterisk.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testAsterisk.sql
new file mode 100644
index 0000000..e88ca43
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testAsterisk.sql
@@ -0,0 +1 @@
+select *, length(l_comment) as len_comment from lineitem order by len_comment;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSort.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSort.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSort.sql
new file mode 100644
index 0000000..7958002
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSort.sql
@@ -0,0 +1 @@
+select l_linenumber, l_orderkey from lineitem order by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupby.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupby.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupby.sql
new file mode 100644
index 0000000..81a1d8e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupby.sql
@@ -0,0 +1 @@
+select max(l_quantity) as maxq, l_orderkey from lineitem group by l_orderkey order by l_orderkey;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupbyWithAlias.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupbyWithAlias.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupbyWithAlias.sql
new file mode 100644
index 0000000..a167e76
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortAfterGroupbyWithAlias.sql
@@ -0,0 +1 @@
+select max(l_quantity) as max_quantity, l_orderkey from lineitem group by l_orderkey order by max_quantity;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortDesc.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortDesc.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortDesc.sql
new file mode 100644
index 0000000..4252643
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortDesc.sql
@@ -0,0 +1 @@
+select l_linenumber, l_orderkey from lineitem order by l_orderkey desc;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortFirstDesc.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortFirstDesc.sql b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortFirstDesc.sql
new file mode 100644
index 0000000..644feb0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestSortQuery/testSortFirstDesc.sql
@@ -0,0 +1 @@
+select col1, col2 from sortfirstdesc order by col1 desc, col2;
\ No newline at end of file


[10/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash.plan
new file mode 100644
index 0000000..c982ee3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+         SCAN(0) on joins.part_
+           => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+           => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+           => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(1) on joins.supplier_
+              => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+              => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+              => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=joins.supplier_
+ 1: type=Broadcast, tables=joins.part_
+ 2: type=Broadcast, tables=default.partsupp
+ 3: type=Broadcast, tables=default.region
+
+SORT(26)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+         SCAN(0) on joins.part_
+           => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+           => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+           => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(1) on joins.supplier_
+              => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+              => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+              => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..19750a2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Hash_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+         SCAN(0) on joins.part_
+           => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+           => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+           => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(1) on joins.supplier_
+              => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+              => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+              => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=joins.supplier_.s_suppkey (INT4), num=32)
+
+SCAN(1) on joins.supplier_
+  => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+  => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+  => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=joins.supplier_.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+  => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+  => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+     => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=joins.part_.p_partkey (INT4), num=32)
+
+SCAN(0) on joins.part_
+  => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+  => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+  => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(3) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(4) on default.region
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=joins.part_.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=joins.supplier_.s_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+  => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+  => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+  => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+     => in schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(1) default.region.r_regionkey (INT4)}
+     => in schema: {(1) default.region.r_regionkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=joins.supplier_.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort.plan
new file mode 100644
index 0000000..c982ee3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+         SCAN(0) on joins.part_
+           => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+           => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+           => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(1) on joins.supplier_
+              => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+              => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+              => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=joins.supplier_
+ 1: type=Broadcast, tables=joins.part_
+ 2: type=Broadcast, tables=default.partsupp
+ 3: type=Broadcast, tables=default.region
+
+SORT(26)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+         SCAN(0) on joins.part_
+           => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+           => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+           => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(1) on joins.supplier_
+              => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+              => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+              => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..19750a2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.Sort_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+         SCAN(0) on joins.part_
+           => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+           => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+           => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(1) on joins.supplier_
+              => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+              => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+              => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=joins.supplier_.s_suppkey (INT4), num=32)
+
+SCAN(1) on joins.supplier_
+  => target list: joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)
+  => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+  => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=joins.supplier_.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: joins.supplier_.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+  => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+  => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+     => in schema: {(7) joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT), joins.supplier_.s_suppkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=joins.part_.p_partkey (INT4), num=32)
+
+SCAN(0) on joins.part_
+  => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)
+  => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+  => in schema: {(9) joins.part_.p_brand (TEXT), joins.part_.p_comment (TEXT), joins.part_.p_container (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_name (TEXT), joins.part_.p_partkey (INT4), joins.part_.p_retailprice (FLOAT8), joins.part_.p_size (INT4), joins.part_.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(3) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(4) on default.region
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=joins.part_.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=joins.supplier_.s_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: joins.part_.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+  => target list: joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)
+  => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+  => in schema: {(9) default.partsupp.ps_partkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+     => in schema: {(2) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(7) default.partsupp.ps_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(1) default.region.r_regionkey (INT4)}
+     => in schema: {(1) default.region.r_regionkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=joins.supplier_.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: joins.supplier_.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+        => in schema: {(8) joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_nationkey (INT4), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: joins.supplier_.s_acctbal (FLOAT8) (asc),joins.supplier_.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),joins.part_.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), joins.part_.p_mfgr (TEXT), joins.part_.p_partkey (INT4), joins.supplier_.s_acctbal (FLOAT8), joins.supplier_.s_address (TEXT), joins.supplier_.s_comment (TEXT), joins.supplier_.s_name (TEXT), joins.supplier_.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.result
new file mode 100644
index 0000000..dc2831c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabases.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------
+4032.68,Supplier#000000002,ETHIOPIA,1,Manufacturer#1,89eJ5ksX3ImxJQBvxObC,,15-679-861-2259, slyly bold instructions. idle dependen
+4192.4,Supplier#000000003,ARGENTINA,2,Manufacturer#1,q1,G3Pj6OjIuUYfUoH18BFTKP5aU9bEV3,11-383-516-1199,blithely silent requests after the express dependencies are sl
+4641.08,Supplier#000000004,MOROCCO,3,Manufacturer#4,Bk7ah4CK8SYQTepEmvMkkgMwg,25-843-787-7479,riously even requests above the exp

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabasesWithJson.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabasesWithJson.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabasesWithJson.result
new file mode 100644
index 0000000..dc0968f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinOnMultipleDatabasesWithJson.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------
+4032.68,Supplier#000000002,ETHIOPIA,1,Manufacturer#1,89eJ5ksX3ImxJQBvxObC,,15-679-861-2259, slyly bold instructions. idle dependen
+4192.4,Supplier#000000003,ARGENTINA,2,Manufacturer#1,q1,G3Pj6OjIuUYfUoH18BFTKP5aU9bEV3,11-383-516-1199,blithely silent requests after the express dependencies are sl
+4641.08,Supplier#000000004,MOROCCO,3,Manufacturer#4,Bk7ah4CK8SYQTepEmvMkkgMwg,25-843-787-7479,riously even requests above the exp
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithJson.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithJson.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithJson.result
new file mode 100644
index 0000000..23d985e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithJson.result
@@ -0,0 +1,27 @@
+len,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment,?multiply
+-------------------------------
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s,50
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca,50
+45,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse,10
+45,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse,20
+45,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse,30
+45,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse,40
+45,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse,50
+108,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,10
+108,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,20
+108,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,30
+108,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,40
+108,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,50
+115,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,10
+115,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,20
+115,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,30
+115,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,40
+115,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,50
\ No newline at end of file


[13/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..742e346
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_custkey (INT4)
+  => out schema: {(1) default.customer.c_custkey (INT4)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+SCAN(1) on default.empty_orders
+  => target list: default.empty_orders.o_orderkey (INT4)
+  => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+  => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(1) default.empty_orders.o_orderkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(1) default.customer.c_custkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort.plan
new file mode 100644
index 0000000..988980c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.empty_orders
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..742e346
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(1) on default.empty_orders
+        => target list: default.empty_orders.o_orderkey (INT4)
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+      SCAN(0) on default.customer
+        => target list: default.customer.c_custkey (INT4)
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+SCAN(0) on default.customer
+  => target list: default.customer.c_custkey (INT4)
+  => out schema: {(1) default.customer.c_custkey (INT4)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+SCAN(1) on default.empty_orders
+  => target list: default.empty_orders.o_orderkey (INT4)
+  => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+  => in schema: {(9) default.empty_orders.o_clerk (TEXT), default.empty_orders.o_comment (TEXT), default.empty_orders.o_custkey (INT4), default.empty_orders.o_orderdate (TEXT), default.empty_orders.o_orderkey (INT4), default.empty_orders.o_orderpriority (TEXT), default.empty_orders.o_orderstatus (TEXT), default.empty_orders.o_shippriority (INT4), default.empty_orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.empty_orders.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.customer.c_custkey (INT4) = default.empty_orders.o_orderkey (INT4)
+     => target list: default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(1) default.empty_orders.o_orderkey (INT4)}
+        => in schema: {(1) default.empty_orders.o_orderkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.customer.c_custkey (INT4)}
+        => in schema: {(1) default.customer.c_custkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.customer.c_custkey (INT4) (asc),default.empty_orders.o_orderkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.empty_orders.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.result
new file mode 100644
index 0000000..e27c711
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithEmptyTable1.result
@@ -0,0 +1,2 @@
+c_custkey,o_orderkey
+-------------------------------

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash.plan
new file mode 100644
index 0000000..d161811
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash.plan
@@ -0,0 +1,63 @@
+explain
+-------------------------------
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(0) on default.region as a
+           => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+         SCAN(1) on default.region as b
+           => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.a
+
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(0) on default.region as a
+           => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+         SCAN(1) on default.region as b
+           => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..cfbfa19
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Hash_NoBroadcast.plan
@@ -0,0 +1,90 @@
+explain
+-------------------------------
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(0) on default.region as a
+           => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+         SCAN(1) on default.region as b
+           => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region as b
+  => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+  => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+  => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.region as a
+  => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+  => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+  => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(10) on eb_0000000000000_0000_000002
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+         SCAN(9) on eb_0000000000000_0000_000001
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort.plan
new file mode 100644
index 0000000..d161811
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort.plan
@@ -0,0 +1,63 @@
+explain
+-------------------------------
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(0) on default.region as a
+           => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+         SCAN(1) on default.region as b
+           => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.a
+
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(0) on default.region as a
+           => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+         SCAN(1) on default.region as b
+           => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..cfbfa19
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.Sort_NoBroadcast.plan
@@ -0,0 +1,90 @@
+explain
+-------------------------------
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(0) on default.region as a
+           => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+         SCAN(1) on default.region as b
+           => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+
+SCAN(1) on default.region as b
+  => target list: default.b.r_name (TEXT) as b_name, default.b.r_name (TEXT)
+  => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+  => in schema: {(3) default.b.r_comment (TEXT), default.b.r_name (TEXT), default.b.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+SCAN(0) on default.region as a
+  => target list: default.a.r_name (TEXT) as a_name, default.a.r_name (TEXT)
+  => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+  => in schema: {(3) default.a.r_comment (TEXT), default.a.r_name (TEXT), default.a.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE)
+
+PROJECTION(3)
+  => Targets: a_name (TEXT), b_name (TEXT)
+  => out schema: {(2) a_name (TEXT), b_name (TEXT)}
+  => in  schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+   SELECTION(6)
+     => Search Cond: default.a.r_name (TEXT) < default.b.r_name (TEXT)
+      JOIN(7)(CROSS)
+        => target list: a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)
+        => out schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+        => in schema: {(4) a_name (TEXT), b_name (TEXT), default.a.r_name (TEXT), default.b.r_name (TEXT)}
+         SCAN(10) on eb_0000000000000_0000_000002
+           => out schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+           => in schema: {(2) a_name (TEXT), default.a.r_name (TEXT)}
+         SCAN(9) on eb_0000000000000_0000_000001
+           => out schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+           => in schema: {(2) b_name (TEXT), default.b.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.result
new file mode 100644
index 0000000..8ddc197
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testCrossJoinWithThetaJoinConditionInWhere.result
@@ -0,0 +1,12 @@
+a_name,b_name
+-------------------------------
+AFRICA,AMERICA
+AFRICA,ASIA
+AFRICA,EUROPE
+AFRICA,MIDDLE EAST
+AMERICA,ASIA
+AMERICA,EUROPE
+AMERICA,MIDDLE EAST
+ASIA,EUROPE
+ASIA,MIDDLE EAST
+EUROPE,MIDDLE EAST

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash.plan
new file mode 100644
index 0000000..69ede30
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash.plan
@@ -0,0 +1,53 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(0) on default.table20 as t3
+     => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(1) on default.table21 as t4
+     => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.t4
+
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(0) on default.table20 as t3
+     => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(1) on default.table21 as t4
+     => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..890f935
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Hash_NoBroadcast.plan
@@ -0,0 +1,80 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(0) on default.table20 as t3
+     => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(1) on default.table21 as t4
+     => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?int8_1 (INT8), num=32)
+
+SCAN(1) on default.table21 as t4
+  => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.t3.id (INT8), num=32)
+
+SCAN(0) on default.table20 as t3
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+  => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+  => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?int8_1 (INT8), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.t3.id (INT8), num=32)
+
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort.plan
new file mode 100644
index 0000000..69ede30
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort.plan
@@ -0,0 +1,53 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(0) on default.table20 as t3
+     => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(1) on default.table21 as t4
+     => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.t4
+
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(0) on default.table20 as t3
+     => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(1) on default.table21 as t4
+     => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..890f935
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.Sort_NoBroadcast.plan
@@ -0,0 +1,80 @@
+explain
+-------------------------------
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(0) on default.table20 as t3
+     => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(1) on default.table21 as t4
+     => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000004)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000004
+   |-eb_0000000000000_0000_000003
+      |-eb_0000000000000_0000_000002
+      |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?int8_1 (INT8), num=32)
+
+SCAN(1) on default.table21 as t4
+  => target list: CAST (default.t4.id (INT4) AS INT8) as ?int8_1, default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(4) default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.t3.id (INT8), num=32)
+
+SCAN(0) on default.table20 as t3
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)
+  => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+  => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?int8_1 (INT8), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.t3.id (INT8), num=32)
+
+JOIN(5)(INNER)
+  => Join Cond: default.t3.id (INT8) = ?int8_1 (INT8)
+  => target list: default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)
+  => out schema: {(8) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+  => in schema: {(9) ?int8_1 (INT8), default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+   SCAN(8) on eb_0000000000000_0000_000002
+     => out schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+     => in schema: {(4) default.t3.id (INT8), default.t3.name (TEXT), default.t3.score (FLOAT4), default.t3.type (TEXT)}
+   SCAN(7) on eb_0000000000000_0000_000001
+     => out schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+     => in schema: {(5) ?int8_1 (INT8), default.t4.id (INT4), default.t4.name (TEXT), default.t4.score (FLOAT4), default.t4.type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.result
new file mode 100644
index 0000000..3626882
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testDifferentTypesJoinCondition.result
@@ -0,0 +1,7 @@
+id,name,score,type,id,name,score,type
+-------------------------------
+1,ooo,1.1,a,1,ooo,1.1,a
+2,ppp,2.3,b,2,ppp,2.3,b
+3,qqq,3.4,c,3,qqq,3.4,c
+4,rrr,4.5,d,4,rrr,4.5,d
+5,xxx,5.6,e,5,xxx,5.6,e

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash.plan
new file mode 100644
index 0000000..de4fc4f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..6153908
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4)
+  => out schema: {(1) default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+  => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(1) default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort.plan
new file mode 100644
index 0000000..de4fc4f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..6153908
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.region
+        => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_regionkey (INT4)
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation
+  => target list: default.nation.n_regionkey (INT4)
+  => out schema: {(1) default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(0) on default.region
+  => target list: CASE WHEN default.region.r_regionkey (INT4) = 1 THEN one WHEN default.region.r_regionkey (INT4) = 2 THEN two WHEN default.region.r_regionkey (INT4) = 3 THEN three WHEN default.region.r_regionkey (INT4) = 4 THEN four ELSE zero END as cond, default.region.r_regionkey (INT4)
+  => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.region.r_regionkey (INT4) = default.nation.n_regionkey (INT4)
+     => target list: cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) cond (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.nation.n_regionkey (INT4)}
+        => in schema: {(1) default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.region.r_regionkey (INT4) (asc),default.nation.n_regionkey (INT4) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+     => in schema: {(3) cond (TEXT), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.result
new file mode 100644
index 0000000..0ac2083
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testInnerJoinAndCaseWhen.result
@@ -0,0 +1,27 @@
+r_regionkey,n_regionkey,cond
+-------------------------------
+0,0,zero
+0,0,zero
+0,0,zero
+0,0,zero
+0,0,zero
+1,1,one
+1,1,one
+1,1,one
+1,1,one
+1,1,one
+2,2,two
+2,2,two
+2,2,two
+2,2,two
+2,2,two
+3,3,three
+3,3,three
+3,3,three
+3,3,three
+3,3,three
+4,4,four
+4,4,four
+4,4,four
+4,4,four
+4,4,four


[51/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
TAJO-1761: Separate an integration unit test kit into an independent module.

Closes #690


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

Branch: refs/heads/master
Commit: a4106883dda73802548dc867ba25e69df630dc9b
Parents: ab60d02
Author: Hyunsik Choi <hy...@apache.org>
Authored: Fri Aug 14 23:20:15 2015 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Fri Aug 14 23:20:15 2015 +0900

----------------------------------------------------------------------
 CHANGES                                         |    3 +
 pom.xml                                         |    2 +
 tajo-cluster-tests/pom.xml                      |  302 ++++
 .../org/apache/tajo/BackendTestingUtil.java     |   71 +
 .../org/apache/tajo/HBaseTestClusterUtil.java   |  184 +++
 .../java/org/apache/tajo/IntegrationTest.java   |   22 +
 .../apache/tajo/LocalTajoTestingUtility.java    |  169 +++
 .../test/java/org/apache/tajo/NamedTest.java    |   27 +
 .../java/org/apache/tajo/QueryTestCaseBase.java | 1030 +++++++++++++
 .../org/apache/tajo/TajoTestingCluster.java     |  778 ++++++++++
 .../test/java/org/apache/tajo/TpchTestBase.java |  113 ++
 tajo-core-tests/pom.xml                         |  356 +++++
 tajo-core-tests/src/test/java/log4j.properties  |   28 +
 .../org/apache/tajo/TestQueryIdFactory.java     |   58 +
 .../test/java/org/apache/tajo/TestTajoIds.java  |  168 +++
 .../org/apache/tajo/benchmark/TestTPCH.java     |   68 +
 .../apache/tajo/cli/tools/TestDDLBuilder.java   |  133 ++
 .../org/apache/tajo/cli/tools/TestTajoDump.java |  124 ++
 .../cli/tsql/TestDefaultCliOutputFormatter.java |  179 +++
 .../apache/tajo/cli/tsql/TestSimpleParser.java  |  286 ++++
 .../org/apache/tajo/cli/tsql/TestTajoCli.java   |  472 ++++++
 .../tajo/cli/tsql/TestTajoCliNegatives.java     |  146 ++
 .../commands/TestExecExternalShellCommand.java  |   45 +
 .../tajo/cli/tsql/commands/TestHdfsCommand.java |   47 +
 .../TestCatalogAdminClientExceptions.java       |  102 ++
 .../tajo/client/TestQueryClientExceptions.java  |  121 ++
 .../org/apache/tajo/client/TestTajoClient.java  |  775 ++++++++++
 .../apache/tajo/client/v2/TestTajoClientV2.java |  274 ++++
 .../tajo/cluster/TestWorkerConnectionInfo.java  |   36 +
 .../engine/codegen/TestEvalCodeGenerator.java   |  310 ++++
 .../engine/codegen/TestGeneratorAdapter.java    |   41 +
 .../apache/tajo/engine/eval/ExprTestBase.java   |  341 +++++
 .../apache/tajo/engine/eval/TestEvalTree.java   |  424 ++++++
 .../tajo/engine/eval/TestEvalTreeUtil.java      |  374 +++++
 .../tajo/engine/eval/TestIntervalType.java      |  124 ++
 .../apache/tajo/engine/eval/TestPredicates.java |  405 +++++
 .../tajo/engine/eval/TestSQLDateTimeTypes.java  |   50 +
 .../tajo/engine/eval/TestSQLExpression.java     | 1001 +++++++++++++
 .../tajo/engine/function/TestAggFunction.java   |   65 +
 .../engine/function/TestBuiltinFunctions.java   |  824 ++++++++++
 .../function/TestConditionalExpressions.java    |  242 +++
 .../engine/function/TestDateTimeFunctions.java  |  483 ++++++
 .../engine/function/TestFunctionLoader.java     |   45 +
 .../engine/function/TestGeneralFunction.java    |   49 +
 .../tajo/engine/function/TestJsonFunctions.java |   66 +
 .../tajo/engine/function/TestMathFunctions.java |  470 ++++++
 .../function/TestPatternMatchingPredicates.java |  139 ++
 .../engine/function/TestPythonFunctions.java    |   43 +
 .../TestStringOperatorsAndFunctions.java        |  615 ++++++++
 .../tajo/engine/parser/TestSQLAnalyzer.java     |  804 ++++++++++
 .../engine/planner/TestJoinOrderAlgorithm.java  |  184 +++
 .../engine/planner/TestLogicalOptimizer.java    |  272 ++++
 .../tajo/engine/planner/TestLogicalPlan.java    |   86 ++
 .../tajo/engine/planner/TestLogicalPlanner.java | 1360 +++++++++++++++++
 .../tajo/engine/planner/TestPlannerUtil.java    |  387 +++++
 .../engine/planner/TestQueryValidation.java     |   65 +
 .../planner/TestUniformRangePartition.java      | 1143 ++++++++++++++
 .../engine/planner/global/TestMasterPlan.java   |   53 +
 .../planner/physical/TestBNLJoinExec.java       |  224 +++
 .../planner/physical/TestExternalSortExec.java  |  187 +++
 .../physical/TestFullOuterHashJoinExec.java     |  414 +++++
 .../physical/TestFullOuterMergeJoinExec.java    |  537 +++++++
 .../planner/physical/TestHashAntiJoinExec.java  |  215 +++
 .../planner/physical/TestHashJoinExec.java      |  281 ++++
 .../planner/physical/TestHashPartitioner.java   |  117 ++
 .../planner/physical/TestHashSemiJoinExec.java  |  220 +++
 .../physical/TestLeftOuterHashJoinExec.java     |  440 ++++++
 .../planner/physical/TestMergeJoinExec.java     |  197 +++
 .../engine/planner/physical/TestNLJoinExec.java |  208 +++
 .../planner/physical/TestPhysicalPlanner.java   | 1144 ++++++++++++++
 .../physical/TestProgressExternalSortExec.java  |  229 +++
 .../physical/TestRightOuterHashJoinExec.java    |  351 +++++
 .../physical/TestRightOuterMergeJoinExec.java   |  531 +++++++
 .../engine/planner/physical/TestSortExec.java   |  179 +++
 .../planner/physical/TestSortIntersectExec.java |  293 ++++
 .../planner/physical/TestTupleSorter.java       |  127 ++
 .../tajo/engine/query/TestAlterTable.java       |  114 ++
 .../tajo/engine/query/TestAlterTablespace.java  |   59 +
 .../apache/tajo/engine/query/TestCTASQuery.java |  281 ++++
 .../tajo/engine/query/TestCaseByCases.java      |  183 +++
 .../tajo/engine/query/TestCreateDatabase.java   |   75 +
 .../tajo/engine/query/TestCreateIndex.java      |  112 ++
 .../tajo/engine/query/TestCreateTable.java      |  643 ++++++++
 .../apache/tajo/engine/query/TestDropTable.java |   38 +
 .../tajo/engine/query/TestGroupByQuery.java     |  870 +++++++++++
 .../tajo/engine/query/TestHBaseTable.java       | 1408 ++++++++++++++++++
 .../tajo/engine/query/TestInSubquery.java       |  177 +++
 .../apache/tajo/engine/query/TestIndexScan.java |  145 ++
 .../tajo/engine/query/TestInnerJoinQuery.java   |  335 +++++
 .../engine/query/TestInnerJoinWithSubQuery.java |  132 ++
 .../tajo/engine/query/TestInsertQuery.java      |  882 +++++++++++
 .../query/TestJoinOnPartitionedTables.java      |  341 +++++
 .../apache/tajo/engine/query/TestJoinQuery.java |  315 ++++
 .../engine/query/TestMultipleJoinTypes.java     |  106 ++
 .../apache/tajo/engine/query/TestNetTypes.java  |  102 ++
 .../tajo/engine/query/TestNullValues.java       |  322 ++++
 .../tajo/engine/query/TestOuterJoinQuery.java   |  457 ++++++
 .../engine/query/TestOuterJoinWithSubQuery.java |  143 ++
 .../engine/query/TestSelectNestedRecord.java    |  119 ++
 .../tajo/engine/query/TestSelectQuery.java      |  778 ++++++++++
 .../tajo/engine/query/TestSetSessionQuery.java  |   80 +
 .../apache/tajo/engine/query/TestSortQuery.java |  377 +++++
 .../tajo/engine/query/TestTablePartitions.java  | 1301 ++++++++++++++++
 .../tajo/engine/query/TestTableSubQuery.java    |   81 +
 .../tajo/engine/query/TestTruncateTable.java    |   96 ++
 .../tajo/engine/query/TestUnionQuery.java       |  693 +++++++++
 .../tajo/engine/query/TestWindowQuery.java      |  465 ++++++
 .../apache/tajo/engine/util/TestTableCache.java |  109 ++
 .../apache/tajo/engine/util/TestTupleUtil.java  |  188 +++
 .../apache/tajo/ha/TestHAServiceHDFSImpl.java   |  160 ++
 .../org/apache/tajo/jdbc/TestResultSet.java     |  224 +++
 .../java/org/apache/tajo/jdbc/TestSQLState.java |   91 ++
 .../tajo/jdbc/TestTajoDatabaseMetaData.java     |  504 +++++++
 .../java/org/apache/tajo/jdbc/TestTajoJdbc.java |  608 ++++++++
 .../tajo/master/TestExecutionBlockCursor.java   |  135 ++
 .../TestNonForwardQueryResultSystemScanner.java |   41 +
 .../apache/tajo/master/TestRepartitioner.java   |  511 +++++++
 .../tajo/master/rule/TestMasterRules.java       |  156 ++
 .../master/scheduler/TestSimpleScheduler.java   |  301 ++++
 .../tajo/querymaster/TestIntermediateEntry.java |   53 +
 .../apache/tajo/querymaster/TestKillQuery.java  |  312 ++++
 .../tajo/querymaster/TestQueryProgress.java     |   77 +
 .../apache/tajo/querymaster/TestQueryState.java |   99 ++
 .../tajo/querymaster/TestTaskStatusUpdate.java  |  191 +++
 .../org/apache/tajo/resource/TestResources.java |   48 +
 .../apache/tajo/storage/TestFileFragment.java   |   93 ++
 .../org/apache/tajo/storage/TestRowFile.java    |  146 ++
 .../java/org/apache/tajo/util/TestJSPUtil.java  |  113 ++
 .../util/history/TestHistoryWriterReader.java   |  313 ++++
 .../tajo/util/metrics/TestMetricsFilter.java    |   52 +
 .../tajo/util/metrics/TestSystemMetrics.java    |  143 ++
 .../apache/tajo/worker/MockExecutionBlock.java  |   42 +
 .../tajo/worker/MockNodeResourceManager.java    |   88 ++
 .../tajo/worker/MockNodeStatusUpdater.java      |   97 ++
 .../apache/tajo/worker/MockTaskExecutor.java    |  153 ++
 .../org/apache/tajo/worker/MockTaskManager.java |   69 +
 .../apache/tajo/worker/MockWorkerContext.java   |  109 ++
 .../apache/tajo/worker/TestDeletionService.java |   61 +
 .../org/apache/tajo/worker/TestFetcher.java     |  236 +++
 .../tajo/worker/TestNodeResourceManager.java    |  281 ++++
 .../tajo/worker/TestNodeStatusUpdater.java      |  192 +++
 .../apache/tajo/worker/TestTaskExecutor.java    |  315 ++++
 .../org/apache/tajo/worker/TestTaskManager.java |  184 +++
 .../tajo/ws/rs/resources/RestTestUtils.java     |   64 +
 .../ws/rs/resources/TestClusterResource.java    |   83 ++
 .../ws/rs/resources/TestDatabasesResource.java  |  189 +++
 .../ws/rs/resources/TestFunctionsResource.java  |   78 +
 .../tajo/ws/rs/resources/TestQueryResource.java |  199 +++
 .../rs/resources/TestQueryResultResource.java   |  296 ++++
 .../ws/rs/resources/TestSessionsResource.java   |  263 ++++
 .../ws/rs/resources/TestTablesResource.java     |  202 +++
 .../resources/dataset/TestAlterTable/table1.tbl |    3 +
 .../resources/dataset/TestAlterTable/table2.tbl |    1 +
 .../dataset/TestCreateTable/table1/table1.tbl   |    3 +
 .../dataset/TestCreateTable/table2/table2.tbl   |    3 +
 .../resources/dataset/TestDropTable/table1.tbl  |    3 +
 .../dataset/TestHBaseTable/splits.data          |    4 +
 .../dataset/TestJoinQuery/table1/table1.tbl     |    5 +
 .../dataset/TestJoinQuery/table2/table2.tbl     |    4 +
 .../dataset/TestNetTypes/table1/table1.tbl      |    5 +
 .../dataset/TestNetTypes/table2/table2.tbl      |    5 +
 .../TestSelectNestedRecord/sample1/table.json   |    3 +
 .../TestSelectNestedRecord/sample2/sample2.json |    1 +
 .../TestSelectNestedRecord/tweets/sample1.json  |    4 +
 .../multibytes_delimiter1/table1.tbl            |    5 +
 .../multibytes_delimiter2/table2.tbl            |    5 +
 .../TestSelectQuery/timezoned/table1.tbl        |    3 +
 .../dataset/TestSortQuery/table1/table1.tbl     |    5 +
 .../dataset/TestSortQuery/table2/table2.tbl     |   24 +
 .../TestTablePartitions/lineitemspecial.tbl     |    5 +
 .../dataset/TestTajoJdbc/table1/table1.tbl      |    5 +
 .../truncate_table2/table2.tbl                  |    4 +
 .../src/test/resources/log4j.properties         |   28 +
 .../src/test/resources/python/__init__.py       |   17 +
 .../src/test/resources/python/test_funcs.py     |   33 +
 .../src/test/resources/python/test_funcs2.py    |   32 +
 .../src/test/resources/python/test_udaf.py      |   76 +
 .../alter_table_add_new_column_ddl.sql          |    1 +
 .../alter_table_add_partition1.sql              |    1 +
 .../alter_table_add_partition2.sql              |    1 +
 .../alter_table_drop_partition1.sql             |    1 +
 .../alter_table_drop_partition2.sql             |    1 +
 .../alter_table_rename_column_ddl.sql           |    1 +
 .../alter_table_rename_table_ddl.sql            |    1 +
 .../alter_table_set_property_delimiter.sql      |    1 +
 .../alter_table_set_property_timezone.sql       |    1 +
 .../TestAlterTable/create_partitioned_table.sql |    1 +
 .../queries/TestAlterTable/table1_ddl.sql       |    1 +
 .../queries/TestAlterTable/table2_ddl.sql       |    1 +
 .../testAlterTableSetProperty.sql               |    1 +
 .../testAlterTableSetProperty2.sql              |    1 +
 .../TestBuiltinFunctions/testAvgDouble.sql      |    1 +
 .../queries/TestBuiltinFunctions/testAvgInt.sql |    1 +
 .../TestBuiltinFunctions/testAvgLong.sql        |    1 +
 .../testAvgLongOverflow.sql                     |    1 +
 .../queries/TestBuiltinFunctions/testCount.sql  |    1 +
 .../TestBuiltinFunctions/testMaxLong.sql        |    1 +
 .../TestBuiltinFunctions/testMaxString.sql      |    1 +
 .../TestBuiltinFunctions/testMinLong.sql        |    1 +
 .../TestBuiltinFunctions/testMinString.sql      |    1 +
 .../queries/TestBuiltinFunctions/testRandom.sql |    1 +
 .../TestBuiltinFunctions/testSplitPart.sql      |    1 +
 .../testSplitPartByString.sql                   |    1 +
 .../testSplitPartNested.sql                     |    1 +
 .../queries/TestCTASQuery/CtasWithGroupby.sql   |    2 +
 .../queries/TestCTASQuery/CtasWithLimit.sql     |   13 +
 .../TestCTASQuery/CtasWithManagedTable.sql      |   12 +
 .../TestCTASQuery/CtasWithMultipleUnions.sql    |   12 +
 .../queries/TestCTASQuery/CtasWithOptions.sql   |   13 +
 .../queries/TestCTASQuery/CtasWithOrderby.sql   |   11 +
 .../queries/TestCTASQuery/CtasWithStoreType.sql |   12 +
 .../queries/TestCTASQuery/CtasWithTextFile.sql  |   12 +
 .../queries/TestCTASQuery/CtasWithUnion.sql     |   35 +
 .../resources/queries/TestCTASQuery/check1.sql  |    1 +
 .../resources/queries/TestCTASQuery/check2.sql  |    1 +
 .../testCtasWithColumnedPartition.sql           |    2 +
 .../TestCTASQuery/testCtasWithGroupby.sql       |    1 +
 .../queries/TestCTASQuery/testCtasWithLimit.sql |    1 +
 .../testCtasWithMultipleUnions.sql              |    1 +
 .../TestCTASQuery/testCtasWithOptions.sql       |    1 +
 .../TestCTASQuery/testCtasWithOrderby.sql       |    1 +
 .../TestCTASQuery/testCtasWithStoreType.sql     |    1 +
 .../TestCTASQuery/testCtasWithTextFile.sql      |    1 +
 .../queries/TestCTASQuery/testCtasWithUnion.sql |    1 +
 .../testCtasWithoutTableDefinition.sql          |    2 +
 .../TestCaseByCases/testTAJO1224Case1.sql       |    1 +
 .../queries/TestCaseByCases/testTAJO415Case.sql |   36 +
 .../queries/TestCaseByCases/testTAJO418Case.sql |   29 +
 .../queries/TestCaseByCases/testTAJO619Case.sql |    4 +
 .../queries/TestCaseByCases/testTAJO718Case.sql |   10 +
 .../queries/TestCaseByCases/testTAJO739Case.sql |    5 +
 .../TestCaseByCases/testTAJO914Case1.sql        |   10 +
 .../TestCaseByCases/testTAJO914Case2.sql        |    9 +
 .../TestCaseByCases/testTAJO914Case3.sql        |   10 +
 .../TestCaseByCases/testTAJO914Case4.sql        |   10 +
 .../TestCaseByCases/testTAJO917Case1.sql        |   13 +
 .../queries/TestCreateIndex/testCreateIndex.sql |    1 +
 .../testCreateIndexOnExpression.sql             |    1 +
 .../testCreateIndexOnLocation.sql               |    1 +
 .../testCreateIndexOnMultiAttrs.sql             |    1 +
 .../testCreateIndexOnMultiExprs.sql             |    1 +
 .../testCreateIndexWithCondition.sql            |    1 +
 .../create_table_various_types.sql              |   50 +
 ...ate_table_various_types_for_hive_catalog.sql |   50 +
 .../quoted_identifier_mixed_chars_1.sql         |    1 +
 .../quoted_identifier_mixed_chars_2.sql         |    1 +
 .../quoted_identifier_mixed_chars_3.sql         |   22 +
 .../quoted_identifier_mixed_chars_ddl_1.sql     |    1 +
 .../quoted_identifier_mixed_chars_ddl_2.sql     |    1 +
 .../quoted_identifier_non_ascii_1.sql           |    1 +
 .../quoted_identifier_non_ascii_2.sql           |    1 +
 .../quoted_identifier_non_ascii_3.sql           |    1 +
 .../quoted_identifier_non_ascii_ddl.sql         |    1 +
 .../queries/TestCreateTable/table1_ddl.sql      |    1 +
 .../TestCreateTable/testNestedRecord1.sql       |    1 +
 .../TestCreateTable/testNestedRecord2.sql       |    1 +
 .../queries/TestDropTable/drop_table_ddl.sql    |    1 +
 .../queries/TestDropTable/table1_ddl.sql        |    1 +
 .../TestGroupByQuery/testComplexParameter.sql   |    1 +
 .../TestGroupByQuery/testComplexParameter2.sql  |    1 +
 .../testComplexParameterWithSubQuery.sql        |    6 +
 .../testComplexTargetWithPythonUdaf.sql         |    1 +
 .../testDistinctAggregation1.sql                |    1 +
 .../testDistinctAggregation2.sql                |    1 +
 .../testDistinctAggregation3.sql                |    1 +
 .../testDistinctAggregation4.sql                |    1 +
 .../testDistinctAggregation5.sql                |    1 +
 .../testDistinctAggregation6.sql                |    9 +
 .../testDistinctAggregation7.sql                |    6 +
 .../testDistinctAggregation8.sql                |    9 +
 .../testDistinctAggregationCaseByCase3.sql      |    8 +
 .../testDistinctAggregationCaseByCase4.sql      |    7 +
 .../testDistinctAggregationWithHaving1.sql      |    1 +
 .../testDistinctAggregationWithUnion1.sql       |   21 +
 .../testDistinctAggregation_case1.sql           |    7 +
 .../testDistinctAggregation_case10.sql          |    5 +
 .../testDistinctAggregation_case2.sql           |    8 +
 .../testDistinctAggregation_case3.sql           |    9 +
 .../testDistinctAggregation_case4.sql           |   10 +
 .../testDistinctAggregation_case5.sql           |   10 +
 .../testDistinctAggregation_case6.sql           |   12 +
 .../testDistinctAggregation_case7.sql           |    9 +
 .../testDistinctAggregation_case8.sql           |   10 +
 .../testDistinctAggregation_case9.sql           |   11 +
 .../testDistinctPythonUdafWithUnion1.sql        |   21 +
 .../queries/TestGroupByQuery/testGroupBy.sql    |    1 +
 .../queries/TestGroupByQuery/testGroupBy2.sql   |    1 +
 .../queries/TestGroupByQuery/testGroupBy3.sql   |    1 +
 .../queries/TestGroupByQuery/testGroupBy4.sql   |    9 +
 .../queries/TestGroupByQuery/testGroupBy5.sql   |    1 +
 .../TestGroupByQuery/testGroupByNested1.sql     |    8 +
 .../TestGroupByQuery/testGroupByNested2.sql     |   10 +
 .../testGroupByWithConstantKeys1.sql            |    1 +
 .../testGroupByWithConstantKeys2.sql            |    1 +
 .../testGroupByWithConstantKeys3.sql            |    8 +
 .../testGroupByWithConstantKeys4.sql            |   12 +
 .../testGroupByWithConstantKeys5.sql            |   13 +
 .../testGroupByWithExpressionKeys1.sql          |    1 +
 .../testGroupByWithExpressionKeys2.sql          |    1 +
 .../testGroupByWithNullData1.sql                |    1 +
 .../testGroupByWithNullData10.sql               |    3 +
 .../testGroupByWithNullData11.sql               |    5 +
 .../testGroupByWithNullData12.sql               |   29 +
 .../testGroupByWithNullData2.sql                |    1 +
 .../testGroupByWithNullData3.sql                |    3 +
 .../testGroupByWithNullData4.sql                |    3 +
 .../testGroupByWithNullData5.sql                |    1 +
 .../testGroupByWithNullData6.sql                |    1 +
 .../testGroupByWithNullData7.sql                |    1 +
 .../testGroupByWithNullData8.sql                |    1 +
 .../testGroupByWithNullData9.sql                |    4 +
 .../testGroupByWithSameConstantKeys1.sql        |    1 +
 .../testGroupByWithSameExprs1.sql               |    8 +
 .../testGroupByWithSameExprs2.sql               |    8 +
 .../TestGroupByQuery/testGroupbyWithJson.json   |  127 ++
 .../TestGroupByQuery/testGroupbyWithLimit1.sql  |    1 +
 .../TestGroupByQuery/testGroupbyWithLimit2.sql  |    1 +
 .../TestGroupByQuery/testGroupbyWithLimit3.sql  |    1 +
 .../testGroupbyWithPythonFunc.sql               |    1 +
 .../testGroupbyWithPythonFunc2.sql              |    1 +
 .../testHavingWithAggFunction.sql               |    1 +
 .../testHavingWithNamedTarget.sql               |   13 +
 .../queries/TestGroupByQuery/testPythonUdaf.sql |    1 +
 .../TestGroupByQuery/testPythonUdaf2.sql        |    1 +
 .../TestGroupByQuery/testPythonUdaf3.sql        |    1 +
 .../testPythonUdafWithHaving.sql                |    3 +
 .../testPythonUdafWithNullData.sql              |    4 +
 .../TestInSubquery/testInAndNotInSubQuery.sql   |    3 +
 .../queries/TestInSubquery/testInSubQuery.sql   |    1 +
 .../queries/TestInSubquery/testInSubQuery2.sql  |    2 +
 .../TestInSubquery/testInSubQueryWithJoin.sql   |    2 +
 .../testInSubQueryWithOtherConditions.sql       |    2 +
 .../testInSubQueryWithTableSubQuery.sql         |    2 +
 .../TestInSubquery/testMultipleInSubQuery.sql   |    5 +
 .../testMultipleNotInSubQuery.sql               |    3 +
 .../testNestedInAndNotInSubQuery.sql            |    5 +
 .../TestInSubquery/testNestedInSubQuery.sql     |    4 +
 .../TestInSubquery/testNestedInSubQuery2.sql    |    4 +
 .../TestInSubquery/testNestedNotInSubQuery.sql  |    4 +
 .../TestInSubquery/testNotInSubQuery.sql        |    1 +
 .../testSameKeyNameOfOuterAndInnerQueries.sql   |   22 +
 .../TestInSubquery/testWithAsteriskAndJoin.sql  |    7 +
 .../testBroadcastTwoPartJoin.sql                |   19 +
 .../testCrossJoinAndCaseWhen.sql                |   18 +
 .../testCrossJoinWithAsterisk1.sql              |    1 +
 .../testCrossJoinWithAsterisk2.sql              |    1 +
 .../testCrossJoinWithAsterisk3.sql              |    1 +
 .../testCrossJoinWithAsterisk4.sql              |    1 +
 .../testBroadcastSubquery.sql                   |   12 +
 .../testBroadcastSubquery2.sql                  |   19 +
 .../testThetaJoinKeyPairs.sql                   |   20 +
 .../TestInsertQuery/full_table_csv_ddl.sql      |    1 +
 .../TestInsertQuery/full_table_parquet_ddl.sql  |    1 +
 .../TestInsertQuery/lineitem_year_month_ddl.sql |   18 +
 .../load_to_lineitem_year_month.sql             |    1 +
 .../TestInsertQuery/nation_diff_col_order.ddl   |    1 +
 .../queries/TestInsertQuery/table1_ddl.sql      |    1 +
 .../queries/TestInsertQuery/test1_ddl.sql       |    1 +
 .../TestInsertQuery/test1_nolength_ddl.sql      |    1 +
 .../queries/TestInsertQuery/testInsertInto.sql  |    1 +
 .../testInsertIntoSelectWithFixedSizeChar.sql   |    4 +
 ...tIntoSelectWithFixedSizeCharWithNoLength.sql |    2 +
 .../TestInsertQuery/testInsertOverwrite.sql     |    1 +
 .../testInsertOverwriteLocation.sql             |    1 +
 ...stInsertOverwriteLocationWithCompression.sql |    1 +
 .../testInsertOverwriteLocationWithUnion.sql    |    4 +
 ...verwriteLocationWithUnionDifferenceAlias.sql |    4 +
 .../testInsertOverwriteSmallerColumns.sql       |    1 +
 .../testInsertOverwriteWithAsterisk.sql         |    1 +
 .../testInsertOverwriteWithAsteriskAndMore.sql  |    1 +
 .../testInsertOverwriteWithCompression.sql      |    1 +
 .../testInsertOverwriteWithCompression_ddl.sql  |    4 +
 .../testInsertOverwriteWithDatabase.sql         |    1 +
 .../testInsertOverwriteWithTargetColumns.sql    |    1 +
 .../testInsertOverwriteWithUnion.sql            |    4 +
 ...stInsertOverwriteWithUnionDifferentAlias.sql |    4 +
 .../testInsertWithDifferentColumnOrder.sql      |    1 +
 .../selfJoinOfPartitionedTable.sql              |    9 +
 .../testBroadcastPartitionTable.sql             |   16 +
 ...estFilterPushDownPartitionColumnCaseWhen.sql |    6 +
 ...rtitionedBroadcastDataFileWithZeroLength.sql |    3 +
 ...titionedBroadcastDataFileWithZeroLength2.sql |    5 +
 .../testNoProjectionJoinQual.sql                |    1 +
 .../testPartialFilterPushDown.sql               |    9 +
 .../testPartialFilterPushDownOuterJoin.sql      |    4 +
 .../testPartialFilterPushDownOuterJoin2.sql     |    5 +
 .../testPartitionTableJoinSmallTable.sql        |   11 +
 .../TestJoinQuery/create_customer_large_ddl.sql |    7 +
 .../TestJoinQuery/create_lineitem_large_ddl.sql |    7 +
 .../TestJoinQuery/create_orders_large_ddl.sql   |    7 +
 .../TestJoinQuery/customer_partition_ddl.sql    |    9 +
 .../TestJoinQuery/insert_into_customer.sql      |   11 +
 .../insert_into_customer_partition.sql          |   11 +
 .../TestJoinQuery/nation_multifile_ddl.sql      |    5 +
 .../queries/TestJoinQuery/oj_table1_ddl.sql     |    3 +
 .../queries/TestJoinQuery/oj_table2_ddl.sql     |    3 +
 .../TestJoinQuery/orders_multifile_ddl.sql      |    5 +
 .../TestJoinQuery/partitioned_customer_ddl.sql  |   19 +
 .../queries/TestJoinQuery/table1_int4_ddl.sql   |    3 +
 .../queries/TestJoinQuery/table1_int8_ddl.sql   |    3 +
 .../TestJoinQuery/testComplexJoinCondition1.sql |    6 +
 .../TestJoinQuery/testComplexJoinCondition2.sql |    6 +
 .../TestJoinQuery/testComplexJoinCondition3.sql |    6 +
 .../TestJoinQuery/testComplexJoinCondition4.sql |    6 +
 .../TestJoinQuery/testComplexJoinCondition5.sql |    6 +
 .../TestJoinQuery/testComplexJoinCondition6.sql |    6 +
 .../TestJoinQuery/testComplexJoinCondition7.sql |    6 +
 .../testComplexJoinsWithCaseWhen.sql            |   11 +
 .../testComplexJoinsWithCaseWhen2.sql           |    9 +
 .../testCrossJoinWithEmptyTable1.sql            |    8 +
 ...stCrossJoinWithThetaJoinConditionInWhere.sql |    2 +
 .../testDifferentTypesJoinCondition.sql         |    1 +
 .../TestJoinQuery/testFullOuterJoin1.sql        |    8 +
 .../testFullOuterJoinWithEmptyTable1.sql        |    8 +
 .../TestJoinQuery/testInnerJoinAndCaseWhen.sql  |   18 +
 .../testInnerJoinWithEmptyTable.sql             |    8 +
 ...stInnerJoinWithThetaJoinConditionInWhere.sql |    3 +
 .../queries/TestJoinQuery/testJoinAsterisk.sql  |    3 +
 .../TestJoinQuery/testJoinCoReferredEvals1.sql  |   11 +
 .../testJoinCoReferredEvalsFilterPushdown.sql   |   13 +
 .../testJoinCoReferredEvalsWithSameExprs1.sql   |   14 +
 .../testJoinCoReferredEvalsWithSameExprs2.sql   |   22 +
 .../testJoinFilterOfRowPreservedTable1.sql      |    8 +
 .../testJoinOnMultipleDatabases.sql             |   25 +
 .../testJoinOnMultipleDatabasesWithJson.json    |  210 +++
 .../queries/TestJoinQuery/testJoinWithJson.json |   92 ++
 .../TestJoinQuery/testJoinWithJson2.json        |  219 +++
 .../testJoinWithMultipleJoinQual1.sql           |   20 +
 .../testJoinWithMultipleJoinQual2.sql           |    8 +
 .../testJoinWithMultipleJoinQual3.sql           |    9 +
 .../testJoinWithMultipleJoinQual4.sql           |   10 +
 .../testJoinWithMultipleJoinTypes.sql           |    4 +
 .../TestJoinQuery/testJoinWithOrPredicates.sql  |    6 +
 .../TestJoinQuery/testLeftOuterJoin1.sql        |    9 +
 .../testLeftOuterJoinWithConstantExpr1.sql      |    9 +
 .../testLeftOuterJoinWithConstantExpr2.sql      |    9 +
 .../testLeftOuterJoinWithConstantExpr3.sql      |   17 +
 .../testLeftOuterJoinWithConstantExpr4.sql      |    6 +
 .../testLeftOuterJoinWithConstantExpr5.sql      |    9 +
 .../testLeftOuterJoinWithEmptyTable1.sql        |    9 +
 .../testLeftOuterJoinWithEmptyTable2.sql        |    9 +
 .../testLeftOuterJoinWithEmptyTable3.sql        |   14 +
 .../testLeftOuterJoinWithEmptyTable4.sql        |   17 +
 .../testLeftOuterJoinWithEmptyTable5.sql        |   11 +
 .../testLeftOuterJoinWithNull1.sql              |   10 +
 .../testLeftOuterJoinWithNull2.sql              |   11 +
 .../testLeftOuterJoinWithNull3.sql              |   10 +
 ...ftOuterJoinWithThetaJoinConditionInWhere.sql |    3 +
 .../queries/TestJoinQuery/testNaturalJoin.sql   |    3 +
 .../TestJoinQuery/testOuterJoinAndCaseWhen1.sql |   12 +
 .../TestJoinQuery/testRightOuterJoin1.sql       |    8 +
 .../testRightOuterJoinWithEmptyTable1.sql       |    8 +
 ...htOuterJoinWithThetaJoinConditionInWhere.sql |    3 +
 .../queries/TestJoinQuery/testTPCHQ2Join.sql    |   25 +
 .../TestJoinQuery/testWhereClauseJoin1.sql      |   11 +
 .../TestJoinQuery/testWhereClauseJoin2.sql      |    9 +
 .../TestJoinQuery/testWhereClauseJoin3.sql      |   10 +
 .../TestJoinQuery/testWhereClauseJoin4.sql      |    9 +
 .../TestJoinQuery/testWhereClauseJoin5.sql      |   15 +
 .../TestJoinQuery/testWhereClauseJoin6.sql      |   19 +
 .../queries/TestLogicalPlanner/window1.sql      |    5 +
 .../queries/TestNetTypes/table1_ddl.sql         |    4 +
 .../queries/TestNetTypes/table2_ddl.sql         |    4 +
 .../queries/TestNetTypes/testGroupby.sql        |    8 +
 .../queries/TestNetTypes/testGroupby2.sql       |    9 +
 .../resources/queries/TestNetTypes/testJoin.sql |    1 +
 .../queries/TestNetTypes/testSelect.sql         |    1 +
 .../resources/queries/TestNetTypes/testSort.sql |    1 +
 .../queries/TestNetTypes/testSort2.sql          |    1 +
 .../TestOuterJoinQuery/testLeftOuterJoin2.sql   |    5 +
 .../TestOuterJoinQuery/testLeftOuterJoin3.sql   |    7 +
 ...tMultipleBroadcastDataFileWithZeroLength.sql |    3 +
 ...MultipleBroadcastDataFileWithZeroLength2.sql |    5 +
 .../TestQueryValidation/error_groupby_1.sql     |    1 +
 .../TestQueryValidation/error_groupby_2.sql     |    1 +
 .../TestQueryValidation/invalid_casewhen_1.sql  |   15 +
 .../TestQueryValidation/invalid_limit_1.sql     |    1 +
 .../invalid_store_format.sql                    |    1 +
 .../TestQueryValidation/valid_groupby_1.sql     |    1 +
 .../TestQueryValidation/valid_limit_1.sql       |    1 +
 .../TestSQLAnalyzer/create_table_nested_1.sql   |    1 +
 .../TestSQLAnalyzer/create_table_nested_2.sql   |    1 +
 .../queries/TestSQLAnalyzer/setcatalog1.sql     |    1 +
 .../queries/TestSQLAnalyzer/setcatalog2.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession1.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession2.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession3.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession4.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession5.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession6.sql     |    1 +
 .../queries/TestSQLAnalyzer/setsession7.sql     |    1 +
 .../queries/TestSQLAnalyzer/settimezone1.sql    |    1 +
 .../queries/TestSQLAnalyzer/settimezone2.sql    |    1 +
 .../queries/TestSQLAnalyzer/settimezone3.sql    |    1 +
 .../queries/TestSQLAnalyzer/window1.sql         |    5 +
 .../queries/TestSQLAnalyzer/window2.sql         |    5 +
 .../queries/TestSQLAnalyzer/window3.sql         |    5 +
 .../queries/TestSQLAnalyzer/window4.sql         |    5 +
 .../queries/TestSQLAnalyzer/window5.sql         |    6 +
 .../queries/TestSQLAnalyzer/window6.sql         |    6 +
 .../queries/TestSQLAnalyzer/window7.sql         |    6 +
 .../queries/TestSQLAnalyzer/window8.sql         |    6 +
 .../queries/TestSQLAnalyzer/window9.sql         |    9 +
 .../TestSelectNestedRecord/sample0_ddl.sql      |    1 +
 .../TestSelectNestedRecord/sample1_ddl.sql      |    7 +
 .../TestSelectNestedRecord/sample2_ddl.sql      |   23 +
 .../testNestedFieldAsGroupbyKey1.sql            |    9 +
 .../testNestedFieldAsJoinKey1.sql               |    7 +
 .../TestSelectNestedRecord/testSelect0.sql      |    1 +
 .../TestSelectNestedRecord/testSelect1.sql      |    1 +
 .../TestSelectNestedRecord/testSelect2.sql      |   61 +
 .../TestSelectNestedRecord/testSelect3.sql      |    1 +
 .../TestSelectNestedRecord/tweets_ddl.sql       |   74 +
 .../queries/TestSelectQuery/customer_ddl.sql    |    9 +
 .../TestSelectQuery/datetime_table_ddl.sql      |    4 +
 .../datetime_table_timezoned_ddl.sql            |    4 +
 .../TestSelectQuery/insert_into_customer.sql    |   11 +
 .../multibytes_delimiter_table1_ddl.sql         |    3 +
 .../multibytes_delimiter_table2_ddl.sql         |    3 +
 .../multibytes_delimiter_table3_ddl.sql         |    3 +
 .../multibytes_delimiter_table4_ddl.sql         |    3 +
 .../queries/TestSelectQuery/testCaseWhen.sql    |   11 +
 .../TestSelectQuery/testCaseWhenRound.sql       |    8 +
 .../TestSelectQuery/testCaseWhenWithoutElse.sql |   10 +
 .../testColumnEqualityButNotJoinCondition1.sql  |    7 +
 .../testColumnEqualityButNotJoinCondition2.sql  |    7 +
 .../TestSelectQuery/testCreateAfterSelect.sql   |    1 +
 .../TestSelectQuery/testDatabaseRef1.sql        |    1 +
 .../TestSelectQuery/testDatabaseRef2.sql        |    1 +
 .../TestSelectQuery/testDatabaseRef3.sql        |    1 +
 .../TestSelectQuery/testExplainSelect.sql       |    1 +
 .../queries/TestSelectQuery/testInClause.sql    |    1 +
 .../queries/TestSelectQuery/testInStrClause.sql |    1 +
 .../queries/TestSelectQuery/testLikeClause.sql  |    1 +
 .../queries/TestSelectQuery/testLimit.sql       |    1 +
 .../testMultiBytesDelimiter1.sql                |    1 +
 .../testMultiBytesDelimiter2.sql                |    1 +
 .../testMultiBytesDelimiter3.sql                |    1 +
 .../testMultiBytesDelimiter4.sql                |    1 +
 .../testNestedPythonFunction.sql                |    1 +
 .../TestSelectQuery/testNonFromSelect1.sql      |    1 +
 .../TestSelectQuery/testNonQualifiedNames.sql   |    1 +
 .../queries/TestSelectQuery/testNotEqual.sql    |    1 +
 .../queries/TestSelectQuery/testNotInClause.sql |    1 +
 .../TestSelectQuery/testNotInStrClause.sql      |    1 +
 .../TestSelectQuery/testRealValueCompare.sql    |    1 +
 .../queries/TestSelectQuery/testSelect.sql      |    1 +
 .../queries/TestSelectQuery/testSelect2.sql     |    1 +
 .../queries/TestSelectQuery/testSelect3.sql     |    1 +
 .../TestSelectQuery/testSelectAsterik.sql       |    1 +
 .../TestSelectQuery/testSelectAsterisk1.sql     |    1 +
 .../TestSelectQuery/testSelectAsterisk2.sql     |    1 +
 .../TestSelectQuery/testSelectAsterisk3.sql     |    1 +
 .../TestSelectQuery/testSelectAsterisk4.sql     |    1 +
 .../TestSelectQuery/testSelectAsterisk5.sql     |    1 +
 .../TestSelectQuery/testSelectColumnAlias1.sql  |    1 +
 ...testSelectColumnAliasExistingInRelation1.sql |    1 +
 ...testSelectColumnAliasExistingInRelation2.sql |    1 +
 ...testSelectColumnAliasExistingInRelation3.sql |   19 +
 .../TestSelectQuery/testSelectDistinct.sql      |    7 +
 .../testSelectOnSessionTable.sql                |    1 +
 .../TestSelectQuery/testSelectPythonFuncs.sql   |    2 +
 ...tSelectSameConstantsWithDifferentAliases.sql |    1 +
 ...SelectSameConstantsWithDifferentAliases2.sql |    1 +
 ...SelectSameConstantsWithDifferentAliases3.sql |   10 +
 .../testSelectSameExprsWithDifferentAliases.sql |    1 +
 .../TestSelectQuery/testSelectWithJson.json     |   74 +
 .../testSelectWithParentheses1.sql              |    1 +
 .../testSelectWithParentheses2.sql              |    1 +
 .../testSelectWithPredicateOnPythonFunc.sql     |    1 +
 .../queries/TestSelectQuery/testSimpleQuery.sql |    1 +
 .../testSimpleQueryWithLimit.sql                |    1 +
 ...testSimpleQueryWithLimitPartitionedTable.sql |    1 +
 .../TestSelectQuery/testStringCompare.sql       |    1 +
 .../TestSelectQuery/testSumFloatOverflow.sql    |    1 +
 .../TestSelectQuery/testSumIntOverflow.sql      |    1 +
 .../TestSelectQuery/testTimezonedTable1.sql     |    1 +
 .../TestSelectQuery/testTimezonedTable2.sql     |    2 +
 .../TestSelectQuery/testTimezonedTable3.sql     |    1 +
 .../TestSelectQuery/testTimezonedTable4.sql     |    2 +
 .../TestSelectQuery/testTimezonedTable5.sql     |    2 +
 .../queries/TestSelectQuery/testWhereCond1.sql  |    1 +
 .../queries/TestSelectQuery/testWhereCond2.sql  |    9 +
 .../TestSelectQuery/testWhereCondWithAlias1.sql |    1 +
 .../TestSelectQuery/testWhereCondWithAlias2.sql |    1 +
 .../create_table_with_asc_desc_keys.sql         |    1 +
 .../create_table_with_date_ddl.sql              |   10 +
 .../queries/TestSortQuery/testAsterisk.sql      |    1 +
 .../queries/TestSortQuery/testSort.sql          |    1 +
 .../TestSortQuery/testSortAfterGroupby.sql      |    1 +
 .../testSortAfterGroupbyWithAlias.sql           |    1 +
 .../queries/TestSortQuery/testSortDesc.sql      |    1 +
 .../queries/TestSortQuery/testSortFirstDesc.sql |    1 +
 .../TestSortQuery/testSortOnNullColumn.sql      |   13 +
 .../TestSortQuery/testSortOnUnicodeTextAsc.sql  |    6 +
 .../TestSortQuery/testSortOnUnicodeTextDesc.sql |    6 +
 .../TestSortQuery/testSortWithAlias1.sql        |    1 +
 .../TestSortQuery/testSortWithAlias2.sql        |    9 +
 .../TestSortQuery/testSortWithAlias3.sql        |   11 +
 .../testSortWithAliasButOriginalName.sql        |    1 +
 .../TestSortQuery/testSortWithAscDescKeys.sql   |    1 +
 .../TestSortQuery/testSortWithConstKeys.sql     |   10 +
 .../queries/TestSortQuery/testSortWithDate.sql  |    1 +
 .../queries/TestSortQuery/testSortWithExpr1.sql |    1 +
 .../queries/TestSortQuery/testSortWithExpr2.sql |    1 +
 .../queries/TestSortQuery/testSortWithJson.json |   65 +
 .../testSubQuerySortAfterGroupMultiBlocks.sql   |    5 +
 .../queries/TestSortQuery/testTopK.sql          |    1 +
 .../queries/TestSortQuery/testTopkWithJson.json |   51 +
 .../queries/TestTPCH/testFirstJoinInQ7.sql      |   13 +
 .../queries/TestTPCH/testQ1OrderBy.sql          |   12 +
 .../queries/TestTPCH/testQ2FourJoins.sql        |   18 +
 .../queries/TestTPCH/testTPCH14Expr.sql         |   12 +
 .../resources/queries/TestTPCH/testTPCHQ5.sql   |   24 +
 .../queries/TestTablePartitions/case1.sql       |   16 +
 .../queries/TestTablePartitions/case10.sql      |    1 +
 .../queries/TestTablePartitions/case11.sql      |    1 +
 .../queries/TestTablePartitions/case12.sql      |    7 +
 .../queries/TestTablePartitions/case13.sql      |   11 +
 .../queries/TestTablePartitions/case14.sql      |    3 +
 .../queries/TestTablePartitions/case15.sql      |    3 +
 .../queries/TestTablePartitions/case2.sql       |   31 +
 .../queries/TestTablePartitions/case3.sql       |    8 +
 .../queries/TestTablePartitions/case4.sql       |    1 +
 .../queries/TestTablePartitions/case5.sql       |    1 +
 .../queries/TestTablePartitions/case6.sql       |    1 +
 .../queries/TestTablePartitions/case7.sql       |    1 +
 .../queries/TestTablePartitions/case8.sql       |    1 +
 .../queries/TestTablePartitions/case9.sql       |    1 +
 .../TestTablePartitions/lineitemspecial_ddl.sql |    3 +
 .../TestTableSubQuery/testGroupBySubQuery.sql   |    1 +
 .../testGroupbySubqueryWithJson.json            |   59 +
 .../TestTableSubQuery/testJoinSubQuery.sql      |    5 +
 .../TestTableSubQuery/testJoinSubQuery2.sql     |    4 +
 .../testJoinSubqueryWithJson.json               |  108 ++
 .../TestTableSubQuery/testTableSubquery1.sql    |    1 +
 .../TestTajoJdbc/create_table_with_date_ddl.sql |   10 +
 .../queries/TestTaskStatusUpdate/case1.sql      |    1 +
 .../queries/TestTaskStatusUpdate/case2.sql      |    5 +
 .../queries/TestTaskStatusUpdate/case3.sql      |   10 +
 .../queries/TestTruncateTable/table1_ddl.sql    |    1 +
 .../queries/TestTruncateTable/table2_ddl.sql    |    1 +
 .../TestUnionQuery/testComplexUnion1.sql        |   27 +
 .../TestUnionQuery/testComplexUnion2.sql        |   35 +
 .../queries/TestUnionQuery/testUnion1.sql       |   19 +
 .../queries/TestUnionQuery/testUnion10.sql      |  158 ++
 .../queries/TestUnionQuery/testUnion11.sql      |    8 +
 .../queries/TestUnionQuery/testUnion12.sql      |   14 +
 .../queries/TestUnionQuery/testUnion13.sql      |   15 +
 .../queries/TestUnionQuery/testUnion14.sql      |    8 +
 .../queries/TestUnionQuery/testUnion15.sql      |   15 +
 .../queries/TestUnionQuery/testUnion16.sql      |   15 +
 .../queries/TestUnionQuery/testUnion2.sql       |   18 +
 .../queries/TestUnionQuery/testUnion3.sql       |   19 +
 .../queries/TestUnionQuery/testUnion4.sql       |   16 +
 .../queries/TestUnionQuery/testUnion5.sql       |   20 +
 .../queries/TestUnionQuery/testUnion6.sql       |   15 +
 .../queries/TestUnionQuery/testUnion7.sql       |   18 +
 .../queries/TestUnionQuery/testUnion8.sql       |   24 +
 .../queries/TestUnionQuery/testUnion9.sql       |   29 +
 .../queries/TestUnionQuery/testUnionAll1.sql    |   19 +
 .../queries/TestUnionQuery/testUnionAll10.sql   |  158 ++
 .../queries/TestUnionQuery/testUnionAll11.sql   |    8 +
 .../queries/TestUnionQuery/testUnionAll12.sql   |   13 +
 .../queries/TestUnionQuery/testUnionAll13.sql   |   14 +
 .../queries/TestUnionQuery/testUnionAll14.sql   |    8 +
 .../queries/TestUnionQuery/testUnionAll15.sql   |   15 +
 .../queries/TestUnionQuery/testUnionAll16.sql   |   15 +
 .../queries/TestUnionQuery/testUnionAll2.sql    |   18 +
 .../queries/TestUnionQuery/testUnionAll3.sql    |   19 +
 .../queries/TestUnionQuery/testUnionAll4.sql    |   16 +
 .../queries/TestUnionQuery/testUnionAll5.sql    |   20 +
 .../queries/TestUnionQuery/testUnionAll6.sql    |   15 +
 .../queries/TestUnionQuery/testUnionAll7.sql    |   18 +
 .../queries/TestUnionQuery/testUnionAll8.sql    |   24 +
 .../queries/TestUnionQuery/testUnionAll9.sql    |   29 +
 .../testUnionAllWithDifferentAlias.sql          |   29 +
 ...estUnionAllWithDifferentAliasAndFunction.sql |   29 +
 .../testUnionAllWithSameAliasNames.sql          |   25 +
 .../testUnionWithDifferentAlias.sql             |   29 +
 .../testUnionWithDifferentAliasAndFunction.sql  |   29 +
 .../testUnionWithSameAliasNames.sql             |   25 +
 .../TestWindowQuery/testComplexOrderBy1.sql     |    5 +
 .../queries/TestWindowQuery/testFirstValue1.sql |   18 +
 .../queries/TestWindowQuery/testLag1.sql        |   18 +
 .../TestWindowQuery/testLagWithDefault.sql      |   18 +
 .../TestWindowQuery/testLagWithNoArgs.sql       |   18 +
 .../queries/TestWindowQuery/testLastValue1.sql  |   18 +
 .../queries/TestWindowQuery/testLead1.sql       |   18 +
 .../TestWindowQuery/testLeadWithDefault.sql     |   18 +
 .../TestWindowQuery/testLeadWithNoArgs.sql      |   18 +
 .../queries/TestWindowQuery/testRowNumber1.sql  |    5 +
 .../queries/TestWindowQuery/testRowNumber2.sql  |    5 +
 .../queries/TestWindowQuery/testRowNumber3.sql  |    7 +
 .../queries/TestWindowQuery/testStdDevPop1.sql  |   14 +
 .../queries/TestWindowQuery/testStdDevSamp1.sql |   14 +
 .../queries/TestWindowQuery/testWindow1.sql     |    1 +
 .../queries/TestWindowQuery/testWindow2.sql     |    1 +
 .../queries/TestWindowQuery/testWindow3.sql     |    1 +
 .../queries/TestWindowQuery/testWindow4.sql     |    1 +
 .../queries/TestWindowQuery/testWindow5.sql     |    1 +
 .../queries/TestWindowQuery/testWindow6.sql     |    1 +
 .../queries/TestWindowQuery/testWindow7.sql     |    1 +
 .../queries/TestWindowQuery/testWindow8.sql     |    7 +
 .../TestWindowQuery/testWindowBeforeLimit.sql   |    6 +
 .../testWindowWithAggregation1.sql              |    4 +
 .../testWindowWithAggregation2.sql              |    7 +
 .../testWindowWithAggregation3.sql              |    5 +
 .../testWindowWithAggregation4.sql              |    8 +
 .../testWindowWithAggregation5.sql              |    9 +
 .../testWindowWithAggregation6.sql              |   10 +
 .../TestWindowQuery/testWindowWithOrderBy1.sql  |    6 +
 .../TestWindowQuery/testWindowWithOrderBy2.sql  |    6 +
 .../TestWindowQuery/testWindowWithOrderBy3.sql  |    6 +
 .../TestWindowQuery/testWindowWithOrderBy4.sql  |    7 +
 .../TestWindowQuery/testWindowWithOrderBy5.sql  |    9 +
 .../TestWindowQuery/testWindowWithSubQuery.sql  |   14 +
 .../TestWindowQuery/testWindowWithSubQuery2.sql |   15 +
 .../TestWindowQuery/testWindowWithSubQuery3.sql |   14 +
 .../TestWindowQuery/testWindowWithSubQuery4.sql |   14 +
 .../TestWindowQuery/testWindowWithSubQuery5.sql |   11 +
 .../TestWindowQuery/testWindowWithSubQuery6.sql |    9 +
 .../default/alter_table_add_partition_1.sql     |    1 +
 .../default/alter_table_add_partition_2.sql     |    1 +
 .../default/alter_table_add_partition_3.sql     |    2 +
 .../default/alter_table_add_partition_4.sql     |    1 +
 .../default/alter_table_add_partition_5.sql     |    1 +
 .../default/alter_table_drop_partition_1.sql    |    1 +
 .../default/alter_table_drop_partition_2.sql    |    1 +
 .../default/alter_table_drop_partition_3.sql    |    1 +
 .../default/alter_table_drop_partition_4.sql    |    1 +
 .../default/alter_table_set_property_1.sql      |    1 +
 .../default/alter_table_set_property_2.sql      |    1 +
 .../default/alter_table_set_property_3.sql      |    1 +
 .../resources/queries/default/asterisk_1.sql    |    1 +
 .../resources/queries/default/asterisk_2.sql    |    1 +
 .../resources/queries/default/asterisk_3.sql    |    1 +
 .../resources/queries/default/asterisk_4.sql    |    1 +
 .../create_partitioned_table_as_select.sql      |   17 +
 .../queries/default/create_table_1.hiveql       |    1 +
 .../queries/default/create_table_1.sql          |    1 +
 .../queries/default/create_table_10.sql         |    1 +
 .../queries/default/create_table_11.hiveql      |    3 +
 .../queries/default/create_table_11.sql         |    3 +
 .../queries/default/create_table_12.hiveql      |    4 +
 .../queries/default/create_table_12.sql         |    3 +
 .../queries/default/create_table_2.hiveql       |    1 +
 .../queries/default/create_table_2.sql          |    1 +
 .../queries/default/create_table_3.sql          |    1 +
 .../queries/default/create_table_4.sql          |    1 +
 .../queries/default/create_table_5.sql          |    1 +
 .../queries/default/create_table_6.sql          |    1 +
 .../queries/default/create_table_7.sql          |    1 +
 .../queries/default/create_table_8.sql          |   48 +
 .../queries/default/create_table_9.sql          |    1 +
 .../queries/default/create_table_like_1.sql     |    1 +
 .../create_table_partition_by_column.sql        |    4 +
 .../create_table_partition_by_hash_1.sql        |    3 +
 .../create_table_partition_by_hash_2.sql        |    7 +
 .../default/create_table_partition_by_list.sql  |    8 +
 .../default/create_table_partition_by_range.sql |    9 +
 .../resources/queries/default/drop_table.sql    |    1 +
 .../queries/default/exists_predicate_1.sql      |    1 +
 .../queries/default/exists_predicate_2.sql      |    1 +
 .../resources/queries/default/groupby_1.sql     |    1 +
 .../resources/queries/default/groupby_2.sql     |    1 +
 .../resources/queries/default/groupby_3.sql     |    1 +
 .../resources/queries/default/groupby_4.sql     |    1 +
 .../resources/queries/default/groupby_5.sql     |    1 +
 .../resources/queries/default/in_subquery_1.sql |    1 +
 .../resources/queries/default/in_subquery_2.sql |    1 +
 .../queries/default/insert_into_select_1.sql    |    1 +
 .../queries/default/insert_into_select_2.sql    |    1 +
 .../queries/default/insert_into_select_3.sql    |    1 +
 .../default/insert_overwrite_into_select_1.sql  |    1 +
 .../insert_overwrite_into_select_2.hiveql       |    1 +
 .../default/insert_overwrite_into_select_2.sql  |    1 +
 .../default/insert_overwrite_into_select_3.sql  |    1 +
 .../test/resources/queries/default/join_1.sql   |    1 +
 .../test/resources/queries/default/join_10.sql  |    1 +
 .../test/resources/queries/default/join_11.sql  |    1 +
 .../test/resources/queries/default/join_12.sql  |    1 +
 .../test/resources/queries/default/join_13.sql  |   13 +
 .../test/resources/queries/default/join_14.sql  |    1 +
 .../resources/queries/default/join_15.hiveql    |    1 +
 .../test/resources/queries/default/join_15.sql  |    1 +
 .../test/resources/queries/default/join_2.sql   |    1 +
 .../test/resources/queries/default/join_3.sql   |    1 +
 .../test/resources/queries/default/join_4.sql   |    1 +
 .../test/resources/queries/default/join_5.sql   |    1 +
 .../test/resources/queries/default/join_6.sql   |    1 +
 .../test/resources/queries/default/join_7.sql   |    1 +
 .../test/resources/queries/default/join_8.sql   |   13 +
 .../test/resources/queries/default/join_9.sql   |    5 +
 .../test/resources/queries/default/select_1.sql |    1 +
 .../resources/queries/default/select_10.hiveql  |    5 +
 .../resources/queries/default/select_10.sql     |    5 +
 .../resources/queries/default/select_11.hiveql  |    4 +
 .../resources/queries/default/select_11.sql     |    6 +
 .../resources/queries/default/select_12.hiveql  |    3 +
 .../resources/queries/default/select_13.hiveql  |    2 +
 .../resources/queries/default/select_13.sql     |    2 +
 .../resources/queries/default/select_14.sql     |    2 +
 .../resources/queries/default/select_15.hiveql  |    1 +
 .../resources/queries/default/select_15.sql     |    1 +
 .../test/resources/queries/default/select_2.sql |    1 +
 .../test/resources/queries/default/select_3.sql |    1 +
 .../test/resources/queries/default/select_4.sql |    1 +
 .../test/resources/queries/default/select_5.sql |    1 +
 .../test/resources/queries/default/select_6.sql |    1 +
 .../test/resources/queries/default/select_7.sql |    1 +
 .../test/resources/queries/default/select_8.sql |    1 +
 .../resources/queries/default/select_9.hiveql   |    4 +
 .../test/resources/queries/default/select_9.sql |    4 +
 .../test/resources/queries/default/set_1.sql    |    1 +
 .../test/resources/queries/default/set_2.sql    |    1 +
 .../test/resources/queries/default/set_3.sql    |    1 +
 .../test/resources/queries/default/set_4.sql    |   36 +
 .../queries/default/table_subquery1.sql         |   19 +
 .../queries/default/table_subquery2.sql         |   21 +
 .../resources/queries/default/union_1.hiveql    |   14 +
 .../after_set_property_delimiter.result         |    3 +
 .../before_set_property_delimiter.result        |    3 +
 .../TestBuiltinFunctions/testAvgDouble.result   |    5 +
 .../TestBuiltinFunctions/testAvgInt.result      |    3 +
 .../TestBuiltinFunctions/testAvgLong.result     |    3 +
 .../testAvgLongOverflow.result                  |    3 +
 .../TestBuiltinFunctions/testCount.result       |    3 +
 .../TestBuiltinFunctions/testMaxLong.result     |    3 +
 .../TestBuiltinFunctions/testMaxString.result   |    3 +
 .../TestBuiltinFunctions/testMinLong.result     |    3 +
 .../TestBuiltinFunctions/testMinString.result   |    3 +
 .../TestBuiltinFunctions/testSplitPart.result   |    7 +
 .../testSplitPartByString.result                |    7 +
 .../testSplitPartNested.result                  |    7 +
 .../TestCTASQuery/testCtasWithGroupby.result    |    7 +
 .../TestCTASQuery/testCtasWithLimit.result      |    5 +
 .../TestCTASQuery/testCtasWithOptions.result    |    5 +
 .../TestCTASQuery/testCtasWithOrderby.result    |    7 +
 .../TestCTASQuery/testCtasWithStoreType.result  |    5 +
 .../TestCTASQuery/testCtasWithTextFile.result   |    5 +
 .../TestCTASQuery/testCtasWithUnion.result      |    8 +
 .../TestCaseByCases/testTAJO1224Case1.result    |    3 +
 .../TestCaseByCases/testTAJO415Case.result      |    7 +
 .../TestCaseByCases/testTAJO418Case.result      |    4 +
 .../TestCaseByCases/testTAJO619Case.result      |    3 +
 .../TestCaseByCases/testTAJO718Case.result      |    5 +
 .../TestCaseByCases/testTAJO739Case.result      |    7 +
 .../TestCaseByCases/testTAJO914Case1.result     |    5 +
 .../TestCaseByCases/testTAJO914Case2.result     |    5 +
 .../TestCaseByCases/testTAJO914Case3.result     |    5 +
 .../TestCaseByCases/testTAJO914Case4.result     |    5 +
 .../TestCaseByCases/testTAJO917Case1.result     |    7 +
 .../quoted_identifier_mixed_chars_1.result      |    5 +
 .../quoted_identifier_mixed_chars_2.result      |    5 +
 .../quoted_identifier_mixed_chars_3.result      |    8 +
 .../quoted_identifier_non_ascii_1.result        |    5 +
 .../quoted_identifier_non_ascii_2.result        |    5 +
 .../quoted_identifier_non_ascii_3.result        |    5 +
 .../testFindScalarFunctions.result              |    2 +
 .../testComplexParameter.result                 |    3 +
 .../testComplexParameter2.result                |    3 +
 .../testComplexParameterWithSubQuery.result     |    3 +
 .../testComplexTargetWithPythonUdaf.result      |    3 +
 .../testDistinctAggregation1.result             |    5 +
 .../testDistinctAggregation2.result             |    5 +
 .../testDistinctAggregation3.result             |    3 +
 .../testDistinctAggregation4.result             |    4 +
 .../testDistinctAggregation5.result             |    4 +
 .../testDistinctAggregation6.result             |    5 +
 .../testDistinctAggregation7.result             |    3 +
 .../testDistinctAggregation8.result             |    7 +
 .../testDistinctAggregationCaseByCase3.result   |    3 +
 .../testDistinctAggregationCaseByCase4.result   |    3 +
 .../testDistinctAggregationWithHaving1.result   |    3 +
 .../testDistinctAggregationWithUnion1.result    |    4 +
 .../testDistinctAggregation_case1.result        |    4 +
 .../testDistinctAggregation_case10.result       |    3 +
 .../testDistinctAggregation_case2.result        |    4 +
 .../testDistinctAggregation_case3.result        |    4 +
 .../testDistinctAggregation_case4.result        |    5 +
 .../testDistinctAggregation_case5.result        |    5 +
 .../testDistinctAggregation_case6.result        |    5 +
 .../testDistinctAggregation_case7.result        |    5 +
 .../testDistinctAggregation_case8.result        |    6 +
 .../testDistinctAggregation_case9.result        |    6 +
 .../testDistinctPythonUdafWithUnion1.result     |    4 +
 .../results/TestGroupByQuery/testGroupBy.result |    3 +
 .../TestGroupByQuery/testGroupBy2.result        |    4 +
 .../TestGroupByQuery/testGroupBy3.result        |    5 +
 .../TestGroupByQuery/testGroupBy4.result        |    5 +
 .../TestGroupByQuery/testGroupBy5.result        |    5 +
 .../TestGroupByQuery/testGroupByNested1.result  |    6 +
 .../TestGroupByQuery/testGroupByNested2.result  |    6 +
 .../testGroupByWithConstantKeys1.result         |    3 +
 .../testGroupByWithConstantKeys2.result         |    5 +
 .../testGroupByWithConstantKeys3.result         |    3 +
 .../testGroupByWithConstantKeys4.result         |    5 +
 .../testGroupByWithConstantKeys5.result         |    5 +
 .../testGroupByWithExpressionKeys1.result       |    5 +
 .../testGroupByWithExpressionKeys2.result       |    5 +
 .../testGroupByWithNullData1.result             |    3 +
 .../testGroupByWithNullData10.result            |    3 +
 .../testGroupByWithNullData11.result            |    2 +
 .../testGroupByWithNullData12.result            |    2 +
 .../testGroupByWithNullData2.result             |    3 +
 .../testGroupByWithNullData3.result             |    3 +
 .../testGroupByWithNullData4.result             |    3 +
 .../testGroupByWithNullData5.result             |    3 +
 .../testGroupByWithNullData6.result             |    3 +
 .../testGroupByWithNullData7.result             |    3 +
 .../testGroupByWithNullData8.result             |    3 +
 .../testGroupByWithNullData9.result             |    2 +
 .../testGroupByWithSameConstantKeys1.result     |    5 +
 .../testGroupByWithSameExprs1.result            |    6 +
 .../testGroupByWithSameExprs2.result            |    6 +
 .../TestGroupByQuery/testGroupbyWithJson.result |    5 +
 .../testGroupbyWithLimit1.result                |    3 +
 .../testGroupbyWithLimit2.result                |    3 +
 .../testGroupbyWithLimit3.result                |    3 +
 .../testGroupbyWithPythonFunc.result            |    7 +
 .../testGroupbyWithPythonFunc2.result           |    7 +
 .../testHavingWithAggFunction.result            |    4 +
 .../testHavingWithNamedTarget.result            |    5 +
 .../TestGroupByQuery/testPythonUdaf.result      |    3 +
 .../TestGroupByQuery/testPythonUdaf2.result     |    4 +
 .../TestGroupByQuery/testPythonUdaf3.result     |    5 +
 .../testPythonUdafWithHaving.result             |    4 +
 .../testPythonUdafWithNullData.result           |    2 +
 .../TestHBaseTable/testBinaryMappedQuery.result |   81 +
 .../results/TestHBaseTable/testCTAS.result      |  100 ++
 .../testColumnKeyValueSelectQuery.result        |   12 +
 .../TestHBaseTable/testIndexPredication.result  |   38 +
 .../TestHBaseTable/testInsertInto.result        |    3 +
 .../testInsertIntoBinaryMultiRegion.result      |  100 ++
 .../testInsertIntoColumnKeyValue.result         |   21 +
 .../testInsertIntoMultiRegion.result            |  100 ++
 .../testInsertIntoMultiRegion2.result           |  100 ++
 ...stInsertIntoMultiRegionMultiRowFields.result |  100 ++
 ...estInsertIntoMultiRegionWithSplitFile.result |  100 ++
 .../testInsertIntoRowField.result               |    4 +
 .../testInsertIntoUsingPut.result               |    3 +
 .../TestHBaseTable/testInsertValues1.result     |    4 +
 .../results/TestHBaseTable/testJoin.result      |    7 +
 .../TestHBaseTable/testNonForwardQuery.result   |  102 ++
 .../testRowFieldSelectQuery.result              |   88 ++
 .../TestHBaseTable/testSimpleSelectQuery.result |   88 ++
 .../testInAndNotInSubQuery.result               |   24 +
 .../TestInSubquery/testInSubQuery.result        |   27 +
 .../TestInSubquery/testInSubQuery2.result       |    3 +
 .../testInSubQueryWithJoin.result               |    5 +
 .../testInSubQueryWithOtherConditions.result    |   25 +
 .../testInSubQueryWithTableSubQuery.result      |    4 +
 .../testMultipleInSubQuery.result               |    5 +
 .../testMultipleNotInSubQuery.result            |   20 +
 .../testNestedInAndNotInSubQuery.result         |    3 +
 .../TestInSubquery/testNestedInSubQuery.result  |    3 +
 .../TestInSubquery/testNestedInSubQuery2.result |    3 +
 .../testNestedNotInSubQuery.result              |    7 +
 .../TestInSubquery/testNotInSubQuery.result     |   22 +
 ...testSameKeyNameOfOuterAndInnerQueries.result |    3 +
 .../testWithAsteriskAndJoin.result              |    6 +
 .../TestIndexScan/testOnMultipleExprs.result    |    3 +
 .../TestIndexScan/testOnMultipleKeys.result     |    3 +
 .../TestIndexScan/testOnMultipleKeys2.result    |    3 +
 .../testOnSortedNonUniqueKeys.result            |    4 +
 .../TestIndexScan/testOnUnsortedTextKeys.result |    3 +
 .../TestIndexScan/testWithGroupBy.result        |    3 +
 .../results/TestIndexScan/testWithJoin.result   |    4 +
 .../results/TestIndexScan/testWithSort.result   |    4 +
 .../testBroadcastTwoPartJoin.Hash.plan          |  135 ++
 ...stBroadcastTwoPartJoin.Hash_NoBroadcast.plan |  249 ++++
 .../testBroadcastTwoPartJoin.Sort.plan          |  135 ++
 ...stBroadcastTwoPartJoin.Sort_NoBroadcast.plan |  249 ++++
 .../testBroadcastTwoPartJoin.result             |    7 +
 .../testComplexJoinCondition1.Hash.plan         |   78 +
 ...tComplexJoinCondition1.Hash_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition1.Sort.plan         |   78 +
 ...tComplexJoinCondition1.Sort_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition1.result            |   27 +
 .../testComplexJoinCondition2.Hash.plan         |   78 +
 ...tComplexJoinCondition2.Hash_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition2.Sort.plan         |   78 +
 ...tComplexJoinCondition2.Sort_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition2.result            |   27 +
 .../testComplexJoinCondition3.Hash.plan         |   78 +
 ...tComplexJoinCondition3.Hash_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition3.Sort.plan         |   78 +
 ...tComplexJoinCondition3.Sort_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition3.result            |   27 +
 .../testComplexJoinCondition4.Hash.plan         |   78 +
 ...tComplexJoinCondition4.Hash_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition4.Sort.plan         |   78 +
 ...tComplexJoinCondition4.Sort_NoBroadcast.plan |  105 ++
 .../testComplexJoinCondition4.result            |   29 +
 .../testCrossJoin.1.Hash.plan                   |   76 +
 .../testCrossJoin.1.Hash_NoBroadcast.plan       |  103 ++
 .../testCrossJoin.1.Sort.plan                   |   76 +
 .../testCrossJoin.1.Sort_NoBroadcast.plan       |  103 ++
 .../TestInnerJoinQuery/testCrossJoin.1.result   |  127 ++
 .../testCrossJoin.2.Hash.plan                   |   51 +
 .../testCrossJoin.2.Hash_NoBroadcast.plan       |   78 +
 .../testCrossJoin.2.Sort.plan                   |   51 +
 .../testCrossJoin.2.Sort_NoBroadcast.plan       |   78 +
 .../TestInnerJoinQuery/testCrossJoin.2.result   |   27 +
 .../testCrossJoin.3.Hash.plan                   |   51 +
 .../testCrossJoin.3.Hash_NoBroadcast.plan       |   78 +
 .../testCrossJoin.3.Sort.plan                   |   51 +
 .../testCrossJoin.3.Sort_NoBroadcast.plan       |   78 +
 .../TestInnerJoinQuery/testCrossJoin.3.result   |   27 +
 .../testCrossJoin.4.Hash.plan                   |   51 +
 .../testCrossJoin.4.Hash_NoBroadcast.plan       |   78 +
 .../testCrossJoin.4.Sort.plan                   |   51 +
 .../testCrossJoin.4.Sort_NoBroadcast.plan       |   78 +
 .../TestInnerJoinQuery/testCrossJoin.4.result   |   27 +
 .../testCrossJoin.5.Hash.plan                   |   76 +
 .../testCrossJoin.5.Hash_NoBroadcast.plan       |  103 ++
 .../testCrossJoin.5.Sort.plan                   |   76 +
 .../testCrossJoin.5.Sort_NoBroadcast.plan       |  103 ++
 .../TestInnerJoinQuery/testCrossJoin.5.result   |   27 +
 .../testCrossJoinAndCaseWhen.Hash.plan          |   78 +
 ...stCrossJoinAndCaseWhen.Hash_NoBroadcast.plan |  105 ++
 .../testCrossJoinAndCaseWhen.Sort.plan          |   78 +
 ...stCrossJoinAndCaseWhen.Sort_NoBroadcast.plan |  105 ++
 .../testCrossJoinAndCaseWhen.result             |   27 +
 .../testCrossJoinWithAsterisk1.Hash.plan        |   76 +
 ...CrossJoinWithAsterisk1.Hash_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk1.Sort.plan        |   76 +
 ...CrossJoinWithAsterisk1.Sort_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk1.result           |   27 +
 .../testCrossJoinWithAsterisk2.Hash.plan        |   76 +
 ...CrossJoinWithAsterisk2.Hash_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk2.Sort.plan        |   76 +
 ...CrossJoinWithAsterisk2.Sort_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk2.result           |   27 +
 .../testCrossJoinWithAsterisk3.Hash.plan        |   76 +
 ...CrossJoinWithAsterisk3.Hash_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk3.Sort.plan        |   76 +
 ...CrossJoinWithAsterisk3.Sort_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk3.result           |   27 +
 .../testCrossJoinWithAsterisk4.Hash.plan        |   76 +
 ...CrossJoinWithAsterisk4.Hash_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk4.Sort.plan        |   76 +
 ...CrossJoinWithAsterisk4.Sort_NoBroadcast.plan |  103 ++
 .../testCrossJoinWithAsterisk4.result           |   27 +
 .../testCrossJoinWithEmptyTable1.Hash.plan      |   78 +
 ...ossJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 ++
 .../testCrossJoinWithEmptyTable1.Sort.plan      |   78 +
 ...ossJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 ++
 .../testCrossJoinWithEmptyTable1.result         |    2 +
 ...sJoinWithThetaJoinConditionInWhere.Hash.plan |   63 +
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   90 ++
 ...sJoinWithThetaJoinConditionInWhere.Sort.plan |   63 +
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   90 ++
 ...rossJoinWithThetaJoinConditionInWhere.result |   12 +
 .../testDifferentTypesJoinCondition.Hash.plan   |   53 +
 ...rentTypesJoinCondition.Hash_NoBroadcast.plan |   80 +
 .../testDifferentTypesJoinCondition.Sort.plan   |   53 +
 ...rentTypesJoinCondition.Sort_NoBroadcast.plan |   80 +
 .../testDifferentTypesJoinCondition.result      |    7 +
 .../testInnerJoinAndCaseWhen.Hash.plan          |   78 +
 ...stInnerJoinAndCaseWhen.Hash_NoBroadcast.plan |  105 ++
 .../testInnerJoinAndCaseWhen.Sort.plan          |   78 +
 ...stInnerJoinAndCaseWhen.Sort_NoBroadcast.plan |  105 ++
 .../testInnerJoinAndCaseWhen.result             |   27 +
 .../testInnerJoinWithEmptyTable.Hash.plan       |   78 +
 ...nnerJoinWithEmptyTable.Hash_NoBroadcast.plan |  105 ++
 .../testInnerJoinWithEmptyTable.Sort.plan       |   78 +
 ...nnerJoinWithEmptyTable.Sort_NoBroadcast.plan |  105 ++
 .../testInnerJoinWithEmptyTable.result          |    2 +
 ...rJoinWithThetaJoinConditionInWhere.Hash.plan |   57 +
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   84 ++
 ...rJoinWithThetaJoinConditionInWhere.Sort.plan |   57 +
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   84 ++
 ...nnerJoinWithThetaJoinConditionInWhere.result |    7 +
 .../testJoinAsterisk.Hash.plan                  |   53 +
 .../testJoinAsterisk.Hash_NoBroadcast.plan      |   80 +
 .../testJoinAsterisk.Sort.plan                  |   53 +
 .../testJoinAsterisk.Sort_NoBroadcast.plan      |   80 +
 .../TestInnerJoinQuery/testJoinAsterisk.result  |    7 +
 .../testJoinCoReferredEvals1.Hash.plan          |   78 +
 ...stJoinCoReferredEvals1.Hash_NoBroadcast.plan |  105 ++
 .../testJoinCoReferredEvals1.Sort.plan          |   78 +
 ...stJoinCoReferredEvals1.Sort_NoBroadcast.plan |  105 ++
 .../testJoinCoReferredEvals1.result             |   27 +
 ...tJoinCoReferredEvalsWithSameExprs1.Hash.plan |   88 ++
 ...redEvalsWithSameExprs1.Hash_NoBroadcast.plan |  115 ++
 ...tJoinCoReferredEvalsWithSameExprs1.Sort.plan |   88 ++
 ...redEvalsWithSameExprs1.Sort_NoBroadcast.plan |  115 ++
 ...testJoinCoReferredEvalsWithSameExprs1.result |   22 +
 ...tJoinCoReferredEvalsWithSameExprs2.Hash.plan |  119 ++
 ...redEvalsWithSameExprs2.Hash_NoBroadcast.plan |  146 ++
 ...tJoinCoReferredEvalsWithSameExprs2.Sort.plan |  119 ++
 ...redEvalsWithSameExprs2.Sort_NoBroadcast.plan |  146 ++
 ...testJoinCoReferredEvalsWithSameExprs2.result |   22 +
 .../testJoinOnMultipleDatabases.Hash.plan       |  135 ++
 ...oinOnMultipleDatabases.Hash_NoBroadcast.plan |  249 ++++
 .../testJoinOnMultipleDatabases.Sort.plan       |  135 ++
 ...oinOnMultipleDatabases.Sort_NoBroadcast.plan |  249 ++++
 .../testJoinOnMultipleDatabases.result          |    5 +
 .../testJoinOnMultipleDatabasesWithJson.result  |    5 +
 .../TestInnerJoinQuery/testJoinWithJson.result  |   27 +
 .../testJoinWithMultipleJoinQual1.Hash.plan     |  135 ++
 ...nWithMultipleJoinQual1.Hash_NoBroadcast.plan |  249 ++++
 .../testJoinWithMultipleJoinQual1.Sort.plan     |  135 ++
 ...nWithMultipleJoinQual1.Sort_NoBroadcast.plan |  249 ++++
 .../testJoinWithMultipleJoinQual1.result        |    2 +
 .../testJoinWithOrPredicates.Hash.plan          |   90 ++
 ...stJoinWithOrPredicates.Hash_NoBroadcast.plan |  117 ++
 .../testJoinWithOrPredicates.Sort.plan          |   90 ++
 ...stJoinWithOrPredicates.Sort_NoBroadcast.plan |  117 ++
 .../testJoinWithOrPredicates.result             |    4 +
 .../testNaturalJoin.Hash.plan                   |   78 +
 .../testNaturalJoin.Hash_NoBroadcast.plan       |  105 ++
 .../testNaturalJoin.Sort.plan                   |   78 +
 .../testNaturalJoin.Sort_NoBroadcast.plan       |  105 ++
 .../TestInnerJoinQuery/testNaturalJoin.result   |   27 +
 .../TestInnerJoinQuery/testTPCHQ2Join.Hash.plan |  135 ++
 .../testTPCHQ2Join.Hash_NoBroadcast.plan        |  249 ++++
 .../TestInnerJoinQuery/testTPCHQ2Join.Sort.plan |  135 ++
 .../testTPCHQ2Join.Sort_NoBroadcast.plan        |  249 ++++
 .../TestInnerJoinQuery/testTPCHQ2Join.result    |    5 +
 .../testWhereClauseJoin1.Hash.plan              |   78 +
 .../testWhereClauseJoin1.Hash_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin1.Sort.plan              |   78 +
 .../testWhereClauseJoin1.Sort_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin1.result                 |   27 +
 .../testWhereClauseJoin2.Hash.plan              |   78 +
 .../testWhereClauseJoin2.Hash_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin2.Sort.plan              |   78 +
 .../testWhereClauseJoin2.Sort_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin2.result                 |   27 +
 .../testWhereClauseJoin3.Hash.plan              |   78 +
 .../testWhereClauseJoin3.Hash_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin3.Sort.plan              |   78 +
 .../testWhereClauseJoin3.Sort_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin3.result                 |   27 +
 .../testWhereClauseJoin4.Hash.plan              |   78 +
 .../testWhereClauseJoin4.Hash_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin4.Sort.plan              |   78 +
 .../testWhereClauseJoin4.Sort_NoBroadcast.plan  |  105 ++
 .../testWhereClauseJoin4.result                 |   27 +
 .../testWhereClauseJoin5.Hash.plan              |   97 ++
 .../testWhereClauseJoin5.Hash_NoBroadcast.plan  |  153 ++
 .../testWhereClauseJoin5.Sort.plan              |   97 ++
 .../testWhereClauseJoin5.Sort_NoBroadcast.plan  |  153 ++
 .../testWhereClauseJoin5.result                 |    5 +
 .../testWhereClauseJoin6.Hash.plan              |  116 ++
 .../testWhereClauseJoin6.Hash_NoBroadcast.plan  |  201 +++
 .../testWhereClauseJoin6.Sort.plan              |  116 ++
 .../testWhereClauseJoin6.Sort_NoBroadcast.plan  |  201 +++
 .../testWhereClauseJoin6.result                 |    5 +
 .../testBroadcastSubquery.Hash.plan             |  109 ++
 .../testBroadcastSubquery.Hash_NoBroadcast.plan |  165 ++
 .../testBroadcastSubquery.Sort.plan             |  109 ++
 .../testBroadcastSubquery.Sort_NoBroadcast.plan |  165 ++
 .../testBroadcastSubquery.result                |    7 +
 .../testBroadcastSubquery2.Hash.plan            |  216 +++
 ...testBroadcastSubquery2.Hash_NoBroadcast.plan |  328 ++++
 .../testBroadcastSubquery2.Sort.plan            |  216 +++
 ...testBroadcastSubquery2.Sort_NoBroadcast.plan |  328 ++++
 .../testBroadcastSubquery2.result               |    3 +
 .../testComplexJoinCondition5.Hash.plan         |   90 ++
 ...tComplexJoinCondition5.Hash_NoBroadcast.plan |  117 ++
 .../testComplexJoinCondition5.Sort.plan         |   90 ++
 ...tComplexJoinCondition5.Sort_NoBroadcast.plan |  117 ++
 .../testComplexJoinCondition5.result            |   29 +
 .../testComplexJoinCondition6.Hash.plan         |  109 ++
 ...tComplexJoinCondition6.Hash_NoBroadcast.plan |  145 ++
 .../testComplexJoinCondition6.Sort.plan         |  109 ++
 ...tComplexJoinCondition6.Sort_NoBroadcast.plan |  145 ++
 .../testComplexJoinCondition6.result            |   56 +
 .../testComplexJoinCondition7.Hash.plan         |  109 ++
 ...tComplexJoinCondition7.Hash_NoBroadcast.plan |  145 ++
 .../testComplexJoinCondition7.Sort.plan         |  109 ++
 ...tComplexJoinCondition7.Sort_NoBroadcast.plan |  145 ++
 .../testComplexJoinCondition7.result            |   56 +
 .../testJoinWithJson2.result                    |    5 +
 .../testJoinWithMultipleJoinQual2.Hash.plan     |   86 ++
 ...nWithMultipleJoinQual2.Hash_NoBroadcast.plan |  142 ++
 .../testJoinWithMultipleJoinQual2.Sort.plan     |   86 ++
 ...nWithMultipleJoinQual2.Sort_NoBroadcast.plan |  142 ++
 .../testJoinWithMultipleJoinQual2.result        |    3 +
 .../testJoinWithMultipleJoinQual3.Hash.plan     |  105 ++
 ...nWithMultipleJoinQual3.Hash_NoBroadcast.plan |  190 +++
 .../testJoinWithMultipleJoinQual3.Sort.plan     |  105 ++
 ...nWithMultipleJoinQual3.Sort_NoBroadcast.plan |  190 +++
 .../testJoinWithMultipleJoinQual3.result        |    5 +
 .../testJoinWithMultipleJoinQual4.Hash.plan     |  109 ++
 ...nWithMultipleJoinQual4.Hash_NoBroadcast.plan |  194 +++
 .../testJoinWithMultipleJoinQual4.Sort.plan     |  109 ++
 ...nWithMultipleJoinQual4.Sort_NoBroadcast.plan |  194 +++
 .../testJoinWithMultipleJoinQual4.result        |    4 +
 .../testThetaJoinKeyPairs.Hash.plan             |  146 ++
 .../testThetaJoinKeyPairs.Hash_NoBroadcast.plan |  200 +++
 .../testThetaJoinKeyPairs.Sort.plan             |  146 ++
 .../testThetaJoinKeyPairs.Sort_NoBroadcast.plan |  200 +++
 .../testThetaJoinKeyPairs.result                |   21 +
 ...estInsertOverwriteWithAsteriskAndMore.result |    7 +
 ...sertOverwriteWithAsteriskUsingParquet.result |    4 +
 ...ertOverwriteWithAsteriskUsingParquet2.result |    4 +
 .../testInsertWithDifferentColumnOrder.result   |   27 +
 .../selfJoinOfPartitionedTable.result           |    7 +
 .../testBroadcastPartitionTable.result          |    5 +
 ...FilterPushDownPartitionColumnCaseWhen.result |    4 +
 ...tionedBroadcastDataFileWithZeroLength.result |    7 +
 ...ionedBroadcastDataFileWithZeroLength2.result |    7 +
 .../testNoProjectionJoinQual.result             |    3 +
 .../testPartialFilterPushDown.result            |    3 +
 .../testPartialFilterPushDownOuterJoin.result   |   27 +
 .../testPartialFilterPushDownOuterJoin2.result  |   27 +
 ...estPartitionMultiplePartitionFilter.1.result |    2 +
 .../testPartitionTableJoinSmallTable.result     |    7 +
 .../TestJoinQuery/testWhereClauseJoin6.result   |    5 +
 .../testComplexJoinsWithCaseWhen.Hash.plan      |   97 ++
 ...mplexJoinsWithCaseWhen.Hash_NoBroadcast.plan |  153 ++
 .../testComplexJoinsWithCaseWhen.Sort.plan      |   97 ++
 ...mplexJoinsWithCaseWhen.Sort_NoBroadcast.plan |  153 ++
 .../testComplexJoinsWithCaseWhen.result         |   27 +
 .../testComplexJoinsWithCaseWhen2.Hash.plan     |  109 ++
 ...plexJoinsWithCaseWhen2.Hash_NoBroadcast.plan |  165 ++
 .../testComplexJoinsWithCaseWhen2.Sort.plan     |  109 ++
 ...plexJoinsWithCaseWhen2.Sort_NoBroadcast.plan |  165 ++
 .../testComplexJoinsWithCaseWhen2.result        |   27 +
 .../testInnerAndOuterWithEmpty.1.Hash.plan      |   74 +
 ...nerAndOuterWithEmpty.1.Hash_NoBroadcast.plan |  130 ++
 .../testInnerAndOuterWithEmpty.1.Sort.plan      |   74 +
 ...nerAndOuterWithEmpty.1.Sort_NoBroadcast.plan |  130 ++
 .../testInnerAndOuterWithEmpty.1.result         |    7 +
 .../testJoinWithMultipleJoinTypes.Hash.plan     |   84 ++
 ...nWithMultipleJoinTypes.Hash_NoBroadcast.plan |  140 ++
 .../testJoinWithMultipleJoinTypes.Sort.plan     |   84 ++
 ...nWithMultipleJoinTypes.Sort_NoBroadcast.plan |  140 ++
 .../testJoinWithMultipleJoinTypes.result        |    6 +
 .../results/TestNetTypes/testGroupby.result     |    7 +
 .../results/TestNetTypes/testGroupby2.result    |    5 +
 .../results/TestNetTypes/testJoin.result        |    6 +
 .../results/TestNetTypes/testSelect.result      |    7 +
 .../results/TestNetTypes/testSort.result        |    7 +
 .../results/TestNetTypes/testSort2.result       |    7 +
 .../testGetClusterDetails.result                |    4 +
 .../testGetNextRowsForAggregateFunction.result  |    3 +
 .../testGetNextRowsForTable.result              |    5 +
 .../testFullOuterJoin1.Hash.plan                |  105 ++
 .../testFullOuterJoin1.Hash_NoBroadcast.plan    |  105 ++
 .../testFullOuterJoin1.Sort.plan                |  105 ++
 .../testFullOuterJoin1.Sort_NoBroadcast.plan    |  105 ++
 .../testFullOuterJoin1.result                   |    7 +
 ...lOuterJoinPredicationCaseByCase1.1.Hash.plan |  153 ++
 ...edicationCaseByCase1.1.Hash_NoBroadcast.plan |  153 ++
 ...lOuterJoinPredicationCaseByCase1.1.Sort.plan |  153 ++
 ...edicationCaseByCase1.1.Sort_NoBroadcast.plan |  153 ++
 ...FullOuterJoinPredicationCaseByCase1.1.result |    9 +
 .../testFullOuterJoinWithEmptyTable1.Hash.plan  |  105 ++
 ...terJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 ++
 .../testFullOuterJoinWithEmptyTable1.Sort.plan  |  105 ++
 ...terJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 ++
 .../testFullOuterJoinWithEmptyTable1.result     |    7 +
 ...testJoinFilterOfRowPreservedTable1.Hash.plan |   78 +
 ...erOfRowPreservedTable1.Hash_NoBroadcast.plan |  105 ++
 ...testJoinFilterOfRowPreservedTable1.Sort.plan |   78 +
 ...erOfRowPreservedTable1.Sort_NoBroadcast.plan |  105 ++
 .../testJoinFilterOfRowPreservedTable1.result   |   15 +
 .../testLeftOuterJoin1.Hash.plan                |   78 +
 .../testLeftOuterJoin1.Hash_NoBroadcast.plan    |  105 ++
 .../testLeftOuterJoin1.Sort.plan                |   78 +
 .../testLeftOuterJoin1.Sort_NoBroadcast.plan    |  105 ++
 .../testLeftOuterJoin1.result                   |    7 +
 .../testLeftOuterJoin2.Hash.plan                |   91 ++
 .../testLeftOuterJoin2.Hash_NoBroadcast.plan    |  176 +++
 .../testLeftOuterJoin2.Sort.plan                |   91 ++
 .../testLeftOuterJoin2.Sort_NoBroadcast.plan    |  176 +++
 .../testLeftOuterJoin2.result                   |    7 +
 .../testLeftOuterJoin3.Hash.plan                |  160 ++
 .../testLeftOuterJoin3.Hash_NoBroadcast.plan    |  272 ++++
 .../testLeftOuterJoin3.Sort.plan                |  160 ++
 .../testLeftOuterJoin3.Sort_NoBroadcast.plan    |  272 ++++
 .../testLeftOuterJoin3.result                   |    9 +
 ...tLeftOuterJoinLeftSideSmallTable.1.Hash.plan |  105 ++
 ...inLeftSideSmallTable.1.Hash_NoBroadcast.plan |  105 ++
 ...tLeftOuterJoinLeftSideSmallTable.1.Sort.plan |  105 ++
 ...inLeftSideSmallTable.1.Sort_NoBroadcast.plan |  105 ++
 ...testLeftOuterJoinLeftSideSmallTable.1.result |    7 +
 ...tOuterJoinPredicationCaseByCase1.1.Hash.plan |   72 +
 ...edicationCaseByCase1.1.Hash_NoBroadcast.plan |  128 ++
 ...tOuterJoinPredicationCaseByCase1.1.Sort.plan |   72 +
 ...edicationCaseByCase1.1.Sort_NoBroadcast.plan |  128 ++
 ...LeftOuterJoinPredicationCaseByCase1.1.result |    7 +
 ...tOuterJoinPredicationCaseByCase2.1.Hash.plan |  122 ++
 ...edicationCaseByCase2.1.Hash_NoBroadcast.plan |  176 +++
 ...tOuterJoinPredicationCaseByCase2.1.Sort.plan |  122 ++
 ...edicationCaseByCase2.1.Sort_NoBroadcast.plan |  176 +++
 ...LeftOuterJoinPredicationCaseByCase2.1.result |    4 +
 ...uterJoinPredicationCaseByCase2_1.1.Hash.plan |   97 ++
 ...icationCaseByCase2_1.1.Hash_NoBroadcast.plan |  182 +++
 ...uterJoinPredicationCaseByCase2_1.1.Sort.plan |   97 ++
 ...icationCaseByCase2_1.1.Sort_NoBroadcast.plan |  182 +++
 ...ftOuterJoinPredicationCaseByCase2_1.1.result |    5 +
 ...tOuterJoinPredicationCaseByCase3.1.Hash.plan |   72 +
 ...edicationCaseByCase3.1.Hash_NoBroadcast.plan |  128 ++
 ...tOuterJoinPredicationCaseByCase3.1.Sort.plan |   72 +
 ...edicationCaseByCase3.1.Sort_NoBroadcast.plan |  128 ++
 ...LeftOuterJoinPredicationCaseByCase3.1.result |    7 +
 ...tOuterJoinPredicationCaseByCase4.1.Hash.plan |   74 +
 ...edicationCaseByCase4.1.Hash_NoBroadcast.plan |  130 ++
 ...tOuterJoinPredicationCaseByCase4.1.Sort.plan |   74 +
 ...edicationCaseByCase4.1.Sort_NoBroadcast.plan |  130 ++
 ...LeftOuterJoinPredicationCaseByCase4.1.result |    7 +
 ...tOuterJoinPredicationCaseByCase5.1.Hash.plan |   74 +
 ...edicationCaseByCase5.1.Hash_NoBroadcast.plan |  130 ++
 ...tOuterJoinPredicationCaseByCase5.1.Sort.plan |   74 +
 ...edicationCaseByCase5.1.Sort_NoBroadcast.plan |  130 ++
 ...LeftOuterJoinPredicationCaseByCase5.1.result |    6 +
 ...tOuterJoinPredicationCaseByCase6.1.Hash.plan |   76 +
 ...edicationCaseByCase6.1.Hash_NoBroadcast.plan |  132 ++
 ...tOuterJoinPredicationCaseByCase6.1.Sort.plan |   76 +
 ...edicationCaseByCase6.1.Sort_NoBroadcast.plan |  132 ++
 ...LeftOuterJoinPredicationCaseByCase6.1.result |    3 +
 ...testLeftOuterJoinWithConstantExpr1.Hash.plan |   86 ++
 ...rJoinWithConstantExpr1.Hash_NoBroadcast.plan |  113 ++
 ...testLeftOuterJoinWithConstantExpr1.Sort.plan |   86 ++
 ...rJoinWithConstantExpr1.Sort_NoBroadcast.plan |  113 ++
 .../testLeftOuterJoinWithConstantExpr1.result   |    7 +
 ...testLeftOuterJoinWithConstantExpr4.Hash.plan |   63 +
 ...rJoinWithConstantExpr4.Hash_NoBroadcast.plan |   90 ++
 ...testLeftOuterJoinWithConstantExpr4.Sort.plan |   63 +
 ...rJoinWithConstantExpr4.Sort_NoBroadcast.plan |   90 ++
 .../testLeftOuterJoinWithConstantExpr4.result   |    7 +
 ...testLeftOuterJoinWithConstantExpr5.Hash.plan |   65 +
 ...rJoinWithConstantExpr5.Hash_NoBroadcast.plan |   92 ++
 ...testLeftOuterJoinWithConstantExpr5.Sort.plan |   65 +
 ...rJoinWithConstantExpr5.Sort_NoBroadcast.plan |   92 ++
 .../testLeftOuterJoinWithConstantExpr5.result   |    6 +
 .../testLeftOuterJoinWithEmptyTable1.Hash.plan  |   78 +
 ...terJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 ++
 .../testLeftOuterJoinWithEmptyTable1.Sort.plan  |   78 +
 ...terJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 ++
 .../testLeftOuterJoinWithEmptyTable1.result     |    7 +
 .../testLeftOuterJoinWithEmptyTable2.Hash.plan  |  109 ++
 ...terJoinWithEmptyTable2.Hash_NoBroadcast.plan |  136 ++
 .../testLeftOuterJoinWithEmptyTable2.Sort.plan  |  109 ++
 ...terJoinWithEmptyTable2.Sort_NoBroadcast.plan |  136 ++
 .../testLeftOuterJoinWithEmptyTable2.result     |    7 +
 .../testLeftOuterJoinWithEmptyTable3.Hash.plan  |  160 ++
 ...terJoinWithEmptyTable3.Hash_NoBroadcast.plan |  187 +++
 .../testLeftOuterJoinWithEmptyTable3.Sort.plan  |  160 ++
 ...terJoinWithEmptyTable3.Sort_NoBroadcast.plan |  187 +++
 .../testLeftOuterJoinWithEmptyTable3.result     |    7 +
 .../testLeftOuterJoinWithEmptyTable4.Hash.plan  |  160 ++
 ...terJoinWithEmptyTable4.Hash_NoBroadcast.plan |  214 +++
 .../testLeftOuterJoinWithEmptyTable4.Sort.plan  |  160 ++
 ...terJoinWithEmptyTable4.Sort_NoBroadcast.plan |  214 +++
 .../testLeftOuterJoinWithEmptyTable4.result     |    4 +
 .../testLeftOuterJoinWithEmptyTable5.Hash.plan  |  109 ++
 ...terJoinWithEmptyTable5.Hash_NoBroadcast.plan |  136 ++
 .../testLeftOuterJoinWithEmptyTable5.Sort.plan  |  109 ++
 ...terJoinWithEmptyTable5.Sort_NoBroadcast.plan |  136 ++
 .../testLeftOuterJoinWithEmptyTable5.result     |    4 +
 .../testLeftOuterJoinWithNull1.Hash.plan        |   82 +
 ...LeftOuterJoinWithNull1.Hash_NoBroadcast.plan |  109 ++
 .../testLeftOuterJoinWithNull1.Sort.plan        |   82 +
 ...LeftOuterJoinWithNull1.Sort_NoBroadcast.plan |  109 ++
 .../testLeftOuterJoinWithNull1.result           |    4 +
 .../testLeftOuterJoinWithNull2.Hash.plan        |   82 +
 ...LeftOuterJoinWithNull2.Hash_NoBroadcast.plan |  109 ++
 .../testLeftOuterJoinWithNull2.Sort.plan        |   82 +
 ...LeftOuterJoinWithNull2.Sort_NoBroadcast.plan |  109 ++
 .../testLeftOuterJoinWithNull2.result           |    4 +
 .../testLeftOuterJoinWithNull3.Hash.plan        |   82 +
 ...LeftOuterJoinWithNull3.Hash_NoBroadcast.plan |  109 ++
 .../testLeftOuterJoinWithNull3.Sort.plan        |   82 +
 ...LeftOuterJoinWithNull3.Sort_NoBroadcast.plan |  109 ++
 .../testLeftOuterJoinWithNull3.result           |    2 +
 ...rJoinWithThetaJoinConditionInWhere.Hash.plan |   57 +
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   84 ++
 ...rJoinWithThetaJoinConditionInWhere.Sort.plan |   57 +
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   84 ++
 ...uterJoinWithThetaJoinConditionInWhere.result |    4 +
 .../testLeftOuterWithEmptyTable.1.Hash.plan     |   53 +
 ...tOuterWithEmptyTable.1.Hash_NoBroadcast.plan |   80 +
 .../testLeftOuterWithEmptyTable.1.Sort.plan     |   53 +
 ...tOuterWithEmptyTable.1.Sort_NoBroadcast.plan |   80 +
 .../testLeftOuterWithEmptyTable.1.result        |    7 +
 ...pleBroadcastDataFileWithZeroLength.Hash.plan |   57 +
 ...DataFileWithZeroLength.Hash_NoBroadcast.plan |   84 ++
 ...pleBroadcastDataFileWithZeroLength.Sort.plan |   57 +
 ...DataFileWithZeroLength.Sort_NoBroadcast.plan |   84 ++
 ...ltipleBroadcastDataFileWithZeroLength.result |    2 +
 ...leBroadcastDataFileWithZeroLength2.Hash.plan |   76 +
 ...ataFileWithZeroLength2.Hash_NoBroadcast.plan |  132 ++
 ...leBroadcastDataFileWithZeroLength2.Sort.plan |   76 +
 ...ataFileWithZeroLength2.Sort_NoBroadcast.plan |  132 ++
 ...tipleBroadcastDataFileWithZeroLength2.result |    7 +
 .../testOuterJoinAndCaseWhen1.Hash.plan         |  126 ++
 ...tOuterJoinAndCaseWhen1.Hash_NoBroadcast.plan |  153 ++
 .../testOuterJoinAndCaseWhen1.Sort.plan         |  126 ++
 ...tOuterJoinAndCaseWhen1.Sort_NoBroadcast.plan |  153 ++
 .../testOuterJoinAndCaseWhen1.result            |    7 +
 .../testRightOuterJoin1.Hash.plan               |   78 +
 .../testRightOuterJoin1.Hash_NoBroadcast.plan   |  105 ++
 .../testRightOuterJoin1.Sort.plan               |   78 +
 .../testRightOuterJoin1.Sort_NoBroadcast.plan   |  105 ++
 .../testRightOuterJoin1.result                  |    7 +
 ...tOuterJoinPredicationCaseByCase1.1.Hash.plan |  101 ++
 ...edicationCaseByCase1.1.Hash_NoBroadcast.plan |  128 ++
 ...tOuterJoinPredicationCaseByCase1.1.Sort.plan |  101 ++
 ...edicationCaseByCase1.1.Sort_NoBroadcast.plan |  128 ++
 ...ightOuterJoinPredicationCaseByCase1.1.result |    4 +
 ...tOuterJoinPredicationCaseByCase2.1.Hash.plan |   76 +
 ...edicationCaseByCase2.1.Hash_NoBroadcast.plan |  132 ++
 ...tOuterJoinPredicationCaseByCase2.1.Sort.plan |   76 +
 ...edicationCaseByCase2.1.Sort_NoBroadcast.plan |  132 ++
 ...ightOuterJoinPredicationCaseByCase2.1.result |    4 +
 ...tOuterJoinPredicationCaseByCase3.1.Hash.plan |  101 ++
 ...edicationCaseByCase3.1.Hash_NoBroadcast.plan |  128 ++
 ...tOuterJoinPredicationCaseByCase3.1.Sort.plan |  101 ++
 ...edicationCaseByCase3.1.Sort_NoBroadcast.plan |  128 ++
 ...ightOuterJoinPredicationCaseByCase3.1.result |    4 +
 .../testRightOuterJoinWithEmptyTable1.Hash.plan |   78 +
 ...terJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 ++
 .../testRightOuterJoinWithEmptyTable1.Sort.plan |   78 +
 ...terJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 ++
 .../testRightOuterJoinWithEmptyTable1.result    |    7 +
 ...rJoinWithThetaJoinConditionInWhere.Hash.plan |   57 +
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   84 ++
 ...rJoinWithThetaJoinConditionInWhere.Sort.plan |   57 +
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   84 ++
 ...uterJoinWithThetaJoinConditionInWhere.result |    4 +
 ...terJoinWithEmptyIntermediateData.1.Hash.plan |  108 ++
 ...mptyIntermediateData.1.Hash_NoBroadcast.plan |  108 ++
 ...terJoinWithEmptyIntermediateData.1.Sort.plan |  108 ++
 ...mptyIntermediateData.1.Sort_NoBroadcast.plan |  108 ++
 ...lOuterJoinWithEmptyIntermediateData.1.result |    2 +
 .../testJoinWithDifferentShuffleKey.1.Hash.plan |  199 +++
 ...hDifferentShuffleKey.1.Hash_NoBroadcast.plan |  199 +++
 .../testJoinWithDifferentShuffleKey.1.Sort.plan |  199 +++
 ...hDifferentShuffleKey.1.Sort_NoBroadcast.plan |  199 +++
 .../testJoinWithDifferentShuffleKey.1.result    |    3 +
 ...testLeftOuterJoinWithConstantExpr2.Hash.plan |   98 ++
 ...rJoinWithConstantExpr2.Hash_NoBroadcast.plan |  125 ++
 ...testLeftOuterJoinWithConstantExpr2.Sort.plan |   98 ++
 ...rJoinWithConstantExpr2.Sort_NoBroadcast.plan |  125 ++
 .../testLeftOuterJoinWithConstantExpr2.result   |    7 +
 ...testLeftOuterJoinWithConstantExpr3.Hash.plan |  156 ++
 ...rJoinWithConstantExpr3.Hash_NoBroadcast.plan |  156 ++
 ...testLeftOuterJoinWithConstantExpr3.Sort.plan |  156 ++
 ...rJoinWithConstantExpr3.Sort_NoBroadcast.plan |  156 ++
 .../testLeftOuterJoinWithConstantExpr3.result   |    7 +
 ...tLeftOuterJoinWithEmptySubquery1.1.Hash.plan |  111 ++
 ...inWithEmptySubquery1.1.Hash_NoBroadcast.plan |  167 +++
 ...tLeftOuterJoinWithEmptySubquery1.1.Sort.plan |  111 ++
 ...inWithEmptySubquery1.1.Sort_NoBroadcast.plan |  167 +++
 ...testLeftOuterJoinWithEmptySubquery1.1.result |    7 +
 ...tLeftOuterJoinWithEmptySubquery2.1.Hash.plan |   86 ++
 ...inWithEmptySubquery2.1.Hash_NoBroadcast.plan |  142 ++
 ...tLeftOuterJoinWithEmptySubquery2.1.Sort.plan |   86 ++
 ...inWithEmptySubquery2.1.Sort_NoBroadcast.plan |  142 ++
 ...testLeftOuterJoinWithEmptySubquery2.1.result |    2 +
 .../TestQueryUnitStatusUpdate/case3.result      |    4 +
 .../create_table_nested_1.result                |   40 +
 .../create_table_nested_2.result                |   57 +
 .../results/TestSQLAnalyzer/setcatalog1.result  |    5 +
 .../results/TestSQLAnalyzer/setcatalog2.result  |    5 +
 .../results/TestSQLAnalyzer/setsession1.result  |    5 +
 .../results/TestSQLAnalyzer/setsession2.result  |    5 +
 .../results/TestSQLAnalyzer/setsession3.result  |    5 +
 .../results/TestSQLAnalyzer/setsession4.result  |    5 +
 .../results/TestSQLAnalyzer/setsession5.result  |    5 +
 .../results/TestSQLAnalyzer/setsession6.result  |    5 +
 .../results/TestSQLAnalyzer/setsession7.result  |    5 +
 .../results/TestSQLAnalyzer/settimezone1.result |    5 +
 .../results/TestSQLAnalyzer/settimezone2.result |    5 +
 .../results/TestSQLAnalyzer/settimezone3.result |    4 +
 .../results/TestSQLAnalyzer/window1.result      |   37 +
 .../results/TestSQLAnalyzer/window2.result      |   44 +
 .../results/TestSQLAnalyzer/window3.result      |   50 +
 .../results/TestSQLAnalyzer/window4.result      |   48 +
 .../results/TestSQLAnalyzer/window5.result      |   77 +
 .../results/TestSQLAnalyzer/window6.result      |   83 ++
 .../results/TestSQLAnalyzer/window7.result      |   81 +
 .../results/TestSQLAnalyzer/window8.result      |   86 ++
 .../results/TestSQLAnalyzer/window9.result      |   56 +
 .../testInsertType1.result                      |    5 +
 .../testInsertType2.result                      |    5 +
 .../testNestedFieldAsGroupbyKey1.result         |    6 +
 .../testNestedFieldAsJoinKey1.result            |    6 +
 .../TestSelectNestedRecord/testSelect0.result   |    5 +
 .../TestSelectNestedRecord/testSelect1.result   |    5 +
 .../TestSelectNestedRecord/testSelect2.result   |    6 +
 .../TestSelectNestedRecord/testSelect3.result   |    3 +
 .../results/TestSelectQuery/testCaseWhen.result |    7 +
 .../TestSelectQuery/testCaseWhenRound.result    |   22 +
 .../testCaseWhenWithoutElse.result              |    7 +
 ...estColumnEqualityButNotJoinCondition1.result |    3 +
 ...estColumnEqualityButNotJoinCondition2.result |    6 +
 .../TestSelectQuery/testDatabaseRef.result      |    7 +
 .../TestSelectQuery/testExplainSelect.result    |    6 +
 .../testExplainSelectPhysical.1.result          |   26 +
 .../testExplainSelectPhysical.2.result          |   88 ++
 .../testExplainSelectPhysical.3.result          |   89 ++
 .../results/TestSelectQuery/testInClause.result |    5 +
 .../TestSelectQuery/testInStrClause.result      |    4 +
 .../TestSelectQuery/testLikeClause.result       |    9 +
 .../results/TestSelectQuery/testLimit.result    |    5 +
 .../testMultiBytesDelimiter1.result             |    7 +
 .../testMultiBytesDelimiter2.result             |    7 +
 .../testMultiBytesDelimiter3.result             |    7 +
 .../testMultiBytesDelimiter4.result             |    7 +
 .../testNestedPythonFunction.result             |    7 +
 .../TestSelectQuery/testNonFromSelect1.result   |    3 +
 .../testNonQualifiedNames.result                |    7 +
 .../results/TestSelectQuery/testNotEqual.result |    5 +
 .../TestSelectQuery/testNotInClause.result      |    4 +
 .../TestSelectQuery/testNotInStrClause.result   |    4 +
 .../TestSelectQuery/testRealValueCompare.result |    3 +
 .../results/TestSelectQuery/testSelect.result   |    7 +
 .../results/TestSelectQuery/testSelect2.result  |    7 +
 .../results/TestSelectQuery/testSelect3.result  |    7 +
 .../TestSelectQuery/testSelectAsterisk1.result  |    7 +
 .../TestSelectQuery/testSelectAsterisk2.result  |    3 +
 .../TestSelectQuery/testSelectAsterisk3.result  |    3 +
 .../TestSelectQuery/testSelectAsterisk4.result  |    7 +
 .../TestSelectQuery/testSelectAsterisk5.result  |    3 +
 .../testSelectColumnAlias1.result               |    7 +
 ...tSelectColumnAliasExistingInRelation1.result |    4 +
 ...tSelectColumnAliasExistingInRelation2.result |    7 +
 ...tSelectColumnAliasExistingInRelation3.result |   11 +
 .../TestSelectQuery/testSelectDistinct.result   |    7 +
 .../testSelectOnSessionTable.result             |    3 +
 .../testSelectPythonFuncs.result                |    7 +
 ...lectSameConstantsWithDifferentAliases.result |    7 +
 ...ectSameConstantsWithDifferentAliases2.result |    7 +
 ...ectSameConstantsWithDifferentAliases3.result |    7 +
 ...stSelectSameExprsWithDifferentAliases.result |    7 +
 .../testSelectWithCommonQuals1.1.plan           |    7 +
 .../testSelectWithCommonQuals1.1.result         |   27 +
 .../testSelectWithCommonQuals2.1.plan           |    7 +
 .../testSelectWithCommonQuals2.1.result         |   27 +
 .../testSelectWithCommonQuals3.1.plan           |    7 +
 .../testSelectWithCommonQuals3.1.result         |    7 +
 .../TestSelectQuery/testSelectWithJson.result   |    7 +
 .../testSelectWithParentheses1.result           |    3 +
 .../testSelectWithParentheses2.result           |    3 +
 .../testSelectWithPredicateOnPythonFunc.result  |   17 +
 .../TestSelectQuery/testSimpleQuery.result      |    7 +
 .../testSimpleQueryWithLimit.result             |    5 +
 ...tSimpleQueryWithLimitPartitionedTable.result |   12 +
 .../TestSelectQuery/testStringCompare.result    |    5 +
 .../TestSelectQuery/testSumFloatOverflow.result |    3 +
 .../TestSelectQuery/testSumIntOverflow.result   |    3 +
 .../TestSelectQuery/testTimezonedTable1.result  |    5 +
 .../TestSelectQuery/testTimezonedTable2.result  |    5 +
 .../TestSelectQuery/testTimezonedTable3.result  |    5 +
 .../results/TestSelectQuery/testUnion1.result   |   10 +
 .../results/TestSelectQuery/testUnion2.result   |   12 +
 .../TestSelectQuery/testWhereCond1.result       |    3 +
 .../TestSelectQuery/testWhereCond2.result       |    3 +
 .../testWhereCondWithAlias1.result              |    4 +
 .../testWhereCondWithAlias2.result              |    4 +
 .../results/TestSortQuery/testAsterisk.result   |    7 +
 .../results/TestSortQuery/testSort.result       |    7 +
 .../TestSortQuery/testSortAfterGroupby.result   |    5 +
 .../testSortAfterGroupbyWithAlias.result        |    5 +
 .../results/TestSortQuery/testSortDesc.result   |    7 +
 .../TestSortQuery/testSortFirstDesc.result      |   10 +
 .../TestSortQuery/testSortOnNullColumn.result   |    6 +
 .../testSortOnUnicodeTextAsc.result             |    6 +
 .../testSortOnUnicodeTextDesc.result            |    6 +
 .../TestSortQuery/testSortWithAlias1.result     |    7 +
 .../TestSortQuery/testSortWithAlias2.result     |    5 +
 .../TestSortQuery/testSortWithAlias3.result     |    7 +
 .../testSortWithAliasButOriginalName.result     |    7 +
 .../testSortWithAscDescKeys.result              |   26 +
 .../TestSortQuery/testSortWithConstKeys.result  |    7 +
 .../TestSortQuery/testSortWithDate.result       |    7 +
 .../TestSortQuery/testSortWithExpr1.result      |    7 +
 .../TestSortQuery/testSortWithExpr2.result      |    7 +
 .../TestSortQuery/testSortWithJson.result       |    5 +
 .../testSubQuerySortAfterGroupMultiBlocks.plan  |  112 ++
 ...testSubQuerySortAfterGroupMultiBlocks.result |    5 +
 .../results/TestSortQuery/testTopK.result       |    5 +
 .../TestSortQuery/testTopkWithJson.result       |    5 +
 .../results/TestTPCH/testFirstJoinInQ7.plan     |  156 ++
 .../results/TestTPCH/testFirstJoinInQ7.result   |    4 +
 .../results/TestTPCH/testQ1OrderBy.plan         |   88 ++
 .../results/TestTPCH/testQ1OrderBy.result       |    4 +
 .../results/TestTPCH/testQ2FourJoins.plan       |  228 +++
 .../results/TestTPCH/testQ2FourJoins.result     |    3 +
 .../results/TestTPCH/testTPCH14Expr.plan        |  119 ++
 .../results/TestTPCH/testTPCH14Expr.result      |    3 +
 .../resources/results/TestTPCH/testTPCHQ5.plan  |  332 +++++
 .../results/TestTPCH/testTPCHQ5.result          |    2 +
 .../TestSpecialCharPartitionKeys1.result        |    4 +
 .../TestSpecialCharPartitionKeys2.result        |    3 +
 .../results/TestTablePartitions/case1.result    |    4 +
 .../results/TestTablePartitions/case10.result   |    7 +
 .../results/TestTablePartitions/case11.result   |    7 +
 .../results/TestTablePartitions/case12.result   |    7 +
 .../results/TestTablePartitions/case13.result   |    7 +
 .../results/TestTablePartitions/case14.result   |    3 +
 .../results/TestTablePartitions/case15.result   |    3 +
 .../results/TestTablePartitions/case2.result    |    6 +
 .../results/TestTablePartitions/case3.result    |    5 +
 .../results/TestTablePartitions/case4.result    |    7 +
 .../results/TestTablePartitions/case5.result    |    7 +
 .../results/TestTablePartitions/case6.result    |    7 +
 .../results/TestTablePartitions/case7.result    |    5 +
 .../results/TestTablePartitions/case8.result    |    7 +
 .../results/TestTablePartitions/case9.result    |    7 +
 ...rtitionedTableWithSmallerExpressions5.result |    7 +
 ...rtitionedTableWithSmallerExpressions6.result |    4 +
 .../testGroupBySubQuery.result                  |    3 +
 .../testGroupbySubqueryWithJson.result          |    3 +
 .../TestTableSubQuery/testJoinSubQuery.result   |    4 +
 .../TestTableSubQuery/testJoinSubQuery2.result  |    4 +
 .../testJoinSubqueryWithJson.result             |    4 +
 .../TestTableSubQuery/testTableSubquery1.result |    7 +
 .../testAlterTableAddDropPartition.result       |    9 +
 .../results/TestTajoCli/testDescTable.result    |   27 +
 .../testDescTableForNestedSchema.result         |   29 +
 .../TestTajoCli/testHelpSessionVars.result      |   44 +
 .../testLocalQueryWithoutFrom.result            |    8 +
 .../TestTajoCli/testNonForwardQueryPause.result |    6 +
 .../testSelectResultWithNullFalse.result        |    8 +
 .../testSelectResultWithNullTrue.result         |    8 +
 ...estSelectResultWithNullTrueDeprecated.result |    9 +
 .../results/TestTajoCli/testSetTimezone1.result |    4 +
 .../TestTajoCli/testStopWhenError.result        |    5 +
 .../testStopWhenErrorDeprecated.result          |    6 +
 .../testQueryFailure.result                     |    0
 .../TestTajoCliNegatives/testQuerySyntax.result |    3 +
 .../testExecuteQueryAsync.result                |    7 +
 .../testExecuteQueryAsyncWithListener.result    |    2 +
 .../testExecuteQueryType1.result                |    7 +
 .../testExecuteQueryType2.result                |    4 +
 .../testExecuteQueryType3.result                |    4 +
 .../TestTajoDatabaseMetaData/getSchemas1.result |    3 +
 .../TestTajoDatabaseMetaData/getSchemas2.result |    3 +
 .../getTableTypes.result                        |    3 +
 .../TestTajoDatabaseMetaData/getTables1.result  |    4 +
 .../TestTajoDatabaseMetaData/getTables2.result  |    4 +
 .../results/TestTajoDump/testDump1.result       |   16 +
 .../results/TestTajoDump/testDump2.result       |   16 +
 .../results/TestTajoDump/testDump3.result       |   20 +
 .../TestTajoJdbc/testSortWithDateTime.result    |    7 +
 .../TestUnionQuery/testComplexUnion1.plan       |   80 +
 .../TestUnionQuery/testComplexUnion1.result     |    6 +
 .../TestUnionQuery/testComplexUnion2.plan       |  116 ++
 .../TestUnionQuery/testComplexUnion2.result     |    7 +
 .../results/TestUnionQuery/testUnion1.result    |    7 +
 .../results/TestUnionQuery/testUnion10.result   |    7 +
 .../results/TestUnionQuery/testUnion11.result   |    3 +
 .../results/TestUnionQuery/testUnion12.result   |    7 +
 .../results/TestUnionQuery/testUnion13.result   |    7 +
 .../results/TestUnionQuery/testUnion14.result   |    9 +
 .../results/TestUnionQuery/testUnion15.result   |    5 +
 .../results/TestUnionQuery/testUnion16.result   |    5 +
 .../results/TestUnionQuery/testUnion2.result    |    5 +
 .../results/TestUnionQuery/testUnion3.result    |    4 +
 .../results/TestUnionQuery/testUnion4.result    |    3 +
 .../results/TestUnionQuery/testUnion5.result    |    3 +
 .../results/TestUnionQuery/testUnion6.result    |    3 +
 .../results/TestUnionQuery/testUnion7.result    |    5 +
 .../results/TestUnionQuery/testUnion8.result    |    3 +
 .../results/TestUnionQuery/testUnion9.result    |    7 +
 .../results/TestUnionQuery/testUnionAll1.result |   10 +
 .../TestUnionQuery/testUnionAll10.result        |   22 +
 .../TestUnionQuery/testUnionAll11.result        |    3 +
 .../TestUnionQuery/testUnionAll12.result        |    7 +
 .../TestUnionQuery/testUnionAll13.result        |    7 +
 .../TestUnionQuery/testUnionAll14.result        |    9 +
 .../TestUnionQuery/testUnionAll15.result        |    5 +
 .../TestUnionQuery/testUnionAll16.result        |    5 +
 .../results/TestUnionQuery/testUnionAll2.result |   12 +
 .../results/TestUnionQuery/testUnionAll3.result |    4 +
 .../results/TestUnionQuery/testUnionAll4.result |    3 +
 .../results/TestUnionQuery/testUnionAll5.result |    3 +
 .../results/TestUnionQuery/testUnionAll6.result |    3 +
 .../results/TestUnionQuery/testUnionAll7.result |   12 +
 .../results/TestUnionQuery/testUnionAll8.result |    3 +
 .../results/TestUnionQuery/testUnionAll9.result |    7 +
 .../testUnionAllWithDifferentAlias.result       |    4 +
 ...UnionAllWithDifferentAliasAndFunction.result |    7 +
 .../testUnionAllWithSameAliasNames.result       |   12 +
 .../testUnionWithDifferentAlias.result          |    4 +
 ...estUnionWithDifferentAliasAndFunction.result |    7 +
 .../testUnionWithSameAliasNames.result          |    5 +
 .../TestWindowQuery/testComplexOrderBy1.result  |    7 +
 .../TestWindowQuery/testFirstValue1.result      |    7 +
 .../results/TestWindowQuery/testLag1.result     |    7 +
 .../TestWindowQuery/testLagWithDefault.result   |    7 +
 .../TestWindowQuery/testLagWithNoArgs.result    |    7 +
 .../TestWindowQuery/testLastValue1.result       |    7 +
 .../results/TestWindowQuery/testLead1.result    |    7 +
 .../TestWindowQuery/testLeadWithDefault.result  |    7 +
 .../TestWindowQuery/testLeadWithNoArgs.result   |    7 +
 .../TestWindowQuery/testRowNumber1.result       |    7 +
 .../TestWindowQuery/testRowNumber2.result       |    7 +
 .../TestWindowQuery/testRowNumber3.result       |    7 +
 .../TestWindowQuery/testStdDevPop1.result       |    7 +
 .../TestWindowQuery/testStdDevSamp1.result      |    7 +
 .../results/TestWindowQuery/testWindow1.result  |    7 +
 .../results/TestWindowQuery/testWindow2.result  |    7 +
 .../results/TestWindowQuery/testWindow3.result  |    7 +
 .../results/TestWindowQuery/testWindow4.result  |    7 +
 .../results/TestWindowQuery/testWindow5.result  |    7 +
 .../results/TestWindowQuery/testWindow6.result  |    7 +
 .../results/TestWindowQuery/testWindow7.result  |    7 +
 .../results/TestWindowQuery/testWindow8.result  |    7 +
 .../testWindowBeforeLimit.result                |    5 +
 .../testWindowWithAggregation1.result           |    3 +
 .../testWindowWithAggregation2.result           |    5 +
 .../testWindowWithAggregation3.result           |    3 +
 .../testWindowWithAggregation4.result           |    5 +
 .../testWindowWithAggregation5.result           |    5 +
 .../testWindowWithAggregation6.result           |    5 +
 .../testWindowWithOrderBy1.result               |    7 +
 .../testWindowWithOrderBy2.result               |    7 +
 .../testWindowWithOrderBy3.result               |    7 +
 .../testWindowWithOrderBy4.result               |    7 +
 .../testWindowWithOrderBy5.result               |    7 +
 .../testWindowWithSubQuery.result               |    7 +
 .../testWindowWithSubQuery2.result              |    5 +
 .../testWindowWithSubQuery3.result              |    7 +
 .../testWindowWithSubQuery4.result              |    7 +
 .../testWindowWithSubQuery5.result              |    5 +
 .../testWindowWithSubQuery6.result              |    3 +
 .../testBuildDDLForBaseTable.result             |    4 +
 .../testBuildDDLForExternalTable.result         |    5 +
 .../testBuildDDLQuotedTableName1.result         |    5 +
 .../testBuildDDLQuotedTableName2.result         |    4 +
 .../src/test/resources/yarn-site.xml            |   25 +
 tajo-core-tests/src/test/tpch/customer.tbl      |    5 +
 tajo-core-tests/src/test/tpch/empty_orders.tbl  |    0
 tajo-core-tests/src/test/tpch/lineitem.tbl      |    5 +
 tajo-core-tests/src/test/tpch/nation.tbl        |   25 +
 tajo-core-tests/src/test/tpch/orders.tbl        |    3 +
 tajo-core-tests/src/test/tpch/part.tbl          |    4 +
 tajo-core-tests/src/test/tpch/partsupp.tbl      |    3 +
 tajo-core-tests/src/test/tpch/region.tbl        |    5 +
 tajo-core-tests/src/test/tpch/supplier.tbl      |    3 +
 tajo-core/pom.xml                               |  173 ---
 tajo-core/src/test/java/log4j.properties        |   28 -
 .../org/apache/tajo/BackendTestingUtil.java     |   74 -
 .../org/apache/tajo/HBaseTestClusterUtil.java   |  184 ---
 .../java/org/apache/tajo/IntegrationTest.java   |   22 -
 .../apache/tajo/LocalTajoTestingUtility.java    |  169 ---
 .../test/java/org/apache/tajo/NamedTest.java    |   27 -
 .../java/org/apache/tajo/QueryTestCaseBase.java | 1030 -------------
 .../org/apache/tajo/TajoTestingCluster.java     |  778 ----------
 .../org/apache/tajo/TestQueryIdFactory.java     |   58 -
 .../test/java/org/apache/tajo/TestTajoIds.java  |  168 ---
 .../test/java/org/apache/tajo/TpchTestBase.java |  113 --
 .../org/apache/tajo/benchmark/TestTPCH.java     |   70 -
 .../apache/tajo/cli/tools/TestDDLBuilder.java   |  133 --
 .../org/apache/tajo/cli/tools/TestTajoDump.java |  124 --
 .../cli/tsql/TestDefaultCliOutputFormatter.java |  181 ---
 .../apache/tajo/cli/tsql/TestSimpleParser.java  |  286 ----
 .../org/apache/tajo/cli/tsql/TestTajoCli.java   |  472 ------
 .../tajo/cli/tsql/TestTajoCliNegatives.java     |  146 --
 .../commands/TestExecExternalShellCommand.java  |   45 -
 .../tajo/cli/tsql/commands/TestHdfsCommand.java |   47 -
 .../TestCatalogAdminClientExceptions.java       |  103 --
 .../tajo/client/TestQueryClientExceptions.java  |  126 --
 .../org/apache/tajo/client/TestTajoClient.java  |  777 ----------
 .../apache/tajo/client/v2/TestTajoClientV2.java |  274 ----
 .../tajo/cluster/TestWorkerConnectionInfo.java  |   36 -
 .../engine/codegen/TestEvalCodeGenerator.java   |  310 ----
 .../engine/codegen/TestGeneratorAdapter.java    |   41 -
 .../apache/tajo/engine/eval/ExprTestBase.java   |  341 -----
 .../apache/tajo/engine/eval/TestEvalTree.java   |  424 ------
 .../tajo/engine/eval/TestEvalTreeUtil.java      |  374 -----
 .../tajo/engine/eval/TestIntervalType.java      |  124 --
 .../apache/tajo/engine/eval/TestPredicates.java |  407 -----
 .../tajo/engine/eval/TestSQLDateTimeTypes.java  |   50 -
 .../tajo/engine/eval/TestSQLExpression.java     | 1001 -------------
 .../tajo/engine/function/TestAggFunction.java   |   65 -
 .../engine/function/TestBuiltinFunctions.java   |  824 ----------
 .../function/TestConditionalExpressions.java    |  242 ---
 .../engine/function/TestDateTimeFunctions.java  |  483 ------
 .../engine/function/TestFunctionLoader.java     |   45 -
 .../engine/function/TestGeneralFunction.java    |   49 -
 .../tajo/engine/function/TestJsonFunctions.java |   66 -
 .../tajo/engine/function/TestMathFunctions.java |  470 ------
 .../function/TestPatternMatchingPredicates.java |  139 --
 .../engine/function/TestPythonFunctions.java    |   45 -
 .../TestStringOperatorsAndFunctions.java        |  615 --------
 .../tajo/engine/parser/TestSQLAnalyzer.java     |  804 ----------
 .../engine/planner/TestJoinOrderAlgorithm.java  |  185 ---
 .../engine/planner/TestLogicalOptimizer.java    |  272 ----
 .../tajo/engine/planner/TestLogicalPlan.java    |   86 --
 .../tajo/engine/planner/TestLogicalPlanner.java | 1360 -----------------
 .../tajo/engine/planner/TestPlannerUtil.java    |  387 -----
 .../engine/planner/TestQueryValidation.java     |   66 -
 .../planner/TestUniformRangePartition.java      | 1143 --------------
 .../engine/planner/global/TestMasterPlan.java   |   53 -
 .../planner/physical/TestBNLJoinExec.java       |  224 ---
 .../planner/physical/TestExternalSortExec.java  |  187 ---
 .../physical/TestFullOuterHashJoinExec.java     |  414 -----
 .../physical/TestFullOuterMergeJoinExec.java    |  537 -------
 .../planner/physical/TestHashAntiJoinExec.java  |  215 ---
 .../planner/physical/TestHashJoinExec.java      |  281 ----
 .../planner/physical/TestHashPartitioner.java   |  117 --
 .../planner/physical/TestHashSemiJoinExec.java  |  220 ---
 .../physical/TestLeftOuterHashJoinExec.java     |  440 ------
 .../planner/physical/TestMergeJoinExec.java     |  197 ---
 .../engine/planner/physical/TestNLJoinExec.java |  208 ---
 .../planner/physical/TestPhysicalPlanner.java   | 1144 --------------
 .../physical/TestProgressExternalSortExec.java  |  229 ---
 .../physical/TestRightOuterHashJoinExec.java    |  351 -----
 .../physical/TestRightOuterMergeJoinExec.java   |  531 -------
 .../engine/planner/physical/TestSortExec.java   |  179 ---
 .../planner/physical/TestSortIntersectExec.java |  293 ----
 .../planner/physical/TestTupleSorter.java       |  127 --
 .../tajo/engine/query/TestAlterTable.java       |  114 --
 .../tajo/engine/query/TestAlterTablespace.java  |   59 -
 .../apache/tajo/engine/query/TestCTASQuery.java |  281 ----
 .../tajo/engine/query/TestCaseByCases.java      |  183 ---
 .../tajo/engine/query/TestCreateDatabase.java   |   75 -
 .../tajo/engine/query/TestCreateIndex.java      |  113 --
 .../tajo/engine/query/TestCreateTable.java      |  643 --------
 .../apache/tajo/engine/query/TestDropTable.java |   38 -
 .../tajo/engine/query/TestGroupByQuery.java     |  870 -----------
 .../tajo/engine/query/TestHBaseTable.java       | 1404 -----------------
 .../tajo/engine/query/TestInSubquery.java       |  177 ---
 .../apache/tajo/engine/query/TestIndexScan.java |  145 --
 .../tajo/engine/query/TestInnerJoinQuery.java   |  335 -----
 .../engine/query/TestInnerJoinWithSubQuery.java |  132 --
 .../tajo/engine/query/TestInsertQuery.java      |  882 -----------
 .../query/TestJoinOnPartitionedTables.java      |  340 -----
 .../apache/tajo/engine/query/TestJoinQuery.java |  315 ----
 .../engine/query/TestMultipleJoinTypes.java     |  106 --
 .../apache/tajo/engine/query/TestNetTypes.java  |  102 --
 .../tajo/engine/query/TestNullValues.java       |  322 ----
 .../tajo/engine/query/TestOuterJoinQuery.java   |  457 ------
 .../engine/query/TestOuterJoinWithSubQuery.java |  144 --
 .../engine/query/TestSelectNestedRecord.java    |  119 --
 .../tajo/engine/query/TestSelectQuery.java      |  778 ----------
 .../tajo/engine/query/TestSetSessionQuery.java  |   81 -
 .../apache/tajo/engine/query/TestSortQuery.java |  378 -----
 .../tajo/engine/query/TestTablePartitions.java  | 1301 ----------------
 .../tajo/engine/query/TestTableSubQuery.java    |   81 -
 .../tajo/engine/query/TestTruncateTable.java    |   96 --
 .../tajo/engine/query/TestUnionQuery.java       |  693 ---------
 .../tajo/engine/query/TestWindowQuery.java      |  465 ------
 .../apache/tajo/engine/util/TestTableCache.java |  109 --
 .../apache/tajo/engine/util/TestTupleUtil.java  |  188 ---
 .../apache/tajo/ha/TestHAServiceHDFSImpl.java   |  160 --
 .../org/apache/tajo/jdbc/TestResultSet.java     |  224 ---
 .../java/org/apache/tajo/jdbc/TestSQLState.java |   91 --
 .../tajo/jdbc/TestTajoDatabaseMetaData.java     |  504 -------
 .../java/org/apache/tajo/jdbc/TestTajoJdbc.java |  608 --------
 .../tajo/master/TestExecutionBlockCursor.java   |  135 --
 .../TestNonForwardQueryResultSystemScanner.java |   41 -
 .../apache/tajo/master/TestRepartitioner.java   |  511 -------
 .../tajo/master/rule/TestMasterRules.java       |  156 --
 .../master/scheduler/TestSimpleScheduler.java   |  301 ----
 .../tajo/querymaster/TestIntermediateEntry.java |   53 -
 .../apache/tajo/querymaster/TestKillQuery.java  |  312 ----
 .../tajo/querymaster/TestQueryProgress.java     |   77 -
 .../apache/tajo/querymaster/TestQueryState.java |   99 --
 .../tajo/querymaster/TestTaskStatusUpdate.java  |  191 ---
 .../org/apache/tajo/resource/TestResources.java |   48 -
 .../apache/tajo/storage/TestFileFragment.java   |   93 --
 .../org/apache/tajo/storage/TestRowFile.java    |  146 --
 .../java/org/apache/tajo/util/TestJSPUtil.java  |  113 --
 .../util/history/TestHistoryWriterReader.java   |  313 ----
 .../tajo/util/metrics/TestMetricsFilter.java    |   52 -
 .../tajo/util/metrics/TestSystemMetrics.java    |  143 --
 .../apache/tajo/worker/MockExecutionBlock.java  |   42 -
 .../tajo/worker/MockNodeResourceManager.java    |   88 --
 .../tajo/worker/MockNodeStatusUpdater.java      |   97 --
 .../apache/tajo/worker/MockTaskExecutor.java    |  153 --
 .../org/apache/tajo/worker/MockTaskManager.java |   69 -
 .../apache/tajo/worker/MockWorkerContext.java   |  109 --
 .../apache/tajo/worker/TestDeletionService.java |   61 -
 .../org/apache/tajo/worker/TestFetcher.java     |  236 ---
 .../tajo/worker/TestNodeResourceManager.java    |  281 ----
 .../tajo/worker/TestNodeStatusUpdater.java      |  192 ---
 .../apache/tajo/worker/TestTaskExecutor.java    |  315 ----
 .../org/apache/tajo/worker/TestTaskManager.java |  184 ---
 .../tajo/ws/rs/resources/RestTestUtils.java     |   64 -
 .../ws/rs/resources/TestClusterResource.java    |   84 --
 .../ws/rs/resources/TestDatabasesResource.java  |  189 ---
 .../ws/rs/resources/TestFunctionsResource.java  |   78 -
 .../tajo/ws/rs/resources/TestQueryResource.java |  199 ---
 .../rs/resources/TestQueryResultResource.java   |  297 ----
 .../ws/rs/resources/TestSessionsResource.java   |  263 ----
 .../ws/rs/resources/TestTablesResource.java     |  204 ---
 .../resources/dataset/TestAlterTable/table1.tbl |    3 -
 .../resources/dataset/TestAlterTable/table2.tbl |    1 -
 .../dataset/TestCreateTable/table1/table1.tbl   |    3 -
 .../dataset/TestCreateTable/table2/table2.tbl   |    3 -
 .../resources/dataset/TestDropTable/table1.tbl  |    3 -
 .../dataset/TestHBaseTable/splits.data          |    4 -
 .../dataset/TestJoinQuery/table1/table1.tbl     |    5 -
 .../dataset/TestJoinQuery/table2/table2.tbl     |    4 -
 .../dataset/TestNetTypes/table1/table1.tbl      |    5 -
 .../dataset/TestNetTypes/table2/table2.tbl      |    5 -
 .../TestSelectNestedRecord/sample1/table.json   |    3 -
 .../TestSelectNestedRecord/sample2/sample2.json |    1 -
 .../TestSelectNestedRecord/tweets/sample1.json  |    4 -
 .../multibytes_delimiter1/table1.tbl            |    5 -
 .../multibytes_delimiter2/table2.tbl            |    5 -
 .../TestSelectQuery/timezoned/table1.tbl        |    3 -
 .../dataset/TestSortQuery/table1/table1.tbl     |    5 -
 .../dataset/TestSortQuery/table2/table2.tbl     |   24 -
 .../TestTablePartitions/lineitemspecial.tbl     |    5 -
 .../dataset/TestTajoJdbc/table1/table1.tbl      |    5 -
 .../truncate_table2/table2.tbl                  |    4 -
 tajo-core/src/test/resources/log4j.properties   |   28 -
 tajo-core/src/test/resources/python/__init__.py |   17 -
 .../src/test/resources/python/test_funcs.py     |   33 -
 .../src/test/resources/python/test_funcs2.py    |   32 -
 .../src/test/resources/python/test_udaf.py      |   76 -
 .../alter_table_add_new_column_ddl.sql          |    1 -
 .../alter_table_add_partition1.sql              |    1 -
 .../alter_table_add_partition2.sql              |    1 -
 .../alter_table_drop_partition1.sql             |    1 -
 .../alter_table_drop_partition2.sql             |    1 -
 .../alter_table_rename_column_ddl.sql           |    1 -
 .../alter_table_rename_table_ddl.sql            |    1 -
 .../alter_table_set_property_delimiter.sql      |    1 -
 .../alter_table_set_property_timezone.sql       |    1 -
 .../TestAlterTable/create_partitioned_table.sql |    1 -
 .../queries/TestAlterTable/table1_ddl.sql       |    1 -
 .../queries/TestAlterTable/table2_ddl.sql       |    1 -
 .../testAlterTableSetProperty.sql               |    1 -
 .../testAlterTableSetProperty2.sql              |    1 -
 .../TestBuiltinFunctions/testAvgDouble.sql      |    1 -
 .../queries/TestBuiltinFunctions/testAvgInt.sql |    1 -
 .../TestBuiltinFunctions/testAvgLong.sql        |    1 -
 .../testAvgLongOverflow.sql                     |    1 -
 .../queries/TestBuiltinFunctions/testCount.sql  |    1 -
 .../TestBuiltinFunctions/testMaxLong.sql        |    1 -
 .../TestBuiltinFunctions/testMaxString.sql      |    1 -
 .../TestBuiltinFunctions/testMinLong.sql        |    1 -
 .../TestBuiltinFunctions/testMinString.sql      |    1 -
 .../queries/TestBuiltinFunctions/testRandom.sql |    1 -
 .../TestBuiltinFunctions/testSplitPart.sql      |    1 -
 .../testSplitPartByString.sql                   |    1 -
 .../testSplitPartNested.sql                     |    1 -
 .../queries/TestCTASQuery/CtasWithGroupby.sql   |    2 -
 .../queries/TestCTASQuery/CtasWithLimit.sql     |   13 -
 .../TestCTASQuery/CtasWithManagedTable.sql      |   12 -
 .../TestCTASQuery/CtasWithMultipleUnions.sql    |   12 -
 .../queries/TestCTASQuery/CtasWithOptions.sql   |   13 -
 .../queries/TestCTASQuery/CtasWithOrderby.sql   |   11 -
 .../queries/TestCTASQuery/CtasWithStoreType.sql |   12 -
 .../queries/TestCTASQuery/CtasWithTextFile.sql  |   12 -
 .../queries/TestCTASQuery/CtasWithUnion.sql     |   35 -
 .../resources/queries/TestCTASQuery/check1.sql  |    1 -
 .../resources/queries/TestCTASQuery/check2.sql  |    1 -
 .../testCtasWithColumnedPartition.sql           |    2 -
 .../TestCTASQuery/testCtasWithGroupby.sql       |    1 -
 .../queries/TestCTASQuery/testCtasWithLimit.sql |    1 -
 .../testCtasWithMultipleUnions.sql              |    1 -
 .../TestCTASQuery/testCtasWithOptions.sql       |    1 -
 .../TestCTASQuery/testCtasWithOrderby.sql       |    1 -
 .../TestCTASQuery/testCtasWithStoreType.sql     |    1 -
 .../TestCTASQuery/testCtasWithTextFile.sql      |    1 -
 .../queries/TestCTASQuery/testCtasWithUnion.sql |    1 -
 .../testCtasWithoutTableDefinition.sql          |    2 -
 .../TestCaseByCases/testTAJO1224Case1.sql       |    1 -
 .../queries/TestCaseByCases/testTAJO415Case.sql |   36 -
 .../queries/TestCaseByCases/testTAJO418Case.sql |   29 -
 .../queries/TestCaseByCases/testTAJO619Case.sql |    4 -
 .../queries/TestCaseByCases/testTAJO718Case.sql |   10 -
 .../queries/TestCaseByCases/testTAJO739Case.sql |    5 -
 .../TestCaseByCases/testTAJO914Case1.sql        |   10 -
 .../TestCaseByCases/testTAJO914Case2.sql        |    9 -
 .../TestCaseByCases/testTAJO914Case3.sql        |   10 -
 .../TestCaseByCases/testTAJO914Case4.sql        |   10 -
 .../TestCaseByCases/testTAJO917Case1.sql        |   13 -
 .../queries/TestCreateIndex/testCreateIndex.sql |    1 -
 .../testCreateIndexOnExpression.sql             |    1 -
 .../testCreateIndexOnLocation.sql               |    1 -
 .../testCreateIndexOnMultiAttrs.sql             |    1 -
 .../testCreateIndexOnMultiExprs.sql             |    1 -
 .../testCreateIndexWithCondition.sql            |    1 -
 .../create_table_various_types.sql              |   50 -
 ...ate_table_various_types_for_hive_catalog.sql |   50 -
 .../quoted_identifier_mixed_chars_1.sql         |    1 -
 .../quoted_identifier_mixed_chars_2.sql         |    1 -
 .../quoted_identifier_mixed_chars_3.sql         |   22 -
 .../quoted_identifier_mixed_chars_ddl_1.sql     |    1 -
 .../quoted_identifier_mixed_chars_ddl_2.sql     |    1 -
 .../quoted_identifier_non_ascii_1.sql           |    1 -
 .../quoted_identifier_non_ascii_2.sql           |    1 -
 .../quoted_identifier_non_ascii_3.sql           |    1 -
 .../quoted_identifier_non_ascii_ddl.sql         |    1 -
 .../queries/TestCreateTable/table1_ddl.sql      |    1 -
 .../TestCreateTable/testNestedRecord1.sql       |    1 -
 .../TestCreateTable/testNestedRecord2.sql       |    1 -
 .../queries/TestDropTable/drop_table_ddl.sql    |    1 -
 .../queries/TestDropTable/table1_ddl.sql        |    1 -
 .../TestGroupByQuery/testComplexParameter.sql   |    1 -
 .../TestGroupByQuery/testComplexParameter2.sql  |    1 -
 .../testComplexParameterWithSubQuery.sql        |    6 -
 .../testComplexTargetWithPythonUdaf.sql         |    1 -
 .../testDistinctAggregation1.sql                |    1 -
 .../testDistinctAggregation2.sql                |    1 -
 .../testDistinctAggregation3.sql                |    1 -
 .../testDistinctAggregation4.sql                |    1 -
 .../testDistinctAggregation5.sql                |    1 -
 .../testDistinctAggregation6.sql                |    9 -
 .../testDistinctAggregation7.sql                |    6 -
 .../testDistinctAggregation8.sql                |    9 -
 .../testDistinctAggregationCaseByCase3.sql      |    8 -
 .../testDistinctAggregationCaseByCase4.sql      |    7 -
 .../testDistinctAggregationWithHaving1.sql      |    1 -
 .../testDistinctAggregationWithUnion1.sql       |   21 -
 .../testDistinctAggregation_case1.sql           |    7 -
 .../testDistinctAggregation_case10.sql          |    5 -
 .../testDistinctAggregation_case2.sql           |    8 -
 .../testDistinctAggregation_case3.sql           |    9 -
 .../testDistinctAggregation_case4.sql           |   10 -
 .../testDistinctAggregation_case5.sql           |   10 -
 .../testDistinctAggregation_case6.sql           |   12 -
 .../testDistinctAggregation_case7.sql           |    9 -
 .../testDistinctAggregation_case8.sql           |   10 -
 .../testDistinctAggregation_case9.sql           |   11 -
 .../testDistinctPythonUdafWithUnion1.sql        |   21 -
 .../queries/TestGroupByQuery/testGroupBy.sql    |    1 -
 .../queries/TestGroupByQuery/testGroupBy2.sql   |    1 -
 .../queries/TestGroupByQuery/testGroupBy3.sql   |    1 -
 .../queries/TestGroupByQuery/testGroupBy4.sql   |    9 -
 .../queries/TestGroupByQuery/testGroupBy5.sql   |    1 -
 .../TestGroupByQuery/testGroupByNested1.sql     |    8 -
 .../TestGroupByQuery/testGroupByNested2.sql     |   10 -
 .../testGroupByWithConstantKeys1.sql            |    1 -
 .../testGroupByWithConstantKeys2.sql            |    1 -
 .../testGroupByWithConstantKeys3.sql            |    8 -
 .../testGroupByWithConstantKeys4.sql            |   12 -
 .../testGroupByWithConstantKeys5.sql            |   13 -
 .../testGroupByWithExpressionKeys1.sql          |    1 -
 .../testGroupByWithExpressionKeys2.sql          |    1 -
 .../testGroupByWithNullData1.sql                |    1 -
 .../testGroupByWithNullData10.sql               |    3 -
 .../testGroupByWithNullData11.sql               |    5 -
 .../testGroupByWithNullData12.sql               |   29 -
 .../testGroupByWithNullData2.sql                |    1 -
 .../testGroupByWithNullData3.sql                |    3 -
 .../testGroupByWithNullData4.sql                |    3 -
 .../testGroupByWithNullData5.sql                |    1 -
 .../testGroupByWithNullData6.sql                |    1 -
 .../testGroupByWithNullData7.sql                |    1 -
 .../testGroupByWithNullData8.sql                |    1 -
 .../testGroupByWithNullData9.sql                |    4 -
 .../testGroupByWithSameConstantKeys1.sql        |    1 -
 .../testGroupByWithSameExprs1.sql               |    8 -
 .../testGroupByWithSameExprs2.sql               |    8 -
 .../TestGroupByQuery/testGroupbyWithJson.json   |  127 --
 .../TestGroupByQuery/testGroupbyWithLimit1.sql  |    1 -
 .../TestGroupByQuery/testGroupbyWithLimit2.sql  |    1 -
 .../TestGroupByQuery/testGroupbyWithLimit3.sql  |    1 -
 .../testGroupbyWithPythonFunc.sql               |    1 -
 .../testGroupbyWithPythonFunc2.sql              |    1 -
 .../testHavingWithAggFunction.sql               |    1 -
 .../testHavingWithNamedTarget.sql               |   13 -
 .../queries/TestGroupByQuery/testPythonUdaf.sql |    1 -
 .../TestGroupByQuery/testPythonUdaf2.sql        |    1 -
 .../TestGroupByQuery/testPythonUdaf3.sql        |    1 -
 .../testPythonUdafWithHaving.sql                |    3 -
 .../testPythonUdafWithNullData.sql              |    4 -
 .../TestInSubquery/testInAndNotInSubQuery.sql   |    3 -
 .../queries/TestInSubquery/testInSubQuery.sql   |    1 -
 .../queries/TestInSubquery/testInSubQuery2.sql  |    2 -
 .../TestInSubquery/testInSubQueryWithJoin.sql   |    2 -
 .../testInSubQueryWithOtherConditions.sql       |    2 -
 .../testInSubQueryWithTableSubQuery.sql         |    2 -
 .../TestInSubquery/testMultipleInSubQuery.sql   |    5 -
 .../testMultipleNotInSubQuery.sql               |    3 -
 .../testNestedInAndNotInSubQuery.sql            |    5 -
 .../TestInSubquery/testNestedInSubQuery.sql     |    4 -
 .../TestInSubquery/testNestedInSubQuery2.sql    |    4 -
 .../TestInSubquery/testNestedNotInSubQuery.sql  |    4 -
 .../TestInSubquery/testNotInSubQuery.sql        |    1 -
 .../testSameKeyNameOfOuterAndInnerQueries.sql   |   22 -
 .../TestInSubquery/testWithAsteriskAndJoin.sql  |    7 -
 .../testBroadcastTwoPartJoin.sql                |   19 -
 .../testCrossJoinAndCaseWhen.sql                |   18 -
 .../testCrossJoinWithAsterisk1.sql              |    1 -
 .../testCrossJoinWithAsterisk2.sql              |    1 -
 .../testCrossJoinWithAsterisk3.sql              |    1 -
 .../testCrossJoinWithAsterisk4.sql              |    1 -
 .../testBroadcastSubquery.sql                   |   12 -
 .../testBroadcastSubquery2.sql                  |   19 -
 .../testThetaJoinKeyPairs.sql                   |   20 -
 .../TestInsertQuery/full_table_csv_ddl.sql      |    1 -
 .../TestInsertQuery/full_table_parquet_ddl.sql  |    1 -
 .../TestInsertQuery/lineitem_year_month_ddl.sql |   18 -
 .../load_to_lineitem_year_month.sql             |    1 -
 .../TestInsertQuery/nation_diff_col_order.ddl   |    1 -
 .../queries/TestInsertQuery/table1_ddl.sql      |    1 -
 .../queries/TestInsertQuery/test1_ddl.sql       |    1 -
 .../TestInsertQuery/test1_nolength_ddl.sql      |    1 -
 .../queries/TestInsertQuery/testInsertInto.sql  |    1 -
 .../testInsertIntoSelectWithFixedSizeChar.sql   |    4 -
 ...tIntoSelectWithFixedSizeCharWithNoLength.sql |    2 -
 .../TestInsertQuery/testInsertOverwrite.sql     |    1 -
 .../testInsertOverwriteLocation.sql             |    1 -
 ...stInsertOverwriteLocationWithCompression.sql |    1 -
 .../testInsertOverwriteLocationWithUnion.sql    |    4 -
 ...verwriteLocationWithUnionDifferenceAlias.sql |    4 -
 .../testInsertOverwriteSmallerColumns.sql       |    1 -
 .../testInsertOverwriteWithAsterisk.sql         |    1 -
 .../testInsertOverwriteWithAsteriskAndMore.sql  |    1 -
 .../testInsertOverwriteWithCompression.sql      |    1 -
 .../testInsertOverwriteWithCompression_ddl.sql  |    4 -
 .../testInsertOverwriteWithDatabase.sql         |    1 -
 .../testInsertOverwriteWithTargetColumns.sql    |    1 -
 .../testInsertOverwriteWithUnion.sql            |    4 -
 ...stInsertOverwriteWithUnionDifferentAlias.sql |    4 -
 .../testInsertWithDifferentColumnOrder.sql      |    1 -
 .../selfJoinOfPartitionedTable.sql              |    9 -
 .../testBroadcastPartitionTable.sql             |   16 -
 ...estFilterPushDownPartitionColumnCaseWhen.sql |    6 -
 ...rtitionedBroadcastDataFileWithZeroLength.sql |    3 -
 ...titionedBroadcastDataFileWithZeroLength2.sql |    5 -
 .../testNoProjectionJoinQual.sql                |    1 -
 .../testPartialFilterPushDown.sql               |    9 -
 .../testPartialFilterPushDownOuterJoin.sql      |    4 -
 .../testPartialFilterPushDownOuterJoin2.sql     |    5 -
 .../testPartitionTableJoinSmallTable.sql        |   11 -
 .../TestJoinQuery/create_customer_large_ddl.sql |    7 -
 .../TestJoinQuery/create_lineitem_large_ddl.sql |    7 -
 .../TestJoinQuery/create_orders_large_ddl.sql   |    7 -
 .../TestJoinQuery/customer_partition_ddl.sql    |    9 -
 .../TestJoinQuery/insert_into_customer.sql      |   11 -
 .../insert_into_customer_partition.sql          |   11 -
 .../TestJoinQuery/nation_multifile_ddl.sql      |    5 -
 .../queries/TestJoinQuery/oj_table1_ddl.sql     |    3 -
 .../queries/TestJoinQuery/oj_table2_ddl.sql     |    3 -
 .../TestJoinQuery/orders_multifile_ddl.sql      |    5 -
 .../TestJoinQuery/partitioned_customer_ddl.sql  |   19 -
 .../queries/TestJoinQuery/table1_int4_ddl.sql   |    3 -
 .../queries/TestJoinQuery/table1_int8_ddl.sql   |    3 -
 .../TestJoinQuery/testComplexJoinCondition1.sql |    6 -
 .../TestJoinQuery/testComplexJoinCondition2.sql |    6 -
 .../TestJoinQuery/testComplexJoinCondition3.sql |    6 -
 .../TestJoinQuery/testComplexJoinCondition4.sql |    6 -
 .../TestJoinQuery/testComplexJoinCondition5.sql |    6 -
 .../TestJoinQuery/testComplexJoinCondition6.sql |    6 -
 .../TestJoinQuery/testComplexJoinCondition7.sql |    6 -
 .../testComplexJoinsWithCaseWhen.sql            |   11 -
 .../testComplexJoinsWithCaseWhen2.sql           |    9 -
 .../testCrossJoinWithEmptyTable1.sql            |    8 -
 ...stCrossJoinWithThetaJoinConditionInWhere.sql |    2 -
 .../testDifferentTypesJoinCondition.sql         |    1 -
 .../TestJoinQuery/testFullOuterJoin1.sql        |    8 -
 .../testFullOuterJoinWithEmptyTable1.sql        |    8 -
 .../TestJoinQuery/testInnerJoinAndCaseWhen.sql  |   18 -
 .../testInnerJoinWithEmptyTable.sql             |    8 -
 ...stInnerJoinWithThetaJoinConditionInWhere.sql |    3 -
 .../queries/TestJoinQuery/testJoinAsterisk.sql  |    3 -
 .../TestJoinQuery/testJoinCoReferredEvals1.sql  |   11 -
 .../testJoinCoReferredEvalsFilterPushdown.sql   |   13 -
 .../testJoinCoReferredEvalsWithSameExprs1.sql   |   14 -
 .../testJoinCoReferredEvalsWithSameExprs2.sql   |   22 -
 .../testJoinFilterOfRowPreservedTable1.sql      |    8 -
 .../testJoinOnMultipleDatabases.sql             |   25 -
 .../testJoinOnMultipleDatabasesWithJson.json    |  210 ---
 .../queries/TestJoinQuery/testJoinWithJson.json |   92 --
 .../TestJoinQuery/testJoinWithJson2.json        |  219 ---
 .../testJoinWithMultipleJoinQual1.sql           |   20 -
 .../testJoinWithMultipleJoinQual2.sql           |    8 -
 .../testJoinWithMultipleJoinQual3.sql           |    9 -
 .../testJoinWithMultipleJoinQual4.sql           |   10 -
 .../testJoinWithMultipleJoinTypes.sql           |    4 -
 .../TestJoinQuery/testJoinWithOrPredicates.sql  |    6 -
 .../TestJoinQuery/testLeftOuterJoin1.sql        |    9 -
 .../testLeftOuterJoinWithConstantExpr1.sql      |    9 -
 .../testLeftOuterJoinWithConstantExpr2.sql      |    9 -
 .../testLeftOuterJoinWithConstantExpr3.sql      |   17 -
 .../testLeftOuterJoinWithConstantExpr4.sql      |    6 -
 .../testLeftOuterJoinWithConstantExpr5.sql      |    9 -
 .../testLeftOuterJoinWithEmptyTable1.sql        |    9 -
 .../testLeftOuterJoinWithEmptyTable2.sql        |    9 -
 .../testLeftOuterJoinWithEmptyTable3.sql        |   14 -
 .../testLeftOuterJoinWithEmptyTable4.sql        |   17 -
 .../testLeftOuterJoinWithEmptyTable5.sql        |   11 -
 .../testLeftOuterJoinWithNull1.sql              |   10 -
 .../testLeftOuterJoinWithNull2.sql              |   11 -
 .../testLeftOuterJoinWithNull3.sql              |   10 -
 ...ftOuterJoinWithThetaJoinConditionInWhere.sql |    3 -
 .../queries/TestJoinQuery/testNaturalJoin.sql   |    3 -
 .../TestJoinQuery/testOuterJoinAndCaseWhen1.sql |   12 -
 .../TestJoinQuery/testRightOuterJoin1.sql       |    8 -
 .../testRightOuterJoinWithEmptyTable1.sql       |    8 -
 ...htOuterJoinWithThetaJoinConditionInWhere.sql |    3 -
 .../queries/TestJoinQuery/testTPCHQ2Join.sql    |   25 -
 .../TestJoinQuery/testWhereClauseJoin1.sql      |   11 -
 .../TestJoinQuery/testWhereClauseJoin2.sql      |    9 -
 .../TestJoinQuery/testWhereClauseJoin3.sql      |   10 -
 .../TestJoinQuery/testWhereClauseJoin4.sql      |    9 -
 .../TestJoinQuery/testWhereClauseJoin5.sql      |   15 -
 .../TestJoinQuery/testWhereClauseJoin6.sql      |   19 -
 .../queries/TestLogicalPlanner/window1.sql      |    5 -
 .../queries/TestNetTypes/table1_ddl.sql         |    4 -
 .../queries/TestNetTypes/table2_ddl.sql         |    4 -
 .../queries/TestNetTypes/testGroupby.sql        |    8 -
 .../queries/TestNetTypes/testGroupby2.sql       |    9 -
 .../resources/queries/TestNetTypes/testJoin.sql |    1 -
 .../queries/TestNetTypes/testSelect.sql         |    1 -
 .../resources/queries/TestNetTypes/testSort.sql |    1 -
 .../queries/TestNetTypes/testSort2.sql          |    1 -
 .../TestOuterJoinQuery/testLeftOuterJoin2.sql   |    5 -
 .../TestOuterJoinQuery/testLeftOuterJoin3.sql   |    7 -
 ...tMultipleBroadcastDataFileWithZeroLength.sql |    3 -
 ...MultipleBroadcastDataFileWithZeroLength2.sql |    5 -
 .../TestQueryValidation/error_groupby_1.sql     |    1 -
 .../TestQueryValidation/error_groupby_2.sql     |    1 -
 .../TestQueryValidation/invalid_casewhen_1.sql  |   15 -
 .../TestQueryValidation/invalid_limit_1.sql     |    1 -
 .../invalid_store_format.sql                    |    1 -
 .../TestQueryValidation/valid_groupby_1.sql     |    1 -
 .../TestQueryValidation/valid_limit_1.sql       |    1 -
 .../TestSQLAnalyzer/create_table_nested_1.sql   |    1 -
 .../TestSQLAnalyzer/create_table_nested_2.sql   |    1 -
 .../queries/TestSQLAnalyzer/setcatalog1.sql     |    1 -
 .../queries/TestSQLAnalyzer/setcatalog2.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession1.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession2.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession3.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession4.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession5.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession6.sql     |    1 -
 .../queries/TestSQLAnalyzer/setsession7.sql     |    1 -
 .../queries/TestSQLAnalyzer/settimezone1.sql    |    1 -
 .../queries/TestSQLAnalyzer/settimezone2.sql    |    1 -
 .../queries/TestSQLAnalyzer/settimezone3.sql    |    1 -
 .../queries/TestSQLAnalyzer/window1.sql         |    5 -
 .../queries/TestSQLAnalyzer/window2.sql         |    5 -
 .../queries/TestSQLAnalyzer/window3.sql         |    5 -
 .../queries/TestSQLAnalyzer/window4.sql         |    5 -
 .../queries/TestSQLAnalyzer/window5.sql         |    6 -
 .../queries/TestSQLAnalyzer/window6.sql         |    6 -
 .../queries/TestSQLAnalyzer/window7.sql         |    6 -
 .../queries/TestSQLAnalyzer/window8.sql         |    6 -
 .../queries/TestSQLAnalyzer/window9.sql         |    9 -
 .../TestSelectNestedRecord/sample0_ddl.sql      |    1 -
 .../TestSelectNestedRecord/sample1_ddl.sql      |    7 -
 .../TestSelectNestedRecord/sample2_ddl.sql      |   23 -
 .../testNestedFieldAsGroupbyKey1.sql            |    9 -
 .../testNestedFieldAsJoinKey1.sql               |    7 -
 .../TestSelectNestedRecord/testSelect0.sql      |    1 -
 .../TestSelectNestedRecord/testSelect1.sql      |    1 -
 .../TestSelectNestedRecord/testSelect2.sql      |   61 -
 .../TestSelectNestedRecord/testSelect3.sql      |    1 -
 .../TestSelectNestedRecord/tweets_ddl.sql       |   74 -
 .../queries/TestSelectQuery/customer_ddl.sql    |    9 -
 .../TestSelectQuery/datetime_table_ddl.sql      |    4 -
 .../datetime_table_timezoned_ddl.sql            |    4 -
 .../TestSelectQuery/insert_into_customer.sql    |   11 -
 .../multibytes_delimiter_table1_ddl.sql         |    3 -
 .../multibytes_delimiter_table2_ddl.sql         |    3 -
 .../multibytes_delimiter_table3_ddl.sql         |    3 -
 .../multibytes_delimiter_table4_ddl.sql         |    3 -
 .../queries/TestSelectQuery/testCaseWhen.sql    |   11 -
 .../TestSelectQuery/testCaseWhenRound.sql       |    8 -
 .../TestSelectQuery/testCaseWhenWithoutElse.sql |   10 -
 .../testColumnEqualityButNotJoinCondition1.sql  |    7 -
 .../testColumnEqualityButNotJoinCondition2.sql  |    7 -
 .../TestSelectQuery/testCreateAfterSelect.sql   |    1 -
 .../TestSelectQuery/testDatabaseRef1.sql        |    1 -
 .../TestSelectQuery/testDatabaseRef2.sql        |    1 -
 .../TestSelectQuery/testDatabaseRef3.sql        |    1 -
 .../TestSelectQuery/testExplainSelect.sql       |    1 -
 .../queries/TestSelectQuery/testInClause.sql    |    1 -
 .../queries/TestSelectQuery/testInStrClause.sql |    1 -
 .../queries/TestSelectQuery/testLikeClause.sql  |    1 -
 .../queries/TestSelectQuery/testLimit.sql       |    1 -
 .../testMultiBytesDelimiter1.sql                |    1 -
 .../testMultiBytesDelimiter2.sql                |    1 -
 .../testMultiBytesDelimiter3.sql                |    1 -
 .../testMultiBytesDelimiter4.sql                |    1 -
 .../testNestedPythonFunction.sql                |    1 -
 .../TestSelectQuery/testNonFromSelect1.sql      |    1 -
 .../TestSelectQuery/testNonQualifiedNames.sql   |    1 -
 .../queries/TestSelectQuery/testNotEqual.sql    |    1 -
 .../queries/TestSelectQuery/testNotInClause.sql |    1 -
 .../TestSelectQuery/testNotInStrClause.sql      |    1 -
 .../TestSelectQuery/testRealValueCompare.sql    |    1 -
 .../queries/TestSelectQuery/testSelect.sql      |    1 -
 .../queries/TestSelectQuery/testSelect2.sql     |    1 -
 .../queries/TestSelectQuery/testSelect3.sql     |    1 -
 .../TestSelectQuery/testSelectAsterik.sql       |    1 -
 .../TestSelectQuery/testSelectAsterisk1.sql     |    1 -
 .../TestSelectQuery/testSelectAsterisk2.sql     |    1 -
 .../TestSelectQuery/testSelectAsterisk3.sql     |    1 -
 .../TestSelectQuery/testSelectAsterisk4.sql     |    1 -
 .../TestSelectQuery/testSelectAsterisk5.sql     |    1 -
 .../TestSelectQuery/testSelectColumnAlias1.sql  |    1 -
 ...testSelectColumnAliasExistingInRelation1.sql |    1 -
 ...testSelectColumnAliasExistingInRelation2.sql |    1 -
 ...testSelectColumnAliasExistingInRelation3.sql |   19 -
 .../TestSelectQuery/testSelectDistinct.sql      |    7 -
 .../testSelectOnSessionTable.sql                |    1 -
 .../TestSelectQuery/testSelectPythonFuncs.sql   |    2 -
 ...tSelectSameConstantsWithDifferentAliases.sql |    1 -
 ...SelectSameConstantsWithDifferentAliases2.sql |    1 -
 ...SelectSameConstantsWithDifferentAliases3.sql |   10 -
 .../testSelectSameExprsWithDifferentAliases.sql |    1 -
 .../TestSelectQuery/testSelectWithJson.json     |   74 -
 .../testSelectWithParentheses1.sql              |    1 -
 .../testSelectWithParentheses2.sql              |    1 -
 .../testSelectWithPredicateOnPythonFunc.sql     |    1 -
 .../queries/TestSelectQuery/testSimpleQuery.sql |    1 -
 .../testSimpleQueryWithLimit.sql                |    1 -
 ...testSimpleQueryWithLimitPartitionedTable.sql |    1 -
 .../TestSelectQuery/testStringCompare.sql       |    1 -
 .../TestSelectQuery/testSumFloatOverflow.sql    |    1 -
 .../TestSelectQuery/testSumIntOverflow.sql      |    1 -
 .../TestSelectQuery/testTimezonedTable1.sql     |    1 -
 .../TestSelectQuery/testTimezonedTable2.sql     |    2 -
 .../TestSelectQuery/testTimezonedTable3.sql     |    1 -
 .../TestSelectQuery/testTimezonedTable4.sql     |    2 -
 .../TestSelectQuery/testTimezonedTable5.sql     |    2 -
 .../queries/TestSelectQuery/testWhereCond1.sql  |    1 -
 .../queries/TestSelectQuery/testWhereCond2.sql  |    9 -
 .../TestSelectQuery/testWhereCondWithAlias1.sql |    1 -
 .../TestSelectQuery/testWhereCondWithAlias2.sql |    1 -
 .../create_table_with_asc_desc_keys.sql         |    1 -
 .../create_table_with_date_ddl.sql              |   10 -
 .../queries/TestSortQuery/testAsterisk.sql      |    1 -
 .../queries/TestSortQuery/testSort.sql          |    1 -
 .../TestSortQuery/testSortAfterGroupby.sql      |    1 -
 .../testSortAfterGroupbyWithAlias.sql           |    1 -
 .../queries/TestSortQuery/testSortDesc.sql      |    1 -
 .../queries/TestSortQuery/testSortFirstDesc.sql |    1 -
 .../TestSortQuery/testSortOnNullColumn.sql      |   13 -
 .../TestSortQuery/testSortOnUnicodeTextAsc.sql  |    6 -
 .../TestSortQuery/testSortOnUnicodeTextDesc.sql |    6 -
 .../TestSortQuery/testSortWithAlias1.sql        |    1 -
 .../TestSortQuery/testSortWithAlias2.sql        |    9 -
 .../TestSortQuery/testSortWithAlias3.sql        |   11 -
 .../testSortWithAliasButOriginalName.sql        |    1 -
 .../TestSortQuery/testSortWithAscDescKeys.sql   |    1 -
 .../TestSortQuery/testSortWithConstKeys.sql     |   10 -
 .../queries/TestSortQuery/testSortWithDate.sql  |    1 -
 .../queries/TestSortQuery/testSortWithExpr1.sql |    1 -
 .../queries/TestSortQuery/testSortWithExpr2.sql |    1 -
 .../queries/TestSortQuery/testSortWithJson.json |   65 -
 .../testSubQuerySortAfterGroupMultiBlocks.sql   |    5 -
 .../queries/TestSortQuery/testTopK.sql          |    1 -
 .../queries/TestSortQuery/testTopkWithJson.json |   51 -
 .../queries/TestTPCH/testFirstJoinInQ7.sql      |   13 -
 .../queries/TestTPCH/testQ1OrderBy.sql          |   12 -
 .../queries/TestTPCH/testQ2FourJoins.sql        |   18 -
 .../queries/TestTPCH/testTPCH14Expr.sql         |   12 -
 .../resources/queries/TestTPCH/testTPCHQ5.sql   |   24 -
 .../queries/TestTablePartitions/case1.sql       |   16 -
 .../queries/TestTablePartitions/case10.sql      |    1 -
 .../queries/TestTablePartitions/case11.sql      |    1 -
 .../queries/TestTablePartitions/case12.sql      |    7 -
 .../queries/TestTablePartitions/case13.sql      |   11 -
 .../queries/TestTablePartitions/case14.sql      |    3 -
 .../queries/TestTablePartitions/case15.sql      |    3 -
 .../queries/TestTablePartitions/case2.sql       |   31 -
 .../queries/TestTablePartitions/case3.sql       |    8 -
 .../queries/TestTablePartitions/case4.sql       |    1 -
 .../queries/TestTablePartitions/case5.sql       |    1 -
 .../queries/TestTablePartitions/case6.sql       |    1 -
 .../queries/TestTablePartitions/case7.sql       |    1 -
 .../queries/TestTablePartitions/case8.sql       |    1 -
 .../queries/TestTablePartitions/case9.sql       |    1 -
 .../TestTablePartitions/lineitemspecial_ddl.sql |    3 -
 .../TestTableSubQuery/testGroupBySubQuery.sql   |    1 -
 .../testGroupbySubqueryWithJson.json            |   59 -
 .../TestTableSubQuery/testJoinSubQuery.sql      |    5 -
 .../TestTableSubQuery/testJoinSubQuery2.sql     |    4 -
 .../testJoinSubqueryWithJson.json               |  108 --
 .../TestTableSubQuery/testTableSubquery1.sql    |    1 -
 .../TestTajoJdbc/create_table_with_date_ddl.sql |   10 -
 .../queries/TestTaskStatusUpdate/case1.sql      |    1 -
 .../queries/TestTaskStatusUpdate/case2.sql      |    5 -
 .../queries/TestTaskStatusUpdate/case3.sql      |   10 -
 .../queries/TestTruncateTable/table1_ddl.sql    |    1 -
 .../queries/TestTruncateTable/table2_ddl.sql    |    1 -
 .../TestUnionQuery/testComplexUnion1.sql        |   27 -
 .../TestUnionQuery/testComplexUnion2.sql        |   35 -
 .../queries/TestUnionQuery/testUnion1.sql       |   19 -
 .../queries/TestUnionQuery/testUnion10.sql      |  158 --
 .../queries/TestUnionQuery/testUnion11.sql      |    8 -
 .../queries/TestUnionQuery/testUnion12.sql      |   14 -
 .../queries/TestUnionQuery/testUnion13.sql      |   15 -
 .../queries/TestUnionQuery/testUnion14.sql      |    8 -
 .../queries/TestUnionQuery/testUnion15.sql      |   15 -
 .../queries/TestUnionQuery/testUnion16.sql      |   15 -
 .../queries/TestUnionQuery/testUnion2.sql       |   18 -
 .../queries/TestUnionQuery/testUnion3.sql       |   19 -
 .../queries/TestUnionQuery/testUnion4.sql       |   16 -
 .../queries/TestUnionQuery/testUnion5.sql       |   20 -
 .../queries/TestUnionQuery/testUnion6.sql       |   15 -
 .../queries/TestUnionQuery/testUnion7.sql       |   18 -
 .../queries/TestUnionQuery/testUnion8.sql       |   24 -
 .../queries/TestUnionQuery/testUnion9.sql       |   29 -
 .../queries/TestUnionQuery/testUnionAll1.sql    |   19 -
 .../queries/TestUnionQuery/testUnionAll10.sql   |  158 --
 .../queries/TestUnionQuery/testUnionAll11.sql   |    8 -
 .../queries/TestUnionQuery/testUnionAll12.sql   |   13 -
 .../queries/TestUnionQuery/testUnionAll13.sql   |   14 -
 .../queries/TestUnionQuery/testUnionAll14.sql   |    8 -
 .../queries/TestUnionQuery/testUnionAll15.sql   |   15 -
 .../queries/TestUnionQuery/testUnionAll16.sql   |   15 -
 .../queries/TestUnionQuery/testUnionAll2.sql    |   18 -
 .../queries/TestUnionQuery/testUnionAll3.sql    |   19 -
 .../queries/TestUnionQuery/testUnionAll4.sql    |   16 -
 .../queries/TestUnionQuery/testUnionAll5.sql    |   20 -
 .../queries/TestUnionQuery/testUnionAll6.sql    |   15 -
 .../queries/TestUnionQuery/testUnionAll7.sql    |   18 -
 .../queries/TestUnionQuery/testUnionAll8.sql    |   24 -
 .../queries/TestUnionQuery/testUnionAll9.sql    |   29 -
 .../testUnionAllWithDifferentAlias.sql          |   29 -
 ...estUnionAllWithDifferentAliasAndFunction.sql |   29 -
 .../testUnionAllWithSameAliasNames.sql          |   25 -
 .../testUnionWithDifferentAlias.sql             |   29 -
 .../testUnionWithDifferentAliasAndFunction.sql  |   29 -
 .../testUnionWithSameAliasNames.sql             |   25 -
 .../TestWindowQuery/testComplexOrderBy1.sql     |    5 -
 .../queries/TestWindowQuery/testFirstValue1.sql |   18 -
 .../queries/TestWindowQuery/testLag1.sql        |   18 -
 .../TestWindowQuery/testLagWithDefault.sql      |   18 -
 .../TestWindowQuery/testLagWithNoArgs.sql       |   18 -
 .../queries/TestWindowQuery/testLastValue1.sql  |   18 -
 .../queries/TestWindowQuery/testLead1.sql       |   18 -
 .../TestWindowQuery/testLeadWithDefault.sql     |   18 -
 .../TestWindowQuery/testLeadWithNoArgs.sql      |   18 -
 .../queries/TestWindowQuery/testRowNumber1.sql  |    5 -
 .../queries/TestWindowQuery/testRowNumber2.sql  |    5 -
 .../queries/TestWindowQuery/testRowNumber3.sql  |    7 -
 .../queries/TestWindowQuery/testStdDevPop1.sql  |   14 -
 .../queries/TestWindowQuery/testStdDevSamp1.sql |   14 -
 .../queries/TestWindowQuery/testWindow1.sql     |    1 -
 .../queries/TestWindowQuery/testWindow2.sql     |    1 -
 .../queries/TestWindowQuery/testWindow3.sql     |    1 -
 .../queries/TestWindowQuery/testWindow4.sql     |    1 -
 .../queries/TestWindowQuery/testWindow5.sql     |    1 -
 .../queries/TestWindowQuery/testWindow6.sql     |    1 -
 .../queries/TestWindowQuery/testWindow7.sql     |    1 -
 .../queries/TestWindowQuery/testWindow8.sql     |    7 -
 .../TestWindowQuery/testWindowBeforeLimit.sql   |    6 -
 .../testWindowWithAggregation1.sql              |    4 -
 .../testWindowWithAggregation2.sql              |    7 -
 .../testWindowWithAggregation3.sql              |    5 -
 .../testWindowWithAggregation4.sql              |    8 -
 .../testWindowWithAggregation5.sql              |    9 -
 .../testWindowWithAggregation6.sql              |   10 -
 .../TestWindowQuery/testWindowWithOrderBy1.sql  |    6 -
 .../TestWindowQuery/testWindowWithOrderBy2.sql  |    6 -
 .../TestWindowQuery/testWindowWithOrderBy3.sql  |    6 -
 .../TestWindowQuery/testWindowWithOrderBy4.sql  |    7 -
 .../TestWindowQuery/testWindowWithOrderBy5.sql  |    9 -
 .../TestWindowQuery/testWindowWithSubQuery.sql  |   14 -
 .../TestWindowQuery/testWindowWithSubQuery2.sql |   15 -
 .../TestWindowQuery/testWindowWithSubQuery3.sql |   14 -
 .../TestWindowQuery/testWindowWithSubQuery4.sql |   14 -
 .../TestWindowQuery/testWindowWithSubQuery5.sql |   11 -
 .../TestWindowQuery/testWindowWithSubQuery6.sql |    9 -
 .../default/alter_table_add_partition_1.sql     |    1 -
 .../default/alter_table_add_partition_2.sql     |    1 -
 .../default/alter_table_add_partition_3.sql     |    2 -
 .../default/alter_table_add_partition_4.sql     |    1 -
 .../default/alter_table_add_partition_5.sql     |    1 -
 .../default/alter_table_drop_partition_1.sql    |    1 -
 .../default/alter_table_drop_partition_2.sql    |    1 -
 .../default/alter_table_drop_partition_3.sql    |    1 -
 .../default/alter_table_drop_partition_4.sql    |    1 -
 .../default/alter_table_set_property_1.sql      |    1 -
 .../default/alter_table_set_property_2.sql      |    1 -
 .../default/alter_table_set_property_3.sql      |    1 -
 .../resources/queries/default/asterisk_1.sql    |    1 -
 .../resources/queries/default/asterisk_2.sql    |    1 -
 .../resources/queries/default/asterisk_3.sql    |    1 -
 .../resources/queries/default/asterisk_4.sql    |    1 -
 .../create_partitioned_table_as_select.sql      |   17 -
 .../queries/default/create_table_1.hiveql       |    1 -
 .../queries/default/create_table_1.sql          |    1 -
 .../queries/default/create_table_10.sql         |    1 -
 .../queries/default/create_table_11.hiveql      |    3 -
 .../queries/default/create_table_11.sql         |    3 -
 .../queries/default/create_table_12.hiveql      |    4 -
 .../queries/default/create_table_12.sql         |    3 -
 .../queries/default/create_table_2.hiveql       |    1 -
 .../queries/default/create_table_2.sql          |    1 -
 .../queries/default/create_table_3.sql          |    1 -
 .../queries/default/create_table_4.sql          |    1 -
 .../queries/default/create_table_5.sql          |    1 -
 .../queries/default/create_table_6.sql          |    1 -
 .../queries/default/create_table_7.sql          |    1 -
 .../queries/default/create_table_8.sql          |   48 -
 .../queries/default/create_table_9.sql          |    1 -
 .../queries/default/create_table_like_1.sql     |    1 -
 .../create_table_partition_by_column.sql        |    4 -
 .../create_table_partition_by_hash_1.sql        |    3 -
 .../create_table_partition_by_hash_2.sql        |    7 -
 .../default/create_table_partition_by_list.sql  |    8 -
 .../default/create_table_partition_by_range.sql |    9 -
 .../resources/queries/default/drop_table.sql    |    1 -
 .../queries/default/exists_predicate_1.sql      |    1 -
 .../queries/default/exists_predicate_2.sql      |    1 -
 .../resources/queries/default/groupby_1.sql     |    1 -
 .../resources/queries/default/groupby_2.sql     |    1 -
 .../resources/queries/default/groupby_3.sql     |    1 -
 .../resources/queries/default/groupby_4.sql     |    1 -
 .../resources/queries/default/groupby_5.sql     |    1 -
 .../resources/queries/default/in_subquery_1.sql |    1 -
 .../resources/queries/default/in_subquery_2.sql |    1 -
 .../queries/default/insert_into_select_1.sql    |    1 -
 .../queries/default/insert_into_select_2.sql    |    1 -
 .../queries/default/insert_into_select_3.sql    |    1 -
 .../default/insert_overwrite_into_select_1.sql  |    1 -
 .../insert_overwrite_into_select_2.hiveql       |    1 -
 .../default/insert_overwrite_into_select_2.sql  |    1 -
 .../default/insert_overwrite_into_select_3.sql  |    1 -
 .../test/resources/queries/default/join_1.sql   |    1 -
 .../test/resources/queries/default/join_10.sql  |    1 -
 .../test/resources/queries/default/join_11.sql  |    1 -
 .../test/resources/queries/default/join_12.sql  |    1 -
 .../test/resources/queries/default/join_13.sql  |   13 -
 .../test/resources/queries/default/join_14.sql  |    1 -
 .../resources/queries/default/join_15.hiveql    |    1 -
 .../test/resources/queries/default/join_15.sql  |    1 -
 .../test/resources/queries/default/join_2.sql   |    1 -
 .../test/resources/queries/default/join_3.sql   |    1 -
 .../test/resources/queries/default/join_4.sql   |    1 -
 .../test/resources/queries/default/join_5.sql   |    1 -
 .../test/resources/queries/default/join_6.sql   |    1 -
 .../test/resources/queries/default/join_7.sql   |    1 -
 .../test/resources/queries/default/join_8.sql   |   13 -
 .../test/resources/queries/default/join_9.sql   |    5 -
 .../test/resources/queries/default/select_1.sql |    1 -
 .../resources/queries/default/select_10.hiveql  |    5 -
 .../resources/queries/default/select_10.sql     |    5 -
 .../resources/queries/default/select_11.hiveql  |    4 -
 .../resources/queries/default/select_11.sql     |    6 -
 .../resources/queries/default/select_12.hiveql  |    3 -
 .../resources/queries/default/select_13.hiveql  |    2 -
 .../resources/queries/default/select_13.sql     |    2 -
 .../resources/queries/default/select_14.sql     |    2 -
 .../resources/queries/default/select_15.hiveql  |    1 -
 .../resources/queries/default/select_15.sql     |    1 -
 .../test/resources/queries/default/select_2.sql |    1 -
 .../test/resources/queries/default/select_3.sql |    1 -
 .../test/resources/queries/default/select_4.sql |    1 -
 .../test/resources/queries/default/select_5.sql |    1 -
 .../test/resources/queries/default/select_6.sql |    1 -
 .../test/resources/queries/default/select_7.sql |    1 -
 .../test/resources/queries/default/select_8.sql |    1 -
 .../resources/queries/default/select_9.hiveql   |    4 -
 .../test/resources/queries/default/select_9.sql |    4 -
 .../test/resources/queries/default/set_1.sql    |    1 -
 .../test/resources/queries/default/set_2.sql    |    1 -
 .../test/resources/queries/default/set_3.sql    |    1 -
 .../test/resources/queries/default/set_4.sql    |   36 -
 .../queries/default/table_subquery1.sql         |   19 -
 .../queries/default/table_subquery2.sql         |   21 -
 .../resources/queries/default/union_1.hiveql    |   14 -
 .../after_set_property_delimiter.result         |    3 -
 .../before_set_property_delimiter.result        |    3 -
 .../TestBuiltinFunctions/testAvgDouble.result   |    5 -
 .../TestBuiltinFunctions/testAvgInt.result      |    3 -
 .../TestBuiltinFunctions/testAvgLong.result     |    3 -
 .../testAvgLongOverflow.result                  |    3 -
 .../TestBuiltinFunctions/testCount.result       |    3 -
 .../TestBuiltinFunctions/testMaxLong.result     |    3 -
 .../TestBuiltinFunctions/testMaxString.result   |    3 -
 .../TestBuiltinFunctions/testMinLong.result     |    3 -
 .../TestBuiltinFunctions/testMinString.result   |    3 -
 .../TestBuiltinFunctions/testSplitPart.result   |    7 -
 .../testSplitPartByString.result                |    7 -
 .../testSplitPartNested.result                  |    7 -
 .../TestCTASQuery/testCtasWithGroupby.result    |    7 -
 .../TestCTASQuery/testCtasWithLimit.result      |    5 -
 .../TestCTASQuery/testCtasWithOptions.result    |    5 -
 .../TestCTASQuery/testCtasWithOrderby.result    |    7 -
 .../TestCTASQuery/testCtasWithStoreType.result  |    5 -
 .../TestCTASQuery/testCtasWithTextFile.result   |    5 -
 .../TestCTASQuery/testCtasWithUnion.result      |    8 -
 .../TestCaseByCases/testTAJO1224Case1.result    |    3 -
 .../TestCaseByCases/testTAJO415Case.result      |    7 -
 .../TestCaseByCases/testTAJO418Case.result      |    4 -
 .../TestCaseByCases/testTAJO619Case.result      |    3 -
 .../TestCaseByCases/testTAJO718Case.result      |    5 -
 .../TestCaseByCases/testTAJO739Case.result      |    7 -
 .../TestCaseByCases/testTAJO914Case1.result     |    5 -
 .../TestCaseByCases/testTAJO914Case2.result     |    5 -
 .../TestCaseByCases/testTAJO914Case3.result     |    5 -
 .../TestCaseByCases/testTAJO914Case4.result     |    5 -
 .../TestCaseByCases/testTAJO917Case1.result     |    7 -
 .../quoted_identifier_mixed_chars_1.result      |    5 -
 .../quoted_identifier_mixed_chars_2.result      |    5 -
 .../quoted_identifier_mixed_chars_3.result      |    8 -
 .../quoted_identifier_non_ascii_1.result        |    5 -
 .../quoted_identifier_non_ascii_2.result        |    5 -
 .../quoted_identifier_non_ascii_3.result        |    5 -
 .../testFindScalarFunctions.result              |    2 -
 .../testComplexParameter.result                 |    3 -
 .../testComplexParameter2.result                |    3 -
 .../testComplexParameterWithSubQuery.result     |    3 -
 .../testComplexTargetWithPythonUdaf.result      |    3 -
 .../testDistinctAggregation1.result             |    5 -
 .../testDistinctAggregation2.result             |    5 -
 .../testDistinctAggregation3.result             |    3 -
 .../testDistinctAggregation4.result             |    4 -
 .../testDistinctAggregation5.result             |    4 -
 .../testDistinctAggregation6.result             |    5 -
 .../testDistinctAggregation7.result             |    3 -
 .../testDistinctAggregation8.result             |    7 -
 .../testDistinctAggregationCaseByCase3.result   |    3 -
 .../testDistinctAggregationCaseByCase4.result   |    3 -
 .../testDistinctAggregationWithHaving1.result   |    3 -
 .../testDistinctAggregationWithUnion1.result    |    4 -
 .../testDistinctAggregation_case1.result        |    4 -
 .../testDistinctAggregation_case10.result       |    3 -
 .../testDistinctAggregation_case2.result        |    4 -
 .../testDistinctAggregation_case3.result        |    4 -
 .../testDistinctAggregation_case4.result        |    5 -
 .../testDistinctAggregation_case5.result        |    5 -
 .../testDistinctAggregation_case6.result        |    5 -
 .../testDistinctAggregation_case7.result        |    5 -
 .../testDistinctAggregation_case8.result        |    6 -
 .../testDistinctAggregation_case9.result        |    6 -
 .../testDistinctPythonUdafWithUnion1.result     |    4 -
 .../results/TestGroupByQuery/testGroupBy.result |    3 -
 .../TestGroupByQuery/testGroupBy2.result        |    4 -
 .../TestGroupByQuery/testGroupBy3.result        |    5 -
 .../TestGroupByQuery/testGroupBy4.result        |    5 -
 .../TestGroupByQuery/testGroupBy5.result        |    5 -
 .../TestGroupByQuery/testGroupByNested1.result  |    6 -
 .../TestGroupByQuery/testGroupByNested2.result  |    6 -
 .../testGroupByWithConstantKeys1.result         |    3 -
 .../testGroupByWithConstantKeys2.result         |    5 -
 .../testGroupByWithConstantKeys3.result         |    3 -
 .../testGroupByWithConstantKeys4.result         |    5 -
 .../testGroupByWithConstantKeys5.result         |    5 -
 .../testGroupByWithExpressionKeys1.result       |    5 -
 .../testGroupByWithExpressionKeys2.result       |    5 -
 .../testGroupByWithNullData1.result             |    3 -
 .../testGroupByWithNullData10.result            |    3 -
 .../testGroupByWithNullData11.result            |    2 -
 .../testGroupByWithNullData12.result            |    2 -
 .../testGroupByWithNullData2.result             |    3 -
 .../testGroupByWithNullData3.result             |    3 -
 .../testGroupByWithNullData4.result             |    3 -
 .../testGroupByWithNullData5.result             |    3 -
 .../testGroupByWithNullData6.result             |    3 -
 .../testGroupByWithNullData7.result             |    3 -
 .../testGroupByWithNullData8.result             |    3 -
 .../testGroupByWithNullData9.result             |    2 -
 .../testGroupByWithSameConstantKeys1.result     |    5 -
 .../testGroupByWithSameExprs1.result            |    6 -
 .../testGroupByWithSameExprs2.result            |    6 -
 .../TestGroupByQuery/testGroupbyWithJson.result |    5 -
 .../testGroupbyWithLimit1.result                |    3 -
 .../testGroupbyWithLimit2.result                |    3 -
 .../testGroupbyWithLimit3.result                |    3 -
 .../testGroupbyWithPythonFunc.result            |    7 -
 .../testGroupbyWithPythonFunc2.result           |    7 -
 .../testHavingWithAggFunction.result            |    4 -
 .../testHavingWithNamedTarget.result            |    5 -
 .../TestGroupByQuery/testPythonUdaf.result      |    3 -
 .../TestGroupByQuery/testPythonUdaf2.result     |    4 -
 .../TestGroupByQuery/testPythonUdaf3.result     |    5 -
 .../testPythonUdafWithHaving.result             |    4 -
 .../testPythonUdafWithNullData.result           |    2 -
 .../TestHBaseTable/testBinaryMappedQuery.result |   81 -
 .../results/TestHBaseTable/testCTAS.result      |  100 --
 .../testColumnKeyValueSelectQuery.result        |   12 -
 .../TestHBaseTable/testIndexPredication.result  |   38 -
 .../TestHBaseTable/testInsertInto.result        |    3 -
 .../testInsertIntoBinaryMultiRegion.result      |  100 --
 .../testInsertIntoColumnKeyValue.result         |   21 -
 .../testInsertIntoMultiRegion.result            |  100 --
 .../testInsertIntoMultiRegion2.result           |  100 --
 ...stInsertIntoMultiRegionMultiRowFields.result |  100 --
 ...estInsertIntoMultiRegionWithSplitFile.result |  100 --
 .../testInsertIntoRowField.result               |    4 -
 .../testInsertIntoUsingPut.result               |    3 -
 .../TestHBaseTable/testInsertValues1.result     |    4 -
 .../results/TestHBaseTable/testJoin.result      |    7 -
 .../TestHBaseTable/testNonForwardQuery.result   |  102 --
 .../testRowFieldSelectQuery.result              |   88 --
 .../TestHBaseTable/testSimpleSelectQuery.result |   88 --
 .../testInAndNotInSubQuery.result               |   24 -
 .../TestInSubquery/testInSubQuery.result        |   27 -
 .../TestInSubquery/testInSubQuery2.result       |    3 -
 .../testInSubQueryWithJoin.result               |    5 -
 .../testInSubQueryWithOtherConditions.result    |   25 -
 .../testInSubQueryWithTableSubQuery.result      |    4 -
 .../testMultipleInSubQuery.result               |    5 -
 .../testMultipleNotInSubQuery.result            |   20 -
 .../testNestedInAndNotInSubQuery.result         |    3 -
 .../TestInSubquery/testNestedInSubQuery.result  |    3 -
 .../TestInSubquery/testNestedInSubQuery2.result |    3 -
 .../testNestedNotInSubQuery.result              |    7 -
 .../TestInSubquery/testNotInSubQuery.result     |   22 -
 ...testSameKeyNameOfOuterAndInnerQueries.result |    3 -
 .../testWithAsteriskAndJoin.result              |    6 -
 .../TestIndexScan/testOnMultipleExprs.result    |    3 -
 .../TestIndexScan/testOnMultipleKeys.result     |    3 -
 .../TestIndexScan/testOnMultipleKeys2.result    |    3 -
 .../testOnSortedNonUniqueKeys.result            |    4 -
 .../TestIndexScan/testOnUnsortedTextKeys.result |    3 -
 .../TestIndexScan/testWithGroupBy.result        |    3 -
 .../results/TestIndexScan/testWithJoin.result   |    4 -
 .../results/TestIndexScan/testWithSort.result   |    4 -
 .../testBroadcastTwoPartJoin.Hash.plan          |  135 --
 ...stBroadcastTwoPartJoin.Hash_NoBroadcast.plan |  249 ----
 .../testBroadcastTwoPartJoin.Sort.plan          |  135 --
 ...stBroadcastTwoPartJoin.Sort_NoBroadcast.plan |  249 ----
 .../testBroadcastTwoPartJoin.result             |    7 -
 .../testComplexJoinCondition1.Hash.plan         |   78 -
 ...tComplexJoinCondition1.Hash_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition1.Sort.plan         |   78 -
 ...tComplexJoinCondition1.Sort_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition1.result            |   27 -
 .../testComplexJoinCondition2.Hash.plan         |   78 -
 ...tComplexJoinCondition2.Hash_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition2.Sort.plan         |   78 -
 ...tComplexJoinCondition2.Sort_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition2.result            |   27 -
 .../testComplexJoinCondition3.Hash.plan         |   78 -
 ...tComplexJoinCondition3.Hash_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition3.Sort.plan         |   78 -
 ...tComplexJoinCondition3.Sort_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition3.result            |   27 -
 .../testComplexJoinCondition4.Hash.plan         |   78 -
 ...tComplexJoinCondition4.Hash_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition4.Sort.plan         |   78 -
 ...tComplexJoinCondition4.Sort_NoBroadcast.plan |  105 --
 .../testComplexJoinCondition4.result            |   29 -
 .../testCrossJoin.1.Hash.plan                   |   76 -
 .../testCrossJoin.1.Hash_NoBroadcast.plan       |  103 --
 .../testCrossJoin.1.Sort.plan                   |   76 -
 .../testCrossJoin.1.Sort_NoBroadcast.plan       |  103 --
 .../TestInnerJoinQuery/testCrossJoin.1.result   |  127 --
 .../testCrossJoin.2.Hash.plan                   |   51 -
 .../testCrossJoin.2.Hash_NoBroadcast.plan       |   78 -
 .../testCrossJoin.2.Sort.plan                   |   51 -
 .../testCrossJoin.2.Sort_NoBroadcast.plan       |   78 -
 .../TestInnerJoinQuery/testCrossJoin.2.result   |   27 -
 .../testCrossJoin.3.Hash.plan                   |   51 -
 .../testCrossJoin.3.Hash_NoBroadcast.plan       |   78 -
 .../testCrossJoin.3.Sort.plan                   |   51 -
 .../testCrossJoin.3.Sort_NoBroadcast.plan       |   78 -
 .../TestInnerJoinQuery/testCrossJoin.3.result   |   27 -
 .../testCrossJoin.4.Hash.plan                   |   51 -
 .../testCrossJoin.4.Hash_NoBroadcast.plan       |   78 -
 .../testCrossJoin.4.Sort.plan                   |   51 -
 .../testCrossJoin.4.Sort_NoBroadcast.plan       |   78 -
 .../TestInnerJoinQuery/testCrossJoin.4.result   |   27 -
 .../testCrossJoin.5.Hash.plan                   |   76 -
 .../testCrossJoin.5.Hash_NoBroadcast.plan       |  103 --
 .../testCrossJoin.5.Sort.plan                   |   76 -
 .../testCrossJoin.5.Sort_NoBroadcast.plan       |  103 --
 .../TestInnerJoinQuery/testCrossJoin.5.result   |   27 -
 .../testCrossJoinAndCaseWhen.Hash.plan          |   78 -
 ...stCrossJoinAndCaseWhen.Hash_NoBroadcast.plan |  105 --
 .../testCrossJoinAndCaseWhen.Sort.plan          |   78 -
 ...stCrossJoinAndCaseWhen.Sort_NoBroadcast.plan |  105 --
 .../testCrossJoinAndCaseWhen.result             |   27 -
 .../testCrossJoinWithAsterisk1.Hash.plan        |   76 -
 ...CrossJoinWithAsterisk1.Hash_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk1.Sort.plan        |   76 -
 ...CrossJoinWithAsterisk1.Sort_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk1.result           |   27 -
 .../testCrossJoinWithAsterisk2.Hash.plan        |   76 -
 ...CrossJoinWithAsterisk2.Hash_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk2.Sort.plan        |   76 -
 ...CrossJoinWithAsterisk2.Sort_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk2.result           |   27 -
 .../testCrossJoinWithAsterisk3.Hash.plan        |   76 -
 ...CrossJoinWithAsterisk3.Hash_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk3.Sort.plan        |   76 -
 ...CrossJoinWithAsterisk3.Sort_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk3.result           |   27 -
 .../testCrossJoinWithAsterisk4.Hash.plan        |   76 -
 ...CrossJoinWithAsterisk4.Hash_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk4.Sort.plan        |   76 -
 ...CrossJoinWithAsterisk4.Sort_NoBroadcast.plan |  103 --
 .../testCrossJoinWithAsterisk4.result           |   27 -
 .../testCrossJoinWithEmptyTable1.Hash.plan      |   78 -
 ...ossJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 --
 .../testCrossJoinWithEmptyTable1.Sort.plan      |   78 -
 ...ossJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 --
 .../testCrossJoinWithEmptyTable1.result         |    2 -
 ...sJoinWithThetaJoinConditionInWhere.Hash.plan |   63 -
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   90 --
 ...sJoinWithThetaJoinConditionInWhere.Sort.plan |   63 -
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   90 --
 ...rossJoinWithThetaJoinConditionInWhere.result |   12 -
 .../testDifferentTypesJoinCondition.Hash.plan   |   53 -
 ...rentTypesJoinCondition.Hash_NoBroadcast.plan |   80 -
 .../testDifferentTypesJoinCondition.Sort.plan   |   53 -
 ...rentTypesJoinCondition.Sort_NoBroadcast.plan |   80 -
 .../testDifferentTypesJoinCondition.result      |    7 -
 .../testInnerJoinAndCaseWhen.Hash.plan          |   78 -
 ...stInnerJoinAndCaseWhen.Hash_NoBroadcast.plan |  105 --
 .../testInnerJoinAndCaseWhen.Sort.plan          |   78 -
 ...stInnerJoinAndCaseWhen.Sort_NoBroadcast.plan |  105 --
 .../testInnerJoinAndCaseWhen.result             |   27 -
 .../testInnerJoinWithEmptyTable.Hash.plan       |   78 -
 ...nnerJoinWithEmptyTable.Hash_NoBroadcast.plan |  105 --
 .../testInnerJoinWithEmptyTable.Sort.plan       |   78 -
 ...nnerJoinWithEmptyTable.Sort_NoBroadcast.plan |  105 --
 .../testInnerJoinWithEmptyTable.result          |    2 -
 ...rJoinWithThetaJoinConditionInWhere.Hash.plan |   57 -
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   84 --
 ...rJoinWithThetaJoinConditionInWhere.Sort.plan |   57 -
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   84 --
 ...nnerJoinWithThetaJoinConditionInWhere.result |    7 -
 .../testJoinAsterisk.Hash.plan                  |   53 -
 .../testJoinAsterisk.Hash_NoBroadcast.plan      |   80 -
 .../testJoinAsterisk.Sort.plan                  |   53 -
 .../testJoinAsterisk.Sort_NoBroadcast.plan      |   80 -
 .../TestInnerJoinQuery/testJoinAsterisk.result  |    7 -
 .../testJoinCoReferredEvals1.Hash.plan          |   78 -
 ...stJoinCoReferredEvals1.Hash_NoBroadcast.plan |  105 --
 .../testJoinCoReferredEvals1.Sort.plan          |   78 -
 ...stJoinCoReferredEvals1.Sort_NoBroadcast.plan |  105 --
 .../testJoinCoReferredEvals1.result             |   27 -
 ...tJoinCoReferredEvalsWithSameExprs1.Hash.plan |   88 --
 ...redEvalsWithSameExprs1.Hash_NoBroadcast.plan |  115 --
 ...tJoinCoReferredEvalsWithSameExprs1.Sort.plan |   88 --
 ...redEvalsWithSameExprs1.Sort_NoBroadcast.plan |  115 --
 ...testJoinCoReferredEvalsWithSameExprs1.result |   22 -
 ...tJoinCoReferredEvalsWithSameExprs2.Hash.plan |  119 --
 ...redEvalsWithSameExprs2.Hash_NoBroadcast.plan |  146 --
 ...tJoinCoReferredEvalsWithSameExprs2.Sort.plan |  119 --
 ...redEvalsWithSameExprs2.Sort_NoBroadcast.plan |  146 --
 ...testJoinCoReferredEvalsWithSameExprs2.result |   22 -
 .../testJoinOnMultipleDatabases.Hash.plan       |  135 --
 ...oinOnMultipleDatabases.Hash_NoBroadcast.plan |  249 ----
 .../testJoinOnMultipleDatabases.Sort.plan       |  135 --
 ...oinOnMultipleDatabases.Sort_NoBroadcast.plan |  249 ----
 .../testJoinOnMultipleDatabases.result          |    5 -
 .../testJoinOnMultipleDatabasesWithJson.result  |    5 -
 .../TestInnerJoinQuery/testJoinWithJson.result  |   27 -
 .../testJoinWithMultipleJoinQual1.Hash.plan     |  135 --
 ...nWithMultipleJoinQual1.Hash_NoBroadcast.plan |  249 ----
 .../testJoinWithMultipleJoinQual1.Sort.plan     |  135 --
 ...nWithMultipleJoinQual1.Sort_NoBroadcast.plan |  249 ----
 .../testJoinWithMultipleJoinQual1.result        |    2 -
 .../testJoinWithOrPredicates.Hash.plan          |   90 --
 ...stJoinWithOrPredicates.Hash_NoBroadcast.plan |  117 --
 .../testJoinWithOrPredicates.Sort.plan          |   90 --
 ...stJoinWithOrPredicates.Sort_NoBroadcast.plan |  117 --
 .../testJoinWithOrPredicates.result             |    4 -
 .../testNaturalJoin.Hash.plan                   |   78 -
 .../testNaturalJoin.Hash_NoBroadcast.plan       |  105 --
 .../testNaturalJoin.Sort.plan                   |   78 -
 .../testNaturalJoin.Sort_NoBroadcast.plan       |  105 --
 .../TestInnerJoinQuery/testNaturalJoin.result   |   27 -
 .../TestInnerJoinQuery/testTPCHQ2Join.Hash.plan |  135 --
 .../testTPCHQ2Join.Hash_NoBroadcast.plan        |  249 ----
 .../TestInnerJoinQuery/testTPCHQ2Join.Sort.plan |  135 --
 .../testTPCHQ2Join.Sort_NoBroadcast.plan        |  249 ----
 .../TestInnerJoinQuery/testTPCHQ2Join.result    |    5 -
 .../testWhereClauseJoin1.Hash.plan              |   78 -
 .../testWhereClauseJoin1.Hash_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin1.Sort.plan              |   78 -
 .../testWhereClauseJoin1.Sort_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin1.result                 |   27 -
 .../testWhereClauseJoin2.Hash.plan              |   78 -
 .../testWhereClauseJoin2.Hash_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin2.Sort.plan              |   78 -
 .../testWhereClauseJoin2.Sort_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin2.result                 |   27 -
 .../testWhereClauseJoin3.Hash.plan              |   78 -
 .../testWhereClauseJoin3.Hash_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin3.Sort.plan              |   78 -
 .../testWhereClauseJoin3.Sort_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin3.result                 |   27 -
 .../testWhereClauseJoin4.Hash.plan              |   78 -
 .../testWhereClauseJoin4.Hash_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin4.Sort.plan              |   78 -
 .../testWhereClauseJoin4.Sort_NoBroadcast.plan  |  105 --
 .../testWhereClauseJoin4.result                 |   27 -
 .../testWhereClauseJoin5.Hash.plan              |   97 --
 .../testWhereClauseJoin5.Hash_NoBroadcast.plan  |  153 --
 .../testWhereClauseJoin5.Sort.plan              |   97 --
 .../testWhereClauseJoin5.Sort_NoBroadcast.plan  |  153 --
 .../testWhereClauseJoin5.result                 |    5 -
 .../testWhereClauseJoin6.Hash.plan              |  116 --
 .../testWhereClauseJoin6.Hash_NoBroadcast.plan  |  201 ---
 .../testWhereClauseJoin6.Sort.plan              |  116 --
 .../testWhereClauseJoin6.Sort_NoBroadcast.plan  |  201 ---
 .../testWhereClauseJoin6.result                 |    5 -
 .../testBroadcastSubquery.Hash.plan             |  109 --
 .../testBroadcastSubquery.Hash_NoBroadcast.plan |  165 --
 .../testBroadcastSubquery.Sort.plan             |  109 --
 .../testBroadcastSubquery.Sort_NoBroadcast.plan |  165 --
 .../testBroadcastSubquery.result                |    7 -
 .../testBroadcastSubquery2.Hash.plan            |  216 ---
 ...testBroadcastSubquery2.Hash_NoBroadcast.plan |  328 ----
 .../testBroadcastSubquery2.Sort.plan            |  216 ---
 ...testBroadcastSubquery2.Sort_NoBroadcast.plan |  328 ----
 .../testBroadcastSubquery2.result               |    3 -
 .../testComplexJoinCondition5.Hash.plan         |   90 --
 ...tComplexJoinCondition5.Hash_NoBroadcast.plan |  117 --
 .../testComplexJoinCondition5.Sort.plan         |   90 --
 ...tComplexJoinCondition5.Sort_NoBroadcast.plan |  117 --
 .../testComplexJoinCondition5.result            |   29 -
 .../testComplexJoinCondition6.Hash.plan         |  109 --
 ...tComplexJoinCondition6.Hash_NoBroadcast.plan |  145 --
 .../testComplexJoinCondition6.Sort.plan         |  109 --
 ...tComplexJoinCondition6.Sort_NoBroadcast.plan |  145 --
 .../testComplexJoinCondition6.result            |   56 -
 .../testComplexJoinCondition7.Hash.plan         |  109 --
 ...tComplexJoinCondition7.Hash_NoBroadcast.plan |  145 --
 .../testComplexJoinCondition7.Sort.plan         |  109 --
 ...tComplexJoinCondition7.Sort_NoBroadcast.plan |  145 --
 .../testComplexJoinCondition7.result            |   56 -
 .../testJoinWithJson2.result                    |    5 -
 .../testJoinWithMultipleJoinQual2.Hash.plan     |   86 --
 ...nWithMultipleJoinQual2.Hash_NoBroadcast.plan |  142 --
 .../testJoinWithMultipleJoinQual2.Sort.plan     |   86 --
 ...nWithMultipleJoinQual2.Sort_NoBroadcast.plan |  142 --
 .../testJoinWithMultipleJoinQual2.result        |    3 -
 .../testJoinWithMultipleJoinQual3.Hash.plan     |  105 --
 ...nWithMultipleJoinQual3.Hash_NoBroadcast.plan |  190 ---
 .../testJoinWithMultipleJoinQual3.Sort.plan     |  105 --
 ...nWithMultipleJoinQual3.Sort_NoBroadcast.plan |  190 ---
 .../testJoinWithMultipleJoinQual3.result        |    5 -
 .../testJoinWithMultipleJoinQual4.Hash.plan     |  109 --
 ...nWithMultipleJoinQual4.Hash_NoBroadcast.plan |  194 ---
 .../testJoinWithMultipleJoinQual4.Sort.plan     |  109 --
 ...nWithMultipleJoinQual4.Sort_NoBroadcast.plan |  194 ---
 .../testJoinWithMultipleJoinQual4.result        |    4 -
 .../testThetaJoinKeyPairs.Hash.plan             |  146 --
 .../testThetaJoinKeyPairs.Hash_NoBroadcast.plan |  200 ---
 .../testThetaJoinKeyPairs.Sort.plan             |  146 --
 .../testThetaJoinKeyPairs.Sort_NoBroadcast.plan |  200 ---
 .../testThetaJoinKeyPairs.result                |   21 -
 ...estInsertOverwriteWithAsteriskAndMore.result |    7 -
 ...sertOverwriteWithAsteriskUsingParquet.result |    4 -
 ...ertOverwriteWithAsteriskUsingParquet2.result |    4 -
 .../testInsertWithDifferentColumnOrder.result   |   27 -
 .../selfJoinOfPartitionedTable.result           |    7 -
 .../testBroadcastPartitionTable.result          |    5 -
 ...FilterPushDownPartitionColumnCaseWhen.result |    4 -
 ...tionedBroadcastDataFileWithZeroLength.result |    7 -
 ...ionedBroadcastDataFileWithZeroLength2.result |    7 -
 .../testNoProjectionJoinQual.result             |    3 -
 .../testPartialFilterPushDown.result            |    3 -
 .../testPartialFilterPushDownOuterJoin.result   |   27 -
 .../testPartialFilterPushDownOuterJoin2.result  |   27 -
 ...estPartitionMultiplePartitionFilter.1.result |    2 -
 .../testPartitionTableJoinSmallTable.result     |    7 -
 .../TestJoinQuery/testWhereClauseJoin6.result   |    5 -
 .../testComplexJoinsWithCaseWhen.Hash.plan      |   97 --
 ...mplexJoinsWithCaseWhen.Hash_NoBroadcast.plan |  153 --
 .../testComplexJoinsWithCaseWhen.Sort.plan      |   97 --
 ...mplexJoinsWithCaseWhen.Sort_NoBroadcast.plan |  153 --
 .../testComplexJoinsWithCaseWhen.result         |   27 -
 .../testComplexJoinsWithCaseWhen2.Hash.plan     |  109 --
 ...plexJoinsWithCaseWhen2.Hash_NoBroadcast.plan |  165 --
 .../testComplexJoinsWithCaseWhen2.Sort.plan     |  109 --
 ...plexJoinsWithCaseWhen2.Sort_NoBroadcast.plan |  165 --
 .../testComplexJoinsWithCaseWhen2.result        |   27 -
 .../testInnerAndOuterWithEmpty.1.Hash.plan      |   74 -
 ...nerAndOuterWithEmpty.1.Hash_NoBroadcast.plan |  130 --
 .../testInnerAndOuterWithEmpty.1.Sort.plan      |   74 -
 ...nerAndOuterWithEmpty.1.Sort_NoBroadcast.plan |  130 --
 .../testInnerAndOuterWithEmpty.1.result         |    7 -
 .../testJoinWithMultipleJoinTypes.Hash.plan     |   84 --
 ...nWithMultipleJoinTypes.Hash_NoBroadcast.plan |  140 --
 .../testJoinWithMultipleJoinTypes.Sort.plan     |   84 --
 ...nWithMultipleJoinTypes.Sort_NoBroadcast.plan |  140 --
 .../testJoinWithMultipleJoinTypes.result        |    6 -
 .../results/TestNetTypes/testGroupby.result     |    7 -
 .../results/TestNetTypes/testGroupby2.result    |    5 -
 .../results/TestNetTypes/testJoin.result        |    6 -
 .../results/TestNetTypes/testSelect.result      |    7 -
 .../results/TestNetTypes/testSort.result        |    7 -
 .../results/TestNetTypes/testSort2.result       |    7 -
 .../testGetClusterDetails.result                |    4 -
 .../testGetNextRowsForAggregateFunction.result  |    3 -
 .../testGetNextRowsForTable.result              |    5 -
 .../testFullOuterJoin1.Hash.plan                |  105 --
 .../testFullOuterJoin1.Hash_NoBroadcast.plan    |  105 --
 .../testFullOuterJoin1.Sort.plan                |  105 --
 .../testFullOuterJoin1.Sort_NoBroadcast.plan    |  105 --
 .../testFullOuterJoin1.result                   |    7 -
 ...lOuterJoinPredicationCaseByCase1.1.Hash.plan |  153 --
 ...edicationCaseByCase1.1.Hash_NoBroadcast.plan |  153 --
 ...lOuterJoinPredicationCaseByCase1.1.Sort.plan |  153 --
 ...edicationCaseByCase1.1.Sort_NoBroadcast.plan |  153 --
 ...FullOuterJoinPredicationCaseByCase1.1.result |    9 -
 .../testFullOuterJoinWithEmptyTable1.Hash.plan  |  105 --
 ...terJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 --
 .../testFullOuterJoinWithEmptyTable1.Sort.plan  |  105 --
 ...terJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 --
 .../testFullOuterJoinWithEmptyTable1.result     |    7 -
 ...testJoinFilterOfRowPreservedTable1.Hash.plan |   78 -
 ...erOfRowPreservedTable1.Hash_NoBroadcast.plan |  105 --
 ...testJoinFilterOfRowPreservedTable1.Sort.plan |   78 -
 ...erOfRowPreservedTable1.Sort_NoBroadcast.plan |  105 --
 .../testJoinFilterOfRowPreservedTable1.result   |   15 -
 .../testLeftOuterJoin1.Hash.plan                |   78 -
 .../testLeftOuterJoin1.Hash_NoBroadcast.plan    |  105 --
 .../testLeftOuterJoin1.Sort.plan                |   78 -
 .../testLeftOuterJoin1.Sort_NoBroadcast.plan    |  105 --
 .../testLeftOuterJoin1.result                   |    7 -
 .../testLeftOuterJoin2.Hash.plan                |   91 --
 .../testLeftOuterJoin2.Hash_NoBroadcast.plan    |  176 ---
 .../testLeftOuterJoin2.Sort.plan                |   91 --
 .../testLeftOuterJoin2.Sort_NoBroadcast.plan    |  176 ---
 .../testLeftOuterJoin2.result                   |    7 -
 .../testLeftOuterJoin3.Hash.plan                |  160 --
 .../testLeftOuterJoin3.Hash_NoBroadcast.plan    |  272 ----
 .../testLeftOuterJoin3.Sort.plan                |  160 --
 .../testLeftOuterJoin3.Sort_NoBroadcast.plan    |  272 ----
 .../testLeftOuterJoin3.result                   |    9 -
 ...tLeftOuterJoinLeftSideSmallTable.1.Hash.plan |  105 --
 ...inLeftSideSmallTable.1.Hash_NoBroadcast.plan |  105 --
 ...tLeftOuterJoinLeftSideSmallTable.1.Sort.plan |  105 --
 ...inLeftSideSmallTable.1.Sort_NoBroadcast.plan |  105 --
 ...testLeftOuterJoinLeftSideSmallTable.1.result |    7 -
 ...tOuterJoinPredicationCaseByCase1.1.Hash.plan |   72 -
 ...edicationCaseByCase1.1.Hash_NoBroadcast.plan |  128 --
 ...tOuterJoinPredicationCaseByCase1.1.Sort.plan |   72 -
 ...edicationCaseByCase1.1.Sort_NoBroadcast.plan |  128 --
 ...LeftOuterJoinPredicationCaseByCase1.1.result |    7 -
 ...tOuterJoinPredicationCaseByCase2.1.Hash.plan |  122 --
 ...edicationCaseByCase2.1.Hash_NoBroadcast.plan |  176 ---
 ...tOuterJoinPredicationCaseByCase2.1.Sort.plan |  122 --
 ...edicationCaseByCase2.1.Sort_NoBroadcast.plan |  176 ---
 ...LeftOuterJoinPredicationCaseByCase2.1.result |    4 -
 ...uterJoinPredicationCaseByCase2_1.1.Hash.plan |   97 --
 ...icationCaseByCase2_1.1.Hash_NoBroadcast.plan |  182 ---
 ...uterJoinPredicationCaseByCase2_1.1.Sort.plan |   97 --
 ...icationCaseByCase2_1.1.Sort_NoBroadcast.plan |  182 ---
 ...ftOuterJoinPredicationCaseByCase2_1.1.result |    5 -
 ...tOuterJoinPredicationCaseByCase3.1.Hash.plan |   72 -
 ...edicationCaseByCase3.1.Hash_NoBroadcast.plan |  128 --
 ...tOuterJoinPredicationCaseByCase3.1.Sort.plan |   72 -
 ...edicationCaseByCase3.1.Sort_NoBroadcast.plan |  128 --
 ...LeftOuterJoinPredicationCaseByCase3.1.result |    7 -
 ...tOuterJoinPredicationCaseByCase4.1.Hash.plan |   74 -
 ...edicationCaseByCase4.1.Hash_NoBroadcast.plan |  130 --
 ...tOuterJoinPredicationCaseByCase4.1.Sort.plan |   74 -
 ...edicationCaseByCase4.1.Sort_NoBroadcast.plan |  130 --
 ...LeftOuterJoinPredicationCaseByCase4.1.result |    7 -
 ...tOuterJoinPredicationCaseByCase5.1.Hash.plan |   74 -
 ...edicationCaseByCase5.1.Hash_NoBroadcast.plan |  130 --
 ...tOuterJoinPredicationCaseByCase5.1.Sort.plan |   74 -
 ...edicationCaseByCase5.1.Sort_NoBroadcast.plan |  130 --
 ...LeftOuterJoinPredicationCaseByCase5.1.result |    6 -
 ...tOuterJoinPredicationCaseByCase6.1.Hash.plan |   76 -
 ...edicationCaseByCase6.1.Hash_NoBroadcast.plan |  132 --
 ...tOuterJoinPredicationCaseByCase6.1.Sort.plan |   76 -
 ...edicationCaseByCase6.1.Sort_NoBroadcast.plan |  132 --
 ...LeftOuterJoinPredicationCaseByCase6.1.result |    3 -
 ...testLeftOuterJoinWithConstantExpr1.Hash.plan |   86 --
 ...rJoinWithConstantExpr1.Hash_NoBroadcast.plan |  113 --
 ...testLeftOuterJoinWithConstantExpr1.Sort.plan |   86 --
 ...rJoinWithConstantExpr1.Sort_NoBroadcast.plan |  113 --
 .../testLeftOuterJoinWithConstantExpr1.result   |    7 -
 ...testLeftOuterJoinWithConstantExpr4.Hash.plan |   63 -
 ...rJoinWithConstantExpr4.Hash_NoBroadcast.plan |   90 --
 ...testLeftOuterJoinWithConstantExpr4.Sort.plan |   63 -
 ...rJoinWithConstantExpr4.Sort_NoBroadcast.plan |   90 --
 .../testLeftOuterJoinWithConstantExpr4.result   |    7 -
 ...testLeftOuterJoinWithConstantExpr5.Hash.plan |   65 -
 ...rJoinWithConstantExpr5.Hash_NoBroadcast.plan |   92 --
 ...testLeftOuterJoinWithConstantExpr5.Sort.plan |   65 -
 ...rJoinWithConstantExpr5.Sort_NoBroadcast.plan |   92 --
 .../testLeftOuterJoinWithConstantExpr5.result   |    6 -
 .../testLeftOuterJoinWithEmptyTable1.Hash.plan  |   78 -
 ...terJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 --
 .../testLeftOuterJoinWithEmptyTable1.Sort.plan  |   78 -
 ...terJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 --
 .../testLeftOuterJoinWithEmptyTable1.result     |    7 -
 .../testLeftOuterJoinWithEmptyTable2.Hash.plan  |  109 --
 ...terJoinWithEmptyTable2.Hash_NoBroadcast.plan |  136 --
 .../testLeftOuterJoinWithEmptyTable2.Sort.plan  |  109 --
 ...terJoinWithEmptyTable2.Sort_NoBroadcast.plan |  136 --
 .../testLeftOuterJoinWithEmptyTable2.result     |    7 -
 .../testLeftOuterJoinWithEmptyTable3.Hash.plan  |  160 --
 ...terJoinWithEmptyTable3.Hash_NoBroadcast.plan |  187 ---
 .../testLeftOuterJoinWithEmptyTable3.Sort.plan  |  160 --
 ...terJoinWithEmptyTable3.Sort_NoBroadcast.plan |  187 ---
 .../testLeftOuterJoinWithEmptyTable3.result     |    7 -
 .../testLeftOuterJoinWithEmptyTable4.Hash.plan  |  160 --
 ...terJoinWithEmptyTable4.Hash_NoBroadcast.plan |  214 ---
 .../testLeftOuterJoinWithEmptyTable4.Sort.plan  |  160 --
 ...terJoinWithEmptyTable4.Sort_NoBroadcast.plan |  214 ---
 .../testLeftOuterJoinWithEmptyTable4.result     |    4 -
 .../testLeftOuterJoinWithEmptyTable5.Hash.plan  |  109 --
 ...terJoinWithEmptyTable5.Hash_NoBroadcast.plan |  136 --
 .../testLeftOuterJoinWithEmptyTable5.Sort.plan  |  109 --
 ...terJoinWithEmptyTable5.Sort_NoBroadcast.plan |  136 --
 .../testLeftOuterJoinWithEmptyTable5.result     |    4 -
 .../testLeftOuterJoinWithNull1.Hash.plan        |   82 -
 ...LeftOuterJoinWithNull1.Hash_NoBroadcast.plan |  109 --
 .../testLeftOuterJoinWithNull1.Sort.plan        |   82 -
 ...LeftOuterJoinWithNull1.Sort_NoBroadcast.plan |  109 --
 .../testLeftOuterJoinWithNull1.result           |    4 -
 .../testLeftOuterJoinWithNull2.Hash.plan        |   82 -
 ...LeftOuterJoinWithNull2.Hash_NoBroadcast.plan |  109 --
 .../testLeftOuterJoinWithNull2.Sort.plan        |   82 -
 ...LeftOuterJoinWithNull2.Sort_NoBroadcast.plan |  109 --
 .../testLeftOuterJoinWithNull2.result           |    4 -
 .../testLeftOuterJoinWithNull3.Hash.plan        |   82 -
 ...LeftOuterJoinWithNull3.Hash_NoBroadcast.plan |  109 --
 .../testLeftOuterJoinWithNull3.Sort.plan        |   82 -
 ...LeftOuterJoinWithNull3.Sort_NoBroadcast.plan |  109 --
 .../testLeftOuterJoinWithNull3.result           |    2 -
 ...rJoinWithThetaJoinConditionInWhere.Hash.plan |   57 -
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   84 --
 ...rJoinWithThetaJoinConditionInWhere.Sort.plan |   57 -
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   84 --
 ...uterJoinWithThetaJoinConditionInWhere.result |    4 -
 .../testLeftOuterWithEmptyTable.1.Hash.plan     |   53 -
 ...tOuterWithEmptyTable.1.Hash_NoBroadcast.plan |   80 -
 .../testLeftOuterWithEmptyTable.1.Sort.plan     |   53 -
 ...tOuterWithEmptyTable.1.Sort_NoBroadcast.plan |   80 -
 .../testLeftOuterWithEmptyTable.1.result        |    7 -
 ...pleBroadcastDataFileWithZeroLength.Hash.plan |   57 -
 ...DataFileWithZeroLength.Hash_NoBroadcast.plan |   84 --
 ...pleBroadcastDataFileWithZeroLength.Sort.plan |   57 -
 ...DataFileWithZeroLength.Sort_NoBroadcast.plan |   84 --
 ...ltipleBroadcastDataFileWithZeroLength.result |    2 -
 ...leBroadcastDataFileWithZeroLength2.Hash.plan |   76 -
 ...ataFileWithZeroLength2.Hash_NoBroadcast.plan |  132 --
 ...leBroadcastDataFileWithZeroLength2.Sort.plan |   76 -
 ...ataFileWithZeroLength2.Sort_NoBroadcast.plan |  132 --
 ...tipleBroadcastDataFileWithZeroLength2.result |    7 -
 .../testOuterJoinAndCaseWhen1.Hash.plan         |  126 --
 ...tOuterJoinAndCaseWhen1.Hash_NoBroadcast.plan |  153 --
 .../testOuterJoinAndCaseWhen1.Sort.plan         |  126 --
 ...tOuterJoinAndCaseWhen1.Sort_NoBroadcast.plan |  153 --
 .../testOuterJoinAndCaseWhen1.result            |    7 -
 .../testRightOuterJoin1.Hash.plan               |   78 -
 .../testRightOuterJoin1.Hash_NoBroadcast.plan   |  105 --
 .../testRightOuterJoin1.Sort.plan               |   78 -
 .../testRightOuterJoin1.Sort_NoBroadcast.plan   |  105 --
 .../testRightOuterJoin1.result                  |    7 -
 ...tOuterJoinPredicationCaseByCase1.1.Hash.plan |  101 --
 ...edicationCaseByCase1.1.Hash_NoBroadcast.plan |  128 --
 ...tOuterJoinPredicationCaseByCase1.1.Sort.plan |  101 --
 ...edicationCaseByCase1.1.Sort_NoBroadcast.plan |  128 --
 ...ightOuterJoinPredicationCaseByCase1.1.result |    4 -
 ...tOuterJoinPredicationCaseByCase2.1.Hash.plan |   76 -
 ...edicationCaseByCase2.1.Hash_NoBroadcast.plan |  132 --
 ...tOuterJoinPredicationCaseByCase2.1.Sort.plan |   76 -
 ...edicationCaseByCase2.1.Sort_NoBroadcast.plan |  132 --
 ...ightOuterJoinPredicationCaseByCase2.1.result |    4 -
 ...tOuterJoinPredicationCaseByCase3.1.Hash.plan |  101 --
 ...edicationCaseByCase3.1.Hash_NoBroadcast.plan |  128 --
 ...tOuterJoinPredicationCaseByCase3.1.Sort.plan |  101 --
 ...edicationCaseByCase3.1.Sort_NoBroadcast.plan |  128 --
 ...ightOuterJoinPredicationCaseByCase3.1.result |    4 -
 .../testRightOuterJoinWithEmptyTable1.Hash.plan |   78 -
 ...terJoinWithEmptyTable1.Hash_NoBroadcast.plan |  105 --
 .../testRightOuterJoinWithEmptyTable1.Sort.plan |   78 -
 ...terJoinWithEmptyTable1.Sort_NoBroadcast.plan |  105 --
 .../testRightOuterJoinWithEmptyTable1.result    |    7 -
 ...rJoinWithThetaJoinConditionInWhere.Hash.plan |   57 -
 ...taJoinConditionInWhere.Hash_NoBroadcast.plan |   84 --
 ...rJoinWithThetaJoinConditionInWhere.Sort.plan |   57 -
 ...taJoinConditionInWhere.Sort_NoBroadcast.plan |   84 --
 ...uterJoinWithThetaJoinConditionInWhere.result |    4 -
 ...terJoinWithEmptyIntermediateData.1.Hash.plan |  108 --
 ...mptyIntermediateData.1.Hash_NoBroadcast.plan |  108 --
 ...terJoinWithEmptyIntermediateData.1.Sort.plan |  108 --
 ...mptyIntermediateData.1.Sort_NoBroadcast.plan |  108 --
 ...lOuterJoinWithEmptyIntermediateData.1.result |    2 -
 .../testJoinWithDifferentShuffleKey.1.Hash.plan |  199 ---
 ...hDifferentShuffleKey.1.Hash_NoBroadcast.plan |  199 ---
 .../testJoinWithDifferentShuffleKey.1.Sort.plan |  199 ---
 ...hDifferentShuffleKey.1.Sort_NoBroadcast.plan |  199 ---
 .../testJoinWithDifferentShuffleKey.1.result    |    3 -
 ...testLeftOuterJoinWithConstantExpr2.Hash.plan |   98 --
 ...rJoinWithConstantExpr2.Hash_NoBroadcast.plan |  125 --
 ...testLeftOuterJoinWithConstantExpr2.Sort.plan |   98 --
 ...rJoinWithConstantExpr2.Sort_NoBroadcast.plan |  125 --
 .../testLeftOuterJoinWithConstantExpr2.result   |    7 -
 ...testLeftOuterJoinWithConstantExpr3.Hash.plan |  156 --
 ...rJoinWithConstantExpr3.Hash_NoBroadcast.plan |  156 --
 ...testLeftOuterJoinWithConstantExpr3.Sort.plan |  156 --
 ...rJoinWithConstantExpr3.Sort_NoBroadcast.plan |  156 --
 .../testLeftOuterJoinWithConstantExpr3.result   |    7 -
 ...tLeftOuterJoinWithEmptySubquery1.1.Hash.plan |  111 --
 ...inWithEmptySubquery1.1.Hash_NoBroadcast.plan |  167 ---
 ...tLeftOuterJoinWithEmptySubquery1.1.Sort.plan |  111 --
 ...inWithEmptySubquery1.1.Sort_NoBroadcast.plan |  167 ---
 ...testLeftOuterJoinWithEmptySubquery1.1.result |    7 -
 ...tLeftOuterJoinWithEmptySubquery2.1.Hash.plan |   86 --
 ...inWithEmptySubquery2.1.Hash_NoBroadcast.plan |  142 --
 ...tLeftOuterJoinWithEmptySubquery2.1.Sort.plan |   86 --
 ...inWithEmptySubquery2.1.Sort_NoBroadcast.plan |  142 --
 ...testLeftOuterJoinWithEmptySubquery2.1.result |    2 -
 .../TestQueryUnitStatusUpdate/case3.result      |    4 -
 .../create_table_nested_1.result                |   40 -
 .../create_table_nested_2.result                |   57 -
 .../results/TestSQLAnalyzer/setcatalog1.result  |    5 -
 .../results/TestSQLAnalyzer/setcatalog2.result  |    5 -
 .../results/TestSQLAnalyzer/setsession1.result  |    5 -
 .../results/TestSQLAnalyzer/setsession2.result  |    5 -
 .../results/TestSQLAnalyzer/setsession3.result  |    5 -
 .../results/TestSQLAnalyzer/setsession4.result  |    5 -
 .../results/TestSQLAnalyzer/setsession5.result  |    5 -
 .../results/TestSQLAnalyzer/setsession6.result  |    5 -
 .../results/TestSQLAnalyzer/setsession7.result  |    5 -
 .../results/TestSQLAnalyzer/settimezone1.result |    5 -
 .../results/TestSQLAnalyzer/settimezone2.result |    5 -
 .../results/TestSQLAnalyzer/settimezone3.result |    4 -
 .../results/TestSQLAnalyzer/window1.result      |   37 -
 .../results/TestSQLAnalyzer/window2.result      |   44 -
 .../results/TestSQLAnalyzer/window3.result      |   50 -
 .../results/TestSQLAnalyzer/window4.result      |   48 -
 .../results/TestSQLAnalyzer/window5.result      |   77 -
 .../results/TestSQLAnalyzer/window6.result      |   83 --
 .../results/TestSQLAnalyzer/window7.result      |   81 -
 .../results/TestSQLAnalyzer/window8.result      |   86 --
 .../results/TestSQLAnalyzer/window9.result      |   56 -
 .../testInsertType1.result                      |    5 -
 .../testInsertType2.result                      |    5 -
 .../testNestedFieldAsGroupbyKey1.result         |    6 -
 .../testNestedFieldAsJoinKey1.result            |    6 -
 .../TestSelectNestedRecord/testSelect0.result   |    5 -
 .../TestSelectNestedRecord/testSelect1.result   |    5 -
 .../TestSelectNestedRecord/testSelect2.result   |    6 -
 .../TestSelectNestedRecord/testSelect3.result   |    3 -
 .../results/TestSelectQuery/testCaseWhen.result |    7 -
 .../TestSelectQuery/testCaseWhenRound.result    |   22 -
 .../testCaseWhenWithoutElse.result              |    7 -
 ...estColumnEqualityButNotJoinCondition1.result |    3 -
 ...estColumnEqualityButNotJoinCondition2.result |    6 -
 .../TestSelectQuery/testDatabaseRef.result      |    7 -
 .../TestSelectQuery/testExplainSelect.result    |    6 -
 .../testExplainSelectPhysical.1.result          |   26 -
 .../testExplainSelectPhysical.2.result          |   88 --
 .../testExplainSelectPhysical.3.result          |   89 --
 .../results/TestSelectQuery/testInClause.result |    5 -
 .../TestSelectQuery/testInStrClause.result      |    4 -
 .../TestSelectQuery/testLikeClause.result       |    9 -
 .../results/TestSelectQuery/testLimit.result    |    5 -
 .../testMultiBytesDelimiter1.result             |    7 -
 .../testMultiBytesDelimiter2.result             |    7 -
 .../testMultiBytesDelimiter3.result             |    7 -
 .../testMultiBytesDelimiter4.result             |    7 -
 .../testNestedPythonFunction.result             |    7 -
 .../TestSelectQuery/testNonFromSelect1.result   |    3 -
 .../testNonQualifiedNames.result                |    7 -
 .../results/TestSelectQuery/testNotEqual.result |    5 -
 .../TestSelectQuery/testNotInClause.result      |    4 -
 .../TestSelectQuery/testNotInStrClause.result   |    4 -
 .../TestSelectQuery/testRealValueCompare.result |    3 -
 .../results/TestSelectQuery/testSelect.result   |    7 -
 .../results/TestSelectQuery/testSelect2.result  |    7 -
 .../results/TestSelectQuery/testSelect3.result  |    7 -
 .../TestSelectQuery/testSelectAsterisk1.result  |    7 -
 .../TestSelectQuery/testSelectAsterisk2.result  |    3 -
 .../TestSelectQuery/testSelectAsterisk3.result  |    3 -
 .../TestSelectQuery/testSelectAsterisk4.result  |    7 -
 .../TestSelectQuery/testSelectAsterisk5.result  |    3 -
 .../testSelectColumnAlias1.result               |    7 -
 ...tSelectColumnAliasExistingInRelation1.result |    4 -
 ...tSelectColumnAliasExistingInRelation2.result |    7 -
 ...tSelectColumnAliasExistingInRelation3.result |   11 -
 .../TestSelectQuery/testSelectDistinct.result   |    7 -
 .../testSelectOnSessionTable.result             |    3 -
 .../testSelectPythonFuncs.result                |    7 -
 ...lectSameConstantsWithDifferentAliases.result |    7 -
 ...ectSameConstantsWithDifferentAliases2.result |    7 -
 ...ectSameConstantsWithDifferentAliases3.result |    7 -
 ...stSelectSameExprsWithDifferentAliases.result |    7 -
 .../testSelectWithCommonQuals1.1.plan           |    7 -
 .../testSelectWithCommonQuals1.1.result         |   27 -
 .../testSelectWithCommonQuals2.1.plan           |    7 -
 .../testSelectWithCommonQuals2.1.result         |   27 -
 .../testSelectWithCommonQuals3.1.plan           |    7 -
 .../testSelectWithCommonQuals3.1.result         |    7 -
 .../TestSelectQuery/testSelectWithJson.result   |    7 -
 .../testSelectWithParentheses1.result           |    3 -
 .../testSelectWithParentheses2.result           |    3 -
 .../testSelectWithPredicateOnPythonFunc.result  |   17 -
 .../TestSelectQuery/testSimpleQuery.result      |    7 -
 .../testSimpleQueryWithLimit.result             |    5 -
 ...tSimpleQueryWithLimitPartitionedTable.result |   12 -
 .../TestSelectQuery/testStringCompare.result    |    5 -
 .../TestSelectQuery/testSumFloatOverflow.result |    3 -
 .../TestSelectQuery/testSumIntOverflow.result   |    3 -
 .../TestSelectQuery/testTimezonedTable1.result  |    5 -
 .../TestSelectQuery/testTimezonedTable2.result  |    5 -
 .../TestSelectQuery/testTimezonedTable3.result  |    5 -
 .../results/TestSelectQuery/testUnion1.result   |   10 -
 .../results/TestSelectQuery/testUnion2.result   |   12 -
 .../TestSelectQuery/testWhereCond1.result       |    3 -
 .../TestSelectQuery/testWhereCond2.result       |    3 -
 .../testWhereCondWithAlias1.result              |    4 -
 .../testWhereCondWithAlias2.result              |    4 -
 .../results/TestSortQuery/testAsterisk.result   |    7 -
 .../results/TestSortQuery/testSort.result       |    7 -
 .../TestSortQuery/testSortAfterGroupby.result   |    5 -
 .../testSortAfterGroupbyWithAlias.result        |    5 -
 .../results/TestSortQuery/testSortDesc.result   |    7 -
 .../TestSortQuery/testSortFirstDesc.result      |   10 -
 .../TestSortQuery/testSortOnNullColumn.result   |    6 -
 .../testSortOnUnicodeTextAsc.result             |    6 -
 .../testSortOnUnicodeTextDesc.result            |    6 -
 .../TestSortQuery/testSortWithAlias1.result     |    7 -
 .../TestSortQuery/testSortWithAlias2.result     |    5 -
 .../TestSortQuery/testSortWithAlias3.result     |    7 -
 .../testSortWithAliasButOriginalName.result     |    7 -
 .../testSortWithAscDescKeys.result              |   26 -
 .../TestSortQuery/testSortWithConstKeys.result  |    7 -
 .../TestSortQuery/testSortWithDate.result       |    7 -
 .../TestSortQuery/testSortWithExpr1.result      |    7 -
 .../TestSortQuery/testSortWithExpr2.result      |    7 -
 .../TestSortQuery/testSortWithJson.result       |    5 -
 .../testSubQuerySortAfterGroupMultiBlocks.plan  |  112 --
 ...testSubQuerySortAfterGroupMultiBlocks.result |    5 -
 .../results/TestSortQuery/testTopK.result       |    5 -
 .../TestSortQuery/testTopkWithJson.result       |    5 -
 .../results/TestTPCH/testFirstJoinInQ7.plan     |  156 --
 .../results/TestTPCH/testFirstJoinInQ7.result   |    4 -
 .../results/TestTPCH/testQ1OrderBy.plan         |   88 --
 .../results/TestTPCH/testQ1OrderBy.result       |    4 -
 .../results/TestTPCH/testQ2FourJoins.plan       |  228 ---
 .../results/TestTPCH/testQ2FourJoins.result     |    3 -
 .../results/TestTPCH/testTPCH14Expr.plan        |  119 --
 .../results/TestTPCH/testTPCH14Expr.result      |    3 -
 .../resources/results/TestTPCH/testTPCHQ5.plan  |  332 -----
 .../results/TestTPCH/testTPCHQ5.result          |    2 -
 .../TestSpecialCharPartitionKeys1.result        |    4 -
 .../TestSpecialCharPartitionKeys2.result        |    3 -
 .../results/TestTablePartitions/case1.result    |    4 -
 .../results/TestTablePartitions/case10.result   |    7 -
 .../results/TestTablePartitions/case11.result   |    7 -
 .../results/TestTablePartitions/case12.result   |    7 -
 .../results/TestTablePartitions/case13.result   |    7 -
 .../results/TestTablePartitions/case14.result   |    3 -
 .../results/TestTablePartitions/case15.result   |    3 -
 .../results/TestTablePartitions/case2.result    |    6 -
 .../results/TestTablePartitions/case3.result    |    5 -
 .../results/TestTablePartitions/case4.result    |    7 -
 .../results/TestTablePartitions/case5.result    |    7 -
 .../results/TestTablePartitions/case6.result    |    7 -
 .../results/TestTablePartitions/case7.result    |    5 -
 .../results/TestTablePartitions/case8.result    |    7 -
 .../results/TestTablePartitions/case9.result    |    7 -
 ...rtitionedTableWithSmallerExpressions5.result |    7 -
 ...rtitionedTableWithSmallerExpressions6.result |    4 -
 .../testGroupBySubQuery.result                  |    3 -
 .../testGroupbySubqueryWithJson.result          |    3 -
 .../TestTableSubQuery/testJoinSubQuery.result   |    4 -
 .../TestTableSubQuery/testJoinSubQuery2.result  |    4 -
 .../testJoinSubqueryWithJson.result             |    4 -
 .../TestTableSubQuery/testTableSubquery1.result |    7 -
 .../testAlterTableAddDropPartition.result       |    9 -
 .../results/TestTajoCli/testDescTable.result    |   27 -
 .../testDescTableForNestedSchema.result         |   29 -
 .../TestTajoCli/testHelpSessionVars.result      |   44 -
 .../testLocalQueryWithoutFrom.result            |    8 -
 .../TestTajoCli/testNonForwardQueryPause.result |    6 -
 .../testSelectResultWithNullFalse.result        |    8 -
 .../testSelectResultWithNullTrue.result         |    8 -
 ...estSelectResultWithNullTrueDeprecated.result |    9 -
 .../results/TestTajoCli/testSetTimezone1.result |    4 -
 .../TestTajoCli/testStopWhenError.result        |    5 -
 .../testStopWhenErrorDeprecated.result          |    6 -
 .../testQueryFailure.result                     |    0
 .../TestTajoCliNegatives/testQuerySyntax.result |    3 -
 .../testExecuteQueryAsync.result                |    7 -
 .../testExecuteQueryAsyncWithListener.result    |    2 -
 .../testExecuteQueryType1.result                |    7 -
 .../testExecuteQueryType2.result                |    4 -
 .../testExecuteQueryType3.result                |    4 -
 .../TestTajoDatabaseMetaData/getSchemas1.result |    3 -
 .../TestTajoDatabaseMetaData/getSchemas2.result |    3 -
 .../getTableTypes.result                        |    3 -
 .../TestTajoDatabaseMetaData/getTables1.result  |    4 -
 .../TestTajoDatabaseMetaData/getTables2.result  |    4 -
 .../results/TestTajoDump/testDump1.result       |   16 -
 .../results/TestTajoDump/testDump2.result       |   16 -
 .../results/TestTajoDump/testDump3.result       |   20 -
 .../TestTajoJdbc/testSortWithDateTime.result    |    7 -
 .../TestUnionQuery/testComplexUnion1.plan       |   80 -
 .../TestUnionQuery/testComplexUnion1.result     |    6 -
 .../TestUnionQuery/testComplexUnion2.plan       |  116 --
 .../TestUnionQuery/testComplexUnion2.result     |    7 -
 .../results/TestUnionQuery/testUnion1.result    |    7 -
 .../results/TestUnionQuery/testUnion10.result   |    7 -
 .../results/TestUnionQuery/testUnion11.result   |    3 -
 .../results/TestUnionQuery/testUnion12.result   |    7 -
 .../results/TestUnionQuery/testUnion13.result   |    7 -
 .../results/TestUnionQuery/testUnion14.result   |    9 -
 .../results/TestUnionQuery/testUnion15.result   |    5 -
 .../results/TestUnionQuery/testUnion16.result   |    5 -
 .../results/TestUnionQuery/testUnion2.result    |    5 -
 .../results/TestUnionQuery/testUnion3.result    |    4 -
 .../results/TestUnionQuery/testUnion4.result    |    3 -
 .../results/TestUnionQuery/testUnion5.result    |    3 -
 .../results/TestUnionQuery/testUnion6.result    |    3 -
 .../results/TestUnionQuery/testUnion7.result    |    5 -
 .../results/TestUnionQuery/testUnion8.result    |    3 -
 .../results/TestUnionQuery/testUnion9.result    |    7 -
 .../results/TestUnionQuery/testUnionAll1.result |   10 -
 .../TestUnionQuery/testUnionAll10.result        |   22 -
 .../TestUnionQuery/testUnionAll11.result        |    3 -
 .../TestUnionQuery/testUnionAll12.result        |    7 -
 .../TestUnionQuery/testUnionAll13.result        |    7 -
 .../TestUnionQuery/testUnionAll14.result        |    9 -
 .../TestUnionQuery/testUnionAll15.result        |    5 -
 .../TestUnionQuery/testUnionAll16.result        |    5 -
 .../results/TestUnionQuery/testUnionAll2.result |   12 -
 .../results/TestUnionQuery/testUnionAll3.result |    4 -
 .../results/TestUnionQuery/testUnionAll4.result |    3 -
 .../results/TestUnionQuery/testUnionAll5.result |    3 -
 .../results/TestUnionQuery/testUnionAll6.result |    3 -
 .../results/TestUnionQuery/testUnionAll7.result |   12 -
 .../results/TestUnionQuery/testUnionAll8.result |    3 -
 .../results/TestUnionQuery/testUnionAll9.result |    7 -
 .../testUnionAllWithDifferentAlias.result       |    4 -
 ...UnionAllWithDifferentAliasAndFunction.result |    7 -
 .../testUnionAllWithSameAliasNames.result       |   12 -
 .../testUnionWithDifferentAlias.result          |    4 -
 ...estUnionWithDifferentAliasAndFunction.result |    7 -
 .../testUnionWithSameAliasNames.result          |    5 -
 .../TestWindowQuery/testComplexOrderBy1.result  |    7 -
 .../TestWindowQuery/testFirstValue1.result      |    7 -
 .../results/TestWindowQuery/testLag1.result     |    7 -
 .../TestWindowQuery/testLagWithDefault.result   |    7 -
 .../TestWindowQuery/testLagWithNoArgs.result    |    7 -
 .../TestWindowQuery/testLastValue1.result       |    7 -
 .../results/TestWindowQuery/testLead1.result    |    7 -
 .../TestWindowQuery/testLeadWithDefault.result  |    7 -
 .../TestWindowQuery/testLeadWithNoArgs.result   |    7 -
 .../TestWindowQuery/testRowNumber1.result       |    7 -
 .../TestWindowQuery/testRowNumber2.result       |    7 -
 .../TestWindowQuery/testRowNumber3.result       |    7 -
 .../TestWindowQuery/testStdDevPop1.result       |    7 -
 .../TestWindowQuery/testStdDevSamp1.result      |    7 -
 .../results/TestWindowQuery/testWindow1.result  |    7 -
 .../results/TestWindowQuery/testWindow2.result  |    7 -
 .../results/TestWindowQuery/testWindow3.result  |    7 -
 .../results/TestWindowQuery/testWindow4.result  |    7 -
 .../results/TestWindowQuery/testWindow5.result  |    7 -
 .../results/TestWindowQuery/testWindow6.result  |    7 -
 .../results/TestWindowQuery/testWindow7.result  |    7 -
 .../results/TestWindowQuery/testWindow8.result  |    7 -
 .../testWindowBeforeLimit.result                |    5 -
 .../testWindowWithAggregation1.result           |    3 -
 .../testWindowWithAggregation2.result           |    5 -
 .../testWindowWithAggregation3.result           |    3 -
 .../testWindowWithAggregation4.result           |    5 -
 .../testWindowWithAggregation5.result           |    5 -
 .../testWindowWithAggregation6.result           |    5 -
 .../testWindowWithOrderBy1.result               |    7 -
 .../testWindowWithOrderBy2.result               |    7 -
 .../testWindowWithOrderBy3.result               |    7 -
 .../testWindowWithOrderBy4.result               |    7 -
 .../testWindowWithOrderBy5.result               |    7 -
 .../testWindowWithSubQuery.result               |    7 -
 .../testWindowWithSubQuery2.result              |    5 -
 .../testWindowWithSubQuery3.result              |    7 -
 .../testWindowWithSubQuery4.result              |    7 -
 .../testWindowWithSubQuery5.result              |    5 -
 .../testWindowWithSubQuery6.result              |    3 -
 .../testBuildDDLForBaseTable.result             |    4 -
 .../testBuildDDLForExternalTable.result         |    5 -
 .../testBuildDDLQuotedTableName1.result         |    5 -
 .../testBuildDDLQuotedTableName2.result         |    4 -
 tajo-core/src/test/resources/yarn-site.xml      |   25 -
 tajo-core/src/test/tpch/customer.tbl            |    5 -
 tajo-core/src/test/tpch/empty_orders.tbl        |    0
 tajo-core/src/test/tpch/lineitem.tbl            |    5 -
 tajo-core/src/test/tpch/nation.tbl              |   25 -
 tajo-core/src/test/tpch/orders.tbl              |    3 -
 tajo-core/src/test/tpch/part.tbl                |    4 -
 tajo-core/src/test/tpch/partsupp.tbl            |    3 -
 tajo-core/src/test/tpch/region.tbl              |    5 -
 tajo-core/src/test/tpch/supplier.tbl            |    3 -
 tajo-project/pom.xml                            |   19 +-
 3480 files changed, 95869 insertions(+), 95392 deletions(-)
----------------------------------------------------------------------



[03/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..cbd07fc
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.Sort_NoBroadcast.plan
@@ -0,0 +1,328 @@
+explain
+-------------------------------
+GROUP_BY(18)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         TABLE_SUBQUERY(14) as default.f
+           => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+            GROUP_BY(12)(l_orderkey)
+              => exprs: (avg(default.e.l_quantity (FLOAT8)))
+              => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+              => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+              => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+               TABLE_SUBQUERY(11) as default.e
+                 => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+                 => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                 => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+                  JOIN(22)(INNER)
+                    => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+                    => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+                    => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+                    => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                     SCAN(8) on default.part
+                       => target list: default.part.p_partkey (INT4)
+                       => out schema: {(1) default.part.p_partkey (INT4)}
+                       => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                     SCAN(7) on default.lineitem as d
+                       => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+                       => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+                       => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+         JOIN(23)(INNER)
+           => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+           => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+            SCAN(5) on default.orders as c
+              => filter: default.c.o_orderkey (INT4) > 0
+              => target list: default.c.o_orderkey (INT4)
+              => out schema: {(1) default.c.o_orderkey (INT4)}
+              => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+            TABLE_SUBQUERY(4) as default.b
+              => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+              => out schema: {(2) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+              => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+               JOIN(21)(INNER)
+                 => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+                 => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+                 => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+                 => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+                  SCAN(1) on default.part
+                    => target list: default.part.p_partkey (INT4)
+                    => out schema: {(1) default.part.p_partkey (INT4)}
+                    => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+                  SCAN(0) on default.lineitem as a
+                    => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+                    => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+                    => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000012)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000012
+   |-eb_0000000000000_0000_000011
+      |-eb_0000000000000_0000_000010
+         |-eb_0000000000000_0000_000009
+            |-eb_0000000000000_0000_000008
+               |-eb_0000000000000_0000_000007
+               |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+12: eb_0000000000000_0000_000012
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.a.l_partkey (INT4), num=32)
+
+SCAN(0) on default.lineitem as a
+  => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)
+  => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+  => in schema: {(16) default.a.l_comment (TEXT), default.a.l_commitdate (TEXT), default.a.l_discount (FLOAT8), default.a.l_extendedprice (FLOAT8), default.a.l_linenumber (INT4), default.a.l_linestatus (TEXT), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_receiptdate (TEXT), default.a.l_returnflag (TEXT), default.a.l_shipdate (TEXT), default.a.l_shipinstruct (TEXT), default.a.l_shipmode (TEXT), default.a.l_suppkey (INT4), default.a.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(1) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.a.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.b.l_orderkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.b
+  => Targets: default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)
+  => out schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+  => in  schema: {(3) default.b.l_linenumber (INT4), default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8)}
+   PROJECTION(3)
+     => Targets: default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8), default.a.l_linenumber (INT4)
+     => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+     => in  schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+      JOIN(21)(INNER)
+        => Join Cond: default.a.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)
+        => out schema: {(3) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_quantity (FLOAT8)}
+        => in schema: {(5) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+         SCAN(27) on eb_0000000000000_0000_000002
+           => out schema: {(1) default.part.p_partkey (INT4)}
+           => in schema: {(1) default.part.p_partkey (INT4)}
+         SCAN(26) on eb_0000000000000_0000_000001
+           => out schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+           => in schema: {(4) default.a.l_linenumber (INT4), default.a.l_orderkey (INT4), default.a.l_partkey (INT4), default.a.l_quantity (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+
+SCAN(5) on default.orders as c
+  => filter: default.c.o_orderkey (INT4) > 0
+  => target list: default.c.o_orderkey (INT4)
+  => out schema: {(1) default.c.o_orderkey (INT4)}
+  => in schema: {(9) default.c.o_clerk (TEXT), default.c.o_comment (TEXT), default.c.o_custkey (INT4), default.c.o_orderdate (TEXT), default.c.o_orderkey (INT4), default.c.o_orderpriority (TEXT), default.c.o_orderstatus (TEXT), default.c.o_shippriority (INT4), default.c.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.d.l_partkey (INT4), num=32)
+
+SCAN(7) on default.lineitem as d
+  => target list: default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)
+  => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+  => in schema: {(16) default.d.l_comment (TEXT), default.d.l_commitdate (TEXT), default.d.l_discount (FLOAT8), default.d.l_extendedprice (FLOAT8), default.d.l_linenumber (INT4), default.d.l_linestatus (TEXT), default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.d.l_receiptdate (TEXT), default.d.l_returnflag (TEXT), default.d.l_shipdate (TEXT), default.d.l_shipinstruct (TEXT), default.d.l_shipmode (TEXT), default.d.l_suppkey (INT4), default.d.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(8) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.b.l_orderkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 10 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+
+JOIN(23)(INNER)
+  => Join Cond: default.c.o_orderkey (INT4) = default.b.l_orderkey (INT4)
+  => target list: default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)
+  => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+  => in schema: {(3) default.b.l_orderkey (INT4), default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+   SCAN(29) on eb_0000000000000_0000_000004
+     => out schema: {(1) default.c.o_orderkey (INT4)}
+     => in schema: {(1) default.c.o_orderkey (INT4)}
+   SCAN(28) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+     => in schema: {(2) default.b.l_quantity (FLOAT8), default.b.l_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.d.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+GROUP_BY(32)(l_orderkey)
+  => exprs: (avg(default.e.l_quantity (FLOAT8)))
+  => target list: default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)
+  => out schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+  => in schema:{(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+   TABLE_SUBQUERY(11) as default.e
+     => Targets: default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)
+     => out schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+     => in  schema: {(2) default.e.l_orderkey (INT4), default.e.l_quantity (FLOAT8)}
+      PROJECTION(10)
+        => Targets: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+        => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+        => in  schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+         JOIN(22)(INNER)
+           => Join Cond: default.d.l_partkey (INT4) = default.part.p_partkey (INT4)
+           => target list: default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)
+           => out schema: {(2) default.d.l_orderkey (INT4), default.d.l_quantity (FLOAT8)}
+           => in schema: {(4) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8), default.part.p_partkey (INT4)}
+            SCAN(31) on eb_0000000000000_0000_000007
+              => out schema: {(1) default.part.p_partkey (INT4)}
+              => in schema: {(1) default.part.p_partkey (INT4)}
+            SCAN(30) on eb_0000000000000_0000_000006
+              => out schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+              => in schema: {(3) default.d.l_orderkey (INT4), default.d.l_partkey (INT4), default.d.l_quantity (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.e.l_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=HASH_SHUFFLE, key=default.f.l_orderkey (INT4), num=32)
+
+TABLE_SUBQUERY(14) as default.f
+  => Targets: default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)
+  => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+  => in  schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+   PROJECTION(13)
+     => Targets: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+     => out schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+     => in  schema: {(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+      GROUP_BY(12)(l_orderkey)
+        => exprs: (avg(?avg_11 (PROTOBUF)))
+        => target list: default.e.l_orderkey (INT4), avg_quantity (FLOAT8)
+        => out schema:{(2) avg_quantity (FLOAT8), default.e.l_orderkey (INT4)}
+        => in schema:{(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+         SCAN(33) on eb_0000000000000_0000_000008
+           => out schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+           => in schema: {(2) default.e.l_orderkey (INT4), ?avg_11 (PROTOBUF)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 10 (type=HASH_SHUFFLE, key=default.c.o_orderkey (INT4), num=32)
+[q_0000000000000_0000] 9 => 10 (type=HASH_SHUFFLE, key=default.f.l_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+GROUP_BY(36)()
+  => exprs: (sum(default.b.l_quantity (FLOAT8)))
+  => target list: ?sum_12 (FLOAT8)
+  => out schema:{(1) ?sum_12 (FLOAT8)}
+  => in schema:{(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+   SELECTION(20)
+     => Search Cond: default.b.l_quantity (FLOAT8) > default.f.avg_quantity (FLOAT8)
+      JOIN(24)(INNER)
+        => Join Cond: default.c.o_orderkey (INT4) = default.f.l_orderkey (INT4)
+        => target list: default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)
+        => out schema: {(2) default.b.l_quantity (FLOAT8), default.f.avg_quantity (FLOAT8)}
+        => in schema: {(4) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4), default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         SCAN(35) on eb_0000000000000_0000_000009
+           => out schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+           => in schema: {(2) default.f.avg_quantity (FLOAT8), default.f.l_orderkey (INT4)}
+         SCAN(34) on eb_0000000000000_0000_000005
+           => out schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+           => in schema: {(2) default.b.l_quantity (FLOAT8), default.c.o_orderkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 10 => 11 (type=HASH_SHUFFLE, key=, num=1)
+
+GROUP_BY(18)()
+  => exprs: (sum(?sum_12 (FLOAT8)))
+  => target list: ?sum (FLOAT8)
+  => out schema:{(1) ?sum (FLOAT8)}
+  => in schema:{(1) ?sum_12 (FLOAT8)}
+   SCAN(37) on eb_0000000000000_0000_000010
+     => out schema: {(1) ?sum_12 (FLOAT8)}
+     => in schema: {(1) ?sum_12 (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000012 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.result
new file mode 100644
index 0000000..dafa89a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testBroadcastSubquery2.result
@@ -0,0 +1,3 @@
+?sum
+-------------------------------
+85.0

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash.plan
new file mode 100644
index 0000000..4e72e08
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash.plan
@@ -0,0 +1,90 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(3) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.nation
+
+SORT(12)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(3) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         PROJECTION(2)
+           => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+           => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in  schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(13) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..2325ed7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Hash_NoBroadcast.plan
@@ -0,0 +1,117 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(3) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+TABLE_SUBQUERY(3) as default.n2
+  => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   PROJECTION(2)
+     => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in  schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+  => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(12)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(11) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(10) on eb_0000000000000_0000_000001
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(1) name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(13) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort.plan
new file mode 100644
index 0000000..4e72e08
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort.plan
@@ -0,0 +1,90 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(3) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.nation
+
+SORT(12)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(3) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         PROJECTION(2)
+           => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+           => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in  schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(13) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..2325ed7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.Sort_NoBroadcast.plan
@@ -0,0 +1,117 @@
+explain
+-------------------------------
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(3) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         SCAN(1) on default.nation
+           => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+TABLE_SUBQUERY(3) as default.n2
+  => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   PROJECTION(2)
+     => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in  schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      SCAN(1) on default.nation
+        => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+  => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(12)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(8)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(11) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(10) on eb_0000000000000_0000_000001
+        => out schema: {(1) name2 (TEXT)}
+        => in schema: {(1) name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(5)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(13) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.result
new file mode 100644
index 0000000..9244a0b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition5.result
@@ -0,0 +1,29 @@
+n_nationkey,name1,name2
+-------------------------------
+0,ALGE,ALGE
+1,ARGE,ARGE
+2,BRAZ,BRAZ
+3,CANA,CANA
+4,EGYP,EGYP
+5,ETHI,ETHI
+6,FRAN,FRAN
+7,GERM,GERM
+8,INDI,INDI
+9,INDO,INDO
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+12,JAPA,JAPA
+13,JORD,JORD
+14,KENY,KENY
+15,MORO,MORO
+16,MOZA,MOZA
+17,PERU,PERU
+18,CHIN,CHIN
+19,ROMA,ROMA
+20,SAUD,SAUD
+21,VIET,VIET
+22,RUSS,RUSS
+23,UNIT,UNIT
+23,UNIT,UNIT
+24,UNIT,UNIT
+24,UNIT,UNIT

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash.plan
new file mode 100644
index 0000000..2402db7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash.plan
@@ -0,0 +1,109 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000005
+3: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.nation
+ 1: type=Broadcast, tables=default.n1
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n2.name2 (TEXT), default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      UNION(21)
+         TABLE_SUBQUERY(14) as default.n2
+           => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+           => out schema: {(1) name2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(3) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+         TABLE_SUBQUERY(13) as default.n2
+           => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+           => out schema: {(1) name2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..15a4a6b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Hash_NoBroadcast.plan
@@ -0,0 +1,145 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000004
+4: eb_0000000000000_0000_000003
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+TABLE_SUBQUERY(13) as default.n2
+  => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(1) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+TABLE_SUBQUERY(14) as default.n2
+  => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(3) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+  => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(17) on eb_0000000000000_0000_000004
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(15) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.n2.name2 (TEXT)}
+        => in schema: {(1) default.n2.name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort.plan
new file mode 100644
index 0000000..2402db7
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort.plan
@@ -0,0 +1,109 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000005
+3: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.nation
+ 1: type=Broadcast, tables=default.n1
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n2.name2 (TEXT), default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      UNION(21)
+         TABLE_SUBQUERY(14) as default.n2
+           => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+           => out schema: {(1) name2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(3) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+         TABLE_SUBQUERY(13) as default.n2
+           => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+           => out schema: {(1) name2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..15a4a6b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.Sort_NoBroadcast.plan
@@ -0,0 +1,145 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+        => out schema: {(1) name2 (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000004
+4: eb_0000000000000_0000_000003
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+TABLE_SUBQUERY(13) as default.n2
+  => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(1) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32)
+
+TABLE_SUBQUERY(14) as default.n2
+  => Targets: substr(default.n2.n_name (TEXT),1,4) as name2
+  => out schema: {(1) name2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(3) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as name1
+  => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=name2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=name1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: name1 (TEXT) = name2 (TEXT)
+     => target list: default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+      SCAN(17) on eb_0000000000000_0000_000004
+        => out schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+        => in schema: {(2) default.n1.n_nationkey (INT4), name1 (TEXT)}
+      SCAN(15) on eb_0000000000000_0000_000001
+        => out schema: {(1) default.n2.name2 (TEXT)}
+        => in schema: {(1) default.n2.name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+     => in schema: {(3) default.n1.n_nationkey (INT4), name1 (TEXT), name2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.result
new file mode 100644
index 0000000..2409634
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition6.result
@@ -0,0 +1,56 @@
+n_nationkey,name1,name2
+-------------------------------
+0,ALGE,ALGE
+0,ALGE,ALGE
+1,ARGE,ARGE
+1,ARGE,ARGE
+2,BRAZ,BRAZ
+2,BRAZ,BRAZ
+3,CANA,CANA
+3,CANA,CANA
+4,EGYP,EGYP
+4,EGYP,EGYP
+5,ETHI,ETHI
+5,ETHI,ETHI
+6,FRAN,FRAN
+6,FRAN,FRAN
+7,GERM,GERM
+7,GERM,GERM
+8,INDI,INDI
+8,INDI,INDI
+9,INDO,INDO
+9,INDO,INDO
+10,IRAN,IRAN
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+11,IRAQ,IRAQ
+12,JAPA,JAPA
+12,JAPA,JAPA
+13,JORD,JORD
+13,JORD,JORD
+14,KENY,KENY
+14,KENY,KENY
+15,MORO,MORO
+15,MORO,MORO
+16,MOZA,MOZA
+16,MOZA,MOZA
+17,PERU,PERU
+17,PERU,PERU
+18,CHIN,CHIN
+18,CHIN,CHIN
+19,ROMA,ROMA
+19,ROMA,ROMA
+20,SAUD,SAUD
+20,SAUD,SAUD
+21,VIET,VIET
+21,VIET,VIET
+22,RUSS,RUSS
+22,RUSS,RUSS
+23,UNIT,UNIT
+23,UNIT,UNIT
+23,UNIT,UNIT
+23,UNIT,UNIT
+24,UNIT,UNIT
+24,UNIT,UNIT
+24,UNIT,UNIT
+24,UNIT,UNIT


[20/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoBinaryMultiRegion.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoBinaryMultiRegion.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoBinaryMultiRegion.result
new file mode 100644
index 0000000..c55873a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoBinaryMultiRegion.result
@@ -0,0 +1,100 @@
+0, value0
+1, value1
+2, value2
+3, value3
+4, value4
+5, value5
+6, value6
+7, value7
+8, value8
+9, value9
+1, value10
+1, value11
+1, value12
+1, value13
+1, value14
+1, value15
+1, value16
+1, value17
+1, value18
+1, value19
+2, value20
+2, value21
+2, value22
+2, value23
+2, value24
+2, value25
+2, value26
+2, value27
+2, value28
+2, value29
+3, value30
+3, value31
+3, value32
+3, value33
+3, value34
+3, value35
+3, value36
+3, value37
+3, value38
+3, value39
+4, value40
+4, value41
+4, value42
+4, value43
+4, value44
+4, value45
+4, value46
+4, value47
+4, value48
+4, value49
+5, value50
+5, value51
+5, value52
+5, value53
+5, value54
+5, value55
+5, value56
+5, value57
+5, value58
+5, value59
+6, value60
+6, value61
+6, value62
+6, value63
+6, value64
+6, value65
+6, value66
+6, value67
+6, value68
+6, value69
+7, value70
+7, value71
+7, value72
+7, value73
+7, value74
+7, value75
+7, value76
+7, value77
+7, value78
+7, value79
+8, value80
+8, value81
+8, value82
+8, value83
+8, value84
+8, value85
+8, value86
+8, value87
+8, value88
+8, value89
+9, value90
+9, value91
+9, value92
+9, value93
+9, value94
+9, value95
+9, value96
+9, value97
+9, value98
+9, value99

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoColumnKeyValue.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoColumnKeyValue.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoColumnKeyValue.result
new file mode 100644
index 0000000..a37593b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoColumnKeyValue.result
@@ -0,0 +1,21 @@
+0, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-0"}
+1, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-1"}
+10, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-10"}
+11, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-11"}
+12, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-12"}
+13, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-13"}
+14, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-14"}
+15, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-15"}
+16, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-16"}
+17, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-17"}
+18, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-18"}
+19, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-19"}
+2, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-2"}
+20, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-20"}
+3, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-3"}
+4, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-4"}
+5, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-5"}
+6, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-6"}
+7, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-7"}
+8, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-8"}
+9, {"ck-0": "value-0", "ck-1": "value-1", "ck-2": "value-2"}, {"": "col3-9"}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion.result
new file mode 100644
index 0000000..72013f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion.result
@@ -0,0 +1,100 @@
+000, value0
+001, value1
+002, value2
+003, value3
+004, value4
+005, value5
+006, value6
+007, value7
+008, value8
+009, value9
+010, value10
+011, value11
+012, value12
+013, value13
+014, value14
+015, value15
+016, value16
+017, value17
+018, value18
+019, value19
+020, value20
+021, value21
+022, value22
+023, value23
+024, value24
+025, value25
+026, value26
+027, value27
+028, value28
+029, value29
+030, value30
+031, value31
+032, value32
+033, value33
+034, value34
+035, value35
+036, value36
+037, value37
+038, value38
+039, value39
+040, value40
+041, value41
+042, value42
+043, value43
+044, value44
+045, value45
+046, value46
+047, value47
+048, value48
+049, value49
+050, value50
+051, value51
+052, value52
+053, value53
+054, value54
+055, value55
+056, value56
+057, value57
+058, value58
+059, value59
+060, value60
+061, value61
+062, value62
+063, value63
+064, value64
+065, value65
+066, value66
+067, value67
+068, value68
+069, value69
+070, value70
+071, value71
+072, value72
+073, value73
+074, value74
+075, value75
+076, value76
+077, value77
+078, value78
+079, value79
+080, value80
+081, value81
+082, value82
+083, value83
+084, value84
+085, value85
+086, value86
+087, value87
+088, value88
+089, value89
+090, value90
+091, value91
+092, value92
+093, value93
+094, value94
+095, value95
+096, value96
+097, value97
+098, value98
+099, value99

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion2.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion2.result
new file mode 100644
index 0000000..be11042
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegion2.result
@@ -0,0 +1,100 @@
+0, value0
+1, value1
+10, value10
+11, value11
+12, value12
+13, value13
+14, value14
+15, value15
+16, value16
+17, value17
+18, value18
+19, value19
+2, value2
+20, value20
+21, value21
+22, value22
+23, value23
+24, value24
+25, value25
+26, value26
+27, value27
+28, value28
+29, value29
+3, value3
+30, value30
+31, value31
+32, value32
+33, value33
+34, value34
+35, value35
+36, value36
+37, value37
+38, value38
+39, value39
+4, value4
+40, value40
+41, value41
+42, value42
+43, value43
+44, value44
+45, value45
+46, value46
+47, value47
+48, value48
+49, value49
+5, value5
+50, value50
+51, value51
+52, value52
+53, value53
+54, value54
+55, value55
+56, value56
+57, value57
+58, value58
+59, value59
+6, value6
+60, value60
+61, value61
+62, value62
+63, value63
+64, value64
+65, value65
+66, value66
+67, value67
+68, value68
+69, value69
+7, value7
+70, value70
+71, value71
+72, value72
+73, value73
+74, value74
+75, value75
+76, value76
+77, value77
+78, value78
+79, value79
+8, value8
+80, value80
+81, value81
+82, value82
+83, value83
+84, value84
+85, value85
+86, value86
+87, value87
+88, value88
+89, value89
+9, value9
+90, value90
+91, value91
+92, value92
+93, value93
+94, value94
+95, value95
+96, value96
+97, value97
+98, value98
+99, value99

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionMultiRowFields.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionMultiRowFields.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionMultiRowFields.result
new file mode 100644
index 0000000..0b740c8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionMultiRowFields.result
@@ -0,0 +1,100 @@
+000_100, value0
+001_101, value1
+002_102, value2
+003_103, value3
+004_104, value4
+005_105, value5
+006_106, value6
+007_107, value7
+008_108, value8
+009_109, value9
+010_110, value10
+011_111, value11
+012_112, value12
+013_113, value13
+014_114, value14
+015_115, value15
+016_116, value16
+017_117, value17
+018_118, value18
+019_119, value19
+020_120, value20
+021_121, value21
+022_122, value22
+023_123, value23
+024_124, value24
+025_125, value25
+026_126, value26
+027_127, value27
+028_128, value28
+029_129, value29
+030_130, value30
+031_131, value31
+032_132, value32
+033_133, value33
+034_134, value34
+035_135, value35
+036_136, value36
+037_137, value37
+038_138, value38
+039_139, value39
+040_140, value40
+041_141, value41
+042_142, value42
+043_143, value43
+044_144, value44
+045_145, value45
+046_146, value46
+047_147, value47
+048_148, value48
+049_149, value49
+050_150, value50
+051_151, value51
+052_152, value52
+053_153, value53
+054_154, value54
+055_155, value55
+056_156, value56
+057_157, value57
+058_158, value58
+059_159, value59
+060_160, value60
+061_161, value61
+062_162, value62
+063_163, value63
+064_164, value64
+065_165, value65
+066_166, value66
+067_167, value67
+068_168, value68
+069_169, value69
+070_170, value70
+071_171, value71
+072_172, value72
+073_173, value73
+074_174, value74
+075_175, value75
+076_176, value76
+077_177, value77
+078_178, value78
+079_179, value79
+080_180, value80
+081_181, value81
+082_182, value82
+083_183, value83
+084_184, value84
+085_185, value85
+086_186, value86
+087_187, value87
+088_188, value88
+089_189, value89
+090_190, value90
+091_191, value91
+092_192, value92
+093_193, value93
+094_194, value94
+095_195, value95
+096_196, value96
+097_197, value97
+098_198, value98
+099_199, value99

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionWithSplitFile.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionWithSplitFile.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionWithSplitFile.result
new file mode 100644
index 0000000..72013f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoMultiRegionWithSplitFile.result
@@ -0,0 +1,100 @@
+000, value0
+001, value1
+002, value2
+003, value3
+004, value4
+005, value5
+006, value6
+007, value7
+008, value8
+009, value9
+010, value10
+011, value11
+012, value12
+013, value13
+014, value14
+015, value15
+016, value16
+017, value17
+018, value18
+019, value19
+020, value20
+021, value21
+022, value22
+023, value23
+024, value24
+025, value25
+026, value26
+027, value27
+028, value28
+029, value29
+030, value30
+031, value31
+032, value32
+033, value33
+034, value34
+035, value35
+036, value36
+037, value37
+038, value38
+039, value39
+040, value40
+041, value41
+042, value42
+043, value43
+044, value44
+045, value45
+046, value46
+047, value47
+048, value48
+049, value49
+050, value50
+051, value51
+052, value52
+053, value53
+054, value54
+055, value55
+056, value56
+057, value57
+058, value58
+059, value59
+060, value60
+061, value61
+062, value62
+063, value63
+064, value64
+065, value65
+066, value66
+067, value67
+068, value68
+069, value69
+070, value70
+071, value71
+072, value72
+073, value73
+074, value74
+075, value75
+076, value76
+077, value77
+078, value78
+079, value79
+080, value80
+081, value81
+082, value82
+083, value83
+084, value84
+085, value85
+086, value86
+087, value87
+088, value88
+089, value89
+090, value90
+091, value91
+092, value92
+093, value93
+094, value94
+095, value95
+096, value96
+097, value97
+098, value98
+099, value99

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoRowField.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoRowField.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoRowField.result
new file mode 100644
index 0000000..152b91b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoRowField.result
@@ -0,0 +1,4 @@
+1_1, 1996-03-13, N, 7706
+2_2, 1997-01-28, N, 1191
+3_2, 1994-02-02, R, 1798
+3_3, 1993-11-09, R, 6540

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoUsingPut.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoUsingPut.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoUsingPut.result
new file mode 100644
index 0000000..e0c97ef
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertIntoUsingPut.result
@@ -0,0 +1,3 @@
+1, 1996-03-13, {"": "N"}, 7706
+2, 1997-01-28, {"": "N"}, 1191
+3, 1994-02-02, {"": "R"}, 1798

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertValues1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertValues1.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertValues1.result
new file mode 100644
index 0000000..45d730a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testInsertValues1.result
@@ -0,0 +1,4 @@
+aaa, a12, {"": "a34"}, 1
+bbb, b12, {"": "b34"}, 2
+ccc, c12, {"": "c34"}, 3
+ddd, d12, {"": "d34"}, 4

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testJoin.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testJoin.result
new file mode 100644
index 0000000..fe4fcae
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testJoin.result
@@ -0,0 +1,7 @@
+rk,col1,col2,col3,l_orderkey,l_linestatus
+-------------------------------
+001,a-1,{"k1":"k1-1", "k2":"k2-1"},1,1,O
+001,a-1,{"k1":"k1-1", "k2":"k2-1"},1,1,O
+002,a-2,{"k1":"k1-2", "k2":"k2-2"},2,2,O
+003,a-3,{"k1":"k1-3", "k2":"k2-3"},3,3,F
+003,a-3,{"k1":"k1-3", "k2":"k2-3"},3,3,F
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testNonForwardQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testNonForwardQuery.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testNonForwardQuery.result
new file mode 100644
index 0000000..4f5fd8f
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testNonForwardQuery.result
@@ -0,0 +1,102 @@
+rk,col1,col2,col3
+-------------------------------
+000,a-0,{"k1":"k1-0", "k2":"k2-0"},0
+001,a-1,{"k1":"k1-1", "k2":"k2-1"},1
+002,a-2,{"k1":"k1-2", "k2":"k2-2"},2
+003,a-3,{"k1":"k1-3", "k2":"k2-3"},3
+004,a-4,{"k1":"k1-4", "k2":"k2-4"},4
+005,a-5,{"k1":"k1-5", "k2":"k2-5"},5
+006,a-6,{"k1":"k1-6", "k2":"k2-6"},6
+007,a-7,{"k1":"k1-7", "k2":"k2-7"},7
+008,a-8,{"k1":"k1-8", "k2":"k2-8"},8
+009,a-9,{"k1":"k1-9", "k2":"k2-9"},9
+010,a-10,{"k1":"k1-10", "k2":"k2-10"},10
+011,a-11,{"k1":"k1-11", "k2":"k2-11"},11
+012,a-12,{"k1":"k1-12", "k2":"k2-12"},12
+013,a-13,{"k1":"k1-13", "k2":"k2-13"},13
+014,a-14,{"k1":"k1-14", "k2":"k2-14"},14
+015,a-15,{"k1":"k1-15", "k2":"k2-15"},15
+016,a-16,{"k1":"k1-16", "k2":"k2-16"},16
+017,a-17,{"k1":"k1-17", "k2":"k2-17"},17
+018,a-18,{"k1":"k1-18", "k2":"k2-18"},18
+019,a-19,{"k1":"k1-19", "k2":"k2-19"},19
+020,a-20,{"k1":"k1-20", "k2":"k2-20"},20
+021,a-21,{"k1":"k1-21", "k2":"k2-21"},21
+022,a-22,{"k1":"k1-22", "k2":"k2-22"},22
+023,a-23,{"k1":"k1-23", "k2":"k2-23"},23
+024,a-24,{"k1":"k1-24", "k2":"k2-24"},24
+025,a-25,{"k1":"k1-25", "k2":"k2-25"},25
+026,a-26,{"k1":"k1-26", "k2":"k2-26"},26
+027,a-27,{"k1":"k1-27", "k2":"k2-27"},27
+028,a-28,{"k1":"k1-28", "k2":"k2-28"},28
+029,a-29,{"k1":"k1-29", "k2":"k2-29"},29
+030,a-30,{"k1":"k1-30", "k2":"k2-30"},30
+031,a-31,{"k1":"k1-31", "k2":"k2-31"},31
+032,a-32,{"k1":"k1-32", "k2":"k2-32"},32
+033,a-33,{"k1":"k1-33", "k2":"k2-33"},33
+034,a-34,{"k1":"k1-34", "k2":"k2-34"},34
+035,a-35,{"k1":"k1-35", "k2":"k2-35"},35
+036,a-36,{"k1":"k1-36", "k2":"k2-36"},36
+037,a-37,{"k1":"k1-37", "k2":"k2-37"},37
+038,a-38,{"k1":"k1-38", "k2":"k2-38"},38
+039,a-39,{"k1":"k1-39", "k2":"k2-39"},39
+040,a-40,{"k1":"k1-40", "k2":"k2-40"},40
+041,a-41,{"k1":"k1-41", "k2":"k2-41"},41
+042,a-42,{"k1":"k1-42", "k2":"k2-42"},42
+043,a-43,{"k1":"k1-43", "k2":"k2-43"},43
+044,a-44,{"k1":"k1-44", "k2":"k2-44"},44
+045,a-45,{"k1":"k1-45", "k2":"k2-45"},45
+046,a-46,{"k1":"k1-46", "k2":"k2-46"},46
+047,a-47,{"k1":"k1-47", "k2":"k2-47"},47
+048,a-48,{"k1":"k1-48", "k2":"k2-48"},48
+049,a-49,{"k1":"k1-49", "k2":"k2-49"},49
+050,a-50,{"k1":"k1-50", "k2":"k2-50"},50
+051,a-51,{"k1":"k1-51", "k2":"k2-51"},51
+052,a-52,{"k1":"k1-52", "k2":"k2-52"},52
+053,a-53,{"k1":"k1-53", "k2":"k2-53"},53
+054,a-54,{"k1":"k1-54", "k2":"k2-54"},54
+055,a-55,{"k1":"k1-55", "k2":"k2-55"},55
+056,a-56,{"k1":"k1-56", "k2":"k2-56"},56
+057,a-57,{"k1":"k1-57", "k2":"k2-57"},57
+058,a-58,{"k1":"k1-58", "k2":"k2-58"},58
+059,a-59,{"k1":"k1-59", "k2":"k2-59"},59
+060,a-60,{"k1":"k1-60", "k2":"k2-60"},60
+061,a-61,{"k1":"k1-61", "k2":"k2-61"},61
+062,a-62,{"k1":"k1-62", "k2":"k2-62"},62
+063,a-63,{"k1":"k1-63", "k2":"k2-63"},63
+064,a-64,{"k1":"k1-64", "k2":"k2-64"},64
+065,a-65,{"k1":"k1-65", "k2":"k2-65"},65
+066,a-66,{"k1":"k1-66", "k2":"k2-66"},66
+067,a-67,{"k1":"k1-67", "k2":"k2-67"},67
+068,a-68,{"k1":"k1-68", "k2":"k2-68"},68
+069,a-69,{"k1":"k1-69", "k2":"k2-69"},69
+070,a-70,{"k1":"k1-70", "k2":"k2-70"},70
+071,a-71,{"k1":"k1-71", "k2":"k2-71"},71
+072,a-72,{"k1":"k1-72", "k2":"k2-72"},72
+073,a-73,{"k1":"k1-73", "k2":"k2-73"},73
+074,a-74,{"k1":"k1-74", "k2":"k2-74"},74
+075,a-75,{"k1":"k1-75", "k2":"k2-75"},75
+076,a-76,{"k1":"k1-76", "k2":"k2-76"},76
+077,a-77,{"k1":"k1-77", "k2":"k2-77"},77
+078,a-78,{"k1":"k1-78", "k2":"k2-78"},78
+079,a-79,{"k1":"k1-79", "k2":"k2-79"},79
+080,a-80,{"k1":"k1-80", "k2":"k2-80"},80
+081,a-81,{"k1":"k1-81", "k2":"k2-81"},81
+082,a-82,{"k1":"k1-82", "k2":"k2-82"},82
+083,a-83,{"k1":"k1-83", "k2":"k2-83"},83
+084,a-84,{"k1":"k1-84", "k2":"k2-84"},84
+085,a-85,{"k1":"k1-85", "k2":"k2-85"},85
+086,a-86,{"k1":"k1-86", "k2":"k2-86"},86
+087,a-87,{"k1":"k1-87", "k2":"k2-87"},87
+088,a-88,{"k1":"k1-88", "k2":"k2-88"},88
+089,a-89,{"k1":"k1-89", "k2":"k2-89"},89
+090,a-90,{"k1":"k1-90", "k2":"k2-90"},90
+091,a-91,{"k1":"k1-91", "k2":"k2-91"},91
+092,a-92,{"k1":"k1-92", "k2":"k2-92"},92
+093,a-93,{"k1":"k1-93", "k2":"k2-93"},93
+094,a-94,{"k1":"k1-94", "k2":"k2-94"},94
+095,a-95,{"k1":"k1-95", "k2":"k2-95"},95
+096,a-96,{"k1":"k1-96", "k2":"k2-96"},96
+097,a-97,{"k1":"k1-97", "k2":"k2-97"},97
+098,a-98,{"k1":"k1-98", "k2":"k2-98"},98
+099,a-99,{"k1":"k1-99", "k2":"k2-99"},99
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testRowFieldSelectQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testRowFieldSelectQuery.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testRowFieldSelectQuery.result
new file mode 100644
index 0000000..34369df
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testRowFieldSelectQuery.result
@@ -0,0 +1,88 @@
+rk1,rk2,col3
+-------------------------------
+field1-21,field2-21,a-21
+field1-22,field2-22,a-22
+field1-23,field2-23,a-23
+field1-24,field2-24,a-24
+field1-25,field2-25,a-25
+field1-26,field2-26,a-26
+field1-27,field2-27,a-27
+field1-28,field2-28,a-28
+field1-29,field2-29,a-29
+field1-30,field2-30,a-30
+field1-31,field2-31,a-31
+field1-32,field2-32,a-32
+field1-33,field2-33,a-33
+field1-34,field2-34,a-34
+field1-35,field2-35,a-35
+field1-36,field2-36,a-36
+field1-37,field2-37,a-37
+field1-38,field2-38,a-38
+field1-39,field2-39,a-39
+field1-3,field2-3,a-3
+field1-40,field2-40,a-40
+field1-41,field2-41,a-41
+field1-42,field2-42,a-42
+field1-43,field2-43,a-43
+field1-44,field2-44,a-44
+field1-45,field2-45,a-45
+field1-46,field2-46,a-46
+field1-47,field2-47,a-47
+field1-48,field2-48,a-48
+field1-49,field2-49,a-49
+field1-4,field2-4,a-4
+field1-50,field2-50,a-50
+field1-51,field2-51,a-51
+field1-52,field2-52,a-52
+field1-53,field2-53,a-53
+field1-54,field2-54,a-54
+field1-55,field2-55,a-55
+field1-56,field2-56,a-56
+field1-57,field2-57,a-57
+field1-58,field2-58,a-58
+field1-59,field2-59,a-59
+field1-5,field2-5,a-5
+field1-60,field2-60,a-60
+field1-61,field2-61,a-61
+field1-62,field2-62,a-62
+field1-63,field2-63,a-63
+field1-64,field2-64,a-64
+field1-65,field2-65,a-65
+field1-66,field2-66,a-66
+field1-67,field2-67,a-67
+field1-68,field2-68,a-68
+field1-69,field2-69,a-69
+field1-6,field2-6,a-6
+field1-70,field2-70,a-70
+field1-71,field2-71,a-71
+field1-72,field2-72,a-72
+field1-73,field2-73,a-73
+field1-74,field2-74,a-74
+field1-75,field2-75,a-75
+field1-76,field2-76,a-76
+field1-77,field2-77,a-77
+field1-78,field2-78,a-78
+field1-79,field2-79,a-79
+field1-7,field2-7,a-7
+field1-80,field2-80,a-80
+field1-81,field2-81,a-81
+field1-82,field2-82,a-82
+field1-83,field2-83,a-83
+field1-84,field2-84,a-84
+field1-85,field2-85,a-85
+field1-86,field2-86,a-86
+field1-87,field2-87,a-87
+field1-88,field2-88,a-88
+field1-89,field2-89,a-89
+field1-8,field2-8,a-8
+field1-90,field2-90,a-90
+field1-91,field2-91,a-91
+field1-92,field2-92,a-92
+field1-93,field2-93,a-93
+field1-94,field2-94,a-94
+field1-95,field2-95,a-95
+field1-96,field2-96,a-96
+field1-97,field2-97,a-97
+field1-98,field2-98,a-98
+field1-99,field2-99,a-99
+field1-9,field2-9,a-9
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestHBaseTable/testSimpleSelectQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestHBaseTable/testSimpleSelectQuery.result b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testSimpleSelectQuery.result
new file mode 100644
index 0000000..ef2f27a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestHBaseTable/testSimpleSelectQuery.result
@@ -0,0 +1,88 @@
+rk,col1,col2,col3
+-------------------------------
+21,a-21,{"k1":"k1-21", "k2":"k2-21"},b-21
+22,a-22,{"k1":"k1-22", "k2":"k2-22"},b-22
+23,a-23,{"k1":"k1-23", "k2":"k2-23"},b-23
+24,a-24,{"k1":"k1-24", "k2":"k2-24"},b-24
+25,a-25,{"k1":"k1-25", "k2":"k2-25"},b-25
+26,a-26,{"k1":"k1-26", "k2":"k2-26"},b-26
+27,a-27,{"k1":"k1-27", "k2":"k2-27"},b-27
+28,a-28,{"k1":"k1-28", "k2":"k2-28"},b-28
+29,a-29,{"k1":"k1-29", "k2":"k2-29"},b-29
+3,a-3,{"k1":"k1-3", "k2":"k2-3"},b-3
+30,a-30,{"k1":"k1-30", "k2":"k2-30"},b-30
+31,a-31,{"k1":"k1-31", "k2":"k2-31"},b-31
+32,a-32,{"k1":"k1-32", "k2":"k2-32"},b-32
+33,a-33,{"k1":"k1-33", "k2":"k2-33"},b-33
+34,a-34,{"k1":"k1-34", "k2":"k2-34"},b-34
+35,a-35,{"k1":"k1-35", "k2":"k2-35"},b-35
+36,a-36,{"k1":"k1-36", "k2":"k2-36"},b-36
+37,a-37,{"k1":"k1-37", "k2":"k2-37"},b-37
+38,a-38,{"k1":"k1-38", "k2":"k2-38"},b-38
+39,a-39,{"k1":"k1-39", "k2":"k2-39"},b-39
+4,a-4,{"k1":"k1-4", "k2":"k2-4"},b-4
+40,a-40,{"k1":"k1-40", "k2":"k2-40"},b-40
+41,a-41,{"k1":"k1-41", "k2":"k2-41"},b-41
+42,a-42,{"k1":"k1-42", "k2":"k2-42"},b-42
+43,a-43,{"k1":"k1-43", "k2":"k2-43"},b-43
+44,a-44,{"k1":"k1-44", "k2":"k2-44"},b-44
+45,a-45,{"k1":"k1-45", "k2":"k2-45"},b-45
+46,a-46,{"k1":"k1-46", "k2":"k2-46"},b-46
+47,a-47,{"k1":"k1-47", "k2":"k2-47"},b-47
+48,a-48,{"k1":"k1-48", "k2":"k2-48"},b-48
+49,a-49,{"k1":"k1-49", "k2":"k2-49"},b-49
+5,a-5,{"k1":"k1-5", "k2":"k2-5"},b-5
+50,a-50,{"k1":"k1-50", "k2":"k2-50"},b-50
+51,a-51,{"k1":"k1-51", "k2":"k2-51"},b-51
+52,a-52,{"k1":"k1-52", "k2":"k2-52"},b-52
+53,a-53,{"k1":"k1-53", "k2":"k2-53"},b-53
+54,a-54,{"k1":"k1-54", "k2":"k2-54"},b-54
+55,a-55,{"k1":"k1-55", "k2":"k2-55"},b-55
+56,a-56,{"k1":"k1-56", "k2":"k2-56"},b-56
+57,a-57,{"k1":"k1-57", "k2":"k2-57"},b-57
+58,a-58,{"k1":"k1-58", "k2":"k2-58"},b-58
+59,a-59,{"k1":"k1-59", "k2":"k2-59"},b-59
+6,a-6,{"k1":"k1-6", "k2":"k2-6"},b-6
+60,a-60,{"k1":"k1-60", "k2":"k2-60"},b-60
+61,a-61,{"k1":"k1-61", "k2":"k2-61"},b-61
+62,a-62,{"k1":"k1-62", "k2":"k2-62"},b-62
+63,a-63,{"k1":"k1-63", "k2":"k2-63"},b-63
+64,a-64,{"k1":"k1-64", "k2":"k2-64"},b-64
+65,a-65,{"k1":"k1-65", "k2":"k2-65"},b-65
+66,a-66,{"k1":"k1-66", "k2":"k2-66"},b-66
+67,a-67,{"k1":"k1-67", "k2":"k2-67"},b-67
+68,a-68,{"k1":"k1-68", "k2":"k2-68"},b-68
+69,a-69,{"k1":"k1-69", "k2":"k2-69"},b-69
+7,a-7,{"k1":"k1-7", "k2":"k2-7"},b-7
+70,a-70,{"k1":"k1-70", "k2":"k2-70"},b-70
+71,a-71,{"k1":"k1-71", "k2":"k2-71"},b-71
+72,a-72,{"k1":"k1-72", "k2":"k2-72"},b-72
+73,a-73,{"k1":"k1-73", "k2":"k2-73"},b-73
+74,a-74,{"k1":"k1-74", "k2":"k2-74"},b-74
+75,a-75,{"k1":"k1-75", "k2":"k2-75"},b-75
+76,a-76,{"k1":"k1-76", "k2":"k2-76"},b-76
+77,a-77,{"k1":"k1-77", "k2":"k2-77"},b-77
+78,a-78,{"k1":"k1-78", "k2":"k2-78"},b-78
+79,a-79,{"k1":"k1-79", "k2":"k2-79"},b-79
+8,a-8,{"k1":"k1-8", "k2":"k2-8"},b-8
+80,a-80,{"k1":"k1-80", "k2":"k2-80"},b-80
+81,a-81,{"k1":"k1-81", "k2":"k2-81"},b-81
+82,a-82,{"k1":"k1-82", "k2":"k2-82"},b-82
+83,a-83,{"k1":"k1-83", "k2":"k2-83"},b-83
+84,a-84,{"k1":"k1-84", "k2":"k2-84"},b-84
+85,a-85,{"k1":"k1-85", "k2":"k2-85"},b-85
+86,a-86,{"k1":"k1-86", "k2":"k2-86"},b-86
+87,a-87,{"k1":"k1-87", "k2":"k2-87"},b-87
+88,a-88,{"k1":"k1-88", "k2":"k2-88"},b-88
+89,a-89,{"k1":"k1-89", "k2":"k2-89"},b-89
+9,a-9,{"k1":"k1-9", "k2":"k2-9"},b-9
+90,a-90,{"k1":"k1-90", "k2":"k2-90"},b-90
+91,a-91,{"k1":"k1-91", "k2":"k2-91"},b-91
+92,a-92,{"k1":"k1-92", "k2":"k2-92"},b-92
+93,a-93,{"k1":"k1-93", "k2":"k2-93"},b-93
+94,a-94,{"k1":"k1-94", "k2":"k2-94"},b-94
+95,a-95,{"k1":"k1-95", "k2":"k2-95"},b-95
+96,a-96,{"k1":"k1-96", "k2":"k2-96"},b-96
+97,a-97,{"k1":"k1-97", "k2":"k2-97"},b-97
+98,a-98,{"k1":"k1-98", "k2":"k2-98"},b-98
+99,a-99,{"k1":"k1-99", "k2":"k2-99"},b-99
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testInAndNotInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testInAndNotInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInAndNotInSubQuery.result
new file mode 100644
index 0000000..1acab75
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInAndNotInSubQuery.result
@@ -0,0 +1,24 @@
+n_name
+-------------------------------
+ALGERIA
+BRAZIL
+CANADA
+CHINA
+EGYPT
+FRANCE
+GERMANY
+INDIA
+INDONESIA
+IRAN
+IRAQ
+JAPAN
+JORDAN
+KENYA
+MOZAMBIQUE
+PERU
+ROMANIA
+RUSSIA
+SAUDI ARABIA
+UNITED KINGDOM
+UNITED STATES
+VIETNAM

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery.result
new file mode 100644
index 0000000..7644296
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery.result
@@ -0,0 +1,27 @@
+n_name
+-------------------------------
+ALGERIA
+ARGENTINA
+BRAZIL
+CANADA
+CHINA
+EGYPT
+ETHIOPIA
+FRANCE
+GERMANY
+INDIA
+INDONESIA
+IRAN
+IRAQ
+JAPAN
+JORDAN
+KENYA
+MOROCCO
+MOZAMBIQUE
+PERU
+ROMANIA
+RUSSIA
+SAUDI ARABIA
+UNITED KINGDOM
+UNITED STATES
+VIETNAM

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery2.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery2.result
new file mode 100644
index 0000000..fbab93d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQuery2.result
@@ -0,0 +1,3 @@
+n_name
+-------------------------------
+ETHIOPIA

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithJoin.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithJoin.result
new file mode 100644
index 0000000..1deee15
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithJoin.result
@@ -0,0 +1,5 @@
+n_name
+-------------------------------
+ARGENTINA
+ETHIOPIA
+MOROCCO

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithOtherConditions.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithOtherConditions.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithOtherConditions.result
new file mode 100644
index 0000000..8367869
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithOtherConditions.result
@@ -0,0 +1,25 @@
+n_name
+-------------------------------
+BRAZIL
+CANADA
+CHINA
+EGYPT
+ETHIOPIA
+FRANCE
+GERMANY
+INDIA
+INDONESIA
+IRAN
+IRAQ
+JAPAN
+JORDAN
+KENYA
+MOROCCO
+MOZAMBIQUE
+PERU
+ROMANIA
+RUSSIA
+SAUDI ARABIA
+UNITED KINGDOM
+UNITED STATES
+VIETNAM

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithTableSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithTableSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithTableSubQuery.result
new file mode 100644
index 0000000..d386836
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testInSubQueryWithTableSubQuery.result
@@ -0,0 +1,4 @@
+n_name
+-------------------------------
+INDIA
+INDONESIA

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleInSubQuery.result
new file mode 100644
index 0000000..1deee15
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleInSubQuery.result
@@ -0,0 +1,5 @@
+n_name
+-------------------------------
+ARGENTINA
+ETHIOPIA
+MOROCCO

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleNotInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleNotInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleNotInSubQuery.result
new file mode 100644
index 0000000..a1e17d5
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testMultipleNotInSubQuery.result
@@ -0,0 +1,20 @@
+n_name
+-------------------------------
+CHINA
+FRANCE
+GERMANY
+INDIA
+INDONESIA
+IRAN
+IRAQ
+JAPAN
+JORDAN
+KENYA
+MOZAMBIQUE
+PERU
+ROMANIA
+RUSSIA
+SAUDI ARABIA
+UNITED KINGDOM
+UNITED STATES
+VIETNAM

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInAndNotInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInAndNotInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInAndNotInSubQuery.result
new file mode 100644
index 0000000..51e570a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInAndNotInSubQuery.result
@@ -0,0 +1,3 @@
+c_name
+-------------------------------
+Customer#000000005

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery.result
new file mode 100644
index 0000000..51e570a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery.result
@@ -0,0 +1,3 @@
+c_name
+-------------------------------
+Customer#000000005

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery2.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery2.result
new file mode 100644
index 0000000..51e570a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedInSubQuery2.result
@@ -0,0 +1,3 @@
+c_name
+-------------------------------
+Customer#000000005

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedNotInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedNotInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedNotInSubQuery.result
new file mode 100644
index 0000000..e746b35
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNestedNotInSubQuery.result
@@ -0,0 +1,7 @@
+c_name
+-------------------------------
+Customer#000000001
+Customer#000000002
+Customer#000000003
+Customer#000000004
+Customer#000000005

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testNotInSubQuery.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testNotInSubQuery.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNotInSubQuery.result
new file mode 100644
index 0000000..50b69bd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testNotInSubQuery.result
@@ -0,0 +1,22 @@
+n_name
+-------------------------------
+CHINA
+ETHIOPIA
+FRANCE
+GERMANY
+INDIA
+INDONESIA
+IRAN
+IRAQ
+JAPAN
+JORDAN
+KENYA
+MOROCCO
+MOZAMBIQUE
+PERU
+ROMANIA
+RUSSIA
+SAUDI ARABIA
+UNITED KINGDOM
+UNITED STATES
+VIETNAM

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.result
new file mode 100644
index 0000000..e3d9398
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testSameKeyNameOfOuterAndInnerQueries.result
@@ -0,0 +1,3 @@
+n_regionkey,?count
+-------------------------------
+1,1

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInSubquery/testWithAsteriskAndJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInSubquery/testWithAsteriskAndJoin.result b/tajo-core-tests/src/test/resources/results/TestInSubquery/testWithAsteriskAndJoin.result
new file mode 100644
index 0000000..734ce36
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInSubquery/testWithAsteriskAndJoin.result
@@ -0,0 +1,6 @@
+l_orderkey,l_partkey,l_suppkey,l_linenumber,l_quantity,l_extendedprice,l_discount,l_tax,l_returnflag,l_linestatus,l_shipdate,l_commitdate,l_receiptdate,l_shipinstruct,l_shipmode,l_comment,o_orderkey,o_custkey,o_orderstatus,o_totalprice,o_orderdate,o_orderpriority,o_clerk,o_shippriority,o_comment
+-------------------------------
+1,1,7311,2,36.0,45983.16,0.09,0.06,N,O,1996-04-12,1996-02-28,1996-04-20,TAKE BACK RETURN,MAIL,ly final dependencies: slyly bold ,1,3,O,173665.47,1996-01-02,5-LOW,Clerk#000000951,0,nstructions sleep furiously among 
+1,1,7706,1,17.0,21168.23,0.04,0.02,N,O,1996-03-13,1996-02-12,1996-03-22,DELIVER IN PERSON,TRUCK,egular courts above the,1,3,O,173665.47,1996-01-02,5-LOW,Clerk#000000951,0,nstructions sleep furiously among 
+2,2,1191,1,38.0,44694.46,0.0,0.05,N,O,1997-01-28,1997-01-14,1997-02-02,TAKE BACK RETURN,RAIL,ven requests. deposits breach a,2,4,O,46929.18,1996-12-01,1-URGENT,Clerk#000000880,0, foxes. pending accounts at the pending, silent asymptot
+3,2,1798,1,45.0,54058.05,0.06,0.0,R,F,1994-02-02,1994-01-04,1994-02-23,NONE,AIR,ongside of the furiously brave acco,3,2,F,193846.25,1993-10-14,5-LOW,Clerk#000000955,0,sly final accounts boost. carefully regular ideas cajole carefully. depos

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleExprs.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleExprs.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleExprs.result
new file mode 100644
index 0000000..bcb645d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleExprs.result
@@ -0,0 +1,3 @@
+l_orderkey,l_linenumber
+-------------------------------
+3,2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys.result
new file mode 100644
index 0000000..86d468e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys.result
@@ -0,0 +1,3 @@
+l_orderkey,l_shipdate,l_comment
+-------------------------------
+2,1997-01-28,ven requests. deposits breach a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys2.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys2.result
new file mode 100644
index 0000000..86d468e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnMultipleKeys2.result
@@ -0,0 +1,3 @@
+l_orderkey,l_shipdate,l_comment
+-------------------------------
+2,1997-01-28,ven requests. deposits breach a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnSortedNonUniqueKeys.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnSortedNonUniqueKeys.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnSortedNonUniqueKeys.result
new file mode 100644
index 0000000..fb8a4c2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnSortedNonUniqueKeys.result
@@ -0,0 +1,4 @@
+l_orderkey,l_partkey,l_suppkey,l_linenumber,l_quantity,l_extendedprice,l_discount,l_tax,l_returnflag,l_linestatus,l_shipdate,l_commitdate,l_receiptdate,l_shipinstruct,l_shipmode,l_comment
+-------------------------------
+1,1,7706,1,17.0,21168.23,0.04,0.02,N,O,1996-03-13,1996-02-12,1996-03-22,DELIVER IN PERSON,TRUCK,egular courts above the
+1,1,7311,2,36.0,45983.16,0.09,0.06,N,O,1996-04-12,1996-02-28,1996-04-20,TAKE BACK RETURN,MAIL,ly final dependencies: slyly bold
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnUnsortedTextKeys.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnUnsortedTextKeys.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnUnsortedTextKeys.result
new file mode 100644
index 0000000..86d468e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testOnUnsortedTextKeys.result
@@ -0,0 +1,3 @@
+l_orderkey,l_shipdate,l_comment
+-------------------------------
+2,1997-01-28,ven requests. deposits breach a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithGroupBy.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithGroupBy.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithGroupBy.result
new file mode 100644
index 0000000..2d1d12e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithGroupBy.result
@@ -0,0 +1,3 @@
+l_shipdate,?count
+-------------------------------
+1997-01-28,1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithJoin.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithJoin.result
new file mode 100644
index 0000000..d119969
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithJoin.result
@@ -0,0 +1,4 @@
+l_shipdate,o_orderstatus
+-------------------------------
+1996-03-13,O
+1996-04-12,O
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithSort.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithSort.result b/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithSort.result
new file mode 100644
index 0000000..774a411
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestIndexScan/testWithSort.result
@@ -0,0 +1,4 @@
+l_shipdate
+-------------------------------
+1996-03-13
+1996-04-12
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash.plan
new file mode 100644
index 0000000..bd3ba1a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+        => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+         SCAN(3) on default.customer
+           => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+           => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+           => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+         SCAN(4) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+           => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(2) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+           => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(1) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+            SCAN(0) on default.lineitem
+              => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+              => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+              => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.orders
+ 1: type=Broadcast, tables=default.part
+ 2: type=Broadcast, tables=default.lineitem
+ 3: type=Broadcast, tables=default.customer
+
+SORT(26)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+        => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+         SCAN(3) on default.customer
+           => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+           => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+           => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+         SCAN(4) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+           => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(2) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+           => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(1) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+            SCAN(0) on default.lineitem
+              => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+              => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+              => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..fc5e3e3
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Hash_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+        => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+         SCAN(3) on default.customer
+           => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+           => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+           => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+         SCAN(4) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+           => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(2) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+           => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(1) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+            SCAN(0) on default.lineitem
+              => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+              => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+              => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+
+SCAN(0) on default.lineitem
+  => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+  => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+  => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.orders.o_orderkey (INT4), num=32)
+
+SCAN(1) on default.orders
+  => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+  => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+  => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.lineitem.l_orderkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.orders.o_orderkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+  => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+  => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+  => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+     => in schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+     => in schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(2) on default.part
+  => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+  => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+SCAN(4) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.customer.c_nationkey (INT4), num=32)
+
+SCAN(3) on default.customer
+  => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+  => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+  => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.lineitem.l_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.orders.o_custkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+  => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+  => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+  => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+     => in schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+     => in schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.customer.c_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+  => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+  => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+  => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+     => in schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+     => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.orders.o_custkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.customer.c_custkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort.plan
new file mode 100644
index 0000000..bd3ba1a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testBroadcastTwoPartJoin.Sort.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+        => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+         SCAN(3) on default.customer
+           => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+           => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+           => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+         SCAN(4) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+           => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(2) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+           => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(1) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+            SCAN(0) on default.lineitem
+              => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+              => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+              => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.orders
+ 1: type=Broadcast, tables=default.part
+ 2: type=Broadcast, tables=default.lineitem
+ 3: type=Broadcast, tables=default.customer
+
+SORT(26)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.orders.o_custkey (INT4) = default.customer.c_custkey (INT4)
+     => target list: default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(5) default.customer.c_custkey (INT4), default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.customer.c_nationkey (INT4) = default.nation.n_nationkey (INT4)
+        => target list: default.customer.c_custkey (INT4), default.nation.n_name (TEXT)
+        => out schema: {(2) default.customer.c_custkey (INT4), default.nation.n_name (TEXT)}
+        => in schema: {(4) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+         SCAN(3) on default.customer
+           => target list: default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)
+           => out schema: {(2) default.customer.c_custkey (INT4), default.customer.c_nationkey (INT4)}
+           => in schema: {(8) default.customer.c_acctbal (FLOAT8), default.customer.c_address (TEXT), default.customer.c_comment (TEXT), default.customer.c_custkey (INT4), default.customer.c_mktsegment (TEXT), default.customer.c_name (TEXT), default.customer.c_nationkey (INT4), default.customer.c_phone (TEXT)}
+         SCAN(4) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+           => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.lineitem.l_partkey (INT4) = default.part.p_partkey (INT4)
+        => target list: default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)
+        => out schema: {(3) default.lineitem.l_orderkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT)}
+        => in schema: {(5) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+         SCAN(2) on default.part
+           => target list: default.part.p_name (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_name (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.lineitem.l_orderkey (INT4) = default.orders.o_orderkey (INT4)
+           => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)
+           => out schema: {(3) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4)}
+           => in schema: {(4) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+            SCAN(1) on default.orders
+              => target list: default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)
+              => out schema: {(2) default.orders.o_custkey (INT4), default.orders.o_orderkey (INT4)}
+              => in schema: {(9) default.orders.o_clerk (TEXT), default.orders.o_comment (TEXT), default.orders.o_custkey (INT4), default.orders.o_orderdate (TEXT), default.orders.o_orderkey (INT4), default.orders.o_orderpriority (TEXT), default.orders.o_orderstatus (TEXT), default.orders.o_shippriority (INT4), default.orders.o_totalprice (FLOAT8)}
+            SCAN(0) on default.lineitem
+              => target list: default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)
+              => out schema: {(2) default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4)}
+              => in schema: {(16) default.lineitem.l_comment (TEXT), default.lineitem.l_commitdate (TEXT), default.lineitem.l_discount (FLOAT8), default.lineitem.l_extendedprice (FLOAT8), default.lineitem.l_linenumber (INT4), default.lineitem.l_linestatus (TEXT), default.lineitem.l_orderkey (INT4), default.lineitem.l_partkey (INT4), default.lineitem.l_quantity (FLOAT8), default.lineitem.l_receiptdate (TEXT), default.lineitem.l_returnflag (TEXT), default.lineitem.l_shipdate (TEXT), default.lineitem.l_shipinstruct (TEXT), default.lineitem.l_shipmode (TEXT), default.lineitem.l_suppkey (INT4), default.lineitem.l_tax (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.lineitem.l_orderkey (INT4) (asc),default.part.p_name (TEXT) (asc),default.nation.n_name (TEXT) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+     => in schema: {(3) default.lineitem.l_orderkey (INT4), default.nation.n_name (TEXT), default.part.p_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================


[41/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
new file mode 100644
index 0000000..02e921a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
@@ -0,0 +1,1360 @@
+/**
+ * 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.planner;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.QueryVars;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.AlterTableOpType;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.algebra.JoinType;
+import org.apache.tajo.benchmark.TPCH;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.partition.PartitionMethodDesc;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.function.FunctionLoader;
+import org.apache.tajo.engine.function.builtin.SumInt;
+import org.apache.tajo.engine.json.CoreGsonHelper;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.Target;
+import org.apache.tajo.plan.expr.*;
+import org.apache.tajo.plan.logical.*;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.session.Session;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.FileUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.TUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.*;
+
+public class TestLogicalPlanner {
+  private static TajoTestingCluster util;
+  private static CatalogService catalog;
+  private static SQLAnalyzer sqlAnalyzer;
+  private static LogicalPlanner planner;
+  private static TPCH tpch;
+  private static Session session = LocalTajoTestingUtility.createDummySession();
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234");
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
+      catalog.createFunction(funcDesc);
+    }
+
+    Schema schema = new Schema();
+    schema.addColumn("name", Type.TEXT);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("deptname", Type.TEXT);
+    schema2.addColumn("manager", Type.TEXT);
+
+    Schema schema3 = new Schema();
+    schema3.addColumn("deptname", Type.TEXT);
+    schema3.addColumn("score", Type.INT4);
+
+    TableMeta meta = CatalogUtil.newTableMeta("TEXT");
+    TableDesc people = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "employee"), schema, meta,
+        CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(people);
+
+    TableDesc student = new TableDesc(
+        CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), schema2, "TEXT", new KeyValueSet(),
+        CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(student);
+
+    TableDesc score = new TableDesc(
+        CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), schema3, "TEXT", new KeyValueSet(),
+        CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(score);
+
+    FunctionDesc funcDesc = new FunctionDesc("sumtest", SumInt.class, FunctionType.AGGREGATION,
+        CatalogUtil.newSimpleDataType(Type.INT4),
+        CatalogUtil.newSimpleDataTypeArray(Type.INT4));
+
+
+    // TPC-H Schema for Complex Queries
+    String [] tpchTables = {
+        "part", "supplier", "partsupp", "nation", "region", "lineitem"
+    };
+    tpch = new TPCH();
+    tpch.loadSchemas();
+    tpch.loadOutSchema();
+    for (String table : tpchTables) {
+      TableMeta m = CatalogUtil.newTableMeta("TEXT");
+      TableDesc d = CatalogUtil.newTableDesc(
+          CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, table), tpch.getSchema(table), m,
+          CommonTestingUtil.getTestDir());
+      catalog.createTable(d);
+    }
+
+    catalog.createFunction(funcDesc);
+    sqlAnalyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  static String[] QUERIES = {
+      "select name, empid, deptname from employee where empId > 500", // 0
+      "select name, empid, e.deptname, manager from employee as e, dept as dp", // 1
+      "select name, empid, e.deptname, manager, score from employee as e, dept, score", // 2
+      "select p.deptname, sumtest(score) from dept as p, score group by p.deptName having sumtest(score) > 30", // 3
+      "select p.deptname, score*200 from dept as p, score order by score*10 asc", // 4
+      "select name from employee where empId = 100", // 5
+      "select name, score from employee, score", // 6
+      "select p.deptName, sumtest(score) from dept as p, score group by p.deptName", // 7
+      "create table store1 as select p.deptName, sumtest(score) from dept as p, score group by p.deptName", // 8
+      "select deptName, sumtest(score) from score group by deptName having sumtest(score) > 30", // 9
+      "select 7 + 8 as res1, 8 * 9 as res2, 10 * 10 as res3", // 10
+      "create index idx_employee on employee using bitmap_idx (name null first, empId desc) where empid > 100", // 11
+      "select name, score from employee, score order by score limit 3", // 12
+      "select length(name), length(deptname), *, empid+10 from employee where empId > 500", // 13
+  };
+
+  private static QueryContext createQueryContext() {
+    QueryContext qc = new QueryContext(util.getConfiguration(), session);
+    qc.put(QueryVars.DEFAULT_SPACE_URI, "file:/");
+    qc.put(QueryVars.DEFAULT_SPACE_ROOT_URI, "file:/");
+    return qc;
+  }
+
+  public static final void testCloneLogicalNode(LogicalNode n1) throws CloneNotSupportedException {
+    LogicalNode copy = (LogicalNode) n1.clone();
+    assertTrue(n1.deepEquals(copy));
+  }
+
+  @Test
+  public final void testSingleRelation() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[0]);
+    LogicalPlan planNode = planner.createPlan(qc, expr);
+    LogicalNode plan = planNode.getRootBlock().getRoot();
+    assertEquals(NodeType.ROOT, plan.getType());
+    testCloneLogicalNode(plan);
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    SelectionNode selNode = projNode.getChild();
+
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+    ScanNode scanNode = selNode.getChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), scanNode.getTableName());
+  }
+
+  public static void assertSchema(Schema expected, Schema schema) {
+    Column expectedColumn;
+    Column column;
+    for (int i = 0; i < expected.size(); i++) {
+      expectedColumn = expected.getColumn(i);
+      column = schema.getColumn(expectedColumn.getSimpleName());
+      assertEquals(expectedColumn.getSimpleName(), column.getSimpleName());
+      assertEquals(expectedColumn.getDataType(), column.getDataType());
+    }
+  }
+
+  @Test
+  public final void testImplicityJoinPlan() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    // two relations
+    Expr expr = sqlAnalyzer.parse(QUERIES[1]);
+    LogicalPlan planNode = planner.createPlan(qc, expr);
+    LogicalNode plan = planNode.getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+    testCloneLogicalNode(root);
+
+    Schema expectedSchema = new Schema();
+    expectedSchema.addColumn("name", Type.TEXT);
+    expectedSchema.addColumn("empid", Type.INT4);
+    expectedSchema.addColumn("deptname", Type.TEXT);
+    expectedSchema.addColumn("manager", Type.TEXT);
+    for (int i = 0; i < expectedSchema.size(); i++) {
+      Column found = root.getOutSchema().getColumn(expectedSchema.getColumn(i).getSimpleName());
+      assertEquals(expectedSchema.getColumn(i).getDataType(), found.getDataType());
+    }
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+
+    assertEquals(NodeType.JOIN, projNode.getChild().getType());
+    JoinNode joinNode = projNode.getChild();
+
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    ScanNode leftNode = joinNode.getLeftChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), leftNode.getTableName());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+    ScanNode rightNode = joinNode.getRightChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), rightNode.getTableName());
+
+    // three relations
+    expr = sqlAnalyzer.parse(QUERIES[2]);
+    plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    testCloneLogicalNode(plan);
+
+    expectedSchema.addColumn("score", Type.INT4);
+    assertSchema(expectedSchema, plan.getOutSchema());
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    root = (LogicalRootNode) plan;
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    projNode = root.getChild();
+
+    assertEquals(NodeType.JOIN, projNode.getChild().getType());
+    joinNode = projNode.getChild();
+
+    assertEquals(NodeType.JOIN, joinNode.getLeftChild().getType());
+
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+    ScanNode scan1 = joinNode.getRightChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), scan1.getTableName());
+
+    JoinNode leftNode2 = joinNode.getLeftChild();
+    assertEquals(NodeType.JOIN, leftNode2.getType());
+
+    assertEquals(NodeType.SCAN, leftNode2.getLeftChild().getType());
+    ScanNode leftScan = leftNode2.getLeftChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), leftScan.getTableName());
+
+    assertEquals(NodeType.SCAN, leftNode2.getRightChild().getType());
+    ScanNode rightScan = leftNode2.getRightChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), rightScan.getTableName());
+  }
+
+
+
+  String [] JOINS = {
+      "select name, dept.deptName, score from employee natural join dept natural join score", // 0
+      "select name, dept.deptName, score from employee inner join dept on employee.deptName = dept.deptName inner join score on dept.deptName = score.deptName", // 1
+      "select name, dept.deptName, score from employee left outer join dept on employee.deptName = dept.deptName right outer join score on dept.deptName = score.deptName" // 2
+  };
+
+  static Schema expectedJoinSchema;
+  static {
+    expectedJoinSchema = new Schema();
+    expectedJoinSchema.addColumn("name", Type.TEXT);
+    expectedJoinSchema.addColumn("deptname", Type.TEXT);
+    expectedJoinSchema.addColumn("score", Type.INT4);
+  }
+
+  @Test
+  public final void testNaturalJoinPlan() throws TajoException {
+    QueryContext qc = createQueryContext();
+    // two relations
+    Expr context = sqlAnalyzer.parse(JOINS[0]);
+    LogicalNode plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertSchema(expectedJoinSchema, plan.getOutSchema());
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode proj = root.getChild();
+    assertEquals(NodeType.JOIN, proj.getChild().getType());
+    JoinNode join = proj.getChild();
+    assertEquals(JoinType.INNER, join.getJoinType());
+    assertEquals(NodeType.SCAN, join.getRightChild().getType());
+    assertTrue(join.hasJoinQual());
+    ScanNode scan = join.getRightChild();
+    assertEquals("default.score", scan.getTableName());
+
+    assertEquals(NodeType.JOIN, join.getLeftChild().getType());
+    join = join.getLeftChild();
+    assertEquals(JoinType.INNER, join.getJoinType());
+    assertEquals(NodeType.SCAN, join.getLeftChild().getType());
+    ScanNode outer = join.getLeftChild();
+    assertEquals("default.employee", outer.getTableName());
+    assertEquals(NodeType.SCAN, join.getRightChild().getType());
+    ScanNode inner = join.getRightChild();
+    assertEquals("default.dept", inner.getTableName());
+  }
+
+  @Test
+  public final void testInnerJoinPlan() throws TajoException {
+    QueryContext qc = createQueryContext();
+    // two relations
+    Expr expr = sqlAnalyzer.parse(JOINS[1]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    LogicalNode root = plan.getRootBlock().getRoot();
+    testJsonSerDerObject(root);
+    assertSchema(expectedJoinSchema, root.getOutSchema());
+
+    assertEquals(NodeType.ROOT, root.getType());
+    assertEquals(NodeType.PROJECTION, ((LogicalRootNode)root).getChild().getType());
+    ProjectionNode proj = ((LogicalRootNode)root).getChild();
+    assertEquals(NodeType.JOIN, proj.getChild().getType());
+    JoinNode join = proj.getChild();
+    assertEquals(JoinType.INNER, join.getJoinType());
+    assertEquals(NodeType.SCAN, join.getRightChild().getType());
+    ScanNode scan = join.getRightChild();
+    assertEquals("default.score", scan.getTableName());
+
+    assertEquals(NodeType.JOIN, join.getLeftChild().getType());
+    join = join.getLeftChild();
+    assertEquals(JoinType.INNER, join.getJoinType());
+    assertEquals(NodeType.SCAN, join.getLeftChild().getType());
+    ScanNode outer = join.getLeftChild();
+    assertEquals("default.employee", outer.getTableName());
+    assertEquals(NodeType.SCAN, join.getRightChild().getType());
+    ScanNode inner = join.getRightChild();
+    assertEquals("default.dept", inner.getTableName());
+    assertTrue(join.hasJoinQual());
+    assertEquals(EvalType.EQUAL, join.getJoinQual().getType());
+  }
+
+  @Test
+  public final void testOuterJoinPlan() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    // two relations
+    Expr expr = sqlAnalyzer.parse(JOINS[2]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertSchema(expectedJoinSchema, plan.getOutSchema());
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode proj = root.getChild();
+    assertEquals(NodeType.JOIN, proj.getChild().getType());
+    JoinNode join = proj.getChild();
+    assertEquals(JoinType.RIGHT_OUTER, join.getJoinType());
+    assertEquals(NodeType.SCAN, join.getRightChild().getType());
+    ScanNode scan = join.getRightChild();
+    assertEquals("default.score", scan.getTableName());
+
+    assertEquals(NodeType.JOIN, join.getLeftChild().getType());
+    join = join.getLeftChild();
+    assertEquals(JoinType.LEFT_OUTER, join.getJoinType());
+    assertEquals(NodeType.SCAN, join.getLeftChild().getType());
+    ScanNode outer = join.getLeftChild();
+    assertEquals("default.employee", outer.getTableName());
+    assertEquals(NodeType.SCAN, join.getRightChild().getType());
+    ScanNode inner = join.getRightChild();
+    assertEquals("default.dept", inner.getTableName());
+    assertTrue(join.hasJoinQual());
+    assertEquals(EvalType.EQUAL, join.getJoinQual().getType());
+  }
+
+
+  @Test
+  public final void testGroupby() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    // without 'having clause'
+    Expr context = sqlAnalyzer.parse(QUERIES[7]);
+    LogicalNode plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+    testQuery7(root.getChild());
+
+    // with having clause
+    context = sqlAnalyzer.parse(QUERIES[3]);
+    plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+    testCloneLogicalNode(plan);
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    root = (LogicalRootNode) plan;
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+    assertEquals(NodeType.HAVING, projNode.getChild().getType());
+    HavingNode havingNode = projNode.getChild();
+    assertEquals(NodeType.GROUP_BY, havingNode.getChild().getType());
+    GroupbyNode groupByNode =  havingNode.getChild();
+
+    assertEquals(NodeType.JOIN, groupByNode.getChild().getType());
+    JoinNode joinNode = groupByNode.getChild();
+
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    ScanNode leftNode = joinNode.getLeftChild();
+    assertEquals("default.dept", leftNode.getTableName());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+    ScanNode rightNode = joinNode.getRightChild();
+    assertEquals("default.score", rightNode.getTableName());
+
+    //LogicalOptimizer.optimize(context, plan);
+  }
+
+
+  @Test
+  public final void testMultipleJoin() throws IOException, TajoException {
+    Expr expr = sqlAnalyzer.parse(
+        FileUtil.readTextFile(new File("src/test/resources/queries/TestJoinQuery/testTPCHQ2Join.sql")));
+    QueryContext qc = createQueryContext();
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    Schema expected = tpch.getOutSchema("q2");
+    assertSchema(expected, plan.getOutSchema());
+  }
+
+  private final void findJoinQual(EvalNode evalNode, Map<BinaryEval, Boolean> qualMap,
+                                  EvalType leftType, EvalType rightType)
+      throws IOException, TajoException {
+    Preconditions.checkArgument(evalNode instanceof BinaryEval);
+    BinaryEval qual = (BinaryEval)evalNode;
+
+    if (qual.getLeftExpr().getType() == leftType && qual.getRightExpr().getType() == rightType) {
+      assertEquals(qual.getLeftExpr().getType(), EvalType.FIELD);
+      FieldEval leftField = (FieldEval)qual.getLeftExpr();
+
+      for (Map.Entry<BinaryEval, Boolean> entry : qualMap.entrySet()) {
+        FieldEval leftJoinField = (FieldEval)entry.getKey().getLeftExpr();
+
+        if (qual.getRightExpr().getType() == entry.getKey().getRightExpr().getType()) {
+          if (rightType == EvalType.FIELD) {
+            FieldEval rightField = (FieldEval)qual.getRightExpr();
+            FieldEval rightJoinField = (FieldEval)entry.getKey().getRightExpr();
+
+            if (leftJoinField.getColumnRef().getQualifiedName().equals(leftField.getColumnRef().getQualifiedName())
+                && rightField.getColumnRef().getQualifiedName().equals(rightJoinField.getColumnRef().getQualifiedName())) {
+              qualMap.put(entry.getKey(), Boolean.TRUE);
+            }
+          } else if (rightType == EvalType.CONST) {
+            ConstEval rightField = (ConstEval)qual.getRightExpr();
+            ConstEval rightJoinField = (ConstEval)entry.getKey().getRightExpr();
+
+            if (leftJoinField.getColumnRef().getQualifiedName().equals(leftField.getColumnRef().getQualifiedName()) &&
+                rightField.getValue().equals(rightJoinField.getValue())) {
+              qualMap.put(entry.getKey(), Boolean.TRUE);
+            }
+          } else if (rightType == EvalType.ROW_CONSTANT) {
+            RowConstantEval rightField = qual.getRightExpr();
+            RowConstantEval rightJoinField = entry.getKey().getRightExpr();
+
+            if (leftJoinField.getColumnRef().getQualifiedName().equals(leftField.getColumnRef().getQualifiedName())) {
+              assertEquals(rightField.getValues().length, rightJoinField.getValues().length);
+              for (int i = 0; i < rightField.getValues().length; i++) {
+                assertEquals(rightField.getValues()[i], rightJoinField.getValues()[i]);
+              }
+              qualMap.put(entry.getKey(), Boolean.TRUE);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  @Test
+  public final void testJoinWithMultipleJoinQual1() throws IOException, TajoException {
+    Expr expr = sqlAnalyzer.parse(
+        FileUtil.readTextFile(new File
+            ("src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual1.sql")));
+    QueryContext qc = createQueryContext();
+
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    LogicalNode node = plan.getRootBlock().getRoot();
+    testJsonSerDerObject(node);
+
+    Schema expected = tpch.getOutSchema("q2");
+    assertSchema(expected, node.getOutSchema());
+
+    LogicalOptimizer optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+    optimizer.optimize(plan);
+
+    LogicalNode[] nodes = PlannerUtil.findAllNodes(node, NodeType.JOIN);
+    Map<BinaryEval, Boolean> qualMap = TUtil.newHashMap();
+    BinaryEval joinQual = new BinaryEval(EvalType.EQUAL
+        , new FieldEval(new Column("default.n.n_regionkey", Type.INT4))
+        , new FieldEval(new Column("default.ps.ps_suppkey", Type.INT4))
+        );
+    qualMap.put(joinQual, Boolean.FALSE);
+
+    for(LogicalNode eachNode : nodes) {
+      JoinNode joinNode = (JoinNode)eachNode;
+      EvalNode[] evalNodes = AlgebraicUtil.toConjunctiveNormalFormArray(joinNode.getJoinQual());
+
+      for(EvalNode evalNode : evalNodes) {
+        findJoinQual(evalNode, qualMap, EvalType.FIELD, EvalType.FIELD);
+      }
+    }
+
+    for (Map.Entry<BinaryEval, Boolean> entry : qualMap.entrySet()) {
+      if (!entry.getValue()) {
+        Preconditions.checkArgument(false,
+            "JoinQual not found. -> required JoinQual:" + entry.getKey().toJson());
+      }
+    }
+  }
+
+  @Test
+  public final void testJoinWithMultipleJoinQual2() throws IOException, TajoException {
+    Expr expr = sqlAnalyzer.parse(
+        FileUtil.readTextFile(new File
+            ("src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual2.sql")));
+    QueryContext qc = createQueryContext();
+
+    LogicalPlan plan = planner.createPlan(qc,expr);
+    LogicalNode node = plan.getRootBlock().getRoot();
+    testJsonSerDerObject(node);
+
+    LogicalOptimizer optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+    optimizer.optimize(plan);
+
+    LogicalNode[] nodes = PlannerUtil.findAllNodes(node, NodeType.SCAN);
+    Map<BinaryEval, Boolean> qualMap = TUtil.newHashMap();
+    BinaryEval joinQual = new BinaryEval(EvalType.EQUAL
+        , new FieldEval(new Column("default.n.n_name", Type.TEXT))
+        , new ConstEval(new TextDatum("MOROCCO"))
+    );
+    qualMap.put(joinQual, Boolean.FALSE);
+
+    for(LogicalNode eachNode : nodes) {
+      ScanNode scanNode = (ScanNode)eachNode;
+      if (scanNode.hasQual()) {
+        EvalNode[] evalNodes = AlgebraicUtil.toConjunctiveNormalFormArray(scanNode.getQual());
+
+        for(EvalNode evalNode : evalNodes) {
+          findJoinQual(evalNode, qualMap, EvalType.FIELD, EvalType.CONST);
+        }
+      }
+    }
+
+    for (Map.Entry<BinaryEval, Boolean> entry : qualMap.entrySet()) {
+      if (!entry.getValue()) {
+        Preconditions.checkArgument(false,
+            "SelectionQual not found. -> required JoinQual:" + entry.getKey().toJson());
+      }
+    }
+  }
+
+  @Test
+  public final void testJoinWithMultipleJoinQual3() throws IOException, TajoException {
+    Expr expr = sqlAnalyzer.parse(
+        FileUtil.readTextFile(new File
+            ("src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual3.sql")));
+    QueryContext qc = createQueryContext();
+
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    LogicalNode node = plan.getRootBlock().getRoot();
+    testJsonSerDerObject(node);
+
+    LogicalOptimizer optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+    optimizer.optimize(plan);
+
+    LogicalNode[] nodes = PlannerUtil.findAllNodes(node, NodeType.SCAN);
+    Map<BinaryEval, Boolean> qualMap = TUtil.newHashMap();
+    TextDatum[] datums = new TextDatum[3];
+    datums[0] = new TextDatum("ARGENTINA");
+    datums[1] = new TextDatum("ETHIOPIA");
+    datums[2] = new TextDatum("MOROCCO");
+
+    BinaryEval joinQual = new BinaryEval(EvalType.EQUAL
+        , new FieldEval(new Column("default.n.n_name", Type.TEXT))
+        , new RowConstantEval(datums)
+    );
+    qualMap.put(joinQual, Boolean.FALSE);
+
+    for(LogicalNode eachNode : nodes) {
+      ScanNode scanNode = (ScanNode)eachNode;
+      if (scanNode.hasQual()) {
+        EvalNode[] evalNodes = AlgebraicUtil.toConjunctiveNormalFormArray(scanNode.getQual());
+
+        for(EvalNode evalNode : evalNodes) {
+          findJoinQual(evalNode, qualMap, EvalType.FIELD, EvalType.ROW_CONSTANT);
+        }
+      }
+    }
+
+    for (Map.Entry<BinaryEval, Boolean> entry : qualMap.entrySet()) {
+      if (!entry.getValue()) {
+        Preconditions.checkArgument(false,
+            "ScanQual not found. -> required JoinQual:" + entry.getKey().toJson());
+      }
+    }
+  }
+
+
+  @Test
+  public final void testJoinWithMultipleJoinQual4() throws IOException, TajoException {
+    Expr expr = sqlAnalyzer.parse(
+        FileUtil.readTextFile(new File
+            ("src/test/resources/queries/TestJoinQuery/testJoinWithMultipleJoinQual4.sql")));
+    QueryContext qc = createQueryContext();
+
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    LogicalNode node = plan.getRootBlock().getRoot();
+    testJsonSerDerObject(node);
+
+    LogicalOptimizer optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+    optimizer.optimize(plan);
+
+    Map<BinaryEval, Boolean> scanMap = TUtil.newHashMap();
+    TextDatum[] datums = new TextDatum[3];
+    datums[0] = new TextDatum("ARGENTINA");
+    datums[1] = new TextDatum("ETHIOPIA");
+    datums[2] = new TextDatum("MOROCCO");
+
+    BinaryEval scanQual = new BinaryEval(EvalType.EQUAL
+        , new FieldEval(new Column("default.n.n_name", Type.TEXT))
+        , new RowConstantEval(datums)
+    );
+    scanMap.put(scanQual, Boolean.FALSE);
+
+    Map<BinaryEval, Boolean> joinQualMap = TUtil.newHashMap();
+    BinaryEval joinQual = new BinaryEval(EvalType.GTH
+        , new FieldEval(new Column("default.t.n_nationkey", Type.INT4))
+        , new FieldEval(new Column("default.s.s_suppkey", Type.INT4))
+    );
+
+    /* following code is commented because theta join is not supported yet
+     * TODO It SHOULD be restored after TAJO-742 is resolved. */
+    //joinQualMap.put(joinQual, Boolean.FALSE);
+
+    LogicalNode[] nodes = PlannerUtil.findAllNodes(node, NodeType.JOIN);
+    for(LogicalNode eachNode : nodes) {
+      JoinNode joinNode = (JoinNode)eachNode;
+      if (joinNode.hasJoinQual()) {
+        EvalNode[] evalNodes = AlgebraicUtil.toConjunctiveNormalFormArray(joinNode.getJoinQual());
+
+        for(EvalNode evalNode : evalNodes) {
+          findJoinQual(evalNode, joinQualMap, EvalType.FIELD, EvalType.FIELD);
+        }
+      }
+    }
+
+    nodes = PlannerUtil.findAllNodes(node, NodeType.SCAN);
+    for(LogicalNode eachNode : nodes) {
+      ScanNode scanNode = (ScanNode)eachNode;
+      if (scanNode.hasQual()) {
+        EvalNode[] evalNodes = AlgebraicUtil.toConjunctiveNormalFormArray(scanNode.getQual());
+
+        for(EvalNode evalNode : evalNodes) {
+          findJoinQual(evalNode, scanMap, EvalType.FIELD, EvalType.ROW_CONSTANT);
+        }
+      }
+    }
+
+
+    for (Map.Entry<BinaryEval, Boolean> entry : joinQualMap.entrySet()) {
+      if (!entry.getValue()) {
+        Preconditions.checkArgument(false,
+            "JoinQual not found. -> required JoinQual:" + entry.getKey().toJson());
+      }
+    }
+
+    for (Map.Entry<BinaryEval, Boolean> entry : scanMap.entrySet()) {
+      if (!entry.getValue()) {
+        Preconditions.checkArgument(false,
+            "ScanQual not found. -> required JoinQual:" + entry.getKey().toJson());
+      }
+    }
+  }
+
+  static void testQuery7(LogicalNode plan) {
+    assertEquals(NodeType.PROJECTION, plan.getType());
+    ProjectionNode projNode = (ProjectionNode) plan;
+    assertEquals(NodeType.GROUP_BY, projNode.getChild().getType());
+    GroupbyNode groupByNode = projNode.getChild();
+
+    assertEquals(NodeType.JOIN, groupByNode.getChild().getType());
+    JoinNode joinNode = groupByNode.getChild();
+
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    ScanNode leftNode = joinNode.getLeftChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), leftNode.getTableName());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+    ScanNode rightNode = joinNode.getRightChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), rightNode.getTableName());
+  }
+
+
+  @Test
+  public final void testStoreTable() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr context = sqlAnalyzer.parse(QUERIES[8]);
+
+    LogicalNode plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+    testCloneLogicalNode(plan);
+    testJsonSerDerObject(plan);
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+
+    assertEquals(NodeType.CREATE_TABLE, root.getChild().getType());
+    StoreTableNode storeNode = root.getChild();
+    testQuery7(storeNode.getChild());
+  }
+
+  @Test
+  public final void testOrderBy() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[4]);
+
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    testCloneLogicalNode(plan);
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+
+    assertEquals(NodeType.SORT, projNode.getChild().getType());
+    SortNode sortNode = projNode.getChild();
+
+    assertEquals(NodeType.JOIN, sortNode.getChild().getType());
+    JoinNode joinNode = sortNode.getChild();
+
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    ScanNode leftNode = joinNode.getLeftChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), leftNode.getTableName());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+    ScanNode rightNode = joinNode.getRightChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), rightNode.getTableName());
+  }
+
+  @Test
+  public final void testLimit() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[12]);
+
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    testCloneLogicalNode(plan);
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+
+    assertEquals(NodeType.LIMIT, projNode.getChild().getType());
+    LimitNode limitNode = projNode.getChild();
+
+    assertEquals(NodeType.SORT, limitNode.getChild().getType());
+  }
+
+  @Test
+  public final void testSPJPush() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[5]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    testCloneLogicalNode(plan);
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    SelectionNode selNode = projNode.getChild();
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+    ScanNode scanNode = selNode.getChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), scanNode.getTableName());
+  }
+
+
+
+  @Test
+  public final void testSPJ() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[6]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    testCloneLogicalNode(plan);
+  }
+
+  @Test
+  public final void testJson() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+	  Expr expr = sqlAnalyzer.parse(QUERIES[9]);
+	  LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+
+	  String json = plan.toJson();
+	  LogicalNode fromJson = CoreGsonHelper.fromJson(json, LogicalNode.class);
+	  assertEquals(NodeType.ROOT, fromJson.getType());
+	  LogicalNode project = ((LogicalRootNode)fromJson).getChild();
+	  assertEquals(NodeType.PROJECTION, project.getType());
+	  assertEquals(NodeType.HAVING, ((ProjectionNode) project).getChild().getType());
+    HavingNode havingNode = ((ProjectionNode) project).getChild();
+    assertEquals(NodeType.GROUP_BY, havingNode.getChild().getType());
+    GroupbyNode groupbyNode = havingNode.getChild();
+    assertEquals(NodeType.SCAN, groupbyNode.getChild().getType());
+	  LogicalNode scan = groupbyNode.getChild();
+	  assertEquals(NodeType.SCAN, scan.getType());
+  }
+
+  @Test
+  public final void testVisitor() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    // two relations
+    Expr expr = sqlAnalyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+
+    TestVisitor vis = new TestVisitor();
+    plan.postOrder(vis);
+
+    assertEquals(NodeType.ROOT, vis.stack.pop().getType());
+    assertEquals(NodeType.PROJECTION, vis.stack.pop().getType());
+    assertEquals(NodeType.JOIN, vis.stack.pop().getType());
+    assertEquals(NodeType.SCAN, vis.stack.pop().getType());
+    assertEquals(NodeType.SCAN, vis.stack.pop().getType());
+  }
+
+  private static class TestVisitor implements LogicalNodeVisitor {
+    Stack<LogicalNode> stack = new Stack<LogicalNode>();
+    @Override
+    public void visit(LogicalNode node) {
+      stack.push(node);
+    }
+  }
+
+
+  @Test
+  public final void testExprNode() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[10]);
+    LogicalPlan rootNode = planner.createPlan(qc, expr);
+    LogicalNode plan = rootNode.getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.EXPRS, root.getChild().getType());
+    Schema out = root.getOutSchema();
+
+    Iterator<Column> it = out.getRootColumns().iterator();
+    Column col = it.next();
+    assertEquals("res1", col.getSimpleName());
+    col = it.next();
+    assertEquals("res2", col.getSimpleName());
+    col = it.next();
+    assertEquals("res3", col.getSimpleName());
+  }
+
+  @Test
+  public final void testCreateIndexNode() throws TajoException {
+    QueryContext qc = new QueryContext(util.getConfiguration(), session);
+    Expr expr = sqlAnalyzer.parse(QUERIES[11]);
+    LogicalPlan rootNode = planner.createPlan(qc, expr);
+    LogicalNode plan = rootNode.getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.CREATE_INDEX, root.getChild().getType());
+    CreateIndexNode createIndexNode = root.getChild();
+
+    assertEquals(NodeType.PROJECTION, createIndexNode.getChild().getType());
+    ProjectionNode projNode = createIndexNode.getChild();
+
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    SelectionNode selNode = projNode.getChild();
+
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+    ScanNode scanNode = selNode.getChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), scanNode.getTableName());
+  }
+
+  @Test
+  public final void testAsterisk() throws CloneNotSupportedException, TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(QUERIES[13]);
+    LogicalPlan planNode = planner.createPlan(qc, expr);
+    LogicalNode plan = planNode.getRootBlock().getRoot();
+    assertEquals(NodeType.ROOT, plan.getType());
+    testCloneLogicalNode(plan);
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+    assertEquals(6, projNode.getOutSchema().size());
+
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    SelectionNode selNode = projNode.getChild();
+
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+    ScanNode scanNode = selNode.getChild();
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), scanNode.getTableName());
+  }
+
+  static final String ALIAS [] = {
+    "select deptName, sum(score) as total from score group by deptName",
+    "select em.empId as id, sum(score) as total from employee as em inner join score using (em.deptName) group by id"
+  };
+
+
+  @Test
+  public final void testAlias1() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(ALIAS[0]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+
+    Schema finalSchema = root.getOutSchema();
+    Iterator<Column> it = finalSchema.getRootColumns().iterator();
+    Column col = it.next();
+    assertEquals("deptname", col.getSimpleName());
+    col = it.next();
+    assertEquals("total", col.getSimpleName());
+
+    expr = sqlAnalyzer.parse(ALIAS[1]);
+    plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    root = (LogicalRootNode) plan;
+
+    finalSchema = root.getOutSchema();
+    it = finalSchema.getRootColumns().iterator();
+    col = it.next();
+    assertEquals("id", col.getSimpleName());
+    col = it.next();
+    assertEquals("total", col.getSimpleName());
+  }
+
+  @Test
+  public final void testAlias2() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(ALIAS[1]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+
+    Schema finalSchema = root.getOutSchema();
+    Iterator<Column> it = finalSchema.getRootColumns().iterator();
+    Column col = it.next();
+    assertEquals("id", col.getSimpleName());
+    col = it.next();
+    assertEquals("total", col.getSimpleName());
+  }
+
+  static final String CREATE_TABLE [] = {
+    "create external table table1 (name text, age int, earn bigint, score real) using csv with ('csv.delimiter'='|') location '/tmp/data'"
+  };
+
+  @Test
+  public final void testCreateTableDef() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(CREATE_TABLE[0]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    LogicalRootNode root = (LogicalRootNode) plan;
+    testJsonSerDerObject(root);
+    assertEquals(NodeType.CREATE_TABLE, root.getChild().getType());
+    CreateTableNode createTable = root.getChild();
+
+    Schema def = createTable.getTableSchema();
+    assertEquals("name", def.getColumn(0).getSimpleName());
+    assertEquals(Type.TEXT, def.getColumn(0).getDataType().getType());
+    assertEquals("age", def.getColumn(1).getSimpleName());
+    assertEquals(Type.INT4, def.getColumn(1).getDataType().getType());
+    assertEquals("earn", def.getColumn(2).getSimpleName());
+    assertEquals(Type.INT8, def.getColumn(2).getDataType().getType());
+    assertEquals("score", def.getColumn(3).getSimpleName());
+    assertEquals(Type.FLOAT4, def.getColumn(3).getDataType().getType());
+    assertTrue("TEXT".equalsIgnoreCase(createTable.getStorageType()));
+    assertEquals("file://tmp/data", createTable.getUri().toString());
+    assertTrue(createTable.hasOptions());
+    assertEquals("|", createTable.getOptions().get("csv.delimiter"));
+  }
+
+  private static final List<Set<Column>> testGenerateCuboidsResult
+    = Lists.newArrayList();
+  private static final int numCubeColumns = 3;
+  private static final Column [] testGenerateCuboids = new Column[numCubeColumns];
+
+  private static final List<Set<Column>> testCubeByResult
+    = Lists.newArrayList();
+  private static final Column [] testCubeByCuboids = new Column[2];
+  static {
+    testGenerateCuboids[0] = new Column("col1", Type.INT4);
+    testGenerateCuboids[1] = new Column("col2", Type.INT8);
+    testGenerateCuboids[2] = new Column("col3", Type.FLOAT4);
+
+    testGenerateCuboidsResult.add(new HashSet<Column>());
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[0]));
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[1]));
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[2]));
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[0],
+        testGenerateCuboids[1]));
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[0],
+        testGenerateCuboids[2]));
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[1],
+        testGenerateCuboids[2]));
+    testGenerateCuboidsResult.add(Sets.newHashSet(testGenerateCuboids[0],
+        testGenerateCuboids[1], testGenerateCuboids[2]));
+
+    testCubeByCuboids[0] = new Column("employee.name", Type.TEXT);
+    testCubeByCuboids[1] = new Column("employee.empid", Type.INT4);
+    testCubeByResult.add(new HashSet<Column>());
+    testCubeByResult.add(Sets.newHashSet(testCubeByCuboids[0]));
+    testCubeByResult.add(Sets.newHashSet(testCubeByCuboids[1]));
+    testCubeByResult.add(Sets.newHashSet(testCubeByCuboids[0],
+        testCubeByCuboids[1]));
+  }
+
+  @Test
+  public final void testGenerateCuboids() {
+    Column [] columns = new Column[3];
+
+    columns[0] = new Column("col1", Type.INT4);
+    columns[1] = new Column("col2", Type.INT8);
+    columns[2] = new Column("col3", Type.FLOAT4);
+
+    List<Column[]> cube = LogicalPlanner.generateCuboids(columns);
+    assertEquals(((int)Math.pow(2, numCubeColumns)), cube.size());
+
+    Set<Set<Column>> cuboids = Sets.newHashSet();
+    for (Column [] cols : cube) {
+      cuboids.add(Sets.newHashSet(cols));
+    }
+
+    for (Set<Column> result : testGenerateCuboidsResult) {
+      assertTrue(cuboids.contains(result));
+    }
+  }
+
+  static final String setStatements [] = {
+    "select deptName from employee where deptName like 'data%' union all select deptName from score where deptName like 'data%'",
+  };
+
+  @Test
+  public final void testSetPlan() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(setStatements[0]);
+    LogicalNode plan = planner.createPlan(qc, expr).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.UNION, root.getChild().getType());
+    UnionNode union = root.getChild();
+    assertEquals(NodeType.PROJECTION, union.getLeftChild().getType());
+    assertEquals(NodeType.PROJECTION, union.getRightChild().getType());
+  }
+
+  static final String [] setQualifiers = {
+    "select name, empid from employee",
+    "select distinct name, empid from employee",
+    "select all name, empid from employee",
+  };
+
+  @Test
+  public void testSetQualifier() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr context = sqlAnalyzer.parse(setQualifiers[0]);
+    LogicalNode plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projectionNode = root.getChild();
+    assertEquals(NodeType.SCAN, projectionNode.getChild().getType());
+
+    context = sqlAnalyzer.parse(setQualifiers[1]);
+    plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertEquals(NodeType.ROOT, plan.getType());
+    root = (LogicalRootNode) plan;
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    projectionNode = root.getChild();
+    assertEquals(NodeType.GROUP_BY, projectionNode.getChild().getType());
+
+    context = sqlAnalyzer.parse(setQualifiers[2]);
+    plan = planner.createPlan(qc, context).getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    root = (LogicalRootNode) plan;
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    projectionNode = root.getChild();
+    assertEquals(NodeType.SCAN, projectionNode.getChild().getType());
+  }
+
+  public void testJsonSerDerObject(LogicalNode rootNode) {
+    String json = rootNode.toJson();
+    LogicalNode fromJson = CoreGsonHelper.fromJson(json, LogicalNode.class);
+    assertTrue("JSON (de) serialization equivalence check", rootNode.deepEquals(fromJson));
+  }
+
+  // Table descriptions
+  //
+  // employee (name text, empid int4, deptname text)
+  // dept (deptname text, manager text)
+  // score (deptname text, score inet4)
+
+  static final String [] insertStatements = {
+      "insert into score select name from employee",                        // 0
+      "insert into score select name, empid from employee",                 // 1
+      "insert into employee (name, deptname) select * from dept",           // 2
+      "insert into location '/tmp/data' select name, empid from employee",  // 3
+      "insert overwrite into employee (name, deptname) select * from dept", // 4
+      "insert overwrite into LOCATION '/tmp/data' select * from dept",      // 5
+      "insert into employee (deptname, name) select deptname, manager from dept"  // 6
+  };
+
+  @Test
+  public final void testInsertInto0() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[0]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+    assertFalse(insertNode.isOverwrite());
+    assertTrue(insertNode.hasTargetTable());
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), insertNode.getTableName());
+  }
+
+  @Test
+  public final void testInsertInto1() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[1]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+    assertFalse(insertNode.isOverwrite());
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), insertNode.getTableName());
+  }
+
+  @Test
+  public final void testInsertInto2() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[2]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+    assertFalse(insertNode.isOverwrite());
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), insertNode.getTableName());
+    assertTrue(insertNode.hasTargetSchema());
+    assertEquals(insertNode.getTargetSchema().getColumn(0).getSimpleName(), "name");
+    assertEquals(insertNode.getTargetSchema().getColumn(1).getSimpleName(), "deptname");
+  }
+
+  @Test
+  public final void testInsertInto3() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[3]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+    assertFalse(insertNode.isOverwrite());
+    assertTrue(insertNode.hasUri());
+  }
+
+  @Test
+  public final void testInsertInto4() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[4]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+    assertTrue(insertNode.isOverwrite());
+    assertTrue(insertNode.hasTargetTable());
+    assertEquals(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), insertNode.getTableName());
+    assertTrue(insertNode.hasTargetSchema());
+    assertEquals(insertNode.getTargetSchema().getColumn(0).getSimpleName(), "name");
+    assertEquals(insertNode.getTargetSchema().getColumn(1).getSimpleName(), "deptname");
+  }
+
+  @Test
+  public final void testInsertInto5() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[5]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+    assertTrue(insertNode.isOverwrite());
+    assertTrue(insertNode.hasUri());
+  }
+
+  @Test
+  public final void testInsertInto6() throws TajoException {
+    QueryContext qc = createQueryContext();
+
+    Expr expr = sqlAnalyzer.parse(insertStatements[6]);
+    LogicalPlan plan = planner.createPlan(qc, expr);
+    assertEquals(1, plan.getQueryBlocks().size());
+    InsertNode insertNode = getInsertNode(plan);
+
+    ProjectionNode subquery = insertNode.getChild();
+    Target[] targets = subquery.getTargets();
+    // targets MUST be manager, NULL as empid, deptname
+    assertEquals(targets[0].getNamedColumn().getQualifiedName(), "default.dept.manager");
+    assertEquals(targets[1].getAlias(), "empid");
+    assertEquals(targets[1].getEvalTree().getType(), EvalType.CONST);
+    assertEquals(targets[2].getNamedColumn().getQualifiedName(), "default.dept.deptname");
+  }
+
+  private static InsertNode getInsertNode(LogicalPlan plan) {
+    LogicalRootNode root = plan.getRootBlock().getRoot();
+    assertEquals(NodeType.INSERT, root.getChild().getType());
+    return root.getChild();
+  }
+
+  String [] ALTER_PARTITIONS = {
+    "ALTER TABLE partitioned_table ADD PARTITION (col1 = 1 , col2 = 2) LOCATION 'hdfs://xxx" +
+      ".com/warehouse/partitioned_table/col1=1/col2=2'", //0
+    "ALTER TABLE partitioned_table DROP PARTITION (col1 = '2015' , col2 = '01', col3 = '11' )", //1
+  };
+
+  @Test
+  public final void testAddPartitionAndDropPartition() throws TajoException {
+    String tableName = CatalogUtil.normalizeIdentifier("partitioned_table");
+    String qualifiedTableName = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, tableName);
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4)
+      .addColumn("name", Type.TEXT)
+      .addColumn("age", Type.INT4)
+      .addColumn("score", Type.FLOAT8);
+
+    KeyValueSet opts = new KeyValueSet();
+    opts.set("file.delimiter", ",");
+
+    Schema partSchema = new Schema();
+    partSchema.addColumn("id", Type.INT4);
+    partSchema.addColumn("name", Type.TEXT);
+
+    PartitionMethodDesc partitionMethodDesc =
+      new PartitionMethodDesc(DEFAULT_DATABASE_NAME, tableName,
+        CatalogProtos.PartitionType.COLUMN, "id,name", partSchema);
+
+    TableDesc desc = null;
+
+    try {
+      desc = new TableDesc(qualifiedTableName, schema, "TEXT", new KeyValueSet(),
+        CommonTestingUtil.getTestDir().toUri());
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+
+    desc.setPartitionMethod(partitionMethodDesc);
+    assertFalse(catalog.existsTable(qualifiedTableName));
+    catalog.createTable(desc);
+    assertTrue(catalog.existsTable(qualifiedTableName));
+
+    TableDesc retrieved = catalog.getTableDesc(qualifiedTableName);
+    assertEquals(retrieved.getName(), qualifiedTableName);
+    assertEquals(retrieved.getPartitionMethod().getPartitionType(), CatalogProtos.PartitionType.COLUMN);
+    assertEquals(retrieved.getPartitionMethod().getExpressionSchema().getColumn(0).getSimpleName(), "id");
+
+    QueryContext qc = new QueryContext(util.getConfiguration(), session);
+
+    // Testing alter table add partition
+    Expr expr = sqlAnalyzer.parse(ALTER_PARTITIONS[0]);
+    LogicalPlan rootNode = planner.createPlan(qc, expr);
+    LogicalNode plan = rootNode.getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    assertEquals(NodeType.ALTER_TABLE, root.getChild().getType());
+
+    AlterTableNode alterTableNode = root.getChild();
+
+    assertEquals(alterTableNode.getAlterTableOpType(), AlterTableOpType.ADD_PARTITION);
+
+    assertEquals(alterTableNode.getPartitionColumns().length, 2);
+    assertEquals(alterTableNode.getPartitionValues().length, 2);
+
+    assertEquals(alterTableNode.getPartitionColumns()[0], "col1");
+    assertEquals(alterTableNode.getPartitionColumns()[1], "col2");
+
+    assertEquals(alterTableNode.getPartitionValues()[0], "1");
+    assertEquals(alterTableNode.getPartitionValues()[1], "2");
+
+    assertEquals(alterTableNode.getLocation(), "hdfs://xxx.com/warehouse/partitioned_table/col1=1/col2=2");
+
+    // Testing alter table drop partition
+    expr = sqlAnalyzer.parse(ALTER_PARTITIONS[1]);
+    rootNode = planner.createPlan(qc, expr);
+    plan = rootNode.getRootBlock().getRoot();
+    testJsonSerDerObject(plan);
+    assertEquals(NodeType.ROOT, plan.getType());
+    root = (LogicalRootNode) plan;
+    assertEquals(NodeType.ALTER_TABLE, root.getChild().getType());
+
+    alterTableNode = root.getChild();
+
+    assertEquals(alterTableNode.getAlterTableOpType(), AlterTableOpType.DROP_PARTITION);
+
+    assertEquals(alterTableNode.getPartitionColumns().length, 3);
+    assertEquals(alterTableNode.getPartitionValues().length, 3);
+
+    assertEquals(alterTableNode.getPartitionColumns()[0], "col1");
+    assertEquals(alterTableNode.getPartitionColumns()[1], "col2");
+    assertEquals(alterTableNode.getPartitionColumns()[2], "col3");
+
+    assertEquals(alterTableNode.getPartitionValues()[0], "2015");
+    assertEquals(alterTableNode.getPartitionValues()[1], "01");
+    assertEquals(alterTableNode.getPartitionValues()[2], "11");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestPlannerUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestPlannerUtil.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestPlannerUtil.java
new file mode 100644
index 0000000..6c4d82d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestPlannerUtil.java
@@ -0,0 +1,387 @@
+/**
+ * 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.planner;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LocatedFileStatus;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.RemoteIterator;
+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.catalog.*;
+import org.apache.tajo.catalog.proto.CatalogProtos.FragmentProto;
+import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.function.builtin.SumInt;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.physical.PhysicalPlanUtil;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.expr.*;
+import org.apache.tajo.plan.logical.*;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.TupleComparator;
+import org.apache.tajo.storage.VTuple;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.storage.fragment.FragmentConvertor;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+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.*;
+
+public class TestPlannerUtil {
+  private static TajoTestingCluster util;
+  private static CatalogService catalog;
+  private static SQLAnalyzer analyzer;
+  private static LogicalPlanner planner;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+
+    Schema schema = new Schema();
+    schema.addColumn("name", Type.TEXT);
+    schema.addColumn("empid", CatalogUtil.newSimpleDataType(Type.INT4));
+    schema.addColumn("deptname", Type.TEXT);
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("deptname", Type.TEXT);
+    schema2.addColumn("manager", Type.TEXT);
+
+    Schema schema3 = new Schema();
+    schema3.addColumn("deptname", Type.TEXT);
+    schema3.addColumn("score", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    TableMeta meta = CatalogUtil.newTableMeta("TEXT");
+    TableDesc people = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "employee"), schema, meta,
+        CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(people);
+
+    TableDesc student =
+        new TableDesc(
+            CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), schema2, "TEXT",
+            new KeyValueSet(), CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(student);
+
+    TableDesc score =
+        new TableDesc(
+            CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), schema3, "TEXT",
+            new KeyValueSet(), CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(score);
+
+    FunctionDesc funcDesc = new FunctionDesc("sumtest", SumInt.class, FunctionType.AGGREGATION,
+        CatalogUtil.newSimpleDataType(Type.INT4),
+        CatalogUtil.newSimpleDataTypeArray(Type.INT4));
+
+    catalog.createFunction(funcDesc);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  @Test
+  public final void testFindTopNode() throws CloneNotSupportedException, TajoException {
+    // two relations
+    Expr expr = analyzer.parse(TestLogicalPlanner.QUERIES[1]);
+    LogicalNode plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(util.getConfiguration()),
+        expr).getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+
+    assertEquals(NodeType.JOIN, projNode.getChild().getType());
+    JoinNode joinNode = projNode.getChild();
+
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    ScanNode leftNode = joinNode.getLeftChild();
+    assertEquals("default.employee", leftNode.getTableName());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+    ScanNode rightNode = joinNode.getRightChild();
+    assertEquals("default.dept", rightNode.getTableName());
+    
+    LogicalNode node = PlannerUtil.findTopNode(root, NodeType.ROOT);
+    assertEquals(NodeType.ROOT, node.getType());
+    
+    node = PlannerUtil.findTopNode(root, NodeType.PROJECTION);
+    assertEquals(NodeType.PROJECTION, node.getType());
+    
+    node = PlannerUtil.findTopNode(root, NodeType.JOIN);
+    assertEquals(NodeType.JOIN, node.getType());
+    
+    node = PlannerUtil.findTopNode(root, NodeType.SCAN);
+    assertEquals(NodeType.SCAN, node.getType());
+  }
+
+  @Test
+  public final void testIsJoinQual() {
+    FieldEval f1 = new FieldEval("part.p_partkey", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f2 = new FieldEval("partsupp.ps_partkey",
+        CatalogUtil.newSimpleDataType(Type.INT4));
+
+
+    BinaryEval [] joinQuals = new BinaryEval[5];
+    int idx = 0;
+    joinQuals[idx++] = new BinaryEval(EvalType.EQUAL, f1, f2);
+    joinQuals[idx++] = new BinaryEval(EvalType.LEQ, f1, f2);
+    joinQuals[idx++] = new BinaryEval(EvalType.LTH, f1, f2);
+    joinQuals[idx++] = new BinaryEval(EvalType.GEQ, f1, f2);
+    joinQuals[idx] = new BinaryEval(EvalType.GTH, f1, f2);
+    for (int i = 0; i < idx; i++) {
+      assertTrue(EvalTreeUtil.isJoinQual(joinQuals[idx], true));
+    }
+
+    BinaryEval [] wrongJoinQuals = new BinaryEval[5];
+    idx = 0;
+    wrongJoinQuals[idx++] = new BinaryEval(EvalType.OR, f1, f2);
+    wrongJoinQuals[idx++] = new BinaryEval(EvalType.PLUS, f1, f2);
+    wrongJoinQuals[idx++] = new BinaryEval(EvalType.LIKE, f1, f2);
+
+    ConstEval f3 = new ConstEval(DatumFactory.createInt4(1));
+    wrongJoinQuals[idx] = new BinaryEval(EvalType.EQUAL, f1, f3);
+
+    for (int i = 0; i < idx; i++) {
+      assertFalse(EvalTreeUtil.isJoinQual(wrongJoinQuals[idx], true));
+    }
+  }
+
+  @Test
+  public final void testGetJoinKeyPairs() {
+    Schema outerSchema = new Schema();
+    outerSchema.addColumn("employee.id1", CatalogUtil.newSimpleDataType(Type.INT4));
+    outerSchema.addColumn("employee.id2", CatalogUtil.newSimpleDataType(Type.INT4));
+    Schema innerSchema = new Schema();
+    innerSchema.addColumn("people.fid1", CatalogUtil.newSimpleDataType(Type.INT4));
+    innerSchema.addColumn("people.fid2", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    FieldEval f1 = new FieldEval("employee.id1", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f2 = new FieldEval("people.fid1", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f3 = new FieldEval("employee.id2", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f4 = new FieldEval("people.fid2", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    EvalNode equiJoinQual = new BinaryEval(EvalType.EQUAL, f1, f2);
+
+    // the case where part is the outer and partsupp is the inner.
+    List<Column[]> pairs = PlannerUtil.getJoinKeyPairs(equiJoinQual, outerSchema,  innerSchema, false);
+    assertEquals(1, pairs.size());
+    assertEquals("employee.id1", pairs.get(0)[0].getQualifiedName());
+    assertEquals("people.fid1", pairs.get(0)[1].getQualifiedName());
+
+    // after exchange of outer and inner
+    pairs = PlannerUtil.getJoinKeyPairs(equiJoinQual, innerSchema, outerSchema, false);
+    assertEquals("people.fid1", pairs.get(0)[0].getQualifiedName());
+    assertEquals("employee.id1", pairs.get(0)[1].getQualifiedName());
+
+    // composited join key test
+    EvalNode joinQual2 = new BinaryEval(EvalType.EQUAL, f3, f4);
+    EvalNode compositedJoinQual = new BinaryEval(EvalType.AND, equiJoinQual, joinQual2);
+    pairs = PlannerUtil.getJoinKeyPairs(compositedJoinQual, outerSchema,  innerSchema, false);
+    assertEquals(2, pairs.size());
+    assertEquals("employee.id1", pairs.get(0)[0].getQualifiedName());
+    assertEquals("people.fid1", pairs.get(0)[1].getQualifiedName());
+    assertEquals("employee.id2", pairs.get(1)[0].getQualifiedName());
+    assertEquals("people.fid2", pairs.get(1)[1].getQualifiedName());
+
+    // after exchange of outer and inner
+    pairs = PlannerUtil.getJoinKeyPairs(compositedJoinQual, innerSchema,  outerSchema, false);
+    assertEquals(2, pairs.size());
+    assertEquals("people.fid1", pairs.get(0)[0].getQualifiedName());
+    assertEquals("employee.id1", pairs.get(0)[1].getQualifiedName());
+    assertEquals("people.fid2", pairs.get(1)[0].getQualifiedName());
+    assertEquals("employee.id2", pairs.get(1)[1].getQualifiedName());
+
+    // Theta join (f1 <= f2)
+    EvalNode thetaJoinQual = new BinaryEval(EvalType.LEQ, f1, f2);
+    pairs = PlannerUtil.getJoinKeyPairs(thetaJoinQual, outerSchema,  innerSchema, true);
+    assertEquals(1, pairs.size());
+    assertEquals("employee.id1", pairs.get(0)[0].getQualifiedName());
+    assertEquals("people.fid1", pairs.get(0)[1].getQualifiedName());
+
+    // Composite Theta join (f1 <= f2 AND f3 = f4)
+    EvalNode compositeThetaJoin = new BinaryEval(EvalType.AND, thetaJoinQual, joinQual2);
+    pairs = PlannerUtil.getJoinKeyPairs(compositeThetaJoin, outerSchema,  innerSchema, true);
+    assertEquals(2, pairs.size());
+    assertEquals("employee.id1", pairs.get(0)[0].getQualifiedName());
+    assertEquals("people.fid1", pairs.get(0)[1].getQualifiedName());
+    assertEquals("employee.id2", pairs.get(1)[0].getQualifiedName());
+    assertEquals("people.fid2", pairs.get(1)[1].getQualifiedName());
+  }
+
+  @Test
+  public final void testGetSortKeysFromJoinQual() {
+    Schema outerSchema = new Schema();
+    outerSchema.addColumn("employee.id1", CatalogUtil.newSimpleDataType(Type.INT4));
+    outerSchema.addColumn("employee.id2", CatalogUtil.newSimpleDataType(Type.INT4));
+    Schema innerSchema = new Schema();
+    innerSchema.addColumn("people.fid1", CatalogUtil.newSimpleDataType(Type.INT4));
+    innerSchema.addColumn("people.fid2", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    FieldEval f1 = new FieldEval("employee.id1", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f2 = new FieldEval("people.fid1", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f3 = new FieldEval("employee.id2", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f4 = new FieldEval("people.fid2", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    EvalNode joinQual = new BinaryEval(EvalType.EQUAL, f1, f2);
+    SortSpec[][] sortSpecs = PlannerUtil.getSortKeysFromJoinQual(joinQual, outerSchema, innerSchema);
+    assertEquals(2, sortSpecs.length);
+    assertEquals(1, sortSpecs[0].length);
+    assertEquals(1, sortSpecs[1].length);
+    assertEquals(outerSchema.getColumn("id1"), sortSpecs[0][0].getSortKey());
+    assertEquals(innerSchema.getColumn("fid1"), sortSpecs[1][0].getSortKey());
+
+    // tests for composited join key
+    EvalNode joinQual2 = new BinaryEval(EvalType.EQUAL, f3, f4);
+    EvalNode compositedJoinQual = new BinaryEval(EvalType.AND, joinQual, joinQual2);
+
+    sortSpecs = PlannerUtil.getSortKeysFromJoinQual(compositedJoinQual, outerSchema, innerSchema);
+    assertEquals(2, sortSpecs.length);
+    assertEquals(2, sortSpecs[0].length);
+    assertEquals(2, sortSpecs[1].length);
+    assertEquals(outerSchema.getColumn("id1"), sortSpecs[0][0].getSortKey());
+    assertEquals(outerSchema.getColumn("id2"), sortSpecs[0][1].getSortKey());
+    assertEquals(innerSchema.getColumn("fid1"), sortSpecs[1][0].getSortKey());
+    assertEquals(innerSchema.getColumn("fid2"), sortSpecs[1][1].getSortKey());
+  }
+
+  @Test
+  public final void testComparatorsFromJoinQual() {
+    Schema outerSchema = new Schema();
+    outerSchema.addColumn("employee.id1", CatalogUtil.newSimpleDataType(Type.INT4));
+    outerSchema.addColumn("employee.id2", CatalogUtil.newSimpleDataType(Type.INT4));
+    Schema innerSchema = new Schema();
+    innerSchema.addColumn("people.fid1", CatalogUtil.newSimpleDataType(Type.INT4));
+    innerSchema.addColumn("people.fid2", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    FieldEval f1 = new FieldEval("employee.id1", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f2 = new FieldEval("people.fid1", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f3 = new FieldEval("employee.id2", CatalogUtil.newSimpleDataType(Type.INT4));
+    FieldEval f4 = new FieldEval("people.fid2", CatalogUtil.newSimpleDataType(Type.INT4));
+
+    EvalNode joinQual = new BinaryEval(EvalType.EQUAL, f1, f2);
+    TupleComparator[] comparators = PhysicalPlanUtil.getComparatorsFromJoinQual(joinQual, outerSchema, innerSchema);
+
+    Tuple t1 = new VTuple(2);
+    t1.put(0, DatumFactory.createInt4(1));
+    t1.put(1, DatumFactory.createInt4(2));
+
+    Tuple t2 = new VTuple(2);
+    t2.put(0, DatumFactory.createInt4(2));
+    t2.put(1, DatumFactory.createInt4(3));
+
+    TupleComparator outerComparator = comparators[0];
+    assertTrue(outerComparator.compare(t1, t2) < 0);
+    assertTrue(outerComparator.compare(t2, t1) > 0);
+
+    TupleComparator innerComparator = comparators[1];
+    assertTrue(innerComparator.compare(t1, t2) < 0);
+    assertTrue(innerComparator.compare(t2, t1) > 0);
+
+    // tests for composited join key
+    EvalNode joinQual2 = new BinaryEval(EvalType.EQUAL, f3, f4);
+    EvalNode compositedJoinQual = new BinaryEval(EvalType.AND, joinQual, joinQual2);
+    comparators = PhysicalPlanUtil.getComparatorsFromJoinQual(compositedJoinQual, outerSchema, innerSchema);
+
+    outerComparator = comparators[0];
+    assertTrue(outerComparator.compare(t1, t2) < 0);
+    assertTrue(outerComparator.compare(t2, t1) > 0);
+
+    innerComparator = comparators[1];
+    assertTrue(innerComparator.compare(t1, t2) < 0);
+    assertTrue(innerComparator.compare(t2, t1) > 0);
+  }
+
+  @Test
+  public void testGetNonZeroLengthDataFiles() throws Exception {
+    String queryFiles = ClassLoader.getSystemResource("queries").toString() + "/TestSelectQuery";
+    Path path = new Path(queryFiles);
+
+    TableDesc tableDesc = new TableDesc();
+    tableDesc.setName("Test");
+    tableDesc.setUri(path.toUri());
+
+    FileSystem fs = path.getFileSystem(util.getConfiguration());
+
+    List<Path> expectedFiles = new ArrayList<Path>();
+    RemoteIterator<LocatedFileStatus> files = fs.listFiles(path, true);
+    while (files.hasNext()) {
+      LocatedFileStatus file = files.next();
+      if (file.isFile() && file.getLen() > 0) {
+        expectedFiles.add(file.getPath());
+      }
+    }
+    int fileNum = expectedFiles.size() / 5;
+
+    int numResultFiles = 0;
+    for (int i = 0; i <= 5; i++) {
+      int start = i * fileNum;
+
+      FragmentProto[] fragments =
+          PhysicalPlanUtil.getNonZeroLengthDataFiles(util.getConfiguration(), tableDesc, start, fileNum);
+      assertNotNull(fragments);
+
+      numResultFiles += fragments.length;
+      int expectedSize = fileNum;
+      if (i == 5) {
+        //last
+        expectedSize = expectedFiles.size() - (fileNum * 5);
+      }
+
+      comparePath(expectedFiles, fragments, start, expectedSize);
+    }
+
+    assertEquals(expectedFiles.size(), numResultFiles);
+  }
+
+  private void comparePath(List<Path> expectedFiles, FragmentProto[] fragments,
+                           int startIndex, int expectedSize) throws Exception {
+    assertEquals(expectedSize, fragments.length);
+
+    int index = 0;
+
+    for (int i = startIndex; i < startIndex + expectedSize; i++, index++) {
+      FileFragment fragment = FragmentConvertor.convert(util.getConfiguration(), fragments[index]);
+      assertEquals(expectedFiles.get(i), fragment.getPath());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestQueryValidation.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestQueryValidation.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestQueryValidation.java
new file mode 100644
index 0000000..f2e8e64
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestQueryValidation.java
@@ -0,0 +1,65 @@
+/*
+ * Lisensed 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.planner;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestQueryValidation extends QueryTestCaseBase {
+
+  @Test
+  public void testInsertWithWrongTargetColumn() throws Exception {
+    executeString("CREATE TABLE T1 (col1 int, col2 int)").close();
+    assertInvalidSQL("INSERT INTO T1 (col1, col3) select l_orderkey, l_partkey from default.lineitem");
+  }
+
+  @Test
+  public void testLimitClauses() throws IOException {
+    // select * from lineitem limit 3;
+    assertValidSQLFromFile("valid_limit_1.sql");
+
+    // select * from lineitem limit l_orderkey;
+    assertInvalidSQLFromFile("invalid_limit_1.sql");
+  }
+
+  @Test
+  public void testGroupByClauses() throws IOException {
+    // select l_orderkey from lineitem group by l_orderkey;
+    assertValidSQLFromFile("valid_groupby_1.sql");
+
+    // select * from lineitem group by l_orderkey;
+    assertPlanError("error_groupby_1.sql");
+    // select l_orderkey from lineitem group by l_paerkey;
+    assertPlanError("error_groupby_2.sql");
+  }
+
+  @Test
+  public void testCaseWhenExprs() throws IOException {
+    // See TAJO-1098
+    assertInvalidSQLFromFile("invalid_casewhen_1.sql");
+  }
+
+  @Test
+  public void testUnsupportedStoreType() throws IOException {
+    // See TAJO-1249
+    assertInvalidSQLFromFile("invalid_store_format.sql");
+  }
+}


[45/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
new file mode 100644
index 0000000..fe51aa4
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
@@ -0,0 +1,1001 @@
+/**
+ * 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.SessionVars;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.exception.UndefinedFunctionException;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.TimestampDatum;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.junit.Test;
+
+import java.util.TimeZone;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
+import static org.junit.Assert.fail;
+
+public class TestSQLExpression extends ExprTestBase {
+
+  @Test
+  public void testQuotedIdentifiers() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("컬럼1", TEXT);
+    schema.addColumn("컬럼2", TEXT);
+    testEval(schema, "테이블1", "123,234", "select \"컬럼1\"::float, cast (\"컬럼2\" as float4) as a from \"테이블1\"",
+        new String[]{"123.0", "234.0"});
+    testEval(schema,
+        "테이블1", "123,234", "select char_length(\"컬럼1\"), \"컬럼2\"::float4 as \"별명1\" from \"테이블1\"",
+        new String[]{"3", "234.0"});
+  }
+
+  @Test
+  public void testNoSuchFunction() {
+    try {
+      testSimpleEval("select test123('abc') col1 ", new String[]{"abc"});
+      fail("This test should throw UndefinedFunctionException");
+    } catch (UndefinedFunctionException e) {
+      //success
+    } catch (Exception e) {
+      fail("This test should throw UndefinedFunctionException: " + e);
+    }
+  }
+
+  @Test
+  public void testSQLStandardCast() throws TajoException {
+    testSimpleEval("select cast (1 as char)", new String[] {"1"});
+    testSimpleEval("select cast (119 as char)", new String[] {"1"});
+
+    testSimpleEval("select cast (1 as int2)", new String[ ]{"1"});
+    testSimpleEval("select cast (1 as int4)", new String[] {"1"});
+    testSimpleEval("select cast (1 as int8)", new String[] {"1"});
+    testSimpleEval("select cast (1 as float)", new String[] {"1.0"});
+    testSimpleEval("select cast (1 as double)", new String[] {"1.0"});
+    testSimpleEval("select cast (1 as text)", new String[] {"1"});
+
+    testSimpleEval("select cast ('123' as int2)", new String[] {"123"});
+    testSimpleEval("select cast ('123' as int4)", new String[] {"123"});
+    testSimpleEval("select cast ('123' as int8)", new String[] {"123"});
+    testSimpleEval("select cast ('123' as float)", new String[] {"123.0"});
+    testSimpleEval("select cast ('123' as double)", new String[] {"123.0"});
+    testSimpleEval("select cast ('123' as text)", new String[] {"123"});
+
+    testSimpleEval("select cast (123 as int2)", new String[] {"123"});
+    testSimpleEval("select cast (123 as int4)", new String[] {"123"});
+    testSimpleEval("select cast (123 as int8)", new String[] {"123"});
+    testSimpleEval("select cast (123 as float)", new String[] {"123.0"});
+    testSimpleEval("select cast (123 as double)", new String[] {"123.0"});
+    testSimpleEval("select cast (123 as text)", new String[] {"123"});
+
+    testSimpleEval("select cast (123.0 as float)", new String[] {"123.0"});
+    testSimpleEval("select cast (123.0 as double)", new String[] {"123.0"});
+  }
+
+  @Test
+  public void testExplicitCast() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", INT1);
+    schema.addColumn("col1", INT2);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", INT8);
+    schema.addColumn("col4", FLOAT4);
+    schema.addColumn("col5", FLOAT8);
+    schema.addColumn("col6", TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testSimpleEval("select cast (1 as char)", new String[]{"1"});
+    testSimpleEval("select cast (119 as char)", new String[] {"1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::int1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::int1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::int1 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::int1 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::int1 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::int1 from table1;", new String [] {"5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::int1 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::int1 from table1;", new String [] {"7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::int2 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::int2 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::int2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::int2 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::int2 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::int2 from table1;", new String [] {"5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::int2 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::int2 from table1;", new String [] {"7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::int4 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::int4 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::int4 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::int4 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::int4 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::int4 from table1;", new String [] {"5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::int4 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::int4 from table1;", new String [] {"7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::int8 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::int8 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::int8 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::int8 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::int8 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::int8 from table1;", new String [] {"5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::int8 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::int8 from table1;", new String [] {"7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::float4 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::float4 from table1;", new String [] {"1.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::float4 from table1;", new String [] {"2.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::float4 from table1;", new String [] {"3.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::float4 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::float4 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::float4 from table1;", new String [] {"6.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::float4 from table1;", new String [] {"7.0"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::float8 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::float8 from table1;", new String [] {"1.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::float8 from table1;", new String [] {"2.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::float8 from table1;", new String [] {"3.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::float8 from table1;", new String[]
+        {Double.valueOf(4.1f).toString()});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::float8 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::float8 from table1;", new String [] {"6.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::float8 from table1;", new String [] {"7.0"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::text from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1::text from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2::text from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3::text from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4::text from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5::text from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col6::text from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col7::text from table1;", new String [] {"7"});
+  }
+
+  @Test
+  public void testImplicitCastForInt1() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col0 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col4 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col5 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col6::int1 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 + col7::int1 from table1;", new String [] {"7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col0 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col1 from table1;", new String [] {"-1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col2 from table1;", new String [] {"-2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col3 from table1;", new String [] {"-3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col4 from table1;", new String [] {"-4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col5 from table1;", new String [] {"-5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col6::int1 from table1;", new String [] {"-6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 - col7::int1 from table1;", new String [] {"-7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col0 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col2 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col3 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col4 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col5 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col6::int1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 * col7::int1 from table1;", new String [] {"0"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col2 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col3 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col4 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col5 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col6::int1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 % col7::int1 from table1;", new String [] {"0"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col6::int1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 = col7::int1 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col6::int1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <> col7::int1 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col6::int1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 > col7::int1 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col6::int1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 >= col7::int1 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col6::int1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 < col7::int1 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col6::int1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0 <= col7::int1 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testImplicitCastForInt2() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col0 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col1 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col2 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col3 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col4 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col5 from table1;", new String [] {"6.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col6::int2 from table1;", new String [] {"7"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 + col7::int2 from table1;", new String [] {"8"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col0 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col2 from table1;", new String [] {"-1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col3 from table1;", new String [] {"-2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col4 from table1;", new String [] {"-3.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col5 from table1;", new String [] {"-4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col6::int2 from table1;", new String [] {"-5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 - col7::int2 from table1;", new String [] {"-6"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col0 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col4 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col5 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col6::int2 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 * col7::int2 from table1;", new String [] {"7"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col2 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col3 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col4 from table1;", new String [] {"1.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col5 from table1;", new String [] {"1.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col6::int2 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 % col7::int2 from table1;", new String [] {"1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col6::int2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 = col7::int2 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col6::int2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <> col7::int2 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col6::int2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 > col7::int2 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col6::int2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 >= col7::int2 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col6::int2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 < col7::int2 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col6::int2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col1 <= col7::int2 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testImplicitCastForInt4() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col0 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col1 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col2 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col3 from table1;", new String [] {"5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col4 from table1;", new String [] {"6.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col5 from table1;", new String [] {"7.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col6::int4 from table1;", new String [] {"8"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 + col7::int4 from table1;", new String [] {"9"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col0 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col2 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col3 from table1;", new String [] {"-1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col4 from table1;", new String [] {"-2.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col5 from table1;", new String [] {
+        (new Integer(2) - 5.1d) +""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col6::int4 from table1;", new String [] {"-4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 - col7::int4 from table1;", new String [] {"-5"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col0 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col1 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col2 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col3 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col4 from table1;", new String [] {"8.2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col5 from table1;", new String [] {"10.2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col6::int4 from table1;", new String [] {"12"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 * col7::int4 from table1;", new String [] {"14"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col2 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col3 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col4 from table1;", new String [] {"2.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col5 from table1;", new String [] {"2.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col6::int4 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 % col7::int4 from table1;", new String [] {"2"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col6::int4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 = col7::int4 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col6::int4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <> col7::int4 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col6::int4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 > col7::int4 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col6::int4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 >= col7::int4 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col6::int4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 < col7::int4 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col6::int4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col2 <= col7::int4 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testImplicitCastForInt8() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col0 from table1;", new String[]{"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col1 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col2 from table1;", new String [] {"5"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col3 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col4 from table1;", new String [] {
+        (new Long(3) + new Float(4.1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col5 from table1;", new String [] {"8.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col6::int8 from table1;", new String [] {"9"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 + col7::int8 from table1;", new String [] {"10"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col0 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col1 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col2 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col3 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col4 from table1;", new String [] {
+        (new Long(3) - new Float(4.1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col5 from table1;", new String [] {
+        (new Long(3) - 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col6::int8 from table1;", new String [] {"-3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 - col7::int8 from table1;", new String [] {"-4"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col0 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col1 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col2 from table1;", new String [] {"6"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col3 from table1;", new String [] {"9"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col4 from table1;", new String [] {
+        (new Long(3) * new Float("4.1"))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col5 from table1;", new String [] {
+        (new Long(3) * new Double("5.1"))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col6::int8 from table1;", new String [] {"18"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 * col7::int8 from table1;", new String [] {"21"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col1 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col2 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col3 from table1;", new String [] {"0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col4 from table1;", new String [] {"3.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col5 from table1;", new String [] {"3.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col6::int8 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 % col7::int8 from table1;", new String [] {"3"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col6::int8 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 = col7::int8 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col6::int8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <> col7::int8 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col6::int8 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 > col7::int8 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col6::int8 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 >= col7::int8 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col6::int8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 < col7::int8 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col6::int8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col3 <= col7::int8 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testImplicitCastForFloat4() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col0 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col1 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col2 from table1;", new String [] {"6.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col3 from table1;", new String [] {"7.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col4 from table1;", new String [] {"8.2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col5 from table1;", new String [] {
+        (new Float(4.1) + 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col6::float4 from table1;", new String [] {"10.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 + col7::float4 from table1;", new String [] {"11.1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col0 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col1 from table1;", new String [] {"3.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col2 from table1;", new String [] {"2.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col3 from table1;", new String [] {
+        (new Float(4.1) - new Long(3))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col4 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col5 from table1;", new String [] {
+        (new Float(4.1) - 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col6::float4 from table1;", new String [] {
+        (4.1f - 6f)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 - col7::float4 from table1;", new String [] {
+        (4.1f - 7f)+""});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col0 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col1 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col2 from table1;", new String [] {"8.2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col3 from table1;", new String [] {
+        (new Float(4.1) * new Long(3))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col4 from table1;", new String [] {
+        (new Float(4.1) * new Float(4.1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col5 from table1;", new String [] {
+        (new Float(4.1) * 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col6::float4 from table1;", new String [] {
+        (new Float(4.1) * 6f)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 * col7::float4 from table1;", new String [] {
+        (new Float(4.1) * 7f)+""});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col1 from table1;", new String [] {
+        (new Float(4.1) % new Integer(1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col2 from table1;", new String [] {
+        (new Float(4.1) % new Integer(2))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col3 from table1;", new String [] {
+        (new Float(4.1) % new Long(3))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col4 from table1;", new String [] {
+        (new Float(4.1) % new Float(4.1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col5 from table1;", new String [] {
+        (new Float(4.1) % 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col6::float4 from table1;", new String [] {
+        (new Float(4.1) % 6f)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 % col7::int1 from table1;", new String [] {
+        (new Float(4.1) % 7f)+""});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col6::int1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 = col7::int1 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col6::int1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <> col7::int1 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col6::int1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 > col7::int1 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col6::int1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 >= col7::int1 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col6::int1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 < col7::int1 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col6::int1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col4 <= col7::int1 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testImplicitCastForFloat8() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col0 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col1 from table1;", new String [] {"6.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col2 from table1;", new String [] {"7.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col3 from table1;", new String [] {"8.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col4 from table1;", new String [] {
+        (5.1d + 4.1f)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col5 from table1;", new String [] {"10.2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col6::int1 from table1;", new String [] {"11.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 + col7::int1 from table1;", new String [] {"12.1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col0 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col1 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col2 from table1;", new String [] {
+        (5.1d - new Integer(2))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col3 from table1;", new String [] {
+        (5.1d - 3l)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col4 from table1;", new String [] {
+        (5.1d - 4.1f)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col5 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col6::float8 from table1;", new String [] {
+        (5.1d - 6d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 - col7::float8 from table1;", new String [] {
+        (5.1d - 7d)+""});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col0 from table1;", new String [] {"0.0"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col1 from table1;", new String [] {"5.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col2 from table1;", new String [] {"10.2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col3 from table1;", new String [] {
+        (5.1d * new Long(3))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col4 from table1;", new String [] {
+        (5.1d * new Float(4.1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col5 from table1;", new String [] {
+        (5.1d * 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col6::float8 from table1;", new String [] {
+        (5.1d * 6d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 * col7::float8 from table1;", new String [] {
+        (5.1d * 7d)+""});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col1 from table1;", new String [] {
+        (5.1d % new Integer(1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col2 from table1;", new String [] {
+        (5.1d % new Integer(2))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col3 from table1;", new String [] {
+        (5.1d % new Long(3))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col4 from table1;", new String [] {
+        (5.1d % new Float(4.1))+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col5 from table1;", new String [] {
+        (5.1d % 5.1d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col6::float8 from table1;", new String [] {
+        (5.1d % 6d)+""});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 % col7::float8 from table1;", new String [] {
+        (5.1d % 7d)+""});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col6::float8 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 = col7::float8 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col6::float8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <> col7::float8 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col6::float8 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 > col7::float8 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col0 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col6::float8 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 >= col7::float8 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col5 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col6::float8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 < col7::float8 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col0 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col5 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col6::float8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col5 <= col7::float8 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testSigned() throws TajoException {
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col8", TajoDataTypes.Type.BOOLEAN);
+
+
+    // sign test
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col4 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col5 from table1;", new String [] {"5.1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col1 from table1;", new String [] {"-1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col2 from table1;", new String [] {"-2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col3 from table1;", new String [] {"-3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col4 from table1;", new String [] {"-4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col5 from table1;", new String [] {"-5.1"});
+  }
+
+  @Test
+  public void testCastWithNestedFunction() throws TajoException {
+    QueryContext context = new QueryContext(getConf());
+    context.put(SessionVars.TIMEZONE, "GMT-6");
+    TimeZone tz = TimeZone.getTimeZone("GMT-6");
+
+    int unixtime = 1389071574; // (int) (System.currentTimeMillis() / 1000);
+    TimestampDatum expected = DatumFactory.createTimestmpDatumWithUnixTime(unixtime);
+    testSimpleEval(context, String.format("select to_timestamp(CAST(split_part('%d.999', '.', 1) as INT8));", unixtime),
+        new String[] {TimestampDatum.asChars(expected.asTimeMeta(), tz, false)});
+  }
+
+  @Test
+  public void testCastFromTable() throws TajoException {
+    QueryContext queryContext = new QueryContext(getConf());
+    queryContext.put(SessionVars.TIMEZONE, "GMT-6");
+    TimeZone tz = TimeZone.getTimeZone("GMT-6");
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+
+    testEval(queryContext, schema,
+        "table1",
+        "123,234",
+        "select cast(col1 as float) as b, cast(col2 as float) as a from table1",
+        new String[]{"123.0", "234.0"});
+    testEval(queryContext, schema, "table1", "123,234", "select col1::float, col2::float from table1",
+        new String[]{"123.0", "234.0"});
+
+    TimestampDatum timestamp = DatumFactory.createTimestamp("1980-04-01 01:50:01" +
+        DateTimeUtil.getTimeZoneDisplayTime(tz));
+
+    testEval(queryContext, schema, "table1", "1980-04-01 01:50:01,234",
+        "select col1::timestamp as t1, col2::float from table1 where t1 = '1980-04-01 01:50:01'::timestamp",
+        new String[]{TimestampDatum.asChars(timestamp.asTimeMeta(), tz, false), "234.0"}
+    );
+
+    testSimpleEval("select '1980-04-01 01:50:01'::timestamp;", new String[]{
+        TimestampDatum.asChars(timestamp.asTimeMeta(), tz, false)});
+    testSimpleEval("select '1980-04-01 01:50:01'::timestamp::text", new String[]{"1980-04-01 01:50:01"});
+
+    testSimpleEval("select (cast ('99999'::int8 as text))::int4 + 1", new String[]{"100000"});
+  }
+
+  @Test
+  public void testBooleanLiteral() throws TajoException {
+    testSimpleEval("select true", new String[] {"t"});
+    testSimpleEval("select false", new String[]{"f"});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", TEXT);
+    testEval(schema, "table1", "123,234", "select col1, col2 from table1 where true", new String[]{"123", "234"});
+  }
+
+  @Test
+  public void testNullComparisons() throws TajoException {
+    testSimpleEval("select (1 > null) is null", new String[] {"t"});
+
+    testSimpleEval("select null is null", new String[] {"t"});
+    testSimpleEval("select null is not null", new String[] {"f"});
+
+    testSimpleEval("select (1 = 1)", new String[] {"t"});
+
+    testSimpleEval("select (1::int2 > null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int2 < null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int2 >= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int2 <= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int2 <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select (1::int4 > null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int4 < null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int4 >= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int4 <= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int4 <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select (1::int8 > null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int8 < null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int8 >= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int8 <= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::int8 <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select (1::float > null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float < null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float >= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float <= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select (1::float8 > null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float8 < null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float8 >= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float8 <= null) is null", new String[] {"t"});
+    testSimpleEval("select (1::float8 <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select ('abc' > null) is null", new String[] {"t"});
+    testSimpleEval("select ('abc' < null) is null", new String[] {"t"});
+    testSimpleEval("select ('abc' >= null) is null", new String[] {"t"});
+    testSimpleEval("select ('abc' <= null) is null", new String[] {"t"});
+    testSimpleEval("select ('abc' <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select ('1980-04-01'::date > null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01'::date < null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01'::date >= null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01'::date <= null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01'::date <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select ('09:08:50'::time > null) is null", new String[] {"t"});
+    testSimpleEval("select ('09:08:50'::time < null) is null", new String[] {"t"});
+    testSimpleEval("select ('09:08:50'::time >= null) is null", new String[] {"t"});
+    testSimpleEval("select ('09:08:50'::time <= null) is null", new String[] {"t"});
+    testSimpleEval("select ('09:08:50'::time <> null) is null", new String[] {"t"});
+
+    testSimpleEval("select ('1980-04-01 01:50:30'::timestamp > null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01 01:50:30'::timestamp < null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01 01:50:30'::timestamp >= null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01 01:50:30'::timestamp <= null) is null", new String[] {"t"});
+    testSimpleEval("select ('1980-04-01 01:50:30'::timestamp <> null) is null", new String[] {"t"});
+
+
+    // Three Valued Logic - AND
+    testSimpleEval("select (true AND true)", new String[] {"t"}); // true - true -> true
+    testSimpleEval("select (true AND 1 > null) is null", new String[] {"t"}); // true - unknown -> unknown
+    testSimpleEval("select (true AND false)", new String[] {"f"}); // true - false -> true
+
+    testSimpleEval("select (1 > null AND true) is null", new String[] {"t"}); // unknown - true -> true
+    testSimpleEval("select (1 > null AND 1 > null) is null", new String[] {"t"}); // unknown - unknown -> unknown
+    testSimpleEval("select (1 > null AND false)", new String[] {"f"}); // unknown - false -> false
+
+    testSimpleEval("select (false AND true)", new String[] {"f"}); // false - true -> true
+    testSimpleEval("select (false AND 1 > null) is null", new String[] {"f"}); // false - unknown -> unknown
+    testSimpleEval("select (false AND false)", new String[] {"f"}); // false - false -> false
+
+    // Three Valued Logic - OR
+    testSimpleEval("select (true OR true)", new String[] {"t"}); // true - true -> true
+    testSimpleEval("select (true OR 1 > null)", new String[] {"t"}); // true - unknown -> true
+    testSimpleEval("select (true OR false)", new String[] {"t"}); // true - false -> true
+
+    testSimpleEval("select (1 > null OR true)", new String[] {"t"}); // unknown - true -> true
+    testSimpleEval("select (1 > null OR 1 > null) is null", new String[] {"t"}); // unknown - unknown -> unknown
+    testSimpleEval("select (1 > null OR false) is null", new String[] {"t"}); // unknown - false -> false
+
+    testSimpleEval("select (false OR true)", new String[] {"t"}); // false - true -> true
+    testSimpleEval("select (false OR 1 > null) is null", new String[] {"t"}); // false - unknown -> unknown
+    testSimpleEval("select (false OR false)", new String[] {"f"}); // false - false -> false
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestAggFunction.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestAggFunction.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestAggFunction.java
new file mode 100644
index 0000000..aa0d360
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/function/TestAggFunction.java
@@ -0,0 +1,65 @@
+/**
+ * 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.function;
+
+import org.apache.tajo.plan.function.FunctionContext;
+import org.junit.Test;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.function.builtin.AvgLong;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestAggFunction {
+
+  @Test
+  public void testAvgInt() {
+    Tuple [] tuples = new Tuple[5];
+
+    for (int i = 1; i <= 5; i++) {
+      tuples[i-1] = new VTuple(1);
+      tuples[i-1].put(0, DatumFactory.createInt4(i));
+    }
+
+    AvgLong avg = new AvgLong();
+    FunctionContext ctx = avg.newContext();
+    for (int i = 1; i <= 5; i++) {
+      avg.eval(ctx, tuples[i-1]);
+    }
+
+    assertTrue(15 / 5 == avg.terminate(ctx).asFloat8());
+
+
+    Tuple [] tuples2 = new Tuple[10];
+
+    FunctionContext ctx2 = avg.newContext();
+    for (int i = 1; i <= 10; i++) {
+      tuples2[i-1] = new VTuple(1);
+      tuples2[i-1].put(0, DatumFactory.createInt4(i));
+      avg.eval(ctx2, tuples2[i-1]);
+    }
+    assertTrue((double)55 / 10 == avg.terminate(ctx2).asFloat8());
+
+
+    avg.merge(ctx, new VTuple(new Datum[] {avg.getPartialResult(ctx2)}));
+    assertTrue((double)(15 + 55) / (5 + 10) == avg.terminate(ctx).asFloat8());
+  }
+}


[46/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
new file mode 100644
index 0000000..3a2de5b
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
@@ -0,0 +1,405 @@
+/**
+ * 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;
+import org.apache.tajo.exception.TajoException;
+import org.junit.Test;
+
+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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+
+    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 TajoException {
+    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 TajoException {
+
+
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("nullable", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "t1", "0,1,2,3,4.1,5.1,cmp,asm,", "SELECT col6 = 'cmp' from t1", new String [] {"t"});
+
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException { // 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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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 TajoException {
+    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"});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
new file mode 100644
index 0000000..1b599a6
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
@@ -0,0 +1,50 @@
+/**
+ * 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.exception.TajoException;
+import org.junit.Test;
+
+public class TestSQLDateTimeTypes extends ExprTestBase {
+
+  @Test
+  public void testTimestamp() throws TajoException {
+    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 TajoException {
+    testSimpleEval("select to_char(TIMESTAMP '1970-01-17 10:09:37', 'YYYY-MM-DD HH24:MI:SS');",
+        new String[]{"1970-01-17 10:09:37"});
+  }
+
+  @Test
+  public void testTimeLiteral() throws TajoException {
+    testSimpleEval("select TIME '10:09:37';", new String[]{"10:09:37"});
+  }
+
+  @Test
+  public void testDateLiteral() throws TajoException {
+    testSimpleEval("select DATE '1970-01-17';", new String[]{"1970-01-17"});
+  }
+
+}


[08/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort.plan
new file mode 100644
index 0000000..c86757c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort.plan
@@ -0,0 +1,90 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SELECTION(2)
+        => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+         JOIN(7)(INNER)
+           => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+           => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+           => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+            SCAN(0) on default.nation as n1
+              => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+              => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+              => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+            SCAN(1) on default.nation as n2
+              => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+              => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+              => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(11)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SELECTION(2)
+     => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+      JOIN(7)(INNER)
+        => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+         SCAN(0) on default.nation as n1
+           => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+           => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+           => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+         SCAN(1) on default.nation as n2
+           => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+           => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..155f466
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.Sort_NoBroadcast.plan
@@ -0,0 +1,117 @@
+explain
+-------------------------------
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SELECTION(2)
+        => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+         JOIN(7)(INNER)
+           => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+           => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+           => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+            SCAN(0) on default.nation as n1
+              => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+              => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+              => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+            SCAN(1) on default.nation as n2
+              => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+              => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+              => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+  => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)
+  => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_name (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+SORT(11)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+   SELECTION(2)
+     => Search Cond: default.n1.n_nationkey (INT4) IN (1, 2) OR default.n2.n_nationkey (INT4) IN (2)
+      JOIN(7)(INNER)
+        => Join Cond: default.n1.n_name (TEXT) = default.n2.n_name (TEXT)
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+         SCAN(10) on eb_0000000000000_0000_000002
+           => out schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+           => in schema: {(2) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+         SCAN(9) on eb_0000000000000_0000_000001
+           => out schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+           => in schema: {(2) default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+PROJECTION(4)
+  => Targets: default.n1.n_nationkey (INT4), default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+  => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+  => in  schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+   SORT(3)
+     => Sort Keys: default.n1.n_nationkey (INT4) (asc)
+      SCAN(12) on eb_0000000000000_0000_000003
+        => out schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.result
new file mode 100644
index 0000000..58a2092
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testJoinWithOrPredicates.result
@@ -0,0 +1,4 @@
+n_nationkey,n_name,n_name
+-------------------------------
+1,ARGENTINA,ARGENTINA
+2,BRAZIL,BRAZIL

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash.plan
new file mode 100644
index 0000000..1ef6092
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..24ef410
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+  => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+  => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+SORT(10)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort.plan
new file mode 100644
index 0000000..1ef6092
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.n1
+
+SORT(10)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..24ef410
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(1) on default.nation as n2
+        => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4), num=32)
+
+SCAN(1) on default.nation as n2
+  => target list: default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)
+  => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+  => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)
+  => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+SORT(10)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   JOIN(6)(INNER)
+     => Join Cond: default.n1.n_comment (TEXT) = default.n2.n_comment (TEXT) AND default.n1.n_name (TEXT) = default.n2.n_name (TEXT) AND default.n1.n_nationkey (INT4) = default.n2.n_nationkey (INT4) AND default.n1.n_regionkey (INT4) = default.n2.n_regionkey (INT4)
+     => target list: default.n1.n_name (TEXT), default.n2.n_name (TEXT)
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(8) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4), default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000002
+        => out schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      SCAN(8) on eb_0000000000000_0000_000001
+        => out schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+        => in schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.n2.n_name (TEXT) (asc)
+   SCAN(11) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+     => in schema: {(2) default.n1.n_name (TEXT), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.result
new file mode 100644
index 0000000..30e6c32
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testNaturalJoin.result
@@ -0,0 +1,27 @@
+n_name,n_name
+-------------------------------
+ALGERIA,ALGERIA
+ARGENTINA,ARGENTINA
+BRAZIL,BRAZIL
+CANADA,CANADA
+CHINA,CHINA
+EGYPT,EGYPT
+ETHIOPIA,ETHIOPIA
+FRANCE,FRANCE
+GERMANY,GERMANY
+INDIA,INDIA
+INDONESIA,INDONESIA
+IRAN,IRAN
+IRAQ,IRAQ
+JAPAN,JAPAN
+JORDAN,JORDAN
+KENYA,KENYA
+MOROCCO,MOROCCO
+MOZAMBIQUE,MOZAMBIQUE
+PERU,PERU
+ROMANIA,ROMANIA
+RUSSIA,RUSSIA
+SAUDI ARABIA,SAUDI ARABIA
+UNITED KINGDOM,UNITED KINGDOM
+UNITED STATES,UNITED STATES
+VIETNAM,VIETNAM

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash.plan
new file mode 100644
index 0000000..baad6d4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+         SCAN(0) on default.part
+           => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+              => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.supplier
+ 2: type=Broadcast, tables=default.partsupp
+ 3: type=Broadcast, tables=default.region
+
+SORT(26)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+         SCAN(0) on default.part
+           => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+              => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..35680f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Hash_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+         SCAN(0) on default.part
+           => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+              => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+SCAN(1) on default.supplier
+  => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+  => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+  => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+  => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+  => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+     => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(0) on default.part
+  => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+  => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(3) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(4) on default.region
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+  => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+  => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+  => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+     => in schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+     => in schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(1) default.region.r_regionkey (INT4)}
+     => in schema: {(1) default.region.r_regionkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================


[02/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash.plan
new file mode 100644
index 0000000..8e6d32b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash.plan
@@ -0,0 +1,109 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?substr_1 (TEXT), ?substr_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+        => out schema: {(2) ?substr_2 (TEXT), default.n2.n_name (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000005
+3: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.nation
+ 1: type=Broadcast, tables=default.n1
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) default.n2.n_name (TEXT), default.n2.?substr_2 (TEXT), ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      UNION(21)
+         TABLE_SUBQUERY(14) as default.n2
+           => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+           => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(3) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+         TABLE_SUBQUERY(13) as default.n2
+           => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+           => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..cd716a4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Hash_NoBroadcast.plan
@@ -0,0 +1,145 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?substr_1 (TEXT), ?substr_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+        => out schema: {(2) ?substr_2 (TEXT), default.n2.n_name (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000004
+4: eb_0000000000000_0000_000003
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32)
+
+TABLE_SUBQUERY(13) as default.n2
+  => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+  => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(1) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32)
+
+TABLE_SUBQUERY(14) as default.n2
+  => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+  => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(3) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=?substr_1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+  => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=?substr_1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?substr_1 (TEXT), ?substr_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(17) on eb_0000000000000_0000_000004
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(15) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.n2.n_name (TEXT), default.n2.?substr_2 (TEXT)}
+        => in schema: {(2) default.n2.n_name (TEXT), default.n2.?substr_2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort.plan
new file mode 100644
index 0000000..8e6d32b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort.plan
@@ -0,0 +1,109 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?substr_1 (TEXT), ?substr_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+        => out schema: {(2) ?substr_2 (TEXT), default.n2.n_name (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000005
+3: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.nation
+ 1: type=Broadcast, tables=default.n1
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) default.n2.n_name (TEXT), default.n2.?substr_2 (TEXT), ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      UNION(21)
+         TABLE_SUBQUERY(14) as default.n2
+           => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+           => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(3) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+         TABLE_SUBQUERY(13) as default.n2
+           => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+           => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+           => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+            SCAN(1) on default.nation
+              => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+              => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+              => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..cd716a4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.Sort_NoBroadcast.plan
@@ -0,0 +1,145 @@
+explain
+-------------------------------
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?substr_1 (TEXT), ?substr_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(0) on default.nation as n1
+        => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+      TABLE_SUBQUERY(6) as default.n2
+        => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+        => out schema: {(2) ?substr_2 (TEXT), default.n2.n_name (TEXT)}
+        => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+         UNION(5)
+            PROJECTION(4)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(3) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+            PROJECTION(2)
+              => Targets: default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)
+              => out schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+              => in  schema: {(4) default.nation.n_nationkey (INT4), default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_comment (TEXT)}
+               SCAN(1) on default.nation
+                 => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+                 => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+                 => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000004
+4: eb_0000000000000_0000_000003
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32)
+
+TABLE_SUBQUERY(13) as default.n2
+  => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+  => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(1) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32)
+
+TABLE_SUBQUERY(14) as default.n2
+  => Targets: default.n2.n_name (TEXT), substr(default.n2.n_name (TEXT),1,4) as ?substr_2
+  => out schema: {(2) default.n2.n_name (TEXT), ?substr_2 (TEXT)}
+  => in  schema: {(4) default.n2.n_comment (TEXT), default.n2.n_name (TEXT), default.n2.n_nationkey (INT4), default.n2.n_regionkey (INT4)}
+   SCAN(3) on default.nation
+     => target list: default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+     => out schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=?substr_1 (TEXT), num=32)
+
+SCAN(0) on default.nation as n1
+  => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), substr(default.n1.n_name (TEXT),1,4) as ?substr_1
+  => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+  => in schema: {(4) default.n1.n_comment (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n1.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=?substr_2 (TEXT), num=32), union delegated scan: eb_0000000000000_0000_000001
+[q_0000000000000_0000] 4 => 3 (type=HASH_SHUFFLE, key=?substr_1 (TEXT), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+SORT(18)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   JOIN(11)(INNER)
+     => Join Cond: ?substr_1 (TEXT) = ?substr_2 (TEXT)
+     => target list: default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(5) ?substr_1 (TEXT), ?substr_2 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+      SCAN(17) on eb_0000000000000_0000_000004
+        => out schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+        => in schema: {(3) ?substr_1 (TEXT), default.n1.n_name (TEXT), default.n1.n_nationkey (INT4)}
+      SCAN(15) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.n2.n_name (TEXT), default.n2.?substr_2 (TEXT)}
+        => in schema: {(2) default.n2.n_name (TEXT), default.n2.?substr_2 (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=RANGE_SHUFFLE, key=default.n1.n_nationkey (INT4), default.n2.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(8)
+  => Sort Keys: default.n1.n_nationkey (INT4) (asc),default.n2.n_name (TEXT) (asc)
+   SCAN(19) on eb_0000000000000_0000_000003
+     => out schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+     => in schema: {(3) default.n1.n_name (TEXT), default.n1.n_nationkey (INT4), default.n2.n_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.result
new file mode 100644
index 0000000..9b278c8
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testComplexJoinCondition7.result
@@ -0,0 +1,56 @@
+n_nationkey,n_name,n_name
+-------------------------------
+0,ALGERIA,ALGERIA
+0,ALGERIA,ALGERIA
+1,ARGENTINA,ARGENTINA
+1,ARGENTINA,ARGENTINA
+2,BRAZIL,BRAZIL
+2,BRAZIL,BRAZIL
+3,CANADA,CANADA
+3,CANADA,CANADA
+4,EGYPT,EGYPT
+4,EGYPT,EGYPT
+5,ETHIOPIA,ETHIOPIA
+5,ETHIOPIA,ETHIOPIA
+6,FRANCE,FRANCE
+6,FRANCE,FRANCE
+7,GERMANY,GERMANY
+7,GERMANY,GERMANY
+8,INDIA,INDIA
+8,INDIA,INDIA
+9,INDONESIA,INDONESIA
+9,INDONESIA,INDONESIA
+10,IRAN,IRAN
+10,IRAN,IRAN
+11,IRAQ,IRAQ
+11,IRAQ,IRAQ
+12,JAPAN,JAPAN
+12,JAPAN,JAPAN
+13,JORDAN,JORDAN
+13,JORDAN,JORDAN
+14,KENYA,KENYA
+14,KENYA,KENYA
+15,MOROCCO,MOROCCO
+15,MOROCCO,MOROCCO
+16,MOZAMBIQUE,MOZAMBIQUE
+16,MOZAMBIQUE,MOZAMBIQUE
+17,PERU,PERU
+17,PERU,PERU
+18,CHINA,CHINA
+18,CHINA,CHINA
+19,ROMANIA,ROMANIA
+19,ROMANIA,ROMANIA
+20,SAUDI ARABIA,SAUDI ARABIA
+20,SAUDI ARABIA,SAUDI ARABIA
+21,VIETNAM,VIETNAM
+21,VIETNAM,VIETNAM
+22,RUSSIA,RUSSIA
+22,RUSSIA,RUSSIA
+23,UNITED KINGDOM,UNITED KINGDOM
+23,UNITED KINGDOM,UNITED KINGDOM
+23,UNITED KINGDOM,UNITED STATES
+23,UNITED KINGDOM,UNITED STATES
+24,UNITED STATES,UNITED KINGDOM
+24,UNITED STATES,UNITED KINGDOM
+24,UNITED STATES,UNITED STATES
+24,UNITED STATES,UNITED STATES

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithJson2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithJson2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithJson2.result
new file mode 100644
index 0000000..155ba42
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithJson2.result
@@ -0,0 +1,5 @@
+n_nationkey,n_name,n_regionkey,n_comment,ps_availqty,s_suppkey
+-------------------------------
+1,ARGENTINA,1,al foxes promise slyly according to the regular accounts. bold requests alon,8895,3
+5,ETHIOPIA,0,ven packages wake quickly. regu,3325,2
+15,MOROCCO,0,rns. blithely bold courts among the closely regular packages use furiously bold platelets?,4651,4
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash.plan
new file mode 100644
index 0000000..f19b5cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash.plan
@@ -0,0 +1,86 @@
+explain
+-------------------------------
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(5) on default.supplier as s
+     => target list: default.s.s_nationkey (INT4)
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+      JOIN(10)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => filter: default.n.n_name (TEXT) = MOROCCO
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000005
+2: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.r
+ 1: type=Broadcast, tables=default.s
+
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(5) on default.supplier as s
+     => target list: default.s.s_nationkey (INT4)
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+      PROJECTION(3)
+        => Targets: default.n.n_nationkey (INT4), name (TEXT), default.n.n_regionkey (INT4), default.n.n_comment (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in  schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+         JOIN(10)(INNER)
+           => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+           => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+            SCAN(1) on default.region as r
+              => target list: default.r.r_regionkey (INT4)
+              => out schema: {(1) default.r.r_regionkey (INT4)}
+              => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+            SCAN(0) on default.nation as n
+              => filter: default.n.n_name (TEXT) = MOROCCO
+              => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+              => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+              => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..59f15f1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Hash_NoBroadcast.plan
@@ -0,0 +1,142 @@
+explain
+-------------------------------
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(5) on default.supplier as s
+     => target list: default.s.s_nationkey (INT4)
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+      JOIN(10)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => filter: default.n.n_name (TEXT) = MOROCCO
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n
+  => filter: default.n.n_name (TEXT) = MOROCCO
+  => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+  => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as r
+  => target list: default.r.r_regionkey (INT4)
+  => out schema: {(1) default.r.r_regionkey (INT4)}
+  => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.t.n_nationkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.t
+  => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+  => out schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+  => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   PROJECTION(3)
+     => Targets: default.n.n_nationkey (INT4), name (TEXT), default.n.n_regionkey (INT4), default.n.n_comment (TEXT)
+     => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+     => in  schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+      JOIN(10)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+         SCAN(14) on eb_0000000000000_0000_000002
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(1) default.r.r_regionkey (INT4)}
+         SCAN(13) on eb_0000000000000_0000_000001
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.s.s_nationkey (INT4), num=32)
+
+SCAN(5) on default.supplier as s
+  => target list: default.s.s_nationkey (INT4)
+  => out schema: {(1) default.s.s_nationkey (INT4)}
+  => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.t.n_nationkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.s.s_nationkey (INT4), num=32)
+
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(16) on eb_0000000000000_0000_000004
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(1) default.s.s_nationkey (INT4)}
+   SCAN(15) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+     => in schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort.plan
new file mode 100644
index 0000000..f19b5cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort.plan
@@ -0,0 +1,86 @@
+explain
+-------------------------------
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(5) on default.supplier as s
+     => target list: default.s.s_nationkey (INT4)
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+      JOIN(10)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => filter: default.n.n_name (TEXT) = MOROCCO
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000005
+2: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.r
+ 1: type=Broadcast, tables=default.s
+
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(5) on default.supplier as s
+     => target list: default.s.s_nationkey (INT4)
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+      PROJECTION(3)
+        => Targets: default.n.n_nationkey (INT4), name (TEXT), default.n.n_regionkey (INT4), default.n.n_comment (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in  schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+         JOIN(10)(INNER)
+           => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+           => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+            SCAN(1) on default.region as r
+              => target list: default.r.r_regionkey (INT4)
+              => out schema: {(1) default.r.r_regionkey (INT4)}
+              => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+            SCAN(0) on default.nation as n
+              => filter: default.n.n_name (TEXT) = MOROCCO
+              => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+              => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+              => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..59f15f1
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.Sort_NoBroadcast.plan
@@ -0,0 +1,142 @@
+explain
+-------------------------------
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(5) on default.supplier as s
+     => target list: default.s.s_nationkey (INT4)
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+      JOIN(10)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => filter: default.n.n_name (TEXT) = MOROCCO
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000006)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000006
+   |-eb_0000000000000_0000_000005
+      |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation as n
+  => filter: default.n.n_name (TEXT) = MOROCCO
+  => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT) as name, default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+  => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+  => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region as r
+  => target list: default.r.r_regionkey (INT4)
+  => out schema: {(1) default.r.r_regionkey (INT4)}
+  => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.n.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.r.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.t.n_nationkey (INT4), num=32)
+
+TABLE_SUBQUERY(4) as default.t
+  => Targets: default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+  => out schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+  => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   PROJECTION(3)
+     => Targets: default.n.n_nationkey (INT4), name (TEXT), default.n.n_regionkey (INT4), default.n.n_comment (TEXT)
+     => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+     => in  schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+      JOIN(10)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4), name (TEXT)}
+         SCAN(14) on eb_0000000000000_0000_000002
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(1) default.r.r_regionkey (INT4)}
+         SCAN(13) on eb_0000000000000_0000_000001
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.s.s_nationkey (INT4), num=32)
+
+SCAN(5) on default.supplier as s
+  => target list: default.s.s_nationkey (INT4)
+  => out schema: {(1) default.s.s_nationkey (INT4)}
+  => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.t.n_nationkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.s.s_nationkey (INT4), num=32)
+
+JOIN(11)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)
+  => out schema: {(4) default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+  => in schema: {(5) default.s.s_nationkey (INT4), default.t.n_comment (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4), default.t.name (TEXT)}
+   SCAN(16) on eb_0000000000000_0000_000004
+     => out schema: {(1) default.s.s_nationkey (INT4)}
+     => in schema: {(1) default.s.s_nationkey (INT4)}
+   SCAN(15) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+     => in schema: {(4) default.t.n_nationkey (INT4), default.t.name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.result
new file mode 100644
index 0000000..c037958
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual2.result
@@ -0,0 +1,3 @@
+n_nationkey,name,n_regionkey,n_comment
+-------------------------------
+15,MOROCCO,0,rns. blithely bold courts among the closely regular packages use furiously bold platelets?

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash.plan
new file mode 100644
index 0000000..195229d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinWithSubQuery/testJoinWithMultipleJoinQual3.Hash.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+JOIN(14)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)
+  => out schema: {(6) default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+  => in schema: {(7) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+      JOIN(12)(INNER)
+        => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+        => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in schema: {(5) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+         SCAN(1) on default.region as r
+           => target list: default.r.r_regionkey (INT4)
+           => out schema: {(1) default.r.r_regionkey (INT4)}
+           => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+         SCAN(0) on default.nation as n
+           => filter: default.n.n_name (TEXT) IN (ARGENTINA, ETHIOPIA, MOROCCO)
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+   JOIN(13)(INNER)
+     => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+     => target list: default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+     => out schema: {(3) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+     => in schema: {(4) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+      SCAN(5) on default.supplier as s
+        => target list: default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+        => out schema: {(2) default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+        => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+      SCAN(7) on default.partsupp as ps
+        => target list: default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)
+        => out schema: {(2) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)}
+        => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000008)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000008
+   |-eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000007
+2: eb_0000000000000_0000_000008
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [ROOT]
+=======================================================
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.ps
+ 1: type=Broadcast, tables=default.s
+ 2: type=Broadcast, tables=default.r
+
+JOIN(14)(INNER)
+  => Join Cond: default.s.s_nationkey (INT4) = default.t.n_nationkey (INT4)
+  => target list: default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)
+  => out schema: {(6) default.ps.ps_availqty (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+  => in schema: {(7) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4), default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+   TABLE_SUBQUERY(4) as default.t
+     => Targets: default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)
+     => out schema: {(4) default.t.n_nationkey (INT4), default.t.n_name (TEXT), default.t.n_regionkey (INT4), default.t.n_comment (TEXT)}
+     => in  schema: {(4) default.t.n_comment (TEXT), default.t.n_name (TEXT), default.t.n_nationkey (INT4), default.t.n_regionkey (INT4)}
+      PROJECTION(3)
+        => Targets: default.n.n_nationkey (INT4), default.n.n_name (TEXT), default.n.n_regionkey (INT4), default.n.n_comment (TEXT)
+        => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+        => in  schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+         JOIN(12)(INNER)
+           => Join Cond: default.n.n_regionkey (INT4) = default.r.r_regionkey (INT4)
+           => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+           => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+           => in schema: {(5) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4), default.r.r_regionkey (INT4)}
+            SCAN(1) on default.region as r
+              => target list: default.r.r_regionkey (INT4)
+              => out schema: {(1) default.r.r_regionkey (INT4)}
+              => in schema: {(3) default.r.r_comment (TEXT), default.r.r_name (TEXT), default.r.r_regionkey (INT4)}
+            SCAN(0) on default.nation as n
+              => filter: default.n.n_name (TEXT) IN (ARGENTINA, ETHIOPIA, MOROCCO)
+              => target list: default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)
+              => out schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+              => in schema: {(4) default.n.n_comment (TEXT), default.n.n_name (TEXT), default.n.n_nationkey (INT4), default.n.n_regionkey (INT4)}
+   JOIN(13)(INNER)
+     => Join Cond: default.s.s_suppkey (INT4) = default.ps.ps_suppkey (INT4)
+     => target list: default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+     => out schema: {(3) default.ps.ps_availqty (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+     => in schema: {(4) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4), default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+      SCAN(5) on default.supplier as s
+        => target list: default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)
+        => out schema: {(2) default.s.s_nationkey (INT4), default.s.s_suppkey (INT4)}
+        => in schema: {(7) default.s.s_acctbal (FLOAT8), default.s.s_address (TEXT), default.s.s_comment (TEXT), default.s.s_name (TEXT), default.s.s_nationkey (INT4), default.s.s_phone (TEXT), default.s.s_suppkey (INT4)}
+      SCAN(7) on default.partsupp as ps
+        => target list: default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)
+        => out schema: {(2) default.ps.ps_availqty (INT4), default.ps.ps_suppkey (INT4)}
+        => in schema: {(5) default.ps.ps_availqty (INT4), default.ps.ps_comment (TEXT), default.ps.ps_partkey (INT4), default.ps.ps_suppkey (INT4), default.ps.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [TERMINAL]
+=======================================================


[38/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestNLJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestNLJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestNLJoinExec.java
new file mode 100644
index 0000000..d7968fe
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestNLJoinExec.java
@@ -0,0 +1,208 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+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.assertTrue;
+
+public class TestNLJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestNLJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+
+  private TableDesc employee;
+  private TableDesc people;
+
+  private MasterPlan masterPlan;
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    Schema schema = new Schema();
+    schema.addColumn("managerid", Type.INT4);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("memid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, schema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(schema.size());
+    for (int i = 0; i < 50; i++) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("dept_" + i)});
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+    employee = CatalogUtil.newTableDesc("default.employee", schema, employeeMeta, employeePath);
+    catalog.createTable(employee);
+    
+    Schema peopleSchema = new Schema();
+    peopleSchema.addColumn("empid", Type.INT4);
+    peopleSchema.addColumn("fk_memid", Type.INT4);
+    peopleSchema.addColumn("name", Type.TEXT);
+    peopleSchema.addColumn("age", Type.INT4);
+    TableMeta peopleMeta = CatalogUtil.newTableMeta("TEXT");
+    Path peoplePath = new Path(testDir, "people.csv");
+    appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(peopleMeta, peopleSchema, peoplePath);
+    appender.init();
+    tuple = new VTuple(peopleSchema.size());
+    for (int i = 1; i < 50; i += 2) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(i),
+          DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(30 + i)});
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+    
+    people = CatalogUtil.newTableDesc("default.people", peopleSchema, peopleMeta, peoplePath);
+    catalog.createTable(people);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+
+    masterPlan = new MasterPlan(LocalTajoTestingUtility.newQueryId(), null, null);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+  
+  String[] QUERIES = {
+    "select managerId, e.empId, deptName, e.memId from employee as e, people p",
+    "select managerId, e.empId, deptName, e.memId from employee as e inner join people as p on " +
+        "e.empId = p.empId and e.memId = p.fk_memId"
+  };
+  
+  @Test
+  public final void testNLCrossJoin() throws IOException, TajoException {
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+    
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testNLCrossJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf),
+        expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    int i = 0;
+    exec.init();
+    while (exec.next() != null) {
+      i++;
+    }
+    exec.close();
+    assertEquals(50*50/2, i); // expected 10 * 5
+  }
+
+  @Test
+  public final void testNLInnerJoin() throws IOException, TajoException {
+    FileFragment[] empFrags = FileTablespace.splitNG(conf, "default.e", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    FileFragment[] peopleFrags = FileTablespace.splitNG(conf, "default.p", people.getMeta(),
+        new Path(people.getUri()), Integer.MAX_VALUE);
+    
+    FileFragment[] merged = TUtil.concat(empFrags, peopleFrags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testNLInnerJoin");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr =  analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf),
+        expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+    
+    Tuple tuple;
+    int i = 1;
+    int count = 0;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      count++;
+      assertTrue(i == tuple.getInt4(0));
+      assertTrue(i == tuple.getInt4(1));
+      assertTrue(("dept_" + i).equals(tuple.getText(2)));
+      assertTrue(10 + i == tuple.getInt4(3));
+      i += 2;
+    }
+    exec.close();
+    assertEquals(50 / 2, count);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
new file mode 100644
index 0000000..69b36c5
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
@@ -0,0 +1,1144 @@
+/**
+ * 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.planner.physical;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.*;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.FunctionLoader;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.planner.global.DataChannel;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.*;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+import org.apache.tajo.plan.logical.*;
+import org.apache.tajo.plan.serder.PlanProto.ShuffleType;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.session.Session;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.storage.fragment.Fragment;
+import org.apache.tajo.unit.StorageUnit;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.apache.tajo.plan.serder.PlanProto.ColumnPartitionEnforcer.ColumnPartitionAlgorithm;
+import static org.apache.tajo.plan.serder.PlanProto.SortEnforce.SortAlgorithm;
+import static org.junit.Assert.*;
+
+public class TestPhysicalPlanner {
+  private static TajoTestingCluster util;
+  private static TajoConf conf;
+  private static CatalogService catalog;
+  private static SQLAnalyzer analyzer;
+  private static LogicalPlanner planner;
+  private static LogicalOptimizer optimizer;
+  private static FileTablespace sm;
+  private static Path testDir;
+  private static Session session = LocalTajoTestingUtility.createDummySession();
+  private static QueryContext defaultContext;
+
+  private static TableDesc employee = null;
+  private static TableDesc score = null;
+  private static TableDesc largeScore = null;
+
+  private static MasterPlan masterPlan;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+
+    util.startCatalogCluster();
+    conf = util.getConfiguration();
+    testDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestPhysicalPlanner");
+    sm = TablespaceManager.getLocalFs();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
+      catalog.createFunction(funcDesc);
+    }
+
+    Schema employeeSchema = new Schema();
+    employeeSchema.addColumn("name", Type.TEXT);
+    employeeSchema.addColumn("empid", Type.INT4);
+    employeeSchema.addColumn("deptname", Type.TEXT);
+
+    Schema scoreSchema = new Schema();
+    scoreSchema.addColumn("deptname", Type.TEXT);
+    scoreSchema.addColumn("class", Type.TEXT);
+    scoreSchema.addColumn("score", Type.INT4);
+    scoreSchema.addColumn("nullable", Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("TEXT");
+
+
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = sm.getAppender(employeeMeta, employeeSchema, employeePath);
+    appender.init();
+    VTuple tuple = new VTuple(employeeSchema.size());
+    for (int i = 0; i < 100; i++) {
+      tuple.put(new Datum[] {DatumFactory.createText("name_" + i),
+          DatumFactory.createInt4(i), DatumFactory.createText("dept_" + i)});
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+
+    employee = new TableDesc(
+        CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "employee"), employeeSchema, employeeMeta,
+        employeePath.toUri());
+    catalog.createTable(employee);
+
+    Path scorePath = new Path(testDir, "score");
+    TableMeta scoreMeta = CatalogUtil.newTableMeta("TEXT", new KeyValueSet());
+    appender = sm.getAppender(scoreMeta, scoreSchema, scorePath);
+    appender.init();
+    score = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "score"), scoreSchema, scoreMeta,
+        scorePath.toUri());
+    tuple = new VTuple(scoreSchema.size());
+    int m = 0;
+    for (int i = 1; i <= 5; i++) {
+      for (int k = 3; k < 5; k++) {
+        for (int j = 1; j <= 3; j++) {
+          tuple.put(
+              new Datum[] {
+                  DatumFactory.createText("name_" + i), // name_1 ~ 5 (cad: // 5)
+                  DatumFactory.createText(k + "rd"), // 3 or 4rd (cad: 2)
+                  DatumFactory.createInt4(j), // 1 ~ 3
+              m % 3 == 1 ? DatumFactory.createText("one") : NullDatum.get()});
+          appender.addTuple(tuple);
+          m++;
+        }
+      }
+    }
+    appender.flush();
+    appender.close();
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+    catalog.createTable(score);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(conf, catalog);
+    masterPlan = new MasterPlan(LocalTajoTestingUtility.newQueryId(), null, null);
+
+    createLargeScoreTable();
+  }
+
+  public static void createLargeScoreTable() throws IOException, TajoException {
+
+    // Preparing a large table
+    Path scoreLargePath = new Path(testDir, "score_large");
+    CommonTestingUtil.cleanupTestDir(scoreLargePath.toString());
+
+    Schema scoreSchmea = score.getSchema();
+    TableMeta scoreLargeMeta = CatalogUtil.newTableMeta("RAW", new KeyValueSet());
+    Appender appender =  ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(scoreLargeMeta, scoreSchmea, scoreLargePath);
+    appender.enableStats();
+    appender.init();
+    largeScore = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "score_large"), scoreSchmea, scoreLargeMeta,
+        scoreLargePath.toUri());
+
+    VTuple tuple = new VTuple(scoreSchmea.size());
+    int m = 0;
+    for (int i = 1; i <= 40000; i++) {
+      for (int k = 3; k < 5; k++) { // |{3,4}| = 2
+        for (int j = 1; j <= 3; j++) { // |{1,2,3}| = 3
+          tuple.put(
+              new Datum[] {
+                  DatumFactory.createText("name_" + i), // name_1 ~ 5 (cad: // 5)
+                  DatumFactory.createText(k + "rd"), // 3 or 4rd (cad: 2)
+                  DatumFactory.createInt4(j), // 1 ~ 3
+                  m % 3 == 1 ? DatumFactory.createText("one") : NullDatum.get()});
+          appender.addTuple(tuple);
+          m++;
+        }
+      }
+    }
+    appender.flush();
+    appender.close();
+    largeScore.setStats(appender.getStats());
+    catalog.createTable(largeScore);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  private String[] QUERIES = {
+      "select name, empId, deptName from employee", // 0
+      "select name, empId, e.deptName, manager from employee as e, dept as dp", // 1
+      "select name, empId, e.deptName, manager, score from employee as e, dept, score", // 2
+      "select p.deptName, sum(score) from dept as p, score group by p.deptName having sum(score) > 30", // 3
+      "select p.deptName, score from dept as p, score order by score asc", // 4
+      "select name from employee where empId = 100", // 5
+      "select deptName, class, score from score", // 6
+      "select deptName, class, sum(score), max(score), min(score) from score group by deptName, class", // 7
+      "select count(*), max(score), min(score) from score", // 8
+      "select count(deptName) from score", // 9
+      "select managerId, empId, deptName from employee order by managerId, empId desc", // 10
+      "select deptName, nullable from score group by deptName, nullable", // 11
+      "select 3 < 4 as ineq, 3.5 * 2 as score", // 12
+      "select (1 > 0) and 3 > 1", // 13
+      "select sum(score), max(score), min(score) from score", // 14
+      "select deptname, sum(score), max(score), min(score) from score group by deptname", // 15
+      "select name from employee where empid >= 0", // 16
+  };
+
+  @Test
+  public final void testCreateScanPlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testCreateScanPlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+    LogicalNode rootNode =plan.getRootBlock().getRoot();
+    optimizer.optimize(plan);
+
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    Tuple tuple;
+    int i = 0;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      assertTrue(tuple.contains(0));
+      assertTrue(tuple.contains(1));
+      assertTrue(tuple.contains(2));
+      i++;
+    }
+    exec.close();
+    assertEquals(100, i);
+  }
+
+  @Test
+  public final void testCreateScanWithFilterPlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testCreateScanWithFilterPlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[16]);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+    LogicalNode rootNode =plan.getRootBlock().getRoot();
+    optimizer.optimize(plan);
+
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    Tuple tuple;
+    int i = 0;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      assertTrue(tuple.contains(0));
+      i++;
+    }
+    exec.close();
+    assertEquals(100, i);
+  }
+
+  @Test
+  public final void testGroupByPlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testGroupByPlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[7]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    int i = 0;
+    Tuple tuple;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      assertEquals(6, tuple.getInt4(2)); // sum
+      assertEquals(3, tuple.getInt4(3)); // max
+      assertEquals(1, tuple.getInt4(4)); // min
+      i++;
+    }
+    exec.close();
+    assertEquals(10, i);
+  }
+
+  @Test
+  public final void testHashGroupByPlanWithALLField() throws IOException, TajoException {
+    // TODO - currently, this query does not use hash-based group operator.
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + 
+        "/testHashGroupByPlanWithALLField");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[15]);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    int i = 0;
+    Tuple tuple;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      assertEquals(12, tuple.getInt4(1)); // sum
+      assertEquals(3, tuple.getInt4(2)); // max
+      assertEquals(1, tuple.getInt4(3)); // min
+      i++;
+    }
+    exec.close();
+    assertEquals(5, i);
+  }
+
+  @Test
+  public final void testSortGroupByPlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testSortGroupByPlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[]{frags[0]}, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[7]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan.getRootBlock().getRoot());
+
+    /*HashAggregateExec hashAgg = (HashAggregateExec) exec;
+
+    SeqScanExec scan = (SeqScanExec) hashAgg.getSubOp();
+
+    Column [] grpColumns = hashAgg.getAnnotation().getGroupingColumns();
+    QueryBlock.SortSpec [] specs = new QueryBlock.SortSpec[grpColumns.length];
+    for (int i = 0; i < grpColumns.length; i++) {
+      specs[i] = new QueryBlock.SortSpec(grpColumns[i], true, false);
+    }
+    SortNode annotation = new SortNode(specs);
+    annotation.setInSchema(scan.getSchema());
+    annotation.setOutSchema(scan.getSchema());
+    SortExec sort = new SortExec(annotation, scan);
+    exec = new SortAggregateExec(hashAgg.getAnnotation(), sort);*/
+
+    int i = 0;
+    Tuple tuple;
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      assertEquals(6, tuple.getInt4(2)); // sum
+      assertEquals(3, tuple.getInt4(3)); // max
+      assertEquals(1, tuple.getInt4(4)); // min
+      i++;
+    }
+    assertEquals(10, i);
+
+    exec.rescan();
+    i = 0;
+    while ((tuple = exec.next()) != null) {
+      assertEquals(6, tuple.getInt4(2)); // sum
+      assertEquals(3, tuple.getInt4(3)); // max
+      assertEquals(1, tuple.getInt4(4)); // min
+      i++;
+    }
+    exec.close();
+    assertEquals(10, i);
+  }
+
+  private String[] CreateTableAsStmts = {
+      "create table grouped1 as select deptName, class, sum(score), max(score), min(score) from score group by deptName, class", // 0
+      "create table grouped2 using rcfile as select deptName, class, sum(score), max(score), min(score) from score group by deptName, class", // 1
+      "create table grouped3 partition by column (dept text,  class text) as select sum(score), max(score), min(score), deptName, class from score group by deptName, class", // 2,
+      "create table score_large_output as select * from score_large", // 4
+      "CREATE TABLE score_part (deptname text, score int4, nullable text) PARTITION BY COLUMN (class text) " +
+          "AS SELECT deptname, score, nullable, class from score_large" // 5
+  };
+
+  @Test
+  public final void testStorePlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testStorePlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    ctx.setOutputPath(new Path(workDir, "grouped1"));
+
+    Expr context = analyzer.parse(CreateTableAsStmts[0]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    TableMeta outputMeta = CatalogUtil.newTableMeta("TEXT");
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    Scanner scanner =  ((FileTablespace) TablespaceManager.getLocalFs())
+        .getFileScanner(outputMeta, rootNode.getOutSchema(), ctx.getOutputPath());
+    scanner.init();
+    Tuple tuple;
+    int i = 0;
+    while ((tuple = scanner.next()) != null) {
+      assertEquals(6, tuple.getInt4(2)); // sum
+      assertEquals(3, tuple.getInt4(3)); // max
+      assertEquals(1, tuple.getInt4(4)); // min
+      i++;
+    }
+    assertEquals(10, i);
+    scanner.close();
+
+    // Examine the statistics information
+    assertEquals(10, ctx.getResultStats().getNumRows().longValue());
+  }
+
+  @Test
+  public final void testStorePlanWithMaxOutputFileSize() throws IOException, TajoException,
+      CloneNotSupportedException {
+
+    TableStats stats = largeScore.getStats();
+    assertTrue("Checking meaningfulness of test", stats.getNumBytes() > StorageUnit.MB);
+
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score_large", largeScore.getMeta(),
+        new Path(largeScore.getUri()), Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testStorePlanWithMaxOutputFileSize");
+
+    QueryContext queryContext = new QueryContext(conf, session);
+    queryContext.setInt(SessionVars.MAX_OUTPUT_FILE_SIZE, 1);
+
+    TaskAttemptContext ctx = new TaskAttemptContext(
+        queryContext,
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    ctx.setOutputPath(new Path(workDir, "maxOutput"));
+
+    Expr context = analyzer.parse(CreateTableAsStmts[3]);
+
+    LogicalPlan plan = planner.createPlan(queryContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    // executing StoreTableExec
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    // checking the number of punctuated files
+    int expectedFileNum = (int) (stats.getNumBytes() / (float) StorageUnit.MB);
+    FileSystem fs = ctx.getOutputPath().getFileSystem(conf);
+    FileStatus [] statuses = fs.listStatus(ctx.getOutputPath().getParent());
+    assertEquals(expectedFileNum, statuses.length);
+
+    // checking the file contents
+    long totalNum = 0;
+    for (FileStatus status : fs.listStatus(ctx.getOutputPath().getParent())) {
+      Scanner scanner =  ((FileTablespace) TablespaceManager.getLocalFs()).getFileScanner(
+          CatalogUtil.newTableMeta("TEXT"),
+          rootNode.getOutSchema(),
+          status.getPath());
+
+      scanner.init();
+      while ((scanner.next()) != null) {
+        totalNum++;
+      }
+      scanner.close();
+    }
+    assertTrue(totalNum == ctx.getResultStats().getNumRows());
+  }
+
+  @Test
+  public final void testStorePlanWithRCFile() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testStorePlanWithRCFile");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    ctx.setOutputPath(new Path(workDir, "grouped2"));
+
+    Expr context = analyzer.parse(CreateTableAsStmts[1]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    TableMeta outputMeta = CatalogUtil.newTableMeta("RCFILE");
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    Scanner scanner = ((FileTablespace) TablespaceManager.getLocalFs()).getFileScanner(
+        outputMeta, rootNode.getOutSchema(), ctx.getOutputPath());
+    scanner.init();
+    Tuple tuple;
+    int i = 0;
+    while ((tuple = scanner.next()) != null) {
+      assertEquals(6, tuple.getInt4(2)); // sum
+      assertEquals(3, tuple.getInt4(3)); // max
+      assertEquals(1, tuple.getInt4(4)); // min
+      i++;
+    }
+    assertEquals(10, i);
+    scanner.close();
+
+    // Examine the statistics information
+    assertEquals(10, ctx.getResultStats().getNumRows().longValue());
+  }
+
+  @Test
+  public final void testEnforceForDefaultColumnPartitionStorePlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testStorePlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    ctx.setOutputPath(new Path(workDir, "grouped3"));
+
+    Expr context = analyzer.parse(CreateTableAsStmts[2]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    assertTrue(exec instanceof SortBasedColPartitionStoreExec);
+  }
+
+  @Test
+  public final void testEnforceForHashBasedColumnPartitionStorePlan() throws IOException, TajoException {
+
+    Expr context = analyzer.parse(CreateTableAsStmts[2]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalRootNode rootNode = (LogicalRootNode) optimizer.optimize(plan);
+    CreateTableNode createTableNode = rootNode.getChild();
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceColumnPartitionAlgorithm(createTableNode.getPID(), ColumnPartitionAlgorithm.HASH_PARTITION);
+
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testStorePlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(enforcer);
+    ctx.setOutputPath(new Path(workDir, "grouped4"));
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    assertTrue(exec instanceof HashBasedColPartitionStoreExec);
+  }
+
+  @Test
+  public final void testEnforceForSortBasedColumnPartitionStorePlan() throws IOException, TajoException {
+
+    Expr context = analyzer.parse(CreateTableAsStmts[2]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalRootNode rootNode = (LogicalRootNode) optimizer.optimize(plan);
+    CreateTableNode createTableNode = rootNode.getChild();
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceColumnPartitionAlgorithm(createTableNode.getPID(), ColumnPartitionAlgorithm.SORT_PARTITION);
+
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testStorePlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(enforcer);
+    ctx.setOutputPath(new Path(workDir, "grouped5"));
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    assertTrue(exec instanceof SortBasedColPartitionStoreExec);
+  }
+
+  @Test
+  public final void testPartitionedStorePlan() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    TaskAttemptId id = LocalTajoTestingUtility.newTaskAttemptId(masterPlan);
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf), id, new FileFragment[] { frags[0] },
+        CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testPartitionedStorePlan"));
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[7]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+
+    int numPartitions = 3;
+    Column key1 = new Column("default.score.deptname", Type.TEXT);
+    Column key2 = new Column("default.score.class", Type.TEXT);
+    DataChannel dataChannel = new DataChannel(masterPlan.newExecutionBlockId(), masterPlan.newExecutionBlockId(),
+        ShuffleType.HASH_SHUFFLE, numPartitions);
+    dataChannel.setShuffleKeys(new Column[]{key1, key2});
+    ctx.setDataChannel(dataChannel);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    TableMeta outputMeta = CatalogUtil.newTableMeta(dataChannel.getStoreType());
+
+    FileSystem fs = sm.getFileSystem();
+    QueryId queryId = id.getTaskId().getExecutionBlockId().getQueryId();
+    ExecutionBlockId ebId = id.getTaskId().getExecutionBlockId();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+    ctx.getHashShuffleAppenderManager().close(ebId);
+
+    String executionBlockBaseDir = queryId.toString() + "/output" + "/" + ebId.getId() + "/hash-shuffle";
+    Path queryLocalTmpDir = new Path(conf.getVar(ConfVars.WORKER_TEMPORAL_DIR) + "/" + executionBlockBaseDir);
+    FileStatus [] list = fs.listStatus(queryLocalTmpDir);
+
+    List<Fragment> fragments = new ArrayList<Fragment>();
+    for (FileStatus status : list) {
+      assertTrue(status.isDirectory());
+      FileStatus [] files = fs.listStatus(status.getPath());
+      for (FileStatus eachFile: files) {
+        fragments.add(new FileFragment("partition", eachFile.getPath(), 0, eachFile.getLen()));
+      }
+    }
+
+    assertEquals(numPartitions, fragments.size());
+    Scanner scanner = new MergeScanner(conf, rootNode.getOutSchema(), outputMeta, TUtil.newList(fragments));
+    scanner.init();
+
+    Tuple tuple;
+    int i = 0;
+    while ((tuple = scanner.next()) != null) {
+      assertEquals(6, tuple.getInt4(2)); // sum
+      assertEquals(3, tuple.getInt4(3)); // max
+      assertEquals(1, tuple.getInt4(4)); // min
+      i++;
+    }
+    assertEquals(10, i);
+    scanner.close();
+
+    // Examine the statistics information
+    assertEquals(10, ctx.getResultStats().getNumRows().longValue());
+
+    fs.delete(queryLocalTmpDir, true);
+  }
+
+  @Test
+  public final void testPartitionedStorePlanWithMaxFileSize() throws IOException, TajoException {
+
+    // Preparing working dir and input fragments
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score_large", largeScore.getMeta(),
+        new Path(largeScore.getUri()), Integer.MAX_VALUE);
+    TaskAttemptId id = LocalTajoTestingUtility.newTaskAttemptId(masterPlan);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testPartitionedStorePlanWithMaxFileSize");
+
+    // Setting session variables
+    QueryContext queryContext = new QueryContext(conf, session);
+    queryContext.setInt(SessionVars.MAX_OUTPUT_FILE_SIZE, 1);
+
+    // Preparing task context
+    TaskAttemptContext ctx = new TaskAttemptContext(queryContext, id, new FileFragment[] { frags[0] }, workDir);
+    ctx.setOutputPath(new Path(workDir, "part-01-000000"));
+    // SortBasedColumnPartitionStoreExec will be chosen by default.
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(CreateTableAsStmts[4]);
+    LogicalPlan plan = planner.createPlan(queryContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    // Executing CREATE TABLE PARTITION BY
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    FileSystem fs = sm.getFileSystem();
+    FileStatus [] list = fs.listStatus(workDir);
+    // checking the number of partitions
+    assertEquals(2, list.length);
+
+    List<Fragment> fragments = Lists.newArrayList();
+    int i = 0;
+    for (FileStatus status : list) {
+      assertTrue(status.isDirectory());
+
+      long fileVolumSum = 0;
+      FileStatus [] fileStatuses = fs.listStatus(status.getPath());
+      for (FileStatus fileStatus : fileStatuses) {
+        fileVolumSum += fileStatus.getLen();
+        fragments.add(new FileFragment("partition", fileStatus.getPath(), 0, fileStatus.getLen()));
+      }
+      assertTrue("checking the meaningfulness of test", fileVolumSum > StorageUnit.MB && fileStatuses.length > 1);
+
+      long expectedFileNum = (long) Math.ceil(fileVolumSum / (float)StorageUnit.MB);
+      assertEquals(expectedFileNum, fileStatuses.length);
+    }
+    TableMeta outputMeta = CatalogUtil.newTableMeta("TEXT");
+    Scanner scanner = new MergeScanner(conf, rootNode.getOutSchema(), outputMeta, TUtil.newList(fragments));
+    scanner.init();
+
+    long rowNum = 0;
+    while (scanner.next() != null) {
+      rowNum++;
+    }
+
+    // checking the number of all written rows
+    assertTrue(largeScore.getStats().getNumRows() == rowNum);
+
+    scanner.close();
+  }
+
+  @Test
+  public final void testPartitionedStorePlanWithEmptyGroupingSet()
+      throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    TaskAttemptId id = LocalTajoTestingUtility.newTaskAttemptId(masterPlan);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + 
+        "/testPartitionedStorePlanWithEmptyGroupingSet");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        id, new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[14]);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+    int numPartitions = 1;
+    DataChannel dataChannel = new DataChannel(masterPlan.newExecutionBlockId(), masterPlan.newExecutionBlockId(),
+        ShuffleType.HASH_SHUFFLE, numPartitions);
+    dataChannel.setShuffleKeys(new Column[]{});
+    ctx.setDataChannel(dataChannel);
+    optimizer.optimize(plan);
+
+    TableMeta outputMeta = CatalogUtil.newTableMeta(dataChannel.getStoreType());
+
+    FileSystem fs = sm.getFileSystem();
+    QueryId queryId = id.getTaskId().getExecutionBlockId().getQueryId();
+    ExecutionBlockId ebId = id.getTaskId().getExecutionBlockId();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+    ctx.getHashShuffleAppenderManager().close(ebId);
+
+    String executionBlockBaseDir = queryId.toString() + "/output" + "/" + ebId.getId() + "/hash-shuffle";
+    Path queryLocalTmpDir = new Path(conf.getVar(ConfVars.WORKER_TEMPORAL_DIR) + "/" + executionBlockBaseDir);
+    FileStatus [] list = fs.listStatus(queryLocalTmpDir);
+
+    List<Fragment> fragments = new ArrayList<Fragment>();
+    for (FileStatus status : list) {
+      assertTrue(status.isDirectory());
+      FileStatus [] files = fs.listStatus(status.getPath());
+      for (FileStatus eachFile: files) {
+        fragments.add(new FileFragment("partition", eachFile.getPath(), 0, eachFile.getLen()));
+      }
+    }
+
+    assertEquals(numPartitions, fragments.size());
+
+    Scanner scanner = new MergeScanner(conf, rootNode.getOutSchema(), outputMeta, TUtil.newList(fragments));
+    scanner.init();
+    Tuple tuple;
+    int i = 0;
+    while ((tuple = scanner.next()) != null) {
+      assertEquals(60, tuple.getInt4(0)); // sum
+      assertEquals(3, tuple.getInt4(1)); // max
+      assertEquals(1, tuple.getInt4(2)); // min
+      i++;
+    }
+    assertEquals(1, i);
+    scanner.close();
+
+    // Examine the statistics information
+    assertEquals(1, ctx.getResultStats().getNumRows().longValue());
+    fs.delete(queryLocalTmpDir, true);
+  }
+
+  @Test
+  public final void testAggregationFunction() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testAggregationFunction");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[8]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    // Set all aggregation functions to the first phase mode
+    GroupbyNode groupbyNode = PlannerUtil.findTopNode(rootNode, NodeType.GROUP_BY);
+    for (AggregationFunctionCallEval function : groupbyNode.getAggFunctions()) {
+      function.setFirstPhase();
+    }
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    exec.init();
+    Tuple tuple = exec.next();
+    assertEquals(30, tuple.getInt8(0));
+    assertEquals(3, tuple.getInt4(1));
+    assertEquals(1, tuple.getInt4(2));
+    assertNull(exec.next());
+    exec.close();
+  }
+
+  @Test
+  public final void testCountFunction() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testCountFunction");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[9]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    // Set all aggregation functions to the first phase mode
+    GroupbyNode groupbyNode = PlannerUtil.findTopNode(rootNode, NodeType.GROUP_BY);
+    for (AggregationFunctionCallEval function : groupbyNode.getAggFunctions()) {
+      function.setFirstPhase();
+    }
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    Tuple tuple = exec.next();
+    assertEquals(30, tuple.getInt8(0));
+    assertNull(exec.next());
+    exec.close();
+  }
+
+  @Test
+  public final void testGroupByWithNullValue() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testGroupByWithNullValue");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(QUERIES[11]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    int count = 0;
+    exec.init();
+    while(exec.next() != null) {
+      count++;
+    }
+    exec.close();
+    assertEquals(10, count);
+  }
+
+  @Test
+  public final void testUnionPlan() throws IOException, TajoException, CloneNotSupportedException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testUnionPlan");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr  context = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+    LogicalRootNode root = (LogicalRootNode) rootNode;
+    UnionNode union = plan.createNode(UnionNode.class);
+    union.setLeftChild((LogicalNode) root.getChild().clone());
+    union.setRightChild((LogicalNode) root.getChild().clone());
+    root.setChild(union);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, root);
+
+    int count = 0;
+    exec.init();
+    while(exec.next() != null) {
+      count++;
+    }
+    exec.close();
+    assertEquals(200, count);
+  }
+
+  @Test
+  public final void testEvalExpr() throws IOException, TajoException {
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testEvalExpr");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] { }, workDir);
+    Expr expr = analyzer.parse(QUERIES[12]);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    Tuple tuple;
+    exec.init();
+    tuple = exec.next();
+    exec.close();
+    assertEquals(true, tuple.getBool(0));
+    assertTrue(7.0d == tuple.getFloat8(1));
+
+    expr = analyzer.parse(QUERIES[13]);
+    plan = planner.createPlan(defaultContext, expr);
+    rootNode = optimizer.optimize(plan);
+
+    phyPlanner = new PhysicalPlannerImpl(conf);
+    exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    tuple = exec.next();
+    exec.close();
+    assertEquals(DatumFactory.createBool(true), tuple.asDatum(0));
+  }
+
+  public final String [] createIndexStmt = {
+      "create index idx_employee on employee using TWO_LEVEL_BIN_TREE (name null first, empId desc)"
+  };
+
+  @Test
+  public final void testCreateIndex() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testCreateIndex");
+    Path indexPath = StorageUtil.concatPath(TajoConf.getWarehouseDir(conf), "default/idx_employee");
+    if (sm.getFileSystem().exists(indexPath)) {
+      sm.getFileSystem().delete(indexPath, true);
+    }
+
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] {frags[0]}, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr context = analyzer.parse(createIndexStmt[0]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    while (exec.next() != null) {
+    }
+    exec.close();
+
+    FileStatus[] list = sm.getFileSystem().listStatus(indexPath);
+    assertEquals(2, list.length);
+  }
+
+  final static String [] duplicateElimination = {
+      "select distinct deptname from score",
+  };
+
+  @Test
+  public final void testDuplicateEliminate() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(),
+        new Path(score.getUri()), Integer.MAX_VALUE);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testDuplicateEliminate");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] {frags[0]}, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(duplicateElimination[0]);
+    LogicalPlan plan = planner.createPlan(defaultContext, expr);
+    LogicalNode rootNode = optimizer.optimize(plan);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    Tuple tuple;
+
+    int cnt = 0;
+    Set<String> expected = Sets.newHashSet(
+        "name_1", "name_2", "name_3", "name_4", "name_5");
+    exec.init();
+    while ((tuple = exec.next()) != null) {
+      assertTrue(expected.contains(tuple.getText(0)));
+      cnt++;
+    }
+    exec.close();
+    assertEquals(5, cnt);
+  }
+
+  public String [] SORT_QUERY = {
+      "select name, empId from employee order by empId"
+  };
+
+  @Test
+  public final void testSortEnforcer() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testSortEnforcer");
+    Expr context = analyzer.parse(SORT_QUERY[0]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    SortNode sortNode = PlannerUtil.findTopNode(rootNode, NodeType.SORT);
+
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceSortAlgorithm(sortNode.getPID(), SortAlgorithm.IN_MEMORY_SORT);
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] {frags[0]}, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    assertTrue(exec instanceof MemSortExec);
+
+    context = analyzer.parse(SORT_QUERY[0]);
+    plan = planner.createPlan(defaultContext, context);
+    optimizer.optimize(plan);
+    rootNode = plan.getRootBlock().getRoot();
+
+    sortNode = PlannerUtil.findTopNode(rootNode, NodeType.SORT);
+
+    enforcer = new Enforcer();
+    enforcer.enforceSortAlgorithm(sortNode.getPID(), SortAlgorithm.MERGE_SORT);
+    ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] {frags[0]}, workDir);
+    ctx.setEnforcer(enforcer);
+
+    phyPlanner = new PhysicalPlannerImpl(conf);
+    exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    assertTrue(exec instanceof ExternalSortExec);
+  }
+
+  @Test
+  public final void testGroupByEnforcer() throws IOException, TajoException {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.score", score.getMeta(), new Path(score.getUri()),
+        Integer.MAX_VALUE);
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/testGroupByEnforcer");
+    Expr context = analyzer.parse(QUERIES[7]);
+    LogicalPlan plan = planner.createPlan(defaultContext, context);
+    optimizer.optimize(plan);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    GroupbyNode groupByNode = PlannerUtil.findTopNode(rootNode, NodeType.GROUP_BY);
+
+    Enforcer enforcer = new Enforcer();
+    enforcer.enforceHashAggregation(groupByNode.getPID());
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] {frags[0]}, workDir);
+    ctx.setEnforcer(enforcer);
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    assertNotNull(PhysicalPlanUtil.findExecutor(exec, HashAggregateExec.class));
+
+    context = analyzer.parse(QUERIES[7]);
+    plan = planner.createPlan(defaultContext, context);
+    optimizer.optimize(plan);
+    rootNode = plan.getRootBlock().getRoot();
+
+    groupByNode = PlannerUtil.findTopNode(rootNode, NodeType.GROUP_BY);
+
+    enforcer = new Enforcer();
+    enforcer.enforceSortAggregation(groupByNode.getPID(), null);
+    ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(masterPlan),
+        new FileFragment[] {frags[0]}, workDir);
+    ctx.setEnforcer(enforcer);
+
+    phyPlanner = new PhysicalPlannerImpl(conf);
+    exec = phyPlanner.createPlan(ctx, rootNode);
+    exec.init();
+    exec.next();
+    exec.close();
+
+    assertTrue(exec instanceof SortAggregateExec);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestProgressExternalSortExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestProgressExternalSortExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestProgressExternalSortExec.java
new file mode 100644
index 0000000..d79d292
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestProgressExternalSortExec.java
@@ -0,0 +1,229 @@
+/**
+ * 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.planner.physical;
+
+
+import org.apache.hadoop.fs.Path;
+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.catalog.*;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Random;
+
+import static junit.framework.Assert.assertNotNull;
+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.assertTrue;
+
+public class TestProgressExternalSortExec {
+  private TajoConf conf;
+  private TajoTestingCluster util;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestProgressExternalSortExec";
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+
+  private final int numTuple = 100000;
+  private Random rnd = new Random(System.currentTimeMillis());
+
+  private TableDesc employee;
+
+  private TableStats testDataStats;
+  @Before
+  public void setUp() throws Exception {
+    this.conf = new TajoConf();
+    util = new TajoTestingCluster();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf.setVar(TajoConf.ConfVars.WORKER_TEMPORAL_DIR, testDir.toString());
+
+    Schema schema = new Schema();
+    schema.addColumn("managerid", TajoDataTypes.Type.INT4);
+    schema.addColumn("empid", TajoDataTypes.Type.INT4);
+    schema.addColumn("deptname", TajoDataTypes.Type.TEXT);
+
+    TableMeta employeeMeta = CatalogUtil.newTableMeta("RAW");
+    Path employeePath = new Path(testDir, "employee.csv");
+    Appender appender = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(employeeMeta, schema, employeePath);
+    appender.enableStats();
+    appender.init();
+    VTuple tuple = new VTuple(schema.size());
+    for (int i = 0; i < numTuple; i++) {
+      tuple.put(new Datum[] {
+          DatumFactory.createInt4(rnd.nextInt(50)),
+          DatumFactory.createInt4(rnd.nextInt(100)),
+          DatumFactory.createText("dept_" + i),
+      });
+      appender.addTuple(tuple);
+    }
+    appender.flush();
+    appender.close();
+
+    testDataStats = appender.getStats();
+    employee = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "employee"), schema, employeeMeta,
+        employeePath.toUri());
+    catalog.createTable(employee);
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    CommonTestingUtil.cleanupTestDir(TEST_PATH);
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      "select managerId, empId from employee order by managerId, empId"
+  };
+
+  @Test
+  public void testExternalSortExecProgressWithMemTableScanner() throws Exception {
+    testProgress(testDataStats.getNumBytes().intValue() * 20);    //multiply 20 for memory fit
+  }
+
+  @Test
+  public void testExternalSortExecProgressWithPairWiseMerger() throws Exception {
+    testProgress(testDataStats.getNumBytes().intValue());
+  }
+
+  private void testProgress(int sortBufferBytesNum) throws Exception {
+    FileFragment[] frags = FileTablespace.splitNG(conf, "default.employee", employee.getMeta(),
+        new Path(employee.getUri()), Integer.MAX_VALUE);
+    Path workDir = new Path(testDir, TestExternalSortExec.class.getName());
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), new FileFragment[] { frags[0] }, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummyContext(conf), expr);
+    LogicalNode rootNode = plan.getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, rootNode);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+
+    // TODO - should be planed with user's optimization hint
+    if (!(proj.getChild() instanceof ExternalSortExec)) {
+      UnaryPhysicalExec sortExec = proj.getChild();
+      SeqScanExec scan = sortExec.getChild();
+
+      ExternalSortExec extSort = new ExternalSortExec(ctx, ((MemSortExec)sortExec).getPlan(), scan);
+
+      extSort.setSortBufferBytesNum(sortBufferBytesNum);
+      proj.setChild(extSort);
+    } else {
+      ((ExternalSortExec)proj.getChild()).setSortBufferBytesNum(sortBufferBytesNum);
+    }
+
+    Tuple tuple;
+    Tuple preVal = null;
+    Tuple curVal;
+    int cnt = 0;
+    exec.init();
+    BaseTupleComparator comparator = new BaseTupleComparator(proj.getSchema(),
+        new SortSpec[]{
+            new SortSpec(new Column("managerid", TajoDataTypes.Type.INT4)),
+            new SortSpec(new Column("empid", TajoDataTypes.Type.INT4))
+        });
+
+    float initProgress = 0.0f;
+    while ((tuple = exec.next()) != null) {
+      if (cnt == 0) {
+        initProgress = exec.getProgress();
+        assertTrue(initProgress > 0.5f && initProgress < 1.0f);
+      }
+
+      if (cnt == testDataStats.getNumRows() / 2) {
+        float progress = exec.getProgress();
+
+        assertTrue(progress > initProgress);
+      }
+      curVal = tuple;
+      if (preVal != null) {
+        assertTrue("prev: " + preVal + ", but cur: " + curVal, comparator.compare(preVal, curVal) <= 0);
+      }
+      preVal = curVal;
+      cnt++;
+    }
+
+    assertEquals(1.0f, exec.getProgress(), 0);
+    assertEquals(numTuple, cnt);
+
+    TableStats tableStats = exec.getInputStats();
+    assertNotNull(tableStats);
+    assertEquals(testDataStats.getNumBytes().longValue(), tableStats.getNumBytes().longValue());
+    assertEquals(cnt, testDataStats.getNumRows().longValue());
+    assertEquals(cnt, tableStats.getNumRows().longValue());
+    assertEquals(testDataStats.getNumBytes().longValue(), tableStats.getReadBytes().longValue());
+
+    // for rescan test
+    preVal = null;
+    exec.rescan();
+
+    cnt = 0;
+    while ((tuple = exec.next()) != null) {
+      curVal = tuple;
+      if (preVal != null) {
+        assertTrue("prev: " + preVal + ", but cur: " + curVal, comparator.compare(preVal, curVal) <= 0);
+      }
+      preVal = curVal;
+      cnt++;
+    }
+    assertEquals(1.0f, exec.getProgress(), 0);
+    assertEquals(numTuple, cnt);
+    exec.close();
+    assertEquals(1.0f, exec.getProgress(), 0);
+
+    tableStats = exec.getInputStats();
+    assertNotNull(tableStats);
+    assertEquals(testDataStats.getNumBytes().longValue(), tableStats.getNumBytes().longValue());
+    assertEquals(cnt, testDataStats.getNumRows().longValue());
+    assertEquals(cnt, tableStats.getNumRows().longValue());
+    assertEquals(testDataStats.getNumBytes().longValue(), tableStats.getReadBytes().longValue());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterHashJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterHashJoinExec.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterHashJoinExec.java
new file mode 100644
index 0000000..fe36602
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/physical/TestRightOuterHashJoinExec.java
@@ -0,0 +1,351 @@
+/**
+ * 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.planner.physical;
+
+import org.apache.hadoop.fs.Path;
+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.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.PhysicalPlanner;
+import org.apache.tajo.engine.planner.PhysicalPlannerImpl;
+import org.apache.tajo.engine.planner.enforce.Enforcer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.fragment.FileFragment;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.worker.TaskAttemptContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.assertEquals;
+
+// this is not a physical operator in itself, but it uses the HashLeftOuterJoinExec with switched inputs order
+public class TestRightOuterHashJoinExec {
+  private TajoConf conf;
+  private final String TEST_PATH = TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestRightOuterHashJoinExec";
+  private TajoTestingCluster util;
+  private CatalogService catalog;
+  private SQLAnalyzer analyzer;
+  private LogicalPlanner planner;
+  private Path testDir;
+  private QueryContext defaultContext;
+
+  private TableDesc dep3;
+  private TableDesc job3;
+  private TableDesc emp3;
+
+  private final String DEP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dep3");
+  private final String JOB3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "job3");
+  private final String EMP3_NAME = CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "emp3");
+
+  @Before
+  public void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.initTestDir();
+    catalog = util.startCatalogCluster().getCatalog();
+    testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    conf = util.getConfiguration();
+
+    //----------------- dep3 ------------------------------
+    // dep_id | dep_name  | loc_id
+    //--------------------------------
+    //  0     | dep_0     | 1000
+    //  1     | dep_1     | 1001
+    //  2     | dep_2     | 1002
+    //  3     | dep_3     | 1003
+    //  4     | dep_4     | 1004
+    //  5     | dep_5     | 1005
+    //  6     | dep_6     | 1006
+    //  7     | dep_7     | 1007
+    //  8     | dep_8     | 1008
+    //  9     | dep_9     | 1009
+    Schema dep3Schema = new Schema();
+    dep3Schema.addColumn("dep_id", Type.INT4);
+    dep3Schema.addColumn("dep_name", Type.TEXT);
+    dep3Schema.addColumn("loc_id", Type.INT4);
+
+
+    TableMeta dep3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path dep3Path = new Path(testDir, "dep3.csv");
+    Appender appender1 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(dep3Meta, dep3Schema, dep3Path);
+    appender1.init();
+    VTuple tuple = new VTuple(dep3Schema.size());
+    for (int i = 0; i < 10; i++) {
+      tuple.put(new Datum[] { DatumFactory.createInt4(i),
+                    DatumFactory.createText("dept_" + i),
+                    DatumFactory.createInt4(1000 + i) });
+      appender1.addTuple(tuple);
+    }
+
+    appender1.flush();
+    appender1.close();
+    dep3 = CatalogUtil.newTableDesc(DEP3_NAME, dep3Schema, dep3Meta, dep3Path);
+    catalog.createTable(dep3);
+
+    //----------------- job3 ------------------------------
+    //  job_id  | job_title
+    // ----------------------
+    //   101    |  job_101
+    //   102    |  job_102
+    //   103    |  job_103
+
+    Schema job3Schema = new Schema();
+    job3Schema.addColumn("job_id", Type.INT4);
+    job3Schema.addColumn("job_title", Type.TEXT);
+
+
+    TableMeta job3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path job3Path = new Path(testDir, "job3.csv");
+    Appender appender2 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(job3Meta, job3Schema, job3Path);
+    appender2.init();
+    VTuple tuple2 = new VTuple(job3Schema.size());
+    for (int i = 1; i < 4; i++) {
+      int x = 100 + i;
+      tuple2.put(new Datum[] { DatumFactory.createInt4(100 + i),
+                    DatumFactory.createText("job_" + x) });
+      appender2.addTuple(tuple2);
+    }
+
+    appender2.flush();
+    appender2.close();
+    job3 = CatalogUtil.newTableDesc(JOB3_NAME, job3Schema, job3Meta, job3Path);
+    catalog.createTable(job3);
+
+
+
+    //---------------------emp3 --------------------
+    // emp_id  | first_name | last_name | dep_id | salary | job_id
+    // ------------------------------------------------------------
+    //  11     |  fn_11     |  ln_11    |  1     | 123    | 101
+    //  13     |  fn_13     |  ln_13    |  3     | 369    | 103
+    //  15     |  fn_15     |  ln_15    |  5     | 615    | null
+    //  17     |  fn_17     |  ln_17    |  7     | 861    | null
+    //  19     |  fn_19     |  ln_19    |  9     | 1107   | null
+    //  21     |  fn_21     |  ln_21    |  1     | 123    | 101
+    //  23     |  fn_23     |  ln_23    |  3     | 369    | 103
+
+    Schema emp3Schema = new Schema();
+    emp3Schema.addColumn("emp_id", Type.INT4);
+    emp3Schema.addColumn("first_name", Type.TEXT);
+    emp3Schema.addColumn("last_name", Type.TEXT);
+    emp3Schema.addColumn("dep_id", Type.INT4);
+    emp3Schema.addColumn("salary", Type.FLOAT4);
+    emp3Schema.addColumn("job_id", Type.INT4);
+
+
+    TableMeta emp3Meta = CatalogUtil.newTableMeta("TEXT");
+    Path emp3Path = new Path(testDir, "emp3.csv");
+    Appender appender3 = ((FileTablespace) TablespaceManager.getLocalFs())
+        .getAppender(emp3Meta, emp3Schema, emp3Path);
+    appender3.init();
+    VTuple tuple3 = new VTuple(emp3Schema.size());
+
+    for (int i = 1; i < 4; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+
+      int y = 20 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(20 + i),
+          DatumFactory.createText("firstname_" + y),
+          DatumFactory.createText("lastname_" + y),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createInt4(100 + i) });
+      appender3.addTuple(tuple3);
+    }
+
+    for (int i = 5; i < 10; i += 2) {
+      int x = 10 + i;
+      tuple3.put(new Datum[] { DatumFactory.createInt4(10 + i),
+          DatumFactory.createText("firstname_" + x),
+          DatumFactory.createText("lastname_" + x),
+          DatumFactory.createInt4(i),
+          DatumFactory.createFloat4(123 * i),
+          DatumFactory.createNullDatum() });
+      appender3.addTuple(tuple3);
+    }
+
+    appender3.flush();
+    appender3.close();
+    emp3 = CatalogUtil.newTableDesc(EMP3_NAME, emp3Schema, emp3Meta, emp3Path);
+    catalog.createTable(emp3);
+
+    analyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    defaultContext = LocalTajoTestingUtility.createDummyContext(conf);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  String[] QUERIES = {
+      "select dep3.dep_id, dep_name, emp_id, salary from emp3 right outer join dep3 on dep3.dep_id = emp3.dep_id", //0 no nulls
+      "select job3.job_id, job_title, emp_id, salary from emp3 right outer join job3 on job3.job_id=emp3.job_id", //1 nulls on the left operand
+      "select job3.job_id, job_title, emp_id, salary from job3 right outer join emp3 on job3.job_id=emp3.job_id" //2 nulls on the right side
+  };
+
+  @Test
+  public final void testRightOuter_HashJoinExec0() throws IOException, TajoException {
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] dep3Frags = FileTablespace.splitNG(conf, DEP3_NAME, dep3.getMeta(), new Path(dep3.getUri()),
+        Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(emp3Frags, dep3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestRightOuter_HashJoinExec0");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[0]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    if (proj.getChild() instanceof RightOuterMergeJoinExec) {
+       //for this small data set this is not likely to happen
+      
+      assertEquals(1, 0);
+    }
+    else{
+       Tuple tuple;
+       int count = 0;
+       int i = 1;
+       exec.init();
+  
+       while ((tuple = exec.next()) != null) {
+         //TODO check contents
+         count = count + 1;
+       }
+       exec.close();
+       assertEquals(12, count);
+    }
+  }
+
+
+  @Test
+  public final void testRightOuter_HashJoinExec1() throws IOException, TajoException {
+    FileFragment[] job3Frags = FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(emp3Frags, job3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestRightOuter_HashJoinExec1");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[1]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    if (proj.getChild() instanceof RightOuterMergeJoinExec) {
+       //for this small data set this is not likely to happen
+      
+      assertEquals(1, 0);
+    }
+    else{
+       Tuple tuple;
+       int count = 0;
+       int i = 1;
+       exec.init();
+  
+       while ((tuple = exec.next()) != null) {
+         //TODO check contents
+         count = count + 1;
+       }
+       exec.close();
+       assertEquals(5, count);
+    }
+  }
+
+    @Test
+  public final void testRightOuter_HashJoinExec2() throws IOException, TajoException {
+    
+    FileFragment[] emp3Frags = FileTablespace.splitNG(conf, EMP3_NAME, emp3.getMeta(), new Path(emp3.getUri()),
+        Integer.MAX_VALUE);
+    FileFragment[] job3Frags = FileTablespace.splitNG(conf, JOB3_NAME, job3.getMeta(), new Path(job3.getUri()),
+        Integer.MAX_VALUE);
+
+    FileFragment[] merged = TUtil.concat(job3Frags, emp3Frags);
+
+    Path workDir = CommonTestingUtil.getTestDir(TajoTestingCluster.DEFAULT_TEST_DIRECTORY + "/TestRightOuter_HashJoinExec2");
+    TaskAttemptContext ctx = new TaskAttemptContext(new QueryContext(conf),
+        LocalTajoTestingUtility.newTaskAttemptId(), merged, workDir);
+    ctx.setEnforcer(new Enforcer());
+    Expr expr = analyzer.parse(QUERIES[2]);
+    LogicalNode plan = planner.createPlan(defaultContext, expr).getRootBlock().getRoot();
+
+    PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf);
+    PhysicalExec exec = phyPlanner.createPlan(ctx, plan);
+
+    ProjectionExec proj = (ProjectionExec) exec;
+    if (proj.getChild() instanceof RightOuterMergeJoinExec) {
+      //for this small data set this is not likely to happen
+      
+      assertEquals(1, 0);
+    }
+    else{
+       Tuple tuple;
+       int count = 0;
+       int i = 1;
+       exec.init();
+  
+       while ((tuple = exec.next()) != null) {
+         //TODO check contents
+         count = count + 1;
+       }
+       exec.close();
+       assertEquals(7, count);
+    }
+  }
+}


[42/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
new file mode 100644
index 0000000..bb14aec
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
@@ -0,0 +1,804 @@
+/**
+ * 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.parser;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.apache.tajo.algebra.*;
+import org.apache.tajo.engine.parser.SQLParser.SqlContext;
+import org.apache.tajo.util.FileUtil;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * This unit tests uses a number of query files located in tajo/tajo-core/queries.
+ * So, you must set tajo/tajo-core/ as the working directory.
+ */
+public class TestSQLAnalyzer {
+
+  public static Expr parseQuery(String sql) {
+    ANTLRInputStream input = new ANTLRInputStream(sql);
+    SQLLexer lexer = new SQLLexer(input);
+    CommonTokenStream tokens = new CommonTokenStream(lexer);
+    SQLParser parser = new SQLParser(tokens);
+    parser.setBuildParseTree(true);
+    SQLAnalyzer visitor = new SQLAnalyzer();
+    SqlContext context = parser.sql();
+    return visitor.visitSql(context);
+  }
+
+  public void assertParseResult(String sqlFileName, String resultFileName) throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/TestSQLAnalyzer/" + sqlFileName);
+    String result = FileUtil.readTextFileFromResource("results/TestSQLAnalyzer/" + resultFileName);
+
+    Expr expr = parseQuery(sql);
+    assertEquals(result.trim(), expr.toJson().trim());
+  }
+
+
+  @Test
+  public void testSelect1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/select_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSelect2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/select_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSelect3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/select_3.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSelect4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/select_4.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSelect5() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/select_5.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testAsterisk1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/asterisk_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testAsterisk2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/asterisk_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testAsterisk3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/asterisk_3.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testAsterisk4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/asterisk_4.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testGroupby1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/groupby_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_3.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_4.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin5() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_5.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin6() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_6.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin7() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_7.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin8() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_8.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin9() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_9.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin10() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_10.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testJoin11() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/join_11.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSet1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/set_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSet2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/set_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSet3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/set_3.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testSet4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/set_4.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testDropTable() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/drop_table.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_3.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_4.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable5() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_5.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable6() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_6.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable7() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_7.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable8() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_8.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable9() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_9.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTable10() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_10.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testCreateTableLike1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_like_1.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertEquals("orig_name", createTable.getLikeParentTableName());
+  }
+
+  @Test
+  public void testCreateTablePartitionByHash1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_partition_by_hash_1.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.HASH, createTable.getPartitionMethod().getPartitionType());
+    CreateTable.HashPartition hashPartition = createTable.getPartitionMethod();
+    assertEquals("col1", hashPartition.getColumns()[0].getCanonicalName());
+    assertTrue(hashPartition.hasQuantifier());
+  }
+
+  @Test
+  public void testCreateTablePartitionByHash2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_partition_by_hash_2.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.HASH, createTable.getPartitionMethod().getPartitionType());
+    CreateTable.HashPartition hashPartition = createTable.getPartitionMethod();
+    assertEquals("col1", hashPartition.getColumns()[0].getCanonicalName());
+    assertTrue(hashPartition.hasSpecifiers());
+    assertEquals(3, hashPartition.getSpecifiers().size());
+  }
+
+  @Test
+  public void testCreateTablePartitionByRange() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_partition_by_range.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.RANGE, createTable.getPartitionMethod().getPartitionType());
+    CreateTable.RangePartition rangePartition = createTable.getPartitionMethod();
+    assertEquals("col1", rangePartition.getColumns()[0].getCanonicalName());
+    assertEquals(3, rangePartition.getSpecifiers().size());
+  }
+
+  @Test
+  public void testCreateTablePartitionByList() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_partition_by_list.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.LIST, createTable.getPartitionMethod().getPartitionType());
+    CreateTable.ListPartition listPartition = createTable.getPartitionMethod();
+    assertEquals("col1", listPartition.getColumns()[0].getCanonicalName());
+    assertEquals(2, listPartition.getSpecifiers().size());
+    Iterator<CreateTable.ListPartitionSpecifier> iterator = listPartition.getSpecifiers().iterator();
+    CreateTable.ListPartitionSpecifier specifier = iterator.next();
+    LiteralValue value1 = (LiteralValue) specifier.getValueList().getValues()[0];
+    LiteralValue value2 = (LiteralValue) specifier.getValueList().getValues()[1];
+    assertEquals("Seoul", value1.getValue());
+    assertEquals("서울", value2.getValue());
+
+    specifier = iterator.next();
+    value1 = (LiteralValue) specifier.getValueList().getValues()[0];
+    value2 = (LiteralValue) specifier.getValueList().getValues()[1];
+    assertEquals("Busan", value1.getValue());
+    assertEquals("부산", value2.getValue());
+  }
+
+  @Test
+  public void testCreateTablePartitionByColumn() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/create_table_partition_by_column.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.COLUMN, createTable.getPartitionMethod().getPartitionType());
+    CreateTable.ColumnPartition columnPartition = createTable.getPartitionMethod();
+    assertEquals(3, columnPartition.getColumns().length);
+    assertEquals("col3", columnPartition.getColumns()[0].getColumnName());
+    assertEquals("col4", columnPartition.getColumns()[1].getColumnName());
+    assertEquals("col5", columnPartition.getColumns()[2].getColumnName());
+  }
+
+  @Test
+  public void testAlterTableAddPartition1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_add_partition_1.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.ADD_PARTITION);
+    assertEquals(2, alterTable.getColumns().length);
+    assertEquals(2, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    assertEquals("col2", alterTable.getColumns()[1].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("1", value1.getValue());
+    LiteralValue value2 = (LiteralValue)alterTable.getValues()[1];
+    assertEquals("2", value2.getValue());
+    assertFalse(alterTable.isIfNotExists());
+  }
+
+  @Test
+  public void testAlterTableAddPartition2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_add_partition_2.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.ADD_PARTITION);
+    assertEquals(2, alterTable.getColumns().length);
+    assertEquals(2, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    assertEquals("col2", alterTable.getColumns()[1].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("1", value1.getValue());
+    LiteralValue value2 = (LiteralValue)alterTable.getValues()[1];
+    assertEquals("2", value2.getValue());
+    assertEquals(alterTable.getLocation(), "hdfs://xxx.com/warehouse/table1/col1=1/col2=2");
+    assertFalse(alterTable.isIfNotExists());
+  }
+
+  @Test
+  public void testAlterTableAddPartition3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_add_partition_3.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.ADD_PARTITION);
+    assertEquals(3, alterTable.getColumns().length);
+    assertEquals(3, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    assertEquals("col2", alterTable.getColumns()[1].getName());
+    assertEquals("col3", alterTable.getColumns()[2].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("2015", value1.getValue());
+    LiteralValue value2 = (LiteralValue)alterTable.getValues()[1];
+    assertEquals("01", value2.getValue());
+    LiteralValue value3 = (LiteralValue)alterTable.getValues()[2];
+    assertEquals("11", value3.getValue());
+    assertEquals(alterTable.getLocation(), "hdfs://xxx.com/warehouse/table1/col1=2015/col2=01/col3=11");
+    assertFalse(alterTable.isIfNotExists());
+  }
+
+  @Test
+  public void testAlterTableAddPartition4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_add_partition_4.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.ADD_PARTITION);
+    assertEquals(1, alterTable.getColumns().length);
+    assertEquals(1, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("TAJO", value1.getValue());
+    assertFalse(alterTable.isIfNotExists());
+  }
+
+  @Test
+  public void testAlterTableAddPartition5() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_add_partition_5.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.ADD_PARTITION);
+    assertEquals(1, alterTable.getColumns().length);
+    assertEquals(1, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("TAJO", value1.getValue());
+    assertTrue(alterTable.isIfNotExists());
+  }
+
+  @Test
+  public void testAlterTableDropPartition1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_drop_partition_1.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.DROP_PARTITION);
+    assertEquals(2, alterTable.getColumns().length);
+    assertEquals(2, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    assertEquals("col2", alterTable.getColumns()[1].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("1", value1.getValue());
+    LiteralValue value2 = (LiteralValue)alterTable.getValues()[1];
+    assertEquals("2", value2.getValue());
+    assertFalse(alterTable.isPurge());
+    assertFalse(alterTable.isIfExists());
+  }
+
+  @Test
+  public void testAlterTableDropPartition2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_drop_partition_2.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.DROP_PARTITION);
+    assertEquals(3, alterTable.getColumns().length);
+    assertEquals(3, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    assertEquals("col2", alterTable.getColumns()[1].getName());
+    assertEquals("col3", alterTable.getColumns()[2].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("2015", value1.getValue());
+    LiteralValue value2 = (LiteralValue)alterTable.getValues()[1];
+    assertEquals("01", value2.getValue());
+    LiteralValue value3 = (LiteralValue)alterTable.getValues()[2];
+    assertEquals("11", value3.getValue());
+    assertFalse(alterTable.isPurge());
+    assertFalse(alterTable.isIfExists());
+  }
+
+  @Test
+  public void testAlterTableDropPartition3() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_drop_partition_3.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.DROP_PARTITION);
+    assertEquals(1, alterTable.getColumns().length);
+    assertEquals(1, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("TAJO", value1.getValue());
+    assertTrue(alterTable.isPurge());
+    assertFalse(alterTable.isIfExists());
+  }
+
+  @Test
+  public void testAlterTableDropPartition4() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_drop_partition_4.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.DROP_PARTITION);
+    assertEquals(1, alterTable.getColumns().length);
+    assertEquals(1, alterTable.getValues().length);
+    assertEquals("col1", alterTable.getColumns()[0].getName());
+    LiteralValue value1 = (LiteralValue)alterTable.getValues()[0];
+    assertEquals("TAJO", value1.getValue());
+    assertTrue(alterTable.isPurge());
+    assertTrue(alterTable.isIfExists());
+  }
+
+  @Test
+  public void testAlterTableSetProperty1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_set_property_1.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.SET_PROPERTY);
+    assertTrue(alterTable.hasParams());
+    assertTrue(alterTable.getParams().containsKey("timezone"));
+    assertEquals("GMT-7", alterTable.getParams().get("timezone"));
+  }
+
+  @Test
+  public void testAlterTableSetProperty2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_set_property_2.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.SET_PROPERTY);
+    assertTrue(alterTable.hasParams());
+    assertTrue(alterTable.getParams().containsKey("text.delimiter"));
+    assertEquals("&", alterTable.getParams().get("text.delimiter"));
+  }
+
+  @Test
+  public void testAlterTableSetProperty3() throws IOException {
+    // update multiple table properties with a single 'SET PROPERTY' sql
+    String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_set_property_3.sql");
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.AlterTable, expr.getType());
+    AlterTable alterTable = (AlterTable)expr;
+    assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.SET_PROPERTY);
+    assertTrue(alterTable.hasParams());
+    assertTrue(alterTable.getParams().containsKey("compression.type"));
+    assertEquals("RECORD", alterTable.getParams().get("compression.type"));
+    assertTrue(alterTable.getParams().containsKey("compression.codec"));
+    assertEquals("org.apache.hadoop.io.compress.SnappyCodec", alterTable.getParams().get("compression.codec"));
+  }
+
+  @Test
+  public void testTableSubQuery1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/table_subquery1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testTableSubQuery2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/table_subquery2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInSubquery1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/in_subquery_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInSubquery2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/in_subquery_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testExistsPredicate1() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/exists_predicate_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testExistsPredicate2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/exists_predicate_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInsertIntoTable() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/insert_into_select_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInsertIntoLocation() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/insert_into_select_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInsertIntoTable2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/insert_into_select_3.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInsertOverwriteIntoTable() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/insert_overwrite_into_select_1.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInsertOverwriteIntoLocation() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/insert_overwrite_into_select_2.sql");
+    parseQuery(sql);
+  }
+
+  @Test
+  public void testInsertOverwriteIntoTable2() throws IOException {
+    String sql = FileUtil.readTextFileFromResource("queries/default/insert_overwrite_into_select_3.sql");
+    parseQuery(sql);
+  }
+
+  static String[] exprs = {
+      "1 + 2", // 0
+      "3 - 4", // 1
+      "5 * 6", // 2
+      "7 / 8", // 3
+      "10 % 2", // 4
+      "1 * 2 > 3 / 4", // 5
+      "1 * 2 < 3 / 4", // 6
+      "1 * 2 = 3 / 4", // 7
+      "1 * 2 != 3 / 4", // 8
+      "1 * 2 <> 3 / 4", // 9
+      "gender in ('male', 'female')", // 10
+      "gender not in ('male', 'female')", // 11
+      "score > 90 and age < 20", // 12
+      "score > 90 and age < 20 and name != 'hyunsik'", // 13
+      "score > 90 or age < 20", // 14
+      "score > 90 or age < 20 and name != 'hyunsik'", // 15
+      "((a+3 > 1) or 1=1) and (3 != (abc + 4) and type in (3,4))", // 16
+      "3", // 17
+      "1.2", // 18
+      "sum(age)", // 19
+      "now()", // 20
+      "not (90 > 100)", // 21
+      "type like '%top'", // 22
+      "type not like 'top%'", // 23
+      "col = 'value'", // 24
+      "col is null", // 25
+      "col is not null", // 26
+      "col = null", // 27
+      "col != null", // 38
+  };
+
+  public static Expr parseExpr(String sql) {
+    ANTLRInputStream input = new ANTLRInputStream(sql);
+    SQLLexer lexer = new SQLLexer(input);
+    CommonTokenStream tokens = new CommonTokenStream(lexer);
+    SQLParser parser = new SQLParser(tokens);
+    parser.setBuildParseTree(true);
+    SQLAnalyzer visitor = new SQLAnalyzer();
+    SQLParser.Value_expressionContext context = parser.value_expression();
+    return visitor.visitValue_expression(context);
+  }
+
+  @Test
+  public void testExprs() {
+    for (int i = 0; i < exprs.length; i++) {
+      parseExpr(exprs[i]);
+    }
+  }
+
+  @Test
+  public void windowFunction1() throws IOException {
+    assertParseResult("window1.sql", "window1.result");
+  }
+
+  @Test
+  public void windowFunction2() throws IOException {
+    assertParseResult("window2.sql", "window2.result");
+  }
+
+  @Test
+  public void windowFunction3() throws IOException {
+    assertParseResult("window3.sql", "window3.result");
+  }
+
+  @Test
+  public void windowFunction4() throws IOException {
+    assertParseResult("window4.sql", "window4.result");
+  }
+
+  @Test
+  public void windowFunction5() throws IOException {
+    assertParseResult("window5.sql", "window5.result");
+  }
+
+  @Test
+  public void windowFunction6() throws IOException {
+    assertParseResult("window6.sql", "window6.result");
+  }
+
+  @Test
+  public void windowFunction7() throws IOException {
+    assertParseResult("window7.sql", "window7.result");
+  }
+
+  @Test
+  public void windowFunction8() throws IOException {
+    assertParseResult("window8.sql", "window8.result");
+  }
+
+  @Test
+  public void windowFunction9() throws IOException {
+    assertParseResult("window9.sql", "window9.result");
+  }
+
+  @Test
+  public void testSetCatalog1() throws IOException {
+    assertParseResult("setcatalog1.sql", "setcatalog1.result");
+  }
+
+  @Test
+  public void testSetCatalog2() throws IOException {
+    assertParseResult("setcatalog2.sql", "setcatalog2.result");
+  }
+
+  @Test
+  public void testTimezone1() throws IOException {
+    assertParseResult("settimezone1.sql", "settimezone1.result");
+  }
+
+  @Test
+  public void testTimezone2() throws IOException {
+    assertParseResult("settimezone2.sql", "settimezone2.result");
+  }
+
+  @Test
+  public void testTimezone3() throws IOException {
+    assertParseResult("settimezone3.sql", "settimezone3.result");
+  }
+
+  @Test
+  public void testSetSession1() throws IOException {
+    assertParseResult("setsession1.sql", "setsession1.result");
+  }
+
+  @Test
+  public void testSetSession2() throws IOException {
+    assertParseResult("setsession2.sql", "setsession2.result");
+  }
+
+  @Test
+  public void testSetSession3() throws IOException {
+    assertParseResult("setsession3.sql", "setsession3.result");
+  }
+
+  @Test
+  public void testSetSession4() throws IOException {
+    assertParseResult("setsession4.sql", "setsession4.result");
+  }
+
+  @Test
+  public void testSetSession5() throws IOException {
+    assertParseResult("setsession5.sql", "setsession5.result");
+  }
+
+  @Test
+  public void testSetSession6() throws IOException {
+    assertParseResult("setsession6.sql", "setsession6.result");
+  }
+
+  @Test
+  public void testSetSession7() throws IOException {
+    assertParseResult("setsession7.sql", "setsession7.result");
+  }
+
+  @Test
+  public void testCreateTableWithNested1() throws IOException {
+    assertParseResult("create_table_nested_1.sql", "create_table_nested_1.result");
+  }
+
+  @Test
+  public void testCreateTableWithNested2() throws IOException {
+    assertParseResult("create_table_nested_2.sql", "create_table_nested_2.result");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestJoinOrderAlgorithm.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestJoinOrderAlgorithm.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestJoinOrderAlgorithm.java
new file mode 100644
index 0000000..19f461b
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestJoinOrderAlgorithm.java
@@ -0,0 +1,184 @@
+/**
+ * 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.planner;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+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.catalog.*;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.engine.function.FunctionLoader;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.*;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.unit.StorageUnit;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.*;
+
+public class TestJoinOrderAlgorithm {
+
+  private static TajoTestingCluster util;
+  private static CatalogService catalog;
+  private static SQLAnalyzer sqlAnalyzer;
+  private static LogicalPlanner planner;
+  private static LogicalOptimizer optimizer;
+  private static QueryContext defaultContext;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
+      catalog.createFunction(funcDesc);
+    }
+
+    Schema schema = new Schema();
+    schema.addColumn("name", Type.TEXT);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("deptname", Type.TEXT);
+    schema2.addColumn("manager", Type.TEXT);
+
+    Schema schema3 = new Schema();
+    schema3.addColumn("deptname", Type.TEXT);
+    schema3.addColumn("score", Type.INT4);
+    schema3.addColumn("phone", Type.INT4);
+
+    TableMeta meta = CatalogUtil.newTableMeta("TEXT");
+    TableDesc people = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "employee"), schema, meta,
+        CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(people);
+
+    TableDesc student =
+        new TableDesc(
+            CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), schema2, "TEXT", new KeyValueSet(),
+            CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(student);
+
+    TableDesc score =
+        new TableDesc(
+            CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), schema3, "TEXT", new KeyValueSet(),
+            CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(score);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // creating table for overflow in JoinOrderOptimizer.
+    Schema schema4 = new Schema();
+    schema4.addColumn("deptname", Type.TEXT);
+    schema4.addColumn("manager", Type.TEXT);
+    // Set store type as FAKEFILE to prevent auto update of physical information in LogicalPlanner.updatePhysicalInfo()
+    TableMeta largeTableMeta = CatalogUtil.newTableMeta("FAKEFILE");
+    TableDesc largeDept;
+    TableStats largeTableStats;
+    FileSystem fs = FileSystem.getLocal(util.getConfiguration());
+    for (int i = 0; i < 6; i++) {
+      Path tablePath = new Path(CommonTestingUtil.getTestDir(), "" + (i+1));
+      fs.create(tablePath);
+      largeDept =
+          new TableDesc(
+              CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "large_dept"+(i+1)), schema4, largeTableMeta,
+              tablePath.toUri());
+      largeTableStats = new TableStats();
+      largeTableStats.setNumBytes(StorageUnit.PB * (i+1));  //1 PB * i
+      largeDept.setStats(largeTableStats);
+      catalog.createTable(largeDept);
+    }
+    ///////////////////////////////////////////////////////////////////////////
+
+    sqlAnalyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(util.getConfiguration());
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  @Test
+  public final void testCheckingInfinityJoinScore() throws Exception {
+    // Test for TAJO-1552
+    String query = "select a.deptname from large_dept1 a, large_dept2 b, large_dept3 c, " +
+        "large_dept4 d, large_dept5 e, large_dept6 f ";
+
+    Expr expr = sqlAnalyzer.parse(query);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    LogicalNode[] joinNodes = PlannerUtil.findAllNodes(newPlan. getRootBlock().getRoot() , NodeType.JOIN);
+    assertNotNull(joinNodes);
+    assertEquals(5, joinNodes.length);
+    assertJoinNode(joinNodes[0], "default.a", "default.b");
+    assertJoinNode(joinNodes[1], null, "default.c");
+    assertJoinNode(joinNodes[2], null, "default.d");
+    assertJoinNode(joinNodes[3], null, "default.e");
+    assertJoinNode(joinNodes[4], null, "default.f");
+
+    optimizer.optimize(newPlan);
+
+    joinNodes = PlannerUtil.findAllNodes(newPlan. getRootBlock().getRoot() , NodeType.JOIN);
+    assertNotNull(joinNodes);
+    assertEquals(5, joinNodes.length);
+    assertJoinNode(joinNodes[0], "default.d", "default.c");
+    assertJoinNode(joinNodes[1], "default.b", "default.a");
+    assertJoinNode(joinNodes[2], null, null);
+    assertJoinNode(joinNodes[3], "default.f", "default.e");
+    assertJoinNode(joinNodes[4], null, null);
+
+  }
+
+  private void assertJoinNode(LogicalNode node, String left, String right) {
+    assertEquals(NodeType.JOIN, node.getType());
+    JoinNode joinNode = (JoinNode)node;
+
+    if (left != null) {
+      assertEquals(left, ((ScanNode)joinNode.getLeftChild()).getCanonicalName());
+    } else {
+      assertEquals(NodeType.JOIN, joinNode.getLeftChild().getType());
+    }
+
+    if (right != null) {
+      assertEquals(right, ((ScanNode)joinNode.getRightChild()).getCanonicalName());
+    } else {
+      assertEquals(NodeType.JOIN, joinNode.getRightChild().getType());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
new file mode 100644
index 0000000..640d88b
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
@@ -0,0 +1,272 @@
+/**
+ * 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.planner;
+
+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.catalog.*;
+import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.engine.function.FunctionLoader;
+import org.apache.tajo.engine.function.builtin.SumInt;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.plan.LogicalOptimizer;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.apache.tajo.plan.logical.*;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.*;
+
+public class TestLogicalOptimizer {
+
+  private static TajoTestingCluster util;
+  private static CatalogService catalog;
+  private static SQLAnalyzer sqlAnalyzer;
+  private static LogicalPlanner planner;
+  private static LogicalOptimizer optimizer;
+  private static QueryContext defaultContext;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    catalog = util.getMiniCatalogCluster().getCatalog();
+    catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
+    catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
+      catalog.createFunction(funcDesc);
+    }
+
+    Schema schema = new Schema();
+    schema.addColumn("name", Type.TEXT);
+    schema.addColumn("empid", Type.INT4);
+    schema.addColumn("deptname", Type.TEXT);
+
+    Schema schema2 = new Schema();
+    schema2.addColumn("deptname", Type.TEXT);
+    schema2.addColumn("manager", Type.TEXT);
+
+    Schema schema3 = new Schema();
+    schema3.addColumn("deptname", Type.TEXT);
+    schema3.addColumn("score", Type.INT4);
+    schema3.addColumn("phone", Type.INT4);
+
+    TableMeta meta = CatalogUtil.newTableMeta("TEXT");
+    TableDesc people = new TableDesc(
+        CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "employee"), schema, meta,
+        CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(people);
+
+    TableDesc student =
+        new TableDesc(
+            CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "dept"), schema2, "TEXT", new KeyValueSet(),
+            CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(student);
+
+    TableDesc score =
+        new TableDesc(
+            CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, "score"), schema3, "TEXT", new KeyValueSet(),
+            CommonTestingUtil.getTestDir().toUri());
+    catalog.createTable(score);
+
+    FunctionDesc funcDesc = new FunctionDesc("sumtest", SumInt.class, FunctionType.GENERAL,
+        CatalogUtil.newSimpleDataType(Type.INT4),
+        CatalogUtil.newSimpleDataTypeArray(Type.INT4));
+
+    catalog.createFunction(funcDesc);
+    sqlAnalyzer = new SQLAnalyzer();
+    planner = new LogicalPlanner(catalog, TablespaceManager.getInstance());
+    optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+
+    defaultContext = LocalTajoTestingUtility.createDummyContext(util.getConfiguration());
+    optimizer = new LogicalOptimizer(util.getConfiguration(), catalog);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    util.shutdownCatalogCluster();
+  }
+
+  static String[] QUERIES = {
+    "select name, manager from employee as e, dept as dp where e.deptName = dp.deptName", // 0
+    "select name, empId, deptName from employee where empId > 500", // 1
+    "select name from employee where empId = 100", // 2
+    "select name, max(empId) as final from employee where empId > 50 group by name", // 3
+    "select name, score from employee natural join score", // 4
+    "select name, score from employee join score on employee.deptName = score.deptName", // 5
+  };
+
+  @Test
+  public final void testProjectionPushWithNaturalJoin() throws TajoException, CloneNotSupportedException {
+    // two relations
+    Expr expr = sqlAnalyzer.parse(QUERIES[4]);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    LogicalNode plan = newPlan.getRootBlock().getRoot();
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+    assertEquals(NodeType.JOIN, projNode.getChild().getType());
+    JoinNode joinNode = projNode.getChild();
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+
+    LogicalNode optimized = optimizer.optimize(newPlan);
+
+    assertEquals(NodeType.ROOT, optimized.getType());
+    root = (LogicalRootNode) optimized;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+    assertEquals(NodeType.JOIN, root.getChild().getType());
+    joinNode = root.getChild();
+    assertEquals(NodeType.SCAN, joinNode.getLeftChild().getType());
+    assertEquals(NodeType.SCAN, joinNode.getRightChild().getType());
+  }
+
+  @Test
+  public final void testProjectionPushWithInnerJoin() throws TajoException {
+    // two relations
+    Expr expr = sqlAnalyzer.parse(QUERIES[5]);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    optimizer.optimize(newPlan);
+  }
+
+  @Test
+  public final void testProjectionPush() throws CloneNotSupportedException, TajoException {
+    // two relations
+    Expr expr = sqlAnalyzer.parse(QUERIES[2]);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    LogicalNode plan = newPlan.getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    SelectionNode selNode = projNode.getChild();
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+
+    LogicalNode optimized = optimizer.optimize(newPlan);
+    assertEquals(NodeType.ROOT, optimized.getType());
+    root = (LogicalRootNode) optimized;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+    assertEquals(NodeType.SCAN, root.getChild().getType());
+  }
+
+  @Test
+  public final void testOptimizeWithGroupBy() throws CloneNotSupportedException, TajoException {
+    Expr expr = sqlAnalyzer.parse(QUERIES[3]);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    LogicalNode plan = newPlan.getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+    assertEquals(NodeType.GROUP_BY, projNode.getChild().getType());
+    GroupbyNode groupbyNode = projNode.getChild();
+    assertEquals(NodeType.SELECTION, groupbyNode.getChild().getType());
+    SelectionNode selNode = groupbyNode.getChild();
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+
+    LogicalNode optimized = optimizer.optimize(newPlan);
+    assertEquals(NodeType.ROOT, optimized.getType());
+    root = (LogicalRootNode) optimized;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+    assertEquals(NodeType.GROUP_BY, root.getChild().getType());
+    groupbyNode = root.getChild();
+    assertEquals(NodeType.SCAN, groupbyNode.getChild().getType());
+  }
+
+  @Test
+  public final void testPushable() throws CloneNotSupportedException, TajoException {
+    // two relations
+    Expr expr = sqlAnalyzer.parse(QUERIES[0]);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    LogicalNode plan = newPlan.getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    LogicalRootNode root = (LogicalRootNode) plan;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    ProjectionNode projNode = root.getChild();
+
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    SelectionNode selNode = projNode.getChild();
+
+    assertEquals(NodeType.JOIN, selNode.getChild().getType());
+    JoinNode joinNode = selNode.getChild();
+    assertFalse(joinNode.hasJoinQual());
+
+    // Test for Pushable
+    assertTrue(LogicalPlanner.checkIfBeEvaluatedAtJoin(newPlan.getRootBlock(), selNode.getQual(), joinNode, false));
+
+    // Optimized plan
+    LogicalNode optimized = optimizer.optimize(newPlan);
+    assertEquals(NodeType.ROOT, optimized.getType());
+    root = (LogicalRootNode) optimized;
+
+    assertEquals(NodeType.JOIN, root.getChild().getType());
+    joinNode = root.getChild();
+    assertTrue(joinNode.hasJoinQual());
+
+    // Scan Pushable Test
+    expr = sqlAnalyzer.parse(QUERIES[1]);
+    newPlan = planner.createPlan(defaultContext, expr);
+    plan = newPlan.getRootBlock().getRoot();
+
+    assertEquals(NodeType.ROOT, plan.getType());
+    root = (LogicalRootNode) plan;
+    TestLogicalPlanner.testCloneLogicalNode(root);
+
+    assertEquals(NodeType.PROJECTION, root.getChild().getType());
+    projNode = root.getChild();
+
+    assertEquals(NodeType.SELECTION, projNode.getChild().getType());
+    selNode = projNode.getChild();
+
+    assertEquals(NodeType.SCAN, selNode.getChild().getType());
+    ScanNode scanNode = selNode.getChild();
+    // Test for Join Node
+    assertTrue(LogicalPlanner.checkIfBeEvaluatedAtRelation(newPlan.getRootBlock(), selNode.getQual(), scanNode));
+  }
+
+  @Test
+  public final void testInsertInto() throws CloneNotSupportedException, TajoException {
+    Expr expr = sqlAnalyzer.parse(TestLogicalPlanner.insertStatements[0]);
+    LogicalPlan newPlan = planner.createPlan(defaultContext, expr);
+    optimizer.optimize(newPlan);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlan.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlan.java
new file mode 100644
index 0000000..d49c43e
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlan.java
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.engine.planner;
+
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.graph.SimpleDirectedGraph;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.LogicalPlanner;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.apache.tajo.plan.LogicalPlan.BlockType;
+import static org.junit.Assert.*;
+
+public class TestLogicalPlan {
+  private static TajoTestingCluster util;
+  private static LogicalPlanner planner;
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    util = new TajoTestingCluster();
+    util.startCatalogCluster();
+    planner = new LogicalPlanner(util.getMiniCatalogCluster().getCatalog(), TablespaceManager.getInstance());
+  }
+
+  public static void tearDown() {
+    util.shutdownCatalogCluster();
+  }
+
+  @Test
+  public final void testQueryBlockGraph() {
+    LogicalPlan plan = new LogicalPlan();
+    LogicalPlan.QueryBlock root = plan.newAndGetBlock(LogicalPlan.ROOT_BLOCK);
+    LogicalPlan.QueryBlock new1 = plan.newQueryBlock();
+    LogicalPlan.QueryBlock new2 = plan.newQueryBlock();
+
+    plan.getQueryBlockGraph().addEdge(new1.getName(), root.getName(),
+        new LogicalPlan.BlockEdge(new1, root, BlockType.TableSubQuery));
+    plan.getQueryBlockGraph().addEdge(new2.getName(), root.getName(),
+        new LogicalPlan.BlockEdge(new2, root, BlockType.TableSubQuery));
+
+    SimpleDirectedGraph<String, LogicalPlan.BlockEdge> graph = plan.getQueryBlockGraph();
+    assertEquals(2, graph.getChildCount(root.getName()));
+
+    assertEquals(root.getName(), graph.getParent(new1.getName(), 0));
+    assertEquals(root.getName(), graph.getParent(new2.getName(), 0));
+
+    assertTrue(graph.isRoot(root.getName()));
+    assertFalse(graph.isRoot(new1.getName()));
+    assertFalse(graph.isRoot(new2.getName()));
+
+    assertFalse(graph.isLeaf(root.getName()));
+    assertTrue(graph.isLeaf(new1.getName()));
+    assertTrue(graph.isLeaf(new2.getName()));
+
+    Set<LogicalPlan.QueryBlock> result = new HashSet<LogicalPlan.QueryBlock>();
+    result.add(new1);
+    result.add(new2);
+
+    Set<LogicalPlan.QueryBlock> childs = new HashSet<LogicalPlan.QueryBlock>(plan.getChildBlocks(root));
+    assertEquals(result, childs);
+
+    assertEquals(root, plan.getParentBlock(new1));
+    assertEquals(root, plan.getParentBlock(new2));
+  }
+}


[06/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash.plan
new file mode 100644
index 0000000..faa5926
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..b468147
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+  => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort.plan
new file mode 100644
index 0000000..faa5926
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..b468147
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.nation.n_nationkey (INT4) + 1 as p1
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4), default.region.r_regionkey (INT4) + 1 as p2
+  => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(6) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4), p1 (INT4), p2 (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+        => in schema: {(3) default.region.r_name (TEXT), default.region.r_regionkey (INT4), p2 (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+        => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), p1 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.region.r_name (TEXT), p1 (INT4), p2 (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.result
new file mode 100644
index 0000000..e8312eb
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin3.result
@@ -0,0 +1,27 @@
+n_name,r_name,p1,p2
+-------------------------------
+ALGERIA,AFRICA,1,1
+ARGENTINA,AMERICA,2,2
+BRAZIL,AMERICA,3,2
+CANADA,AMERICA,4,2
+CHINA,ASIA,19,3
+EGYPT,MIDDLE EAST,5,5
+ETHIOPIA,AFRICA,6,1
+FRANCE,EUROPE,7,4
+GERMANY,EUROPE,8,4
+INDIA,ASIA,9,3
+INDONESIA,ASIA,10,3
+IRAN,MIDDLE EAST,11,5
+IRAQ,MIDDLE EAST,12,5
+JAPAN,ASIA,13,3
+JORDAN,MIDDLE EAST,14,5
+KENYA,AFRICA,15,1
+MOROCCO,AFRICA,16,1
+MOZAMBIQUE,AFRICA,17,1
+PERU,AMERICA,18,2
+ROMANIA,EUROPE,20,4
+RUSSIA,EUROPE,23,4
+SAUDI ARABIA,MIDDLE EAST,21,5
+UNITED KINGDOM,EUROPE,24,4
+UNITED STATES,AMERICA,25,2
+VIETNAM,ASIA,22,3

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash.plan
new file mode 100644
index 0000000..9ca4d41
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..a93456c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort.plan
new file mode 100644
index 0000000..9ca4d41
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..a93456c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT), default.nation.n_nationkey (INT4) + default.region.r_regionkey (INT4) as ?plus
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(5) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+        => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(3) ?plus (INT4), default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.result
new file mode 100644
index 0000000..ed21017
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin4.result
@@ -0,0 +1,27 @@
+n_name,r_name,?plus
+-------------------------------
+ALGERIA,AFRICA,0
+ARGENTINA,AMERICA,2
+BRAZIL,AMERICA,3
+CANADA,AMERICA,4
+CHINA,ASIA,20
+EGYPT,MIDDLE EAST,8
+ETHIOPIA,AFRICA,5
+FRANCE,EUROPE,9
+GERMANY,EUROPE,10
+INDIA,ASIA,10
+INDONESIA,ASIA,11
+IRAN,MIDDLE EAST,14
+IRAQ,MIDDLE EAST,15
+JAPAN,ASIA,14
+JORDAN,MIDDLE EAST,17
+KENYA,AFRICA,14
+MOROCCO,AFRICA,15
+MOZAMBIQUE,AFRICA,16
+PERU,AMERICA,18
+ROMANIA,EUROPE,22
+RUSSIA,EUROPE,25
+SAUDI ARABIA,MIDDLE EAST,24
+UNITED KINGDOM,EUROPE,26
+UNITED STATES,AMERICA,25
+VIETNAM,ASIA,23

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash.plan
new file mode 100644
index 0000000..cfde80a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash.plan
@@ -0,0 +1,97 @@
+explain
+-------------------------------
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(0) on default.part
+        => target list: default.part.p_partkey (INT4)
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+      JOIN(9)(INNER)
+        => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+        => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(1) on default.supplier
+           => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+           => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+           => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(2) on default.partsupp
+           => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+           => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+           => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000005
+2: eb_0000000000000_0000_000006
+3: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.supplier
+ 1: type=Broadcast, tables=default.partsupp
+
+SORT(16)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(0) on default.part
+        => target list: default.part.p_partkey (INT4)
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+      JOIN(9)(INNER)
+        => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+        => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(1) on default.supplier
+           => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+           => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+           => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(2) on default.partsupp
+           => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+           => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+           => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(17) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..d4b5001
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Hash_NoBroadcast.plan
@@ -0,0 +1,153 @@
+explain
+-------------------------------
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(0) on default.part
+        => target list: default.part.p_partkey (INT4)
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+      JOIN(9)(INNER)
+        => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+        => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(1) on default.supplier
+           => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+           => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+           => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(2) on default.partsupp
+           => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+           => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+           => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+            |-eb_0000000000000_0000_000002
+            |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+SCAN(1) on default.supplier
+  => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+  => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+  => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(9)(INNER)
+  => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+  => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+  => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(13) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+     => in schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(12) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(0) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+SORT(16)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(15) on eb_0000000000000_0000_000004
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(1) default.part.p_partkey (INT4)}
+      SCAN(14) on eb_0000000000000_0000_000003
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(17) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort.plan
new file mode 100644
index 0000000..cfde80a
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort.plan
@@ -0,0 +1,97 @@
+explain
+-------------------------------
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(0) on default.part
+        => target list: default.part.p_partkey (INT4)
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+      JOIN(9)(INNER)
+        => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+        => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(1) on default.supplier
+           => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+           => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+           => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(2) on default.partsupp
+           => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+           => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+           => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000005
+2: eb_0000000000000_0000_000006
+3: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.supplier
+ 1: type=Broadcast, tables=default.partsupp
+
+SORT(16)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(0) on default.part
+        => target list: default.part.p_partkey (INT4)
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+      JOIN(9)(INNER)
+        => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+        => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(1) on default.supplier
+           => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+           => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+           => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(2) on default.partsupp
+           => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+           => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+           => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(17) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..d4b5001
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.Sort_NoBroadcast.plan
@@ -0,0 +1,153 @@
+explain
+-------------------------------
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(0) on default.part
+        => target list: default.part.p_partkey (INT4)
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+      JOIN(9)(INNER)
+        => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+        => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(1) on default.supplier
+           => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+           => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+           => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+         SCAN(2) on default.partsupp
+           => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+           => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+           => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000007)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000007
+   |-eb_0000000000000_0000_000006
+      |-eb_0000000000000_0000_000005
+         |-eb_0000000000000_0000_000004
+         |-eb_0000000000000_0000_000003
+            |-eb_0000000000000_0000_000002
+            |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+6: eb_0000000000000_0000_000006
+7: eb_0000000000000_0000_000007
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+SCAN(1) on default.supplier
+  => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)
+  => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+  => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(9)(INNER)
+  => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+  => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+  => in schema: {(5) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(13) on eb_0000000000000_0000_000002
+     => out schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+     => in schema: {(3) default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(12) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(0) on default.part
+  => target list: default.part.p_partkey (INT4)
+  => out schema: {(1) default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+SORT(16)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(10)(INNER)
+     => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+     => target list: default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(4) default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+      SCAN(15) on eb_0000000000000_0000_000004
+        => out schema: {(1) default.part.p_partkey (INT4)}
+        => in schema: {(1) default.part.p_partkey (INT4)}
+      SCAN(14) on eb_0000000000000_0000_000003
+        => out schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+        => in schema: {(3) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 6 (type=RANGE_SHUFFLE, key=default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000005
+
+SORT(4)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(17) on eb_0000000000000_0000_000005
+     => out schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+     => in schema: {(3) default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.result
new file mode 100644
index 0000000..b4aea02
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin5.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,p_partkey
+-------------------------------
+4032.68,Supplier#000000002,1
+4192.4,Supplier#000000003,2
+4641.08,Supplier#000000004,3


[33/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java
new file mode 100644
index 0000000..0b42a6d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinQuery.java
@@ -0,0 +1,457 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.SQLException;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+public class TestOuterJoinQuery extends TestJoinQuery {
+
+  public TestOuterJoinQuery(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithThetaJoinConditionInWhere() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testRightOuterJoinWithThetaJoinConditionInWhere() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoin1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithConstantExpr1() throws Exception {
+    // outer join with constant projections
+    //
+    // select c_custkey, orders.o_orderkey, 'val' as val from customer
+    // left outer join orders on c_custkey = o_orderkey;
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithConstantExpr4() throws Exception {
+    // outer join with constant projections
+    //
+    // select
+    //   c_custkey,
+    //   orders.o_orderkey,
+    //   1 as key1
+    // from customer left outer join orders on c_custkey = o_orderkey and key1 = 1;
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithConstantExpr5() throws Exception {
+    // outer join with constant projections
+    //
+    // select
+    //   c_custkey,
+    //   orders.o_orderkey,
+    //   1 as key1
+    // from customer left outer join orders on c_custkey = o_orderkey and key1 = 1;
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testRightOuterJoin1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testFullOuterJoin1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public void testOuterJoinAndCaseWhen1() throws Exception {
+    executeDDL("oj_table1_ddl.sql", "table1", "testOuterJoinAndCaseWhen1");
+    executeDDL("oj_table2_ddl.sql", "table2", "testOuterJoinAndCaseWhen2");
+    try {
+      runSimpleTests();
+    } finally {
+      executeString("DROP TABLE testOuterJoinAndCaseWhen1");
+      executeString("DROP TABLE testOuterJoinAndCaseWhen2");
+    }
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithEmptyTable1() throws Exception {
+    /*
+    select
+      c_custkey,
+      empty_orders.o_orderkey,
+      empty_orders.o_orderstatus,
+      empty_orders.o_orderdate
+    from
+      customer left outer join empty_orders on c_custkey = o_orderkey
+    order by
+      c_custkey, o_orderkey;
+     */
+
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithEmptyTable2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithEmptyTable3() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithEmptyTable4() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithEmptyTable5() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testRightOuterJoinWithEmptyTable1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testFullOuterJoinWithEmptyTable1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithNull1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithNull2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithNull3() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable12 t2\n" +
+          "on t1.id = t2.id\n" +
+          "left outer join jointable13 t3\n" +
+          "on t1.id = t3.id and t2.id = t3.id")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id, t4.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable12 t2\n" +
+          "on t1.id = t2.id\n" +
+          "left outer join jointable13 t3\n" +
+          "on t2.id = t3.id\n" +
+          "inner join jointable14 t4\n" +
+          "on t2.id = t4.id")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase2() throws Exception {
+    // outer -> outer -> inner
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id, t4.id\n" +
+          "from jointable11 t1\n" +
+          "inner join jointable14 t4\n" +
+          "on t1.id = t4.id and t4.id > 1\n" +
+          "left outer join jointable13 t3\n" +
+          "on t4.id = t3.id and t3.id = 2\n" +
+          "left outer join jointable12 t2\n" +
+          "on t1.id = t2.id \n" +
+          "where t1.id > 1")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase2_1() throws Exception {
+    // inner(on predication) -> outer(on predication) -> outer -> where
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable12 t2 \n" +
+          "on t1.id = t2.id and (concat(t1.name, cast(t2.id as TEXT)) = 'table11-11' or concat(t1.name, cast(t2.id as TEXT)) = 'table11-33')\n" +
+          "left outer join jointable13 t3\n" +
+          "on t1.id = t3.id ")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase3() throws Exception {
+    // https://cwiki.apache.org/confluence/display/Hive/OuterJoinBehavior
+    // Case J1: Join Predicate on Preserved Row Table
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable12 t2\n" +
+          "on t1.id = t2.id and t2.id > 1 \n" +
+          "left outer join jointable13 t3\n" +
+          "on t1.id = t3.id")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase4() throws Exception {
+    // https://cwiki.apache.org/confluence/display/Hive/OuterJoinBehavior
+    // Case J2: Join Predicate on Null Supplying Table
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable12 t2\n" +
+          "on t1.id = t2.id\n" +
+          "left outer join jointable13 t3\n" +
+          "on t1.id = t3.id\n" +
+          "where t1.name > 'table11-1'")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase5() throws Exception {
+    // https://cwiki.apache.org/confluence/display/Hive/OuterJoinBehavior
+    // Case W1: Where Predicate on Preserved Row Table
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable12 t2\n" +
+          "on t1.id = t2.id\n" +
+          "left outer join jointable13 t3\n" +
+          "on t1.id = t3.id\n" +
+          "where t3.id > 2")
+  })
+  public final void testLeftOuterJoinPredicationCaseByCase6() throws Exception {
+    // https://cwiki.apache.org/confluence/display/Hive/OuterJoinBehavior
+    // Case W2: Where Predicate on Null Supplying Table
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id\n" +
+          "from jointable11 t1\n" +
+          "left outer join jointable15 t2\n" +
+          "on t1.id = t2.id")
+  })
+  public final void testLeftOuterWithEmptyTable() throws Exception {
+    // https://cwiki.apache.org/confluence/display/Hive/OuterJoinBehavior
+    // Case W2: Where Predicate on Null Supplying Table
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "right outer join jointable12 t2\n" +
+          "on t1.id = t2.id\n" +
+          "right outer join jointable13 t3\n" +
+          "on t1.id = t3.id and t2.id = t3.id")
+  })
+  public final void testRightOuterJoinPredicationCaseByCase1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t3.id, t4.id\n" +
+          "from jointable11 t1\n" +
+          "inner join jointable14 t4\n" +
+          "on t1.id = t4.id and t4.id > 1\n" +
+          "right outer join jointable13 t3\n" +
+          "on t4.id = t3.id and t3.id = 2\n" +
+          "where t3.id > 1")
+  })
+  public final void testRightOuterJoinPredicationCaseByCase2() throws Exception {
+    // inner -> right
+    // Notice: Join order should be preserved with origin order.
+    // JoinEdge: t1 -> t4, t3 -> t1,t4
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t2.id, t3.id\n" +
+          "from jointable11 t1\n" +
+          "right outer join jointable12 t2 \n" +
+          "on t1.id = t2.id and (concat(t1.name, cast(t2.id as TEXT)) = 'table11-11' or concat(t1.name, cast(t2.id as TEXT)) = 'table11-33')\n" +
+          "right outer join jointable13 t3\n" +
+          "on t1.id = t3.id ")
+  })
+  public final void testRightOuterJoinPredicationCaseByCase3() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select t1.id, t1.name, t3.id, t4.id\n" +
+          "from jointable11 t1\n" +
+          "full outer join jointable13 t3\n" +
+          "on t1.id = t3.id\n" +
+          "full outer join jointable14 t4\n" +
+          "on t3.id = t4.id \n" +
+          "order by t4.id")
+  })
+  public final void testFullOuterJoinPredicationCaseByCase1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testJoinFilterOfRowPreservedTable1() throws Exception {
+    // this test is for join filter of a row preserved table.
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoin2() throws Exception {
+    // large, large, small, small
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoin3() throws Exception {
+    // large, large, small, large, small, small
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select a.id, b.name from jointable1 a left outer join jointable_large b on a.id = b.id order by a.id")
+  })
+  public final void testLeftOuterJoinLeftSideSmallTable() throws Exception {
+   runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest
+  public void testMultipleBroadcastDataFileWithZeroLength() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true, sort = true)
+  @SimpleTest
+  public void testMultipleBroadcastDataFileWithZeroLength2() throws Exception {
+    runSimpleTests();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java
new file mode 100644
index 0000000..00ce150
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestOuterJoinWithSubQuery.java
@@ -0,0 +1,143 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.NamedTest;
+import org.apache.tajo.conf.TajoConf;
+import org.junit.*;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.assertEquals;
+
+@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
+@NamedTest("TestJoinQuery")
+public class TestOuterJoinWithSubQuery extends TestJoinQuery {
+
+  public TestOuterJoinWithSubQuery(String joinOption) throws Exception {
+    super(joinOption);
+  }
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    TestJoinQuery.setup();
+  }
+
+  @AfterClass
+  public static void classTearDown() throws SQLException {
+    TestJoinQuery.classTearDown();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithConstantExpr2() throws Exception {
+    // outer join with constant projections
+    //
+    // select c_custkey, o.o_orderkey, 'val' as val from customer left outer join
+    // (select * from orders) o on c_custkey = o.o_orderkey
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest()
+  public final void testLeftOuterJoinWithConstantExpr3() throws Exception {
+    // outer join with constant projections
+    //
+    // select a.c_custkey, 123::INT8 as const_val, b.min_name from customer a
+    // left outer join ( select c_custkey, min(c_name) as min_name from customer group by c_custkey) b
+    // on a.c_custkey = b.c_custkey;
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select a.id, b.id from jointable11 a " +
+          "left outer join (" +
+          "select jointable12.id from jointable12 inner join lineitem " +
+          "on jointable12.id = lineitem.l_orderkey and jointable12.id > 10) b " +
+          "on a.id = b.id order by a.id")
+  })
+  public final void testLeftOuterJoinWithEmptySubquery1() throws Exception {
+    try {
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+      runSimpleTests();
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$TEST_MIN_TASK_NUM.varname,
+          TajoConf.ConfVars.$TEST_MIN_TASK_NUM.defaultVal);
+    }
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select a.id, b.id from " +
+          "(select jointable12.id, jointable12.name, lineitem.l_shipdate " +
+          "from jointable12 inner join lineitem on jointable12.id = lineitem.l_orderkey and jointable12.id > 10) a " +
+          "left outer join jointable11 b on a.id = b.id")
+  })
+  public final void testLeftOuterJoinWithEmptySubquery2() throws Exception {
+    //Empty Preserved Row table
+    try {
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+      runSimpleTests();
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$TEST_MIN_TASK_NUM.varname,
+          TajoConf.ConfVars.$TEST_MIN_TASK_NUM.defaultVal);
+    }
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select a.l_orderkey \n" +
+          "from (select * from lineitem where l_orderkey < 0) a\n" +
+          "full outer join (select * from lineitem where l_orderkey < 0) b\n" +
+          "on a.l_orderkey = b.l_orderkey")
+  })
+  public void testFullOuterJoinWithEmptyIntermediateData() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true, parameterized = true)
+  @SimpleTest(queries = {
+      @QuerySpec("select count(b.id) " +
+          "from (select id, count(*) as cnt from jointable_large group by id) a " +
+          "left outer join (select id, count(*) as cnt from jointable_large where id < 200 group by id) b " +
+          "on a.id = b.id")
+  })
+  public void testJoinWithDifferentShuffleKey() throws Exception {
+    int originConfValue = conf.getIntVar(TajoConf.ConfVars.$DIST_QUERY_JOIN_PARTITION_VOLUME);
+    testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$DIST_QUERY_JOIN_PARTITION_VOLUME.varname, "1");
+    try {
+      runSimpleTests();
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.$DIST_QUERY_JOIN_PARTITION_VOLUME.varname,
+          "" + originConfValue);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectNestedRecord.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectNestedRecord.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectNestedRecord.java
new file mode 100644
index 0000000..41df0fa
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectNestedRecord.java
@@ -0,0 +1,119 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.util.TUtil;
+import org.junit.Test;
+
+import java.sql.ResultSet;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestSelectNestedRecord extends QueryTestCaseBase {
+
+  @Test
+  public final void testSelect0() throws Exception {
+    List<String> tables = executeDDL("sample1_ddl.sql", "sample1", "sample1");
+    assertEquals(TUtil.newList("sample1"), tables);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelect1() throws Exception {
+    List<String> tables = executeDDL("sample1_ddl.sql", "sample1", "sample2");
+    assertEquals(TUtil.newList("sample2"), tables);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelect2() throws Exception {
+    List<String> tables = executeDDL("tweets_ddl.sql", "tweets", "tweets");
+    assertEquals(TUtil.newList("tweets"), tables);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelect3() throws Exception {
+    List<String> tables = executeDDL("sample2_ddl.sql", "sample2", "sample5");
+    assertEquals(TUtil.newList("sample5"), tables);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNestedFieldAsGroupbyKey1() throws Exception {
+    List<String> tables = executeDDL("tweets_ddl.sql", "tweets", "tweets");
+    assertEquals(TUtil.newList("tweets"), tables);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNestedFieldAsJoinKey1() throws Exception {
+    List<String> tables = executeDDL("tweets_ddl.sql", "tweets", "tweets");
+    assertEquals(TUtil.newList("tweets"), tables);
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testInsertType1() throws Exception {
+    // all columns
+    List<String> tables = executeDDL("sample1_ddl.sql", "sample1", "sample3");
+    assertEquals(TUtil.newList("sample3"), tables);
+
+    executeString("CREATE TABLE clone (title TEXT, name RECORD (first_name TEXT, last_name TEXT)) USING JSON;").close();
+
+    executeString("INSERT INTO clone (title, name.first_name, name.last_name) SELECT title, name.first_name, name.last_name from sample3").close();
+    ResultSet res = executeString("select title, name.first_name, name.last_name from clone");
+    assertResultSet(res);
+    res.close();
+  }
+
+  @Test
+  public final void testInsertType2() throws Exception {
+    // some columns
+    List<String> tables = executeDDL("sample1_ddl.sql", "sample1", "sample4");
+    assertEquals(TUtil.newList("sample4"), tables);
+
+    executeString("CREATE TABLE clone2 (title TEXT, name RECORD (first_name TEXT, last_name TEXT)) USING JSON;").close();
+
+    executeString("INSERT INTO clone2 (title, name.last_name) SELECT title, name.last_name from sample4").close();
+    ResultSet res = executeString("select title, name.first_name, name.last_name from clone2");
+    assertResultSet(res);
+    res.close();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
new file mode 100644
index 0000000..27c2fcd
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
@@ -0,0 +1,778 @@
+/**
+ * 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.query;
+
+import com.google.common.collect.Lists;
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ipc.ClientProtos;
+import org.apache.tajo.plan.rewrite.BaseLogicalPlanRewriteRuleProvider;
+import org.apache.tajo.plan.rewrite.LogicalPlanRewriteRule;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+import java.util.*;
+
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+public class TestSelectQuery extends QueryTestCaseBase {
+
+  public TestSelectQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testNonQualifiedNames() throws Exception {
+    // select l_orderkey, l_partkey from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNonFromSelect1() throws Exception {
+    // select upper('abc');
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSimpleQuery() throws Exception {
+    // select * from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSimpleQueryWithLimit() throws Exception {
+    // select * from lineitem limit 3;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSimpleQueryWithLimitPartitionedTable() throws Exception {
+    // select * from customer_parts limit 10;
+    executeDDL("customer_ddl.sql", null);
+    for (int i = 0; i < 5; i++) {
+      executeFile("insert_into_customer.sql").close();
+    }
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+
+    executeString("DROP TABLE customer_parts PURGE").close();
+  }
+
+  @Test
+  public final void testExplainSelect() throws Exception {
+    // explain select l_orderkey, l_partkey from lineitem;
+    testingCluster.getConfiguration().set(ConfVars.$TEST_PLAN_SHAPE_FIX_ENABLED.varname, "true");
+    try {
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      testingCluster.getConfiguration().set(ConfVars.$TEST_PLAN_SHAPE_FIX_ENABLED.varname, "false");
+    }
+  }
+
+  @Test
+  @SimpleTest(queries = {
+      @QuerySpec("explain global select l_orderkey, l_partkey from lineitem"),
+      @QuerySpec("explain global select n1.n_nationkey, n1.n_name, n2.n_name from nation n1 join nation n2 " +
+          "on n1.n_name = upper(n2.n_name) order by n1.n_nationkey"),
+      @QuerySpec("explain global select l_linenumber, count(*), count(distinct l_orderkey), sum(distinct l_orderkey) from lineitem " +
+          "group by l_linenumber having sum(distinct l_orderkey) = 6")})
+  public final void testExplainSelectPhysical() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  public final void testSelect() throws Exception {
+    // select l_orderkey, l_partkey from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelect2() throws Exception {
+    // select l_orderkey, l_partkey, l_orderkey + l_partkey as plus from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelect3() throws Exception {
+    // select l_orderkey + l_partkey as plus from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectColumnAlias1() throws Exception {
+    // select l_orderkey as col1, l_orderkey + 1 as col2 from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectColumnAliasExistingInRelation1() throws Exception {
+    // We intend that 'l_orderkey' in where clause points to "default.lineitem.l_orderkey"
+    // select (l_orderkey + l_orderkey) l_orderkey from lineitem where l_orderkey > 2;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectColumnAliasExistingInRelation2() throws Exception {
+    // We intend that 'l_orderkey' in orderby clause points to (-l_orderkey).
+    // select (-l_orderkey) as l_orderkey from lineitem order by l_orderkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectColumnAliasExistingInRelation3() throws Exception {
+    // This is a reproduction code and validator of TAJO-975 Bug
+    // Please see TAJO-975 in order to know this test in detail.
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+
+  @Test
+  public final void testSelectSameConstantsWithDifferentAliases() throws Exception {
+    // select l_orderkey, '20130819' as date1, '20130819' as date2 from lineitem where l_orderkey > -1;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectSameConstantsWithDifferentAliases2() throws Exception {
+    // select l_orderkey, '20130819' as date1, '20130819' as date2, '20130819' as date3, '20130819' as date4
+    // from lineitem where l_orderkey > -1;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectSameConstantsWithDifferentAliases3() throws Exception {
+    // select l_orderkey, '20130819' as date1, '20130819', '20130819', '20130819'
+    // from lineitem where l_orderkey > -1;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectSameExprsWithDifferentAliases() throws Exception {
+    // select l_orderkey, l_partkey + 1 as plus1, l_partkey + 1 as plus2 from lineitem where l_orderkey > -1;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWhereCond1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWhereCond2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWhereCondWithAlias1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testWhereCondWithAlias2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectAsterisk1() throws Exception {
+    // select * from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectAsterisk2() throws Exception {
+    // select * from lineitem where l_orderkey = 2;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectAsterisk3() throws Exception {
+    // select * from lineitem where l_orderkey % 2 = 0;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectAsterisk4() throws Exception {
+    // select length(l_comment), l_extendedprice * l_discount, *, l_tax * 10 from lineitem;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectAsterisk5() throws Exception {
+    // select * from (select l_orderkey, 1 from lineitem where l_orderkey % 2 = 0) t1;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectDistinct() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testLikeClause() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testStringCompare() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testRealValueCompare() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testCaseWhen() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testCaseWhenWithoutElse() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNotEqual() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testInClause() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testInStrClause() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNotInStrClause() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testNotInClause() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testCreateAfterSelect() throws Exception {
+    ResultSet res = testBase.execute(
+        "create table orderkeys as select l_orderkey from lineitem");
+    res.close();
+    TajoTestingCluster cluster = testBase.getTestingCluster();
+    CatalogService catalog = cluster.getMaster().getCatalog();
+    assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, "orderkeys"));
+    TableDesc orderKeys = catalog.getTableDesc(DEFAULT_DATABASE_NAME, "orderkeys");
+    if (!cluster.isHiveCatalogStoreRunning()) {
+      assertEquals(5, orderKeys.getStats().getNumRows().intValue());
+    }
+  }
+
+  @Test
+  public final void testLimit() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSelectWithJson() throws Exception {
+    // select l_orderkey, l_partkey + 1 as plus1, l_partkey + 1 as plus2 from lineitem where l_orderkey > -1;
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testDatabaseRef() throws Exception {
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      executeString("CREATE DATABASE \"TestSelectQuery\"").close();
+      executeString("CREATE TABLE \"TestSelectQuery\".\"LineItem\" AS SELECT * FROM default.lineitem" ).close();
+
+      ResultSet res = executeFile("testDatabaseRef1.sql");
+      assertResultSet(res, "testDatabaseRef.result");
+      cleanupQuery(res);
+
+      res = executeFile("testDatabaseRef2.sql");
+      assertResultSet(res, "testDatabaseRef.result");
+      cleanupQuery(res);
+
+      res = executeFile("testDatabaseRef3.sql");
+      assertResultSet(res, "testDatabaseRef.result");
+      cleanupQuery(res);
+
+      executeString("DROP DATABASE \"TestSelectQuery\"").close();
+    }
+  }
+
+  @Test
+  public final void testSumIntOverflow() throws Exception {
+    // Test data's min value is 17 and number of rows is 5.
+    // 25264513 = 2147483647/17/5
+    // result is 116,848,374,845 ==> int overflow
+    // select sum(cast(l_quantity * 25264513 as INT4)) from lineitem where l_quantity > 0;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSumFloatOverflow() throws Exception {
+    // Test data's min value is 21168.23 and number of rows is 5.
+    // 3.21506374375027E33 = 3.40282346638529E38/21168/ 5
+    // result is 6.838452478692677E38 ==> float4 overflow
+    // select sum(cast(L_EXTENDEDPRICE * 3.21506374375027E33 as FLOAT4)) from lineitem where l_quantity > 0;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  public static class RulesForErrorInjection extends BaseLogicalPlanRewriteRuleProvider {
+    public RulesForErrorInjection(TajoConf conf) {
+      super(conf);
+    }
+
+    @Override
+    public Collection<Class<? extends LogicalPlanRewriteRule>> getPostRules() {
+      List<Class<? extends LogicalPlanRewriteRule>> addedRules = Lists.newArrayList(super.getPostRules());
+      return addedRules;
+    }
+  }
+
+  @Test
+  public final void testQueryMasterTaskInitError() throws Exception {
+    // In this testcase we can check that a TajoClient receives QueryMasterTask's init error message.
+    testingCluster.setAllWorkersConfValue(ConfVars.LOGICAL_PLAN_REWRITE_RULE_PROVIDER_CLASS.name(),
+        RulesForErrorInjection.class.getCanonicalName());
+
+    try {
+      // If client can't receive error status, thread runs forever.
+      Thread t = new Thread() {
+        public void run() {
+          try {
+            ClientProtos.SubmitQueryResponse response = client.executeQuery("select l_orderkey from lineitem");
+            QueryStatus status = client.getQueryStatus(new QueryId(response.getQueryId()));
+            assertEquals(QueryState.QUERY_ERROR, status.getState());
+            assertEquals(NullPointerException.class.getName(), status.getErrorMessage());
+          } catch (Exception e) {
+            fail(e.getMessage());
+          }
+        }
+      };
+
+      t.start();
+
+      for (int i = 0; i < 10; i++) {
+        Thread.sleep(1 * 1000);
+        if (!t.isAlive()) {
+          break;
+        }
+      }
+
+      // If query runs more than 10 secs, test is fail.
+      assertFalse(t.isAlive());
+    } finally {
+      // recover the rewrite rule provider to default
+      testingCluster.setAllWorkersConfValue(ConfVars.LOGICAL_PLAN_REWRITE_RULE_PROVIDER_CLASS.name(), "");
+    }
+  }
+
+  @Test
+  public final void testNowInMultipleTasks() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4);
+    schema.addColumn("name", Type.TEXT);
+    String[] data = new String[]{ "1|table11-1", "2|table11-2", "3|table11-3", "4|table11-4", "5|table11-5" };
+    TajoTestingCluster.createTable("testNowInMultipleTasks".toLowerCase(), schema, tableOptions, data, 2);
+
+    try {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+
+      ResultSet res = executeString("select concat(substr(to_char(now(),'yyyymmddhh24miss'), 1, 14), 'aaa'), sleep(1) " +
+          "from testNowInMultipleTasks");
+
+      String nowValue = null;
+      int numRecords = 0;
+      while (res.next()) {
+        String currentNowValue = res.getString(1);
+        if (nowValue != null) {
+          assertTrue(nowValue + " is different to " + currentNowValue, nowValue.equals(currentNowValue));
+        }
+        nowValue = currentNowValue;
+        numRecords++;
+      }
+      assertEquals(5, numRecords);
+
+      res.close();
+
+      res = executeString("select concat(substr(to_char(current_timestamp,'yyyymmddhh24miss'), 1, 14), 'aaa'), sleep(1) " +
+          "from testNowInMultipleTasks");
+
+      nowValue = null;
+      numRecords = 0;
+      while (res.next()) {
+        String currentNowValue = res.getString(1);
+        if (nowValue != null) {
+          assertTrue(nowValue.equals(currentNowValue));
+        }
+        nowValue = currentNowValue;
+        numRecords++;
+      }
+      assertEquals(5, numRecords);
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname,
+          ConfVars.$TEST_MIN_TASK_NUM.defaultVal);
+      executeString("DROP TABLE testNowInMultipleTasks PURGE");
+    }
+  }
+
+  @Test
+  public void testCaseWhenRound() throws Exception {
+    /*
+    select *
+        from (select n_nationkey as key,
+    case
+      when n_nationkey > 6 then round((n_nationkey * 100 / 2.123) / (n_regionkey * 50 / 2.123), 2) else 100.0 end as val
+    from
+      nation
+    where
+      n_regionkey > 0 and n_nationkey > 0
+    ) a
+    order by
+      a.key
+    */
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testColumnEqualityButNotJoinCondition1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testColumnEqualityButNotJoinCondition2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testTimezonedTable1() throws Exception {
+    // Table - GMT (No table property or no system timezone)
+    // Client - GMT (default client time zone is used if no TIME ZONE session variable is given.)
+    try {
+      executeDDL("datetime_table_ddl.sql", "timezoned", new String[]{"timezoned1"});
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE IF EXISTS timezoned1");
+    }
+  }
+
+  @Test
+  public void testTimezonedTable2() throws Exception {
+    // Table - timezone = GMT+9
+    // Client - GMT (SET TIME ZONE 'GMT';)
+    try {
+      executeDDL("datetime_table_timezoned_ddl.sql", "timezoned", new String[]{"timezoned2"});
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE IF EXISTS timezoned2");
+    }
+  }
+
+  @Test
+  public void testTimezonedTable3() throws Exception {
+    // Table - timezone = GMT+9
+    // Client - GMT+9 through TajoClient API
+
+    Map<String,String> sessionVars = new HashMap<String, String>();
+    sessionVars.put(SessionVars.TIMEZONE.name(), "GMT+9");
+    getClient().updateSessionVariables(sessionVars);
+
+    try {
+      executeDDL("datetime_table_timezoned_ddl.sql", "timezoned", new String[]{"timezoned3"});
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE IF EXISTS timezoned3");
+    }
+
+    getClient().unsetSessionVariables(Lists.newArrayList("TIMEZONE"));
+  }
+
+  @Test
+  public void testTimezonedTable4() throws Exception {
+    // Table - timezone = GMT+9
+    // Client - GMT+9 (SET TIME ZONE 'GMT+9';)
+
+    try {
+      executeDDL("datetime_table_timezoned_ddl.sql", "timezoned", new String[]{"timezoned4"});
+      ResultSet res = executeQuery();
+      assertResultSet(res, "testTimezonedTable3.result");
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE IF EXISTS timezoned4");
+    }
+  }
+
+  @Test
+  public void testTimezonedTable5() throws Exception {
+    // Table - timezone = GMT+9 (by a specified system timezone)
+    // TajoClient uses JVM default timezone (GMT+9)
+
+    try {
+      testingCluster.getConfiguration().setSystemTimezone(TimeZone.getTimeZone("GMT+9"));
+
+      executeDDL("datetime_table_ddl.sql", "timezoned", new String[]{"timezoned5"});
+      ResultSet res = executeQuery();
+      assertResultSet(res, "testTimezonedTable3.result");
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE IF EXISTS timezoned5");
+
+      // restore the config
+      testingCluster.getConfiguration().setSystemTimezone(TimeZone.getTimeZone("GMT"));
+    }
+  }
+  
+  @Test
+  public void testMultiBytesDelimiter1() throws Exception {
+    executeDDL("multibytes_delimiter_table1_ddl.sql", "multibytes_delimiter1");
+    try {
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE table1");
+    }
+  }
+  
+  @Test
+  public void testMultiBytesDelimiter2() throws Exception {
+    executeDDL("multibytes_delimiter_table2_ddl.sql", "multibytes_delimiter2");
+    try {
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE table2");
+    }
+  }
+
+  @Test
+  public void testMultiBytesDelimiter3() throws Exception {
+    executeDDL("multibytes_delimiter_table3_ddl.sql", "multibytes_delimiter1");
+    try {
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE table1");
+    }
+  }
+
+  @Test
+  public void testMultiBytesDelimiter4() throws Exception {
+    executeDDL("multibytes_delimiter_table4_ddl.sql", "multibytes_delimiter2");
+    try {
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      executeString("DROP TABLE table2");
+    }
+  }
+
+  @Test
+  public void testSelectPythonFuncs() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testSelectWithPredicateOnPythonFunc() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testNestedPythonFunction() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testSelectWithParentheses1() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testSelectWithParentheses2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public void testSelectOnSessionTable() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  @Option(withExplain = true)
+  @SimpleTest (
+      queries = @QuerySpec("select * from nation where (n_regionkey = 1 or n_name is not null) and (n_regionkey = 1 or n_comment is not null)")
+  )
+  public void testSelectWithCommonQuals1() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true)
+  @SimpleTest(
+      queries = @QuerySpec("select * from nation where (n_regionkey = 1 or n_name is not null) and (n_regionkey = 1 or n_name is not null)")
+  )
+  public void testSelectWithCommonQuals2() throws Exception {
+    runSimpleTests();
+  }
+
+  @Test
+  @Option(withExplain = true)
+  @SimpleTest(
+      queries = @QuerySpec("select * from nation where (n_regionkey = 1 and n_name is not null) or (n_regionkey = 1 and n_comment is not null)")
+  )
+  public void testSelectWithCommonQuals3() throws Exception {
+    runSimpleTests();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java
new file mode 100644
index 0000000..358afbc
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.engine.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@Category(IntegrationTest.class)
+public class TestSetSessionQuery extends QueryTestCaseBase {
+
+  public TestSetSessionQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testSetCatalog1() throws Exception {
+    executeString("CREATE DATABASE testsetcatalog;").close();
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, getClient().getCurrentDatabase());
+    executeString("SET CATALOG testsetcatalog").close();
+    assertEquals("testsetcatalog", getClient().getCurrentDatabase());
+    executeString("SET CATALOG \"default\"").close();
+    executeString("DROP DATABASE testsetcatalog;").close();
+  }
+
+  @Test
+  public final void testSetCatalog2() throws Exception {
+    executeString("CREATE DATABASE \"testSetCatalog\";").close();
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, getClient().getCurrentDatabase());
+    executeString("SET CATALOG \"testSetCatalog\"").close();
+    assertEquals("testSetCatalog", getClient().getCurrentDatabase());
+    executeString("SET CATALOG \"default\"").close();
+    executeString("DROP DATABASE \"testSetCatalog\";").close();
+  }
+
+  @Test
+  public final void testSetTimezone() throws Exception {
+    assertFalse(getClient().existSessionVariable("TIMEZONE"));
+    executeString("SET TIME ZONE 'GMT+9'").close();
+    assertTrue(getClient().existSessionVariable("TIMEZONE"));
+    executeString("SET TIME ZONE to DEFAULT").close();
+  }
+
+  @Test
+  public final void testSetSession1() throws Exception {
+    assertFalse(getClient().existSessionVariable("key1"));
+    executeString("SET SESSION key1 to true").close();
+    assertTrue(getClient().existSessionVariable("key1"));
+
+    executeString("SET SESSION key1 to true").close();
+    executeString("SET SESSION key2 to 'val1'").close();
+    assertTrue(getClient().existSessionVariable("key1"));
+    assertTrue(getClient().existSessionVariable("key2"));
+    executeString("RESET key1").close();
+    executeString("SET SESSION key2 to DEFAULT").close();
+    assertFalse(getClient().existSessionVariable("key2"));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
new file mode 100644
index 0000000..9e632ab
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
@@ -0,0 +1,377 @@
+/**
+ * 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.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+
+import static org.junit.Assert.assertEquals;
+
+@Category(IntegrationTest.class)
+public class TestSortQuery extends QueryTestCaseBase {
+
+  public TestSortQuery() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Test
+  public final void testSort() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithAlias1() throws Exception {
+    // select l_linenumber, l_orderkey as sortkey from lineitem order by sortkey;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithAlias2() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithAlias3() throws Exception {
+    ResultSet res = executeQuery();
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithExpr1() throws Exception {
+    // select l_linenumber, l_orderkey as sortkey from lineitem order by l_orderkey + 1;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithExpr2() throws Exception {
+    // select l_linenumber, l_orderkey as sortkey from lineitem order by l_linenumber, l_orderkey, (l_orderkey is null);
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithAliasButOriginalName() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortDesc() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+
+  @Test
+  public final void testSortFirstDesc() throws Exception {
+    try {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+      tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+      Schema schema = new Schema();
+      schema.addColumn("col1", Type.INT4);
+      schema.addColumn("col2", Type.TEXT);
+      String[] data = new String[]{
+          "1|abc",
+          "3|dfa",
+          "3|das",
+          "1|abb",
+          "1|abc",
+          "3|dfb",
+          "3|dat",
+          "1|abe"
+      };
+      TajoTestingCluster.createTable("sortfirstdesc", schema, tableOptions, data, 2);
+
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "0");
+      executeString("DROP TABLE sortfirstdesc PURGE;").close();
+    }
+  }
+
+
+  @Test
+  public final void testTopK() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortAfterGroupby() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortAfterGroupbyWithAlias() throws Exception {
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithDate() throws Exception {
+    // skip this test if catalog uses HiveCatalogStore.
+    // It is because HiveCatalogStore does not support Time data type.
+
+    if (!testingCluster.isHiveCatalogStoreRunning()) {
+      // create external table table1 (col1 timestamp, col2 date, col3 time) ...
+      executeDDL("create_table_with_date_ddl.sql", "table1");
+
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    }
+  }
+
+  @Test
+  public final void testAsterisk() throws Exception {
+    //select *, length(l_comment) as len_comment from lineitem order by len_comment;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithAscDescKeys() throws Exception {
+    executeDDL("create_table_with_asc_desc_keys.sql", "table2");
+
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortWithJson() throws Exception {
+    // select max(l_quantity) as max_quantity, l_orderkey from lineitem group by l_orderkey order by max_quantity;
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testTopkWithJson() throws Exception {
+    // select l_orderkey, l_linenumber from lineitem order by l_orderkey desc limit 3;
+    ResultSet res = executeJsonQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  public final void testSortOnNullColumn() throws Exception {
+    try {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+      tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+      Schema schema = new Schema();
+      schema.addColumn("id", Type.INT4);
+      schema.addColumn("name", Type.TEXT);
+      String[] data = new String[]{
+          "1|BRAZIL",
+          "2|ALGERIA",
+          "3|ARGENTINA",
+          "4|CANADA"
+      };
+      TajoTestingCluster.createTable("nullsort", schema, tableOptions, data, 2);
+
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "0");
+      executeString("DROP TABLE nullsort PURGE;").close();
+    }
+  }
+
+  @Test
+  public final void testSortOnNullColumn2() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4);
+    schema.addColumn("name", Type.TEXT);
+    String[] data = new String[]{ "1|111", "2|\\N", "3|333" };
+    TajoTestingCluster.createTable("testSortOnNullColumn2".toLowerCase(), schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select * from testSortOnNullColumn2 order by name asc");
+      String ascExpected = "id,name\n" +
+          "-------------------------------\n" +
+          "1,111\n" +
+          "3,333\n" +
+          "2,null\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+
+      res = executeString("select * from testSortOnNullColumn2 order by name desc");
+      String descExpected = "id,name\n" +
+          "-------------------------------\n" +
+          "2,null\n" +
+          "3,333\n" +
+          "1,111\n";
+
+      assertEquals(descExpected, resultSetToString(res));
+      res.close();
+    } finally {
+      executeString("DROP TABLE testSortOnNullColumn2 PURGE");
+    }
+  }
+
+  @Test
+  public final void testSortOnNullColumn3() throws Exception {
+    KeyValueSet tableOptions = new KeyValueSet();
+    tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+    tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+    Schema schema = new Schema();
+    schema.addColumn("id", Type.INT4);
+    schema.addColumn("name", Type.TEXT);
+    String[] data = new String[]{ "1|111", "2|\\N", "3|333" };
+    TajoTestingCluster.createTable("testSortOnNullColumn3".toLowerCase(), schema, tableOptions, data, 1);
+
+    try {
+      ResultSet res = executeString("select * from testSortOnNullColumn3 order by name null first");
+      String ascExpected = "id,name\n" +
+          "-------------------------------\n" +
+          "2,null\n" +
+          "1,111\n" +
+          "3,333\n";
+
+      assertEquals(ascExpected, resultSetToString(res));
+      res.close();
+
+    } finally {
+      executeString("DROP TABLE testSortOnNullColumn3 PURGE");
+    }
+  }
+
+  @Test
+  public final void testSortOnUnicodeTextAsc() throws Exception {
+    try {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+      tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+      Schema schema = new Schema();
+      schema.addColumn("col1", Type.INT4);
+      schema.addColumn("col2", Type.TEXT);
+      String[] data = new String[]{
+          "1|하하하",
+          "2|캬캬캬",
+          "3|가가가",
+          "4|냐하하"
+      };
+      TajoTestingCluster.createTable("unicode_sort1", schema, tableOptions, data, 2);
+
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "0");
+      executeString("DROP TABLE unicode_sort1 PURGE;").close();
+    }
+  }
+
+  @Test
+  public final void testSortOnUnicodeTextDesc() throws Exception {
+    try {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "2");
+      KeyValueSet tableOptions = new KeyValueSet();
+      tableOptions.set(StorageConstants.TEXT_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER);
+      tableOptions.set(StorageConstants.TEXT_NULL, "\\\\N");
+
+      Schema schema = new Schema();
+      schema.addColumn("col1", Type.INT4);
+      schema.addColumn("col2", Type.TEXT);
+      String[] data = new String[]{
+          "1|하하하",
+          "2|캬캬캬",
+          "3|가가가",
+          "4|냐하하"
+      };
+      TajoTestingCluster.createTable("unicode_sort2", schema, tableOptions, data, 2);
+
+      ResultSet res = executeQuery();
+      assertResultSet(res);
+      cleanupQuery(res);
+    } finally {
+      testingCluster.setAllTajoDaemonConfValue(ConfVars.$TEST_MIN_TASK_NUM.varname, "0");
+      executeString("DROP TABLE unicode_sort2 PURGE;").close();
+    }
+  }
+
+  @Test
+  public final void testSortWithConstKeys() throws Exception {
+    // select
+    //   l_orderkey,
+    //   l_linenumber,
+    //   1 as key1,
+    //   2 as key2
+    // from
+    //   lineitem
+    // order by
+    //   key1,
+    //  key2;
+    ResultSet res = executeQuery();
+    assertResultSet(res);
+    cleanupQuery(res);
+  }
+
+  @Test
+  @Option(withExplain = true, withExplainGlobal = true)
+  @SimpleTest()
+  public final void testSubQuerySortAfterGroupMultiBlocks() throws Exception {
+    runSimpleTests();
+  }
+}


[07/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort.plan
new file mode 100644
index 0000000..baad6d4
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort.plan
@@ -0,0 +1,135 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+         SCAN(0) on default.part
+           => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+              => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000009
+2: eb_0000000000000_0000_000010
+3: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.part
+ 1: type=Broadcast, tables=default.supplier
+ 2: type=Broadcast, tables=default.partsupp
+ 3: type=Broadcast, tables=default.region
+
+SORT(26)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+         SCAN(0) on default.part
+           => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+              => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..35680f2
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.Sort_NoBroadcast.plan
@@ -0,0 +1,249 @@
+explain
+-------------------------------
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      JOIN(15)(INNER)
+        => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+        => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+         SCAN(4) on default.region
+           => target list: default.region.r_regionkey (INT4)
+           => out schema: {(1) default.region.r_regionkey (INT4)}
+           => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+         SCAN(3) on default.nation
+           => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+           => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+           => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+      JOIN(14)(INNER)
+        => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+        => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+         SCAN(0) on default.part
+           => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+           => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+           => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+         JOIN(13)(INNER)
+           => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+           => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+           => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+           => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(1) on default.supplier
+              => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+              => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+              => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+            SCAN(2) on default.partsupp
+              => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+              => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+              => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000011)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000011
+   |-eb_0000000000000_0000_000010
+      |-eb_0000000000000_0000_000009
+         |-eb_0000000000000_0000_000008
+            |-eb_0000000000000_0000_000007
+            |-eb_0000000000000_0000_000006
+         |-eb_0000000000000_0000_000005
+            |-eb_0000000000000_0000_000004
+            |-eb_0000000000000_0000_000003
+               |-eb_0000000000000_0000_000002
+               |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000006
+6: eb_0000000000000_0000_000007
+7: eb_0000000000000_0000_000005
+8: eb_0000000000000_0000_000008
+9: eb_0000000000000_0000_000009
+10: eb_0000000000000_0000_000010
+11: eb_0000000000000_0000_000011
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+
+SCAN(2) on default.partsupp
+  => target list: default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)
+  => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+  => in schema: {(5) default.partsupp.ps_availqty (INT4), default.partsupp.ps_comment (TEXT), default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.partsupp.ps_supplycost (FLOAT8)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+SCAN(1) on default.supplier
+  => target list: default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)
+  => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+  => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.partsupp.ps_suppkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.supplier.s_suppkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+
+JOIN(13)(INNER)
+  => Join Cond: default.supplier.s_suppkey (INT4) = default.partsupp.ps_suppkey (INT4)
+  => target list: default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+  => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+  => in schema: {(9) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(19) on eb_0000000000000_0000_000002
+     => out schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+     => in schema: {(7) default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT), default.supplier.s_suppkey (INT4)}
+   SCAN(18) on eb_0000000000000_0000_000001
+     => out schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+     => in schema: {(2) default.partsupp.ps_partkey (INT4), default.partsupp.ps_suppkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+SCAN(0) on default.part
+  => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)
+  => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+  => in schema: {(9) default.part.p_brand (TEXT), default.part.p_comment (TEXT), default.part.p_container (TEXT), default.part.p_mfgr (TEXT), default.part.p_name (TEXT), default.part.p_partkey (INT4), default.part.p_retailprice (FLOAT8), default.part.p_size (INT4), default.part.p_type (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000006 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(3) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)
+  => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000007 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(4) on default.region
+  => target list: default.region.r_regionkey (INT4)
+  => out schema: {(1) default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 5 (type=HASH_SHUFFLE, key=default.partsupp.ps_partkey (INT4), num=32)
+[q_0000000000000_0000] 4 => 5 (type=HASH_SHUFFLE, key=default.part.p_partkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+
+JOIN(14)(INNER)
+  => Join Cond: default.part.p_partkey (INT4) = default.partsupp.ps_partkey (INT4)
+  => target list: default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)
+  => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+  => in schema: {(9) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+   SCAN(21) on eb_0000000000000_0000_000004
+     => out schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+     => in schema: {(2) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4)}
+   SCAN(20) on eb_0000000000000_0000_000003
+     => out schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+     => in schema: {(7) default.partsupp.ps_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000008 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 6 => 8 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 7 => 8 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+JOIN(15)(INNER)
+  => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+  => target list: default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+  => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4), default.region.r_regionkey (INT4)}
+   SCAN(23) on eb_0000000000000_0000_000007
+     => out schema: {(1) default.region.r_regionkey (INT4)}
+     => in schema: {(1) default.region.r_regionkey (INT4)}
+   SCAN(22) on eb_0000000000000_0000_000006
+     => out schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+     => in schema: {(3) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000009 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 5 => 9 (type=HASH_SHUFFLE, key=default.supplier.s_nationkey (INT4), num=32)
+[q_0000000000000_0000] 8 => 9 (type=HASH_SHUFFLE, key=default.nation.n_nationkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+SORT(26)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   JOIN(16)(INNER)
+     => Join Cond: default.supplier.s_nationkey (INT4) = default.nation.n_nationkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(10) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+      SCAN(25) on eb_0000000000000_0000_000008
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_nationkey (INT4)}
+      SCAN(24) on eb_0000000000000_0000_000005
+        => out schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+        => in schema: {(8) default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_nationkey (INT4), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000010 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 9 => 10 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000009
+
+SORT(6)
+  => Sort Keys: default.supplier.s_acctbal (FLOAT8) (asc),default.supplier.s_name (TEXT) (asc),default.nation.n_name (TEXT) (asc),default.part.p_partkey (INT4) (asc)
+   SCAN(27) on eb_0000000000000_0000_000009
+     => out schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+     => in schema: {(8) default.nation.n_name (TEXT), default.part.p_mfgr (TEXT), default.part.p_partkey (INT4), default.supplier.s_acctbal (FLOAT8), default.supplier.s_address (TEXT), default.supplier.s_comment (TEXT), default.supplier.s_name (TEXT), default.supplier.s_phone (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000011 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.result
new file mode 100644
index 0000000..dc2831c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testTPCHQ2Join.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------
+4032.68,Supplier#000000002,ETHIOPIA,1,Manufacturer#1,89eJ5ksX3ImxJQBvxObC,,15-679-861-2259, slyly bold instructions. idle dependen
+4192.4,Supplier#000000003,ARGENTINA,2,Manufacturer#1,q1,G3Pj6OjIuUYfUoH18BFTKP5aU9bEV3,11-383-516-1199,blithely silent requests after the express dependencies are sl
+4641.08,Supplier#000000004,MOROCCO,3,Manufacturer#4,Bk7ah4CK8SYQTepEmvMkkgMwg,25-843-787-7479,riously even requests above the exp

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash.plan
new file mode 100644
index 0000000..fff6752
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..ce8b39b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort.plan
new file mode 100644
index 0000000..fff6752
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..ce8b39b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.result
new file mode 100644
index 0000000..bbc2186
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin1.result
@@ -0,0 +1,27 @@
+n_name,r_name,n_regionkey,r_regionkey
+-------------------------------
+ALGERIA,AFRICA,0,0
+ARGENTINA,AMERICA,1,1
+BRAZIL,AMERICA,1,1
+CANADA,AMERICA,1,1
+CHINA,ASIA,2,2
+EGYPT,MIDDLE EAST,4,4
+ETHIOPIA,AFRICA,0,0
+FRANCE,EUROPE,3,3
+GERMANY,EUROPE,3,3
+INDIA,ASIA,2,2
+INDONESIA,ASIA,2,2
+IRAN,MIDDLE EAST,4,4
+IRAQ,MIDDLE EAST,4,4
+JAPAN,ASIA,2,2
+JORDAN,MIDDLE EAST,4,4
+KENYA,AFRICA,0,0
+MOROCCO,AFRICA,0,0
+MOZAMBIQUE,AFRICA,0,0
+PERU,AMERICA,1,1
+ROMANIA,EUROPE,3,3
+RUSSIA,EUROPE,3,3
+SAUDI ARABIA,MIDDLE EAST,4,4
+UNITED KINGDOM,EUROPE,3,3
+UNITED STATES,AMERICA,1,1
+VIETNAM,ASIA,2,2

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash.plan
new file mode 100644
index 0000000..abcdf6e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash_NoBroadcast.plan
new file mode 100644
index 0000000..32b75cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Hash_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort.plan
new file mode 100644
index 0000000..abcdf6e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort.plan
@@ -0,0 +1,78 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000003
+2: eb_0000000000000_0000_000004
+3: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: type=Broadcast, tables=default.region
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort_NoBroadcast.plan
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort_NoBroadcast.plan b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort_NoBroadcast.plan
new file mode 100644
index 0000000..32b75cd
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.Sort_NoBroadcast.plan
@@ -0,0 +1,105 @@
+explain
+-------------------------------
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(1) on default.region
+        => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(0) on default.nation
+        => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+explain
+-------------------------------
+-------------------------------------------------------------------------------
+Execution Block Graph (TERMINAL - eb_0000000000000_0000_000005)
+-------------------------------------------------------------------------------
+|-eb_0000000000000_0000_000005
+   |-eb_0000000000000_0000_000004
+      |-eb_0000000000000_0000_000003
+         |-eb_0000000000000_0000_000002
+         |-eb_0000000000000_0000_000001
+-------------------------------------------------------------------------------
+Order of Execution
+-------------------------------------------------------------------------------
+1: eb_0000000000000_0000_000001
+2: eb_0000000000000_0000_000002
+3: eb_0000000000000_0000_000003
+4: eb_0000000000000_0000_000004
+5: eb_0000000000000_0000_000005
+-------------------------------------------------------------------------------
+
+=======================================================
+Block Id: eb_0000000000000_0000_000001 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+
+SCAN(0) on default.nation
+  => target list: default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)
+  => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+  => in schema: {(4) default.nation.n_comment (TEXT), default.nation.n_name (TEXT), default.nation.n_nationkey (INT4), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000002 [LEAF]
+=======================================================
+
+[Outgoing]
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+SCAN(1) on default.region
+  => target list: default.region.r_name (TEXT), default.region.r_regionkey (INT4)
+  => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+  => in schema: {(3) default.region.r_comment (TEXT), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000003 [INTERMEDIATE]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 1 => 3 (type=HASH_SHUFFLE, key=default.nation.n_regionkey (INT4), num=32)
+[q_0000000000000_0000] 2 => 3 (type=HASH_SHUFFLE, key=default.region.r_regionkey (INT4), num=32)
+
+[Outgoing]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+SORT(11)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   JOIN(7)(INNER)
+     => Join Cond: default.nation.n_regionkey (INT4) = default.region.r_regionkey (INT4)
+     => target list: default.nation.n_name (TEXT), default.region.r_name (TEXT)
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(4) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4), default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(10) on eb_0000000000000_0000_000002
+        => out schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+        => in schema: {(2) default.region.r_name (TEXT), default.region.r_regionkey (INT4)}
+      SCAN(9) on eb_0000000000000_0000_000001
+        => out schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+        => in schema: {(2) default.nation.n_name (TEXT), default.nation.n_regionkey (INT4)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000004 [ROOT]
+=======================================================
+
+[Incoming]
+[q_0000000000000_0000] 3 => 4 (type=RANGE_SHUFFLE, key=default.nation.n_name (TEXT), num=32)
+
+[Enforcers]
+ 0: sorted input=eb_0000000000000_0000_000003
+
+SORT(3)
+  => Sort Keys: default.nation.n_name (TEXT) (asc)
+   SCAN(12) on eb_0000000000000_0000_000003
+     => out schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+     => in schema: {(2) default.nation.n_name (TEXT), default.region.r_name (TEXT)}
+
+=======================================================
+Block Id: eb_0000000000000_0000_000005 [TERMINAL]
+=======================================================

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.result
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.result b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.result
new file mode 100644
index 0000000..8eaef8d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/results/TestInnerJoinQuery/testWhereClauseJoin2.result
@@ -0,0 +1,27 @@
+n_name,r_name
+-------------------------------
+ALGERIA,AFRICA
+ARGENTINA,AMERICA
+BRAZIL,AMERICA
+CANADA,AMERICA
+CHINA,ASIA
+EGYPT,MIDDLE EAST
+ETHIOPIA,AFRICA
+FRANCE,EUROPE
+GERMANY,EUROPE
+INDIA,ASIA
+INDONESIA,ASIA
+IRAN,MIDDLE EAST
+IRAQ,MIDDLE EAST
+JAPAN,ASIA
+JORDAN,MIDDLE EAST
+KENYA,AFRICA
+MOROCCO,AFRICA
+MOZAMBIQUE,AFRICA
+PERU,AMERICA
+ROMANIA,EUROPE
+RUSSIA,EUROPE
+SAUDI ARABIA,MIDDLE EAST
+UNITED KINGDOM,EUROPE
+UNITED STATES,AMERICA
+VIETNAM,ASIA


[48/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

Posted by hy...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java
new file mode 100644
index 0000000..69bf30a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java
@@ -0,0 +1,286 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql;
+
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestSimpleParser {
+
+  @Test
+  public final void testSpecialCases() throws InvalidStatementException {
+    List<ParsedResult> res1 = SimpleParser.parseScript("");
+    assertEquals(0, res1.size());
+
+    List<ParsedResult> res2 = SimpleParser.parseScript("a");
+    assertEquals(1, res2.size());
+
+    List<ParsedResult> res3 = SimpleParser.parseScript("?");
+    assertEquals(0, res3.size());
+
+    List<ParsedResult> res4 = SimpleParser.parseScript("\\");
+    assertEquals(1, res4.size());
+  }
+
+  @Test
+  public final void testMetaCommands() throws InvalidStatementException {
+    List<ParsedResult> res1 = SimpleParser.parseScript("\\d");
+    assertEquals(1, res1.size());
+    assertEquals(ParsedResult.StatementType.META, res1.get(0).getType());
+    assertEquals("\\d", res1.get(0).getHistoryStatement());
+
+    List<ParsedResult> res2 = SimpleParser.parseScript("\\d;\\c;\\f;");
+    assertEquals(3, res2.size());
+    assertEquals(ParsedResult.StatementType.META, res2.get(0).getType());
+    assertEquals("\\d", res2.get(0).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.META, res2.get(1).getType());
+    assertEquals("\\c", res2.get(1).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.META, res2.get(2).getType());
+    assertEquals("\\f", res2.get(2).getHistoryStatement());
+
+    List<ParsedResult> res3 = SimpleParser.parseScript("\n\t\t  \\d;\n\\c;\t\t\\f  ;");
+    assertEquals(3, res3.size());
+    assertEquals(ParsedResult.StatementType.META, res3.get(0).getType());
+    assertEquals("\\d", res3.get(0).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.META, res3.get(1).getType());
+    assertEquals("\\c", res3.get(1).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.META, res3.get(2).getType());
+    assertEquals("\\f", res3.get(2).getHistoryStatement());
+
+    List<ParsedResult> res4 = SimpleParser.parseScript("\\\td;");
+    assertEquals(1, res4.size());
+    assertEquals("\\\td", res4.get(0).getHistoryStatement());
+  }
+
+  @Test
+  public final void testParseScript() throws InvalidStatementException {
+    List<ParsedResult> res1 = SimpleParser.parseScript("select * from test;");
+    assertEquals(1, res1.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res1.get(0).getType());
+    assertEquals("select * from test", res1.get(0).getStatement());
+    assertEquals("select * from test", res1.get(0).getHistoryStatement());
+
+    List<ParsedResult> res2 = SimpleParser.parseScript("select * from test;");
+    assertEquals(1, res2.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res2.get(0).getType());
+    assertEquals("select * from test", res2.get(0).getStatement());
+    assertEquals("select * from test", res2.get(0).getHistoryStatement());
+
+    List<ParsedResult> res3 = SimpleParser.parseScript("select * from test1;select * from test2;");
+    assertEquals(2, res3.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res3.get(0).getType());
+    assertEquals("select * from test1", res3.get(0).getStatement());
+    assertEquals("select * from test1", res3.get(0).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res3.get(1).getType());
+    assertEquals("select * from test2", res3.get(1).getStatement());
+    assertEquals("select * from test2", res3.get(1).getHistoryStatement());
+
+    List<ParsedResult> res4 = SimpleParser.parseScript("\t\t\n\rselect * from \ntest1;select * from test2\n;");
+    assertEquals(2, res4.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res4.get(0).getType());
+    assertEquals("select * from \ntest1", res4.get(0).getStatement());
+    assertEquals("select * from test1", res4.get(0).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res4.get(1).getType());
+    assertEquals("select * from test2", res4.get(1).getStatement());
+    assertEquals("select * from test2", res4.get(1).getHistoryStatement());
+
+    List<ParsedResult> res5 =
+        SimpleParser.parseScript("\t\t\n\rselect * from \ntest1;\\d test;select * from test2;\n\nselect 1;");
+    assertEquals(4, res5.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res5.get(0).getType());
+    assertEquals("select * from \ntest1", res5.get(0).getStatement());
+    assertEquals("select * from test1", res5.get(0).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.META, res5.get(1).getType());
+    assertEquals("\\d test", res5.get(1).getStatement());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res5.get(2).getType());
+    assertEquals("select * from test2", res5.get(2).getStatement());
+    assertEquals("select * from test2", res5.get(2).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res5.get(3).getType());
+    assertEquals("select 1", res5.get(3).getStatement());
+    assertEquals("select 1", res5.get(3).getHistoryStatement());
+
+    List<ParsedResult> res6 =
+        SimpleParser.parseScript("select * from \n--test1; select * from test2;\ntest3;");
+    assertEquals(1, res6.size());
+    assertEquals("select * from test3", res6.get(0).getHistoryStatement());
+    assertEquals("select * from \n--test1; select * from test2;\ntest3", res6.get(0).getStatement());
+
+    List<ParsedResult> res7 =
+        SimpleParser.parseScript("select * from --test1; select * from test2;\ntest3;");
+    assertEquals(1, res7.size());
+    assertEquals("select * from test3", res7.get(0).getHistoryStatement());
+    assertEquals("select * from --test1; select * from test2;\ntest3", res7.get(0).getStatement());
+
+    List<ParsedResult> res8 = SimpleParser.parseScript("\\d test\nselect * \n--from test1;\nfrom test2;\\d test2;");
+    assertEquals(3, res8.size());
+    assertEquals(ParsedResult.StatementType.META, res8.get(0).getType());
+    assertEquals("\\d test", res8.get(0).getStatement());
+    assertEquals("\\d test", res8.get(0).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res8.get(1).getType());
+    assertEquals("select * \n--from test1;\nfrom test2", res8.get(1).getStatement());
+    assertEquals("select * from test2", res8.get(1).getHistoryStatement());
+    assertEquals(ParsedResult.StatementType.META, res8.get(2).getType());
+    assertEquals("\\d test2", res8.get(2).getStatement());
+    assertEquals("\\d test2", res8.get(2).getHistoryStatement());
+  }
+
+  @Test
+  public final void testParseLines() throws InvalidStatementException {
+    SimpleParser simpleParser = new SimpleParser();
+    List<ParsedResult> res1 = null;
+
+    res1 = simpleParser.parseLines("select * from test1; select * from test2;");
+    assertEquals(2, res1.size());
+    assertEquals("select * from test1", res1.get(0).getStatement());
+    assertEquals("select * from test2", res1.get(1).getStatement());
+    assertEquals("select * from test1", res1.get(0).getHistoryStatement());
+    assertEquals("select * from test2", res1.get(1).getHistoryStatement());
+
+    // select * from
+    // test1; select * from test2;
+    simpleParser = new SimpleParser();
+    res1 = simpleParser.parseLines("select * from ");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("test1; select * from test2;");
+    assertEquals(2, res1.size());
+    assertEquals("select * from \ntest1", res1.get(0).getStatement());
+    assertEquals("select * from test2", res1.get(1).getStatement());
+    assertEquals("select * from test1", res1.get(0).getHistoryStatement());
+    assertEquals("select * from test2", res1.get(1).getHistoryStatement());
+
+    // select * from
+    // --test1; select * from test2;
+    // test3;
+    simpleParser = new SimpleParser();
+    res1 = simpleParser.parseLines("select * from ");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("--test1; select * from test2;");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("test3;");
+    assertEquals(1, res1.size());
+    assertEquals("select * from test3", res1.get(0).getHistoryStatement());
+    assertEquals("select * from \n--test1; select * from test2;\ntest3", res1.get(0).getStatement());
+
+    // select * from
+    // test1 --select * from test2;
+    // where col1 = '123';
+    simpleParser = new SimpleParser();
+    res1 = simpleParser.parseLines("select * from ");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("test1 --select * from test2;");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("where col1 = '123';");
+    assertEquals(1, res1.size());
+    assertEquals("select * from test1 where col1 = '123'", res1.get(0).getHistoryStatement());
+    assertEquals("select * from \ntest1 --select * from test2;\nwhere col1 = '123'", res1.get(0).getStatement());
+
+    // Case for sql statement already including '\n'
+    // This test is important for tsql because CLI input always has '\n'.
+    simpleParser = new SimpleParser();
+    res1 = simpleParser.parseLines("select\n");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("*\n");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("from\n");
+    assertEquals(0, res1.size());
+    res1 = simpleParser.parseLines("test1;\n");
+    assertEquals(1, res1.size());
+    assertEquals("select\n*\nfrom\ntest1", res1.get(0).getStatement());
+    assertEquals("select * from test1", res1.get(0).getHistoryStatement());
+  }
+
+  @Test
+  public final void testQuoted() throws InvalidStatementException {
+    List<ParsedResult> res1 = SimpleParser.parseScript("select '\n;' from test;");
+    assertEquals(1, res1.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res1.get(0).getType());
+    assertEquals("select '\n;' from test", res1.get(0).getHistoryStatement());
+    assertEquals("select '\n;' from test", res1.get(0).getStatement());
+
+    List<ParsedResult> res2 = SimpleParser.parseScript("select 'abc\nbbc\nddf' from test;");
+    assertEquals(1, res2.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res2.get(0).getType());
+    assertEquals("select 'abc\nbbc\nddf' from test", res2.get(0).getHistoryStatement());
+    assertEquals("select 'abc\nbbc\nddf' from test", res2.get(0).getStatement());
+
+    List<ParsedResult> res3 = SimpleParser.parseScript("select '--test', \n'--test2' from test");
+    assertEquals(1, res3.size());
+    assertEquals(ParsedResult.StatementType.STATEMENT, res3.get(0).getType());
+    assertEquals("select '--test', '--test2' from test", res3.get(0).getHistoryStatement());
+    assertEquals("select '--test', \n'--test2' from test", res3.get(0).getStatement());
+
+    try {
+      SimpleParser.parseScript("select 'abc");
+      assertTrue(false);
+    } catch (InvalidStatementException is) {
+      assertTrue(true);
+    }
+  }
+
+  @Test
+  public final void testParseLines1() throws InvalidStatementException {
+    String [] lines = {
+      "select abc, ",
+      "bbc from test"
+    };
+    SimpleParser parser = new SimpleParser();
+    List<ParsedResult> result1 = parser.parseLines(lines[0]);
+    assertEquals(0, result1.size());
+    List<ParsedResult> result2 = parser.parseLines(lines[1]);
+    assertEquals(0, result2.size());
+    List<ParsedResult> result3 = parser.EOF();
+    assertEquals(1, result3.size());
+    assertEquals(lines[0] + lines[1], result3.get(0).getHistoryStatement());
+    assertEquals(lines[0] + "\n" + lines[1], result3.get(0).getStatement());
+  }
+
+  @Test
+  public final void testParseLines2() throws InvalidStatementException {
+    String [] lines = {
+        "select abc, '",
+        "bbc' from test; select * from test3;"
+    };
+    SimpleParser parser = new SimpleParser();
+    List<ParsedResult> result1 = parser.parseLines(lines[0]);
+    assertEquals(0, result1.size());
+    List<ParsedResult> result2 = parser.parseLines(lines[1]);
+    assertEquals(2, result2.size());
+    assertEquals("select abc, 'bbc' from test", result2.get(0).getHistoryStatement());
+    assertEquals("select * from test3", result2.get(1).getHistoryStatement());
+  }
+
+  @Test
+  public final void testParseLines3() throws InvalidStatementException {
+    String [] lines = {
+        "select abc, 'bbc",
+        "' from test; select * from test3;"
+    };
+    SimpleParser parser = new SimpleParser();
+    List<ParsedResult> result1 = parser.parseLines(lines[0]);
+    assertEquals(0, result1.size());
+    List<ParsedResult> result2 = parser.parseLines(lines[1]);
+    assertEquals(2, result2.size());
+    assertEquals("select abc, 'bbc' from test", result2.get(0).getHistoryStatement());
+    assertEquals("select * from test3", result2.get(1).getHistoryStatement());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java
new file mode 100644
index 0000000..e744631
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java
@@ -0,0 +1,472 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.PosixParser;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.ConfigKey;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.storage.StorageUtil;
+import org.apache.tajo.storage.TablespaceManager;
+import org.apache.tajo.util.FileUtil;
+import org.junit.*;
+import org.junit.rules.TestName;
+
+import java.io.*;
+import java.net.URL;
+
+import static org.junit.Assert.*;
+
+public class TestTajoCli {
+  protected static final TpchTestBase testBase;
+  protected static final TajoTestingCluster cluster;
+
+  /** the base path of result directories */
+  protected static final Path resultBasePath;
+  static {
+    testBase = TpchTestBase.getInstance();
+    cluster = testBase.getTestingCluster();
+    URL resultBaseURL = ClassLoader.getSystemResource("results");
+    resultBasePath = new Path(resultBaseURL.toString());
+  }
+
+  private TajoCli tajoCli;
+  private Path currentResultPath;
+  private ByteArrayOutputStream out;
+
+  @Rule
+  public TestName name = new TestName();
+
+  public TestTajoCli() {
+    String className = getClass().getSimpleName();
+    currentResultPath = new Path(resultBasePath, className);
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    out = new ByteArrayOutputStream();
+    tajoCli = new TajoCli(cluster.getConfiguration(), new String[]{}, System.in, out);
+  }
+
+  @After
+  public void tearDown() throws IOException {
+    out.close();
+    if (tajoCli != null) {
+      tajoCli.close();
+    }
+  }
+
+  private static void setVar(TajoCli cli, ConfigKey key, String val) throws Exception {
+    cli.executeMetaCommand("\\set " + key.keyname() + " " + val);
+  }
+
+  private static void assertSessionVar(TajoCli cli, String key, String expectedVal) {
+    assertEquals(cli.getContext().getCliSideVar(key), expectedVal);
+  }
+
+  private void assertOutputResult(String actual) throws Exception {
+    assertOutputResult(name.getMethodName() + ".result", actual);
+  }
+
+  private void assertOutputResult(String expectedResultFile, String actual) throws Exception {
+    assertOutputResult(expectedResultFile, actual, null, null);
+  }
+
+  private void assertOutputResult(String expectedResultFile, String actual, String[] paramKeys, String[] paramValues)
+    throws Exception {
+    FileSystem fs = currentResultPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
+    Path resultFile = StorageUtil.concatPath(currentResultPath, expectedResultFile);
+    assertTrue(resultFile.toString() + " existence check", fs.exists(resultFile));
+
+    String expectedResult = FileUtil.readTextFile(new File(resultFile.toUri()));
+
+    if (paramKeys != null) {
+      for (int i = 0; i < paramKeys.length; i++) {
+        if (i < paramValues.length) {
+          expectedResult = expectedResult.replace(paramKeys[i], paramValues[i]);
+        }
+      }
+    }
+    assertEquals(expectedResult.trim(), actual.trim());
+  }
+
+  @Test
+  public void testParseParam() throws Exception {
+    String[] args = new String[]{"-f", "test.sql", "--param", "test1=10", "--param", "test2=20"};
+
+    CommandLineParser parser = new PosixParser();
+    CommandLine cmd = parser.parse(TajoCli.options, args);
+
+    String fileName = cmd.getOptionValue("f");
+    assertNotNull(fileName);
+    assertEquals(args[1], fileName);
+
+    String[] paramValues = cmd.getOptionValues("param");
+
+    assertNotNull(paramValues);
+    assertEquals(2, paramValues.length);
+
+    assertEquals("test1=10", paramValues[0]);
+    assertEquals("test2=20", paramValues[1]);
+  }
+
+  @Test
+  public void testParseConf() throws Exception {
+    String[] args = new String[]{"--conf", "tajo.cli.print.pause=false",
+      "--conf", "tajo.executor.join.inner.in-memory-table-num=256"};
+
+    CommandLineParser parser = new PosixParser();
+    CommandLine cmd = parser.parse(TajoCli.options, args);
+    String[] confValues = cmd.getOptionValues("conf");
+
+    assertNotNull(confValues);
+    assertEquals(2, confValues.length);
+
+    assertEquals("tajo.cli.print.pause=false", confValues[0]);
+    assertEquals("tajo.executor.join.inner.in-memory-table-num=256", confValues[1]);
+
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+    TajoCli testCli = new TajoCli(tajoConf, args, System.in, System.out);
+    try {
+      assertEquals("false", testCli.getContext().get(SessionVars.CLI_PAGING_ENABLED));
+      assertEquals("256", testCli.getContext().getConf().get("tajo.executor.join.inner.in-memory-table-num"));
+    } finally {
+      testCli.close();
+    }
+  }
+
+  @Test
+  public void testReplaceParam() throws Exception {
+    String sql = "select * from lineitem where l_tax > ${tax} and l_returnflag > '${returnflag}'";
+    String[] params = new String[]{"tax=10", "returnflag=A"};
+
+
+    String expected = "select * from lineitem where l_tax > 10 and l_returnflag > 'A'";
+    assertEquals(expected, TajoCli.replaceParam(sql, params));
+  }
+
+  @Test
+  public void testLocalQueryWithoutFrom() throws Exception {
+    String sql = "select 'abc', '123'; select substr('123456', 1,3);";
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+    tajoCli.executeScript(sql);
+    String consoleResult = new String(out.toByteArray());
+
+    assertOutputResult(consoleResult);
+  }
+
+  @Test
+  public void testConnectDatabase() throws Exception {
+    String databaseName;
+
+    if (cluster.isHiveCatalogStoreRunning()) {
+      databaseName = "TEST_CONNECTION_DATABASE".toLowerCase();
+    } else {
+      databaseName = "TEST_CONNECTION_DATABASE";
+    }
+    String sql = "create database \"" + databaseName + "\";";
+
+    tajoCli.executeScript(sql);
+
+    tajoCli.executeMetaCommand("\\c " + databaseName);
+    assertEquals(databaseName, tajoCli.getContext().getCurrentDatabase());
+
+    tajoCli.executeMetaCommand("\\c default");
+    assertEquals("default", tajoCli.getContext().getCurrentDatabase());
+
+    tajoCli.executeMetaCommand("\\c \"" + databaseName + "\"");
+    assertEquals(databaseName, tajoCli.getContext().getCurrentDatabase());
+  }
+
+  private void verifyDescTable(String sql, String tableName, String resultFileName) throws Exception {
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+    tajoCli.executeScript(sql);
+
+    tajoCli.executeMetaCommand("\\d " + tableName);
+    tajoCli.executeMetaCommand("\\d \"" + tableName + "\"");
+
+    String consoleResult = new String(out.toByteArray());
+
+    if (!cluster.isHiveCatalogStoreRunning()) {
+      assertOutputResult(resultFileName, consoleResult, new String[]{"${table.path}"},
+        new String[]{TablespaceManager.getDefault().getTableUri("default", tableName).toString()});
+    }
+  }
+
+  @Test
+  public void testDescTable() throws Exception {
+    String tableName;
+    if (cluster.isHiveCatalogStoreRunning()) {
+      tableName = "TEST_DESC_TABLE".toLowerCase();
+    } else {
+      tableName = "TEST_DESC_TABLE";
+    }
+
+    String sql = "create table \"" + tableName + "\" (col1 int4, col2 int4);";
+    verifyDescTable(sql, tableName, "testDescTable.result");
+  }
+
+  @Test
+  public void testDescTableForNestedSchema() throws Exception {
+    String tableName;
+    if (cluster.isHiveCatalogStoreRunning()) {
+      tableName = "TEST_DESC_TABLE_NESTED".toLowerCase();
+    } else {
+      tableName = "TEST_DESC_TABLE_NESTED";
+    }
+
+    String sql = "create table \"" + tableName + "\" (col1 int4, col2 int4, col3 record (col4 record (col5 text)));";
+    verifyDescTable(sql, tableName, "testDescTableForNestedSchema.result");
+  }
+
+  @Test
+  public void testSelectResultWithNullFalse() throws Exception {
+    String sql =
+      "select\n" +
+        "  c_custkey,\n" +
+        "  orders.o_orderkey,\n" +
+        "  orders.o_orderstatus \n" +
+        "from\n" +
+        "  orders full outer join customer on c_custkey = o_orderkey\n" +
+        "order by\n" +
+        "  c_custkey,\n" +
+        "  orders.o_orderkey;\n";
+
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+    tajoCli.executeScript(sql);
+
+    String consoleResult = new String(out.toByteArray());
+    assertOutputResult(consoleResult);
+  }
+
+  private void verifySelectResultWithNullTrue() throws Exception {
+    String sql =
+      "select\n" +
+        "  c_custkey,\n" +
+        "  orders.o_orderkey,\n" +
+        "  orders.o_orderstatus \n" +
+        "from\n" +
+        "  orders full outer join customer on c_custkey = o_orderkey\n" +
+        "order by\n" +
+        "  c_custkey,\n" +
+        "  orders.o_orderkey;\n";
+
+
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+    assertSessionVar(tajoCli, SessionVars.CLI_NULL_CHAR.keyname(), "testnull");
+
+    tajoCli.executeScript(sql);
+
+    String consoleResult = new String(out.toByteArray());
+    assertOutputResult(consoleResult);
+  }
+
+  @Test
+  public void testSelectResultWithNullTrueDeprecated() throws Exception {
+    setVar(tajoCli, TajoConf.ConfVars.$CLI_NULL_CHAR, "testnull");
+    verifySelectResultWithNullTrue();
+  }
+
+  @Test
+  public void testSelectResultWithNullTrue() throws Exception {
+    setVar(tajoCli, SessionVars.CLI_NULL_CHAR, "testnull");
+    verifySelectResultWithNullTrue();
+  }
+
+  private void verifyStopWhenError() throws Exception {
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+
+    assertSessionVar(tajoCli, SessionVars.ON_ERROR_STOP.keyname(), "true");
+
+    tajoCli.executeScript("select count(*) from lineitem; " +
+      "select count(*) from lineitem2; " +
+      "select count(*) from orders");
+
+    String consoleResult = new String(out.toByteArray());
+    assertOutputResult(consoleResult);
+  }
+
+  @Test
+  public void testGetConf() throws Exception {
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    TajoCli tajoCli = new TajoCli(tajoConf, new String[]{}, System.in, out);
+    try {
+      tajoCli.executeMetaCommand("\\getconf tajo.rootdir");
+
+      String consoleResult = new String(out.toByteArray());
+      assertEquals(consoleResult, tajoCli.getContext().getConf().getVar(TajoConf.ConfVars.ROOT_DIR) + "\n");
+    } finally {
+      tajoCli.close();
+    }
+  }
+
+  @Test
+  public void testShowMasters() throws Exception {
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    TajoCli tajoCli = new TajoCli(tajoConf, new String[]{}, System.in, out);
+    tajoCli.executeMetaCommand("\\admin -showmasters");
+
+    String consoleResult = new String(out.toByteArray());
+
+    String masterAddress = tajoCli.getContext().getConf().getVar(TajoConf.ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS);
+    String host = masterAddress.split(":")[0];
+    tajoCli.close();
+    assertEquals(consoleResult, host + "\n");
+  }
+
+  @Test
+  public void testStopWhenErrorDeprecated() throws Exception {
+    tajoCli.executeMetaCommand("\\set tajo.cli.error.stop true");
+    verifyStopWhenError();
+  }
+
+  @Test
+  public void testStopWhenError() throws Exception {
+    tajoCli.executeMetaCommand("\\set ON_ERROR_STOP true");
+    verifyStopWhenError();
+  }
+
+  @Test
+  public void testHelpSessionVars() throws Exception {
+    tajoCli.executeMetaCommand("\\help set");
+    assertOutputResult(new String(out.toByteArray()));
+  }
+
+  @Test
+  public void testTimeZoneSessionVars1() throws Exception {
+    tajoCli.executeMetaCommand("\\set TIMEZONE GMT+1");
+    tajoCli.executeMetaCommand("\\set");
+    String output = new String(out.toByteArray());
+    assertTrue(output.contains("'TIMEZONE'='GMT+1'"));
+  }
+
+  @Test
+  public void testTimeZoneSessionVars2() throws Exception {
+    tajoCli.executeScript("SET TIME ZONE 'GMT+2'");
+    tajoCli.executeMetaCommand("\\set");
+    String output = new String(out.toByteArray());
+    assertTrue(output.contains("'TIMEZONE'='GMT+2'"));
+  }
+
+  @Test
+  public void testTimeZoneTest1() throws Exception {
+    String tableName = "test1";
+    tajoCli.executeMetaCommand("\\set TIMEZONE GMT+0");
+    tajoCli.executeScript("create table " + tableName + " (col1 TIMESTAMP)");
+    tajoCli.executeScript("insert into " + tableName + " select to_timestamp(0)");
+    tajoCli.executeScript("select * from " + tableName);
+    String consoleResult = new String(out.toByteArray());
+    tajoCli.executeScript("DROP TABLE " + tableName + " PURGE");
+    assertTrue(consoleResult.contains("1970-01-01 00:00:00"));
+  }
+
+  @Test
+  public void testTimeZoneTest2() throws Exception {
+    String tableName = "test1";
+    tajoCli.executeMetaCommand("\\set TIMEZONE GMT+1");
+    tajoCli.executeScript("create table " + tableName + " (col1 TIMESTAMP)");
+    tajoCli.executeScript("insert into " + tableName + " select to_timestamp(0)");
+    tajoCli.executeScript("select * from " + tableName);
+    String consoleResult = new String(out.toByteArray());
+    tajoCli.executeScript("DROP TABLE " + tableName + " PURGE");
+    assertTrue(consoleResult.contains("1970-01-01 01:00:00"));
+  }
+
+  @Test(timeout = 3000)
+  public void testNonForwardQueryPause() throws Exception {
+    final String sql = "select * from default.lineitem";
+    TajoCli cli = null;
+    try {
+      TableDesc tableDesc = cluster.getMaster().getCatalog().getTableDesc("default", "lineitem");
+      assertNotNull(tableDesc);
+      assertEquals(0L, tableDesc.getStats().getNumRows().longValue());
+
+      InputStream testInput = new ByteArrayInputStream(new byte[]{(byte) DefaultTajoCliOutputFormatter.QUIT_COMMAND});
+      cli = new TajoCli(cluster.getConfiguration(), new String[]{}, testInput, out);
+      setVar(cli, SessionVars.CLI_PAGE_ROWS, "2");
+      setVar(cli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+
+      cli.executeScript(sql);
+
+      String consoleResult;
+      consoleResult = new String(out.toByteArray());
+      assertOutputResult(consoleResult);
+    } finally {
+      cli.close();
+    }
+  }
+
+  @Test
+  public void testAlterTableAddDropPartition() throws Exception {
+    String tableName = CatalogUtil.normalizeIdentifier("testAlterTableAddPartition");
+
+    tajoCli.executeScript("create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8)");
+    tajoCli.executeScript("alter table " + tableName + " add partition (key2 = 0.1)");
+    tajoCli.executeScript("alter table " + tableName + " add partition (key = 0.1)");
+    tajoCli.executeScript("alter table " + tableName + " drop partition (key = 0.1)");
+    tajoCli.executeScript("alter table " + tableName + " drop partition (key = 0.1)");
+
+    tajoCli.executeScript("drop table " + tableName);
+    tajoCli.executeScript("create table " + tableName
+      + " (col1 int4, col2 int4) partition by column(col3 float8, col4 int4)");
+
+    TajoClient client = testBase.getTestingCluster().newTajoClient();
+    TableDesc tableDesc = client.getTableDesc(tableName);
+
+    String partitionLocation = tableDesc.getUri().toString() + "/col5=0.1/col6=10";
+    tajoCli.executeScript("alter table " + tableName + " add partition (col3 = 0.1, col4 = 10)"
+      + " location '" + partitionLocation + "'");
+
+    Path partitionPath = new Path(partitionLocation);
+    FileSystem fs = testBase.getTestingCluster().getDefaultFileSystem();
+    assertTrue(fs.exists(partitionPath));
+
+    tajoCli.executeScript("alter table " + tableName + " drop partition (col3 = 0.1, col4 = 10)");
+
+    String consoleResult = new String(out.toByteArray());
+    assertOutputResult(consoleResult);
+  }
+
+  public static class TajoCliOutputTestFormatter extends DefaultTajoCliOutputFormatter {
+    @Override
+    protected String getResponseTimeReadable(float responseTime) {
+      return "";
+    }
+    @Override
+    public void printProgress(PrintWriter sout, QueryStatus status) {
+      //nothing to do
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
new file mode 100644
index 0000000..edbeff6
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.ConfigKey;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.util.FileUtil;
+import org.junit.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestTajoCliNegatives extends QueryTestCaseBase {
+  private static TajoCli tajoCli;
+  private static ByteArrayOutputStream out;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    out = new ByteArrayOutputStream();
+    tajoCli = new TajoCli(testingCluster.getConfiguration(), new String[]{}, System.in, out);
+  }
+
+  @AfterClass
+  public static void tearDown() throws IOException {
+    out.close();
+    if (tajoCli != null) {
+      tajoCli.close();
+    }
+  }
+
+  @Before
+  public void resetConsole() throws IOException {
+    out.reset();
+  }
+
+  public void assertMetaCommandFailures(String cmd) throws Exception {
+    Path resultFile = getResultFile(getMethodName() + ".result");
+    String expected = FileUtil.readTextFile(new File(resultFile.toUri()));
+
+    tajoCli.executeMetaCommand(cmd);
+    String consoleResult = new String(out.toByteArray());
+    assertEquals(expected, consoleResult);
+  }
+
+  public void assertMetaCommandFailure(String cmd, String expectedMsg) throws Exception {
+    tajoCli.executeMetaCommand(cmd);
+    String consoleResult = new String(out.toByteArray());
+    assertEquals(expectedMsg, consoleResult);
+  }
+
+  public void assertScriptFailure(String cmd) throws Exception {
+    Path resultFile = getResultFile(getMethodName() + ".result");
+    String expected = FileUtil.readTextFile(new File(resultFile.toUri()));
+
+    tajoCli.executeScript(cmd);
+    String consoleResult = new String(out.toByteArray());
+    assertEquals(expected, consoleResult);
+  }
+
+  public void assertScriptFailure(String cmd, String expectedMsg) throws Exception {
+    tajoCli.executeScript(cmd);
+    String consoleResult = new String(out.toByteArray());
+    assertEquals(expectedMsg, consoleResult);
+  }
+
+  @Test
+  public void testConnectDatabase() throws Exception {
+    assertMetaCommandFailure("\\c unknown_db", "ERROR: database 'unknown_db' does not exist");
+  }
+
+  @Test
+  public void testDescTable() throws Exception {
+    assertMetaCommandFailure("\\d unknown_table", "ERROR: relation 'unknown_table' does not exist\n");
+  }
+
+  @Test
+  public void testQueryVerification() throws Exception {
+    assertScriptFailure("select * from unknown_table", "ERROR: relation 'default.unknown_table' does not exist\n");
+  }
+
+  @Test
+  public void testQuerySyntax() throws Exception {
+    assertScriptFailure("select * from unknown-table");
+  }
+
+  private static void setVar(TajoCli cli, ConfigKey key, String val) throws Exception {
+    cli.executeMetaCommand("\\set " + key.keyname() + " " + val);
+  }
+
+  public static class TajoCliOutputTestFormatter extends DefaultTajoCliOutputFormatter {
+    @Override
+    protected String getResponseTimeReadable(float responseTime) {
+      return "";
+    }
+    @Override
+    public void printProgress(PrintWriter sout, QueryStatus status) {
+      //nothing to do
+    }
+  }
+
+  @Test
+  public void testQueryNotImplementedFeature() throws Exception {
+
+    try {
+      client.updateQuery("CREATE DATABASE TestTajoCliNegatives");
+      client.updateQuery("CREATE TABLE TestTajoCliNegatives.table12u79 ( name RECORD(last TEXT, first TEXT) )");
+
+      assertScriptFailure("select name FROM TestTajoCliNegatives.table12u79",
+          "ERROR: not implemented feature: record field projection\n");
+
+    } finally {
+      client.updateQuery("DROP TABLE IF EXISTS TestTajoCliNegatives.table12u79");
+      client.updateQuery("DROP DATABASE IF EXISTS TestTajoCliNegatives");
+    }
+  }
+
+  @Test
+  public void testQueryFailure() throws Exception {
+    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
+    assertScriptFailure("select fail(3, l_orderkey, 'testQueryFailure') from default.lineitem" ,
+        "ERROR: No error message\n");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java
new file mode 100644
index 0000000..ed7ee4a
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql.commands;
+
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.cli.tsql.TajoCli;
+import org.apache.tajo.conf.TajoConf;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestExecExternalShellCommand {
+  @Test
+  public void testCommand() throws Exception {
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+    TajoCli cli = new TajoCli(tajoConf, new String[]{}, null, out);
+
+    cli.executeMetaCommand("\\! echo \"this is test\"");
+    String consoleResult = new String(out.toByteArray());
+    assertEquals("this is test\n", consoleResult);
+
+    assertEquals(-1, cli.executeMetaCommand("\\! error_command"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java
new file mode 100644
index 0000000..496c7e3
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql.commands;
+
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.cli.tsql.TajoCli;
+import org.apache.tajo.conf.TajoConf;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestHdfsCommand {
+  @Test
+  public void testHdfCommand() throws Exception {
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+    System.setOut(new PrintStream(out));
+    System.setErr(new PrintStream(out));
+    TajoCli cli = new TajoCli(tajoConf, new String[]{}, null, out);
+
+    cli.executeMetaCommand("\\dfs -test");
+    String consoleResult = new String(out.toByteArray());
+    assertEquals("-test: Not enough arguments: expected 1 but got 0\n" +
+        "Usage: hadoop fs [generic options] -test -[defsz] <path>\n", consoleResult);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java
new file mode 100644
index 0000000..4b8000d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.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.client;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.exception.*;
+import org.apache.tajo.util.KeyValueSet;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.net.URI;
+
+import static org.junit.Assert.assertFalse;
+
+public class TestCatalogAdminClientExceptions extends QueryTestCaseBase {
+  private static TajoTestingCluster cluster;
+  private static TajoClient client;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+    client = cluster.newTajoClient();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    client.close();
+  }
+
+  @Test(expected = DuplicateDatabaseException.class)
+  public final void testCreateDatabase() throws TajoException {
+    client.createDatabase("default"); // duplicate database
+  }
+
+  @Test
+  public final void testExistDatabase() {
+    assertFalse(client.existDatabase("unknown-database")); // unknown database
+  }
+
+  @Test(expected = UndefinedDatabaseException.class)
+  public final void testDropDatabase() throws TajoException {
+    client.dropDatabase("unknown-database"); // unknown database
+  }
+
+  @Test(expected = UnavailableTableLocationException.class)
+  public final void testCreateExternalTableUnavailableLocation() throws TajoException {
+    client.createExternalTable("table128237", new Schema(), URI.create("/tajo/test1bcd"),
+        new TableMeta("TEXT", new KeyValueSet()));
+  }
+
+  @Test(expected = DuplicateTableException.class)
+  public final void testCreateExternalTableDuplicated() throws TajoException {
+    client.createExternalTable("default.lineitem", new Schema(), URI.create("/"),
+        new TableMeta("TEXT", new KeyValueSet()));
+  }
+
+  @Test(expected = InsufficientPrivilegeException.class)
+  public final void testCreateExternalTableInsufficientPrivilege() throws TajoException {
+    Path p = TajoConf.getWarehouseDir(conf);
+    client.createExternalTable("information_schema.table1237891", new Schema(), p.toUri(),
+        new TableMeta("TEXT", new KeyValueSet()));
+  }
+
+  @Test(expected = UndefinedTableException.class)
+  public final void testDropTableAbsent() throws UndefinedTableException, InsufficientPrivilegeException {
+    client.dropTable("unknown-table"); // unknown table
+  }
+
+  @Test(expected = InsufficientPrivilegeException.class)
+  public final void testDropTableInsufficient() throws UndefinedTableException, InsufficientPrivilegeException {
+    client.dropTable("information_schema.tables"); // cannot be dropped
+  }
+
+  @Test(expected = UndefinedTableException.class)
+  public final void testGetTableDesc() throws UndefinedTableException {
+    client.getTableDesc("unknown-table");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java
new file mode 100644
index 0000000..0457e23
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.client;
+
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.TpchTestBase;
+import org.apache.tajo.annotation.NotThreadSafe;
+import org.apache.tajo.error.Errors;
+import org.apache.tajo.exception.*;
+import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+@NotThreadSafe
+public class TestQueryClientExceptions {
+  private static TajoTestingCluster cluster;
+  private static TajoClient client;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    cluster = TpchTestBase.getInstance().getTestingCluster();
+    client = cluster.newTajoClient();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    client.close();
+  }
+
+  @Test
+  public void testExecuteQuery() {
+    // This is just an error propagation unit test. Specified SQL errors will be addressed in other unit tests.
+    ReturnState state = client.executeQuery("select * from unknown_table").getState();
+    assertEquals(Errors.ResultCode.UNDEFINED_TABLE, state.getReturnCode());
+
+    state = client.executeQuery("create table default.lineitem (name int);").getState();
+    assertEquals(Errors.ResultCode.DUPLICATE_TABLE, state.getReturnCode());
+  }
+
+  @Test(expected = DuplicateTableException.class)
+  public void testUpdateQuery() throws TajoException {
+    client.updateQuery("create table default.lineitem (name int);");
+  }
+
+  @Test(expected = UndefinedTableException.class)
+  public void testExecuteQueryAndGetResult() throws TajoException {
+    // This is just an error propagation unit test. Specified SQL errors will be addressed in other unit tests.
+    client.executeQueryAndGetResult("select * from unknown_table");
+  }
+
+  @Test
+  public void testCloseQuery() {
+    // absent query id
+    client.closeQuery(LocalTajoTestingUtility.newQueryId());
+    client.closeNonForwardQuery(LocalTajoTestingUtility.newQueryId());
+  }
+
+  @Test(expected = UndefinedDatabaseException .class)
+  public void testSelectDatabase() throws UndefinedDatabaseException {
+    // absent database name
+    client.selectDatabase("unknown_db");
+  }
+
+  @Test(expected = NoSuchSessionVariableException.class)
+  public void testGetSessionVar() throws NoSuchSessionVariableException {
+    // absent session variable
+    client.getSessionVariable("unknown-var");
+  }
+
+  @Test(expected = QueryNotFoundException.class)
+  public void testGetQueryResult() throws TajoException {
+    // absent query id
+    client.getQueryResult(LocalTajoTestingUtility.newQueryId());
+  }
+
+  @Test(expected = QueryNotFoundException.class)
+  public void testGetResultResponse() throws TajoException {
+    // absent query id
+    client.getResultResponse(LocalTajoTestingUtility.newQueryId());
+  }
+
+  @Test(expected = QueryNotFoundException.class)
+  public void testFetchNextQueryResult() throws TajoException {
+    client.fetchNextQueryResult(LocalTajoTestingUtility.newQueryId(), 100);
+  }
+
+  @Test(expected = QueryNotFoundException.class)
+  public void testKillQuery() throws QueryNotFoundException {
+    client.killQuery(LocalTajoTestingUtility.newQueryId());
+  }
+
+  @Test(expected = QueryNotFoundException.class)
+  public void testGetQueryInfo() throws QueryNotFoundException {
+    client.getQueryInfo(LocalTajoTestingUtility.newQueryId());
+  }
+
+  @Test(expected = QueryNotFoundException.class)
+  public void testGetQueryHistory() throws QueryNotFoundException {
+    client.getQueryHistory(LocalTajoTestingUtility.newQueryId());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java
new file mode 100644
index 0000000..93a48f0
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java
@@ -0,0 +1,775 @@
+/**
+ * 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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.*;
+import org.apache.tajo.TajoProtos.QueryState;
+import org.apache.tajo.annotation.NotThreadSafe;
+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.exception.TajoException;
+import org.apache.tajo.exception.UnsupportedException;
+import org.apache.tajo.ipc.ClientProtos;
+import org.apache.tajo.ipc.ClientProtos.QueryHistoryProto;
+import org.apache.tajo.ipc.ClientProtos.QueryInfoProto;
+import org.apache.tajo.ipc.ClientProtos.StageHistoryProto;
+import org.apache.tajo.storage.StorageConstants;
+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.io.InputStream;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+@Category(IntegrationTest.class)
+@NotThreadSafe
+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 = cluster.newTajoClient();
+    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 TajoException {
+    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));
+      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));
+      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, TajoException, InterruptedException {
+    int currentNum = client.getAllDatabaseNames().size();
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase());
+
+    String databaseName = CatalogUtil.normalizeIdentifier("testcurrentdatabase");
+    client.createDatabase(databaseName);
+    assertEquals(currentNum + 1, client.getAllDatabaseNames().size());
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase());
+    client.selectDatabase(databaseName);
+    assertEquals(databaseName, client.getCurrentDatabase());
+    client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME);
+    client.dropDatabase(databaseName);
+
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testSelectDatabaseToInvalidOne() throws IOException, TajoException, InterruptedException {
+    int currentNum = client.getAllDatabaseNames().size();
+    assertFalse(client.existDatabase("invaliddatabase"));
+
+    try {
+      client.selectDatabase("invaliddatabase");
+      assertFalse(true);
+    } catch (Throwable t) {
+      assertFalse(false);
+    }
+
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testDropCurrentDatabase() throws IOException, TajoException, InterruptedException {
+    int currentNum = client.getAllDatabaseNames().size();
+    String databaseName = CatalogUtil.normalizeIdentifier("testdropcurrentdatabase");
+    client.createDatabase(databaseName);
+    client.selectDatabase(databaseName);
+    assertEquals(databaseName, client.getCurrentDatabase());
+
+    try {
+      client.dropDatabase(databaseName);
+      assertFalse(true);
+    } catch (Throwable t) {
+      assertFalse(false);
+    }
+
+    client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME);
+    client.dropDatabase(databaseName);
+    assertEquals(currentNum, client.getAllDatabaseNames().size());
+  }
+
+  @Test
+  public final void testSessionVariables() throws IOException, TajoException, InterruptedException {
+    String prefixName = "key_";
+    String prefixValue = "val_";
+
+    List<String> unsetList = new ArrayList<>();
+    for(Map.Entry<String, String> entry: client.getAllSessionVariables().entrySet()) {
+      unsetList.add(entry.getKey());
+    }
+    client.unsetSessionVariables(unsetList);
+
+    for (int i = 0; i < 10; i++) {
+      String key = prefixName + i;
+      String val = prefixValue + i;
+
+      // Basically,
+      assertEquals(i + 4, 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 + 5, 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, TajoException, 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, TajoException {
+    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, TajoException {
+    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.toUri(), 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, TajoException {
+    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.toUri(), 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, TajoException {
+    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, TajoException {
+    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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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, TajoException {
+    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, TajoException {
+    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.toUri(), 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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    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) )";
+
+    try {
+      client.updateQuery(rangeSql);
+      fail();
+    } catch (UnsupportedException se) {
+    }
+ 
+    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') )";
+
+    try {
+      assertFalse(client.updateQuery(listSql));
+      fail();
+    } catch (UnsupportedException se) {
+    }
+
+    String hashSql = "create table " + tableName + " (deptname text, score int4)";
+    hashSql += "PARTITION BY HASH (deptname)";
+    hashSql += "PARTITIONS 2";
+
+    try {
+      assertFalse(client.updateQuery(hashSql));
+      fail();
+    } catch (UnsupportedException se) {
+    }
+  }
+
+  @Test
+  public final void testCreateAndDropTablePartitionedColumnByExecuteQuery() throws IOException, TajoException {
+    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 = new Path(client.getTableDesc(tableName).getUri());
+    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, TajoException {
+    Collection<FunctionDesc> catalogFunctions = cluster.getMaster().getCatalog().getFunctions();
+    String functionName = "sum";
+    int numFunctions = 0;
+    for(FunctionDesc eachFunction: catalogFunctions) {
+      if(functionName.equals(eachFunction.getFunctionName())) {
+        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 SQLException, TajoException {
+    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 {
+      while (true) {
+        Thread.sleep(100);
+
+        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;
+        }
+      }
+
+      QueryStatus queryStatus = client.getQueryStatus(queryId);
+      assertNotNull(queryStatus);
+      assertTrue(TajoClientUtil.isQueryComplete(queryStatus.getState()));
+
+      ResultSet resultSet = client.getQueryResult(queryId);
+      assertNotNull(resultSet);
+
+      int count = 0;
+      while(resultSet.next()) {
+        count++;
+      }
+
+      assertEquals(5, count);
+    } finally {
+      client.closeQuery(queryId);
+    }
+  }
+
+  @Test
+  public void testNullCharSessionInCTAS() throws Exception {
+    String sql =
+        "create table nullcharsession as select\n" +
+          "  c_custkey,\n" +
+          "  orders.o_orderkey,\n" +
+          "  orders.o_orderstatus \n" +
+          "from\n" +
+          "  orders full outer join customer on c_custkey = o_orderkey\n" +
+          "order by\n" +
+          "  c_custkey,\n" +
+          "  orders.o_orderkey;\n";
+
+    Map<String, String> variables = new HashMap<String, String>();
+    variables.put(SessionVars.NULL_CHAR.keyname(), "\\\\T");
+    client.updateSessionVariables(variables);
+    ResultSet res = client.executeQueryAndGetResult(sql);
+    res.close();
+
+    TableDesc resultDesc = client.getTableDesc("nullcharsession");
+    assertNullCharSessionVar(resultDesc);
+  }
+
+
+  public void assertNullCharSessionVar(TableDesc resultDesc) throws Exception {
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+
+    assertEquals(resultDesc.getMeta().getOption(StorageConstants.TEXT_NULL), "\\\\T");
+
+    Path path = new Path(resultDesc.getUri());
+    FileSystem fs = path.getFileSystem(tajoConf);
+
+    FileStatus[] files = fs.listStatus(path);
+    assertNotNull(files);
+    assertEquals(1, files.length);
+
+    InputStream in = fs.open(files[0].getPath());
+    byte[] buf = new byte[1024];
+
+
+    int readBytes = in.read(buf);
+    assertTrue(readBytes > 0);
+
+    // text type field's value is replaced with \T
+    String expected = "1|1|O\n" +
+        "2|2|O\n" +
+        "3|3|F\n" +
+        "4||\\T\n" +
+        "5||\\T\n";
+
+    String resultDatas = new String(buf, 0, readBytes);
+
+    assertEquals(expected, resultDatas);
+  }
+
+  @Test(timeout = 30000)
+  public void testGetQueryInfoAndHistory() throws Exception {
+    String sql = "select count(*) from lineitem";
+    ClientProtos.SubmitQueryResponse response = client.executeQuery(sql);
+
+    assertNotNull(response);
+    QueryId queryId = new QueryId(response.getQueryId());
+
+    QueryInfoProto queryInfo;
+    while (true) {
+      queryInfo = client.getQueryInfo(queryId);
+
+      if (queryInfo != null && queryInfo.getQueryState() == QueryState.QUERY_SUCCEEDED) {
+        break;
+      }
+      Thread.sleep(100);
+    }
+
+    assertNotNull(queryInfo);
+    assertEquals(queryId.toString(), queryInfo.getQueryId());
+
+    QueryHistoryProto queryHistory = client.getQueryHistory(queryId);
+    assertNotNull(queryHistory);
+    assertEquals(queryId.toString(), queryHistory.getQueryId());
+    assertEquals(2, queryHistory.getStageHistoriesCount());
+
+    List<ClientProtos.StageHistoryProto> taskHistories =
+        new ArrayList<StageHistoryProto>(queryHistory.getStageHistoriesList());
+    Collections.sort(taskHistories, new Comparator<StageHistoryProto>() {
+      @Override
+      public int compare(ClientProtos.StageHistoryProto o1, StageHistoryProto o2) {
+        return o1.getExecutionBlockId().compareTo(o2.getExecutionBlockId());
+      }
+    });
+    assertEquals(5, taskHistories.get(0).getTotalReadRows());
+    assertEquals(1, taskHistories.get(0).getTotalWriteRows());
+    assertEquals(1, taskHistories.get(1).getTotalReadRows());
+    assertEquals(1, taskHistories.get(1).getTotalWriteRows());
+  }
+}