You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/01/28 13:19:42 UTC

git commit: TAJO-560: CTAS PARTITION BY with UNION can cause invalid global plan. (hyunsik)

Updated Branches:
  refs/heads/master 2046c0b62 -> 6aa96fa9b


TAJO-560: CTAS PARTITION BY with UNION can cause invalid global plan. (hyunsik)


Project: http://git-wip-us.apache.org/repos/asf/incubator-tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tajo/commit/6aa96fa9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/6aa96fa9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/6aa96fa9

Branch: refs/heads/master
Commit: 6aa96fa9bc58d002efeae03f775162ccee6545e5
Parents: 2046c0b
Author: Hyunsik Choi <hy...@apache.org>
Authored: Tue Jan 28 21:19:12 2014 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Tue Jan 28 21:19:12 2014 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |   3 +
 .../engine/planner/global/GlobalPlanner.java    | 194 +++++++++++++------
 .../apache/tajo/engine/query/TestCTASQuery.java | 107 +++++-----
 .../tajo/engine/query/TestSelectQuery.java      |  19 +-
 .../queries/TestCTASQuery/CtasWithGroupby.sql   |   2 +
 .../queries/TestCTASQuery/CtasWithLimit.sql     |  13 ++
 .../queries/TestCTASQuery/CtasWithOrderby.sql   |  11 ++
 .../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 +
 .../TestCTASQuery/testCtasWithOrderby.sql       |   1 +
 .../queries/TestCTASQuery/testCtasWithUnion.sql |   1 +
 .../testCtasWithoutTableDefinition.sql          |   2 +
 .../TestSelectQuery/testSelectAsterisk1.sql     |   1 +
 .../TestSelectQuery/testSelectAsterisk2.sql     |   1 +
 .../TestSelectQuery/testSelectAsterisk3.sql     |   1 +
 .../TestCTASQuery/testCtasWithGroupby.result    |   7 +
 .../TestCTASQuery/testCtasWithLimit.result      |   5 +
 .../TestCTASQuery/testCtasWithOrderby.result    |   7 +
 .../TestCTASQuery/testCtasWithUnion.result      |   8 +
 .../TestSelectQuery/testSelectAsterik.result    |   7 -
 .../TestSelectQuery/testSelectAsterisk1.result  |   7 +
 .../TestSelectQuery/testSelectAsterisk2.result  |   3 +
 .../TestSelectQuery/testSelectAsterisk3.result  |   3 +
 27 files changed, 336 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index b606e08..e3f2bff 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -231,6 +231,9 @@ Release 0.8.0 - unreleased
 
   BUG FIXES
 
+    TAJO-560: CTAS PARTITION BY with UNION can cause invalid global plan.
+    (hyunsik)
+
     TAJO-558: HCatalogStore can't scan columns. (jaehwa)
 
     TAJO-556: java.lang.NoSuchFieldError: IS_SECURITY_ENABLED. (jaehwa)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
index 6e44bb8..b9683eb 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
@@ -271,7 +271,34 @@ public class GlobalPlanner {
 
   public boolean hasUnionChild(UnaryNode node) {
 
-    if (node.getChild().getType() == NodeType.TABLE_SUBQUERY) {
+    // there are two cases:
+    //
+    // The first case is:
+    //
+    //  create table [tbname] as select * from ( select ... UNION select ...) T
+    //
+    // We can generalize this case as 'a store operator on the top of union'.
+    // In this case, a store operator determines a shuffle method.
+    //
+    // The second case is:
+    //
+    // select avg(..) from (select ... UNION select ) T
+    //
+    // We can generalize this case as 'a shuffle required operator on the top of union'.
+
+    if (node.getChild() instanceof UnaryNode) { // first case
+      UnaryNode child = node.getChild();
+
+      if (child.getChild().getType() == NodeType.PROJECTION) {
+        child = child.getChild();
+      }
+
+      if (child.getChild().getType() == NodeType.TABLE_SUBQUERY) {
+        TableSubQueryNode tableSubQuery = child.getChild();
+        return tableSubQuery.getSubQuery().getType() == NodeType.UNION;
+      }
+
+    } else if (node.getChild().getType() == NodeType.TABLE_SUBQUERY) { // second case
       TableSubQueryNode tableSubQuery = node.getChild();
       return tableSubQuery.getSubQuery().getType() == NodeType.UNION;
     }
@@ -279,7 +306,7 @@ public class GlobalPlanner {
     return false;
   }
 
-  private static ExecutionBlock buildGroupbyAndUnionPlan(MasterPlan masterPlan, ExecutionBlock lastBlock,
+  private ExecutionBlock buildGroupbyAndUnionPlan(MasterPlan masterPlan, ExecutionBlock lastBlock,
                                                   GroupbyNode firstPhaseGroupBy, GroupbyNode secondPhaseGroupBy) {
     DataChannel lastDataChannel = null;
 
@@ -428,75 +455,130 @@ public class GlobalPlanner {
     return currentBlock;
   }
 
-
+  /**
+   * It builds a distributed execution block for CTAS, InsertNode, and StoreTableNode.
+   */
   private ExecutionBlock buildStorePlan(GlobalPlanContext context,
-                                        ExecutionBlock childBlock,
-                                        StoreTableNode currentNode) 
-    throws PlanningException {
-    PartitionMethodDesc partitionMethod = currentNode.getPartitionMethod();
-
-    // if result table is not a partitioned table, directly store it
-    if(partitionMethod == null) {
-
-      if (childBlock.getPlan() == null) { // when the below is union
-        for (ExecutionBlock grandChildBlock : context.plan.getChilds(childBlock)) {
-          StoreTableNode copy = PlannerUtil.clone(context.plan.getLogicalPlan(), currentNode);
-          copy.setChild(grandChildBlock.getPlan());
-          grandChildBlock.setPlan(copy);
-        }
-        return childBlock;
-      } else {
-        currentNode.setChild(childBlock.getPlan());
-        currentNode.setInSchema(childBlock.getPlan().getOutSchema());
-        childBlock.setPlan(currentNode);
-        return childBlock;
+                                        ExecutionBlock lastBlock,
+                                        StoreTableNode currentNode) throws PlanningException {
+
+
+    if(currentNode.hasPartition()) { // if a target table is a partitioned table
+
+      // Verify supported partition types
+      PartitionMethodDesc partitionMethod = currentNode.getPartitionMethod();
+      if (partitionMethod.getPartitionType() != CatalogProtos.PartitionType.COLUMN) {
+        throw new PlanningException(String.format("Not supported partitionsType :%s",
+            partitionMethod.getPartitionType()));
       }
+
+      if (hasUnionChild(currentNode)) { // if it has union children
+        return buildShuffleAndStorePlanToPartitionedTableWithUnion(context, currentNode, lastBlock);
+      } else { // otherwise
+        return buildShuffleAndStorePlanToPartitionedTable(context, currentNode, lastBlock);
+      }
+    } else { // if result table is not a partitioned table, directly store it
+      return buildNoPartitionedStorePlan(context, currentNode, lastBlock);
     }
+  }
 
-    // if result table is a partitioned table
-    // 1. replace StoreTableNode with its child node,
-    //    old execution block ends at the child node
-    LogicalNode childNode = currentNode.getChild();
-    childBlock.setPlan(childNode);
+  /**
+   * It makes a plan to store directly union plans into a non-partitioned table.
+   */
+  private ExecutionBlock buildShuffleAndStorePlanNoPartitionedTableWithUnion(GlobalPlanContext context,
+                                                                             StoreTableNode currentNode,
+                                                                             ExecutionBlock childBlock) {
+    for (ExecutionBlock grandChildBlock : context.plan.getChilds(childBlock)) {
+      StoreTableNode copy = PlannerUtil.clone(context.plan.getLogicalPlan(), currentNode);
+      copy.setChild(grandChildBlock.getPlan());
+      grandChildBlock.setPlan(copy);
+    }
+    return childBlock;
+  }
 
-    // 2. create a new execution block, pipeline 2 exec blocks through a DataChannel
-    MasterPlan masterPlan = context.plan;
-    ExecutionBlock currentBlock = masterPlan.newExecutionBlock();
-    DataChannel channel;
-    CatalogProtos.PartitionType partitionsType = partitionMethod.getPartitionType();
+  /**
+   * It inserts shuffle and adds store plan on a partitioned table,
+   * and it push downs those plans into child unions.
+   */
+  private ExecutionBlock buildShuffleAndStorePlanToPartitionedTableWithUnion(GlobalPlanContext context,
+                                                                             StoreTableNode currentNode,
+                                                                             ExecutionBlock lastBlock)
+      throws PlanningException {
 
-    if(partitionsType == CatalogProtos.PartitionType.COLUMN) {
-      channel = new DataChannel(childBlock, currentBlock, HASH_SHUFFLE, 32);
-      if (currentNode.getType() == NodeType.INSERT) {
-        InsertNode insertNode = (InsertNode) currentNode;
-        channel.setSchema(((InsertNode)currentNode).getProjectedSchema());
-        Column [] shuffleKeys = new Column[partitionMethod.getExpressionSchema().getColumnNum()];
-        int i = 0;
-        for (Column column : partitionMethod.getExpressionSchema().getColumns()) {
-          int id = insertNode.getTableSchema().getColumnId(column.getQualifiedName());
-          shuffleKeys[i++] = insertNode.getProjectedSchema().getColumn(id);
-        }
-        channel.setShuffleKeys(shuffleKeys);
-      } else {
-        channel.setShuffleKeys(partitionMethod.getExpressionSchema().toArray());
-      }
-      channel.setSchema(childNode.getOutSchema());
+    MasterPlan masterPlan = context.plan;
+    DataChannel lastChannel = null;
+    for (DataChannel channel : masterPlan.getIncomingChannels(lastBlock.getId())) {
+      ExecutionBlock childBlock = masterPlan.getExecBlock(channel.getSrcId());
+      setShuffleKeysFromPartitionedTableStore(currentNode, channel);
+      channel.setSchema(childBlock.getPlan().getOutSchema());
       channel.setStoreType(storeType);
-
-    } else {
-      throw new PlanningException(String.format("Not Supported PartitionsType :%s", partitionsType));
+      lastChannel = channel;
     }
 
-    // 3. create a ScanNode for scanning shuffle data
-    //    StoreTableNode as the root node of the new execution block
+    ScanNode scanNode = buildInputExecutor(masterPlan.getLogicalPlan(), lastChannel);
+    currentNode.setChild(scanNode);
+    currentNode.setInSchema(scanNode.getOutSchema());
+    lastBlock.setPlan(currentNode);
+    return lastBlock;
+  }
+
+  /**
+   * It inserts shuffle and adds store plan on a partitioned table.
+   */
+  private ExecutionBlock buildShuffleAndStorePlanToPartitionedTable(GlobalPlanContext context,
+                                                                    StoreTableNode currentNode,
+                                                                    ExecutionBlock lastBlock)
+      throws PlanningException {
+    MasterPlan masterPlan = context.plan;
+
+    ExecutionBlock nextBlock = masterPlan.newExecutionBlock();
+    DataChannel channel = new DataChannel(lastBlock, nextBlock, HASH_SHUFFLE, 32);
+    setShuffleKeysFromPartitionedTableStore(currentNode, channel);
+    channel.setSchema(lastBlock.getPlan().getOutSchema());
+    channel.setStoreType(storeType);
+
     ScanNode scanNode = buildInputExecutor(masterPlan.getLogicalPlan(), channel);
     currentNode.setChild(scanNode);
     currentNode.setInSchema(scanNode.getOutSchema());
-    currentBlock.setPlan(currentNode);
+    nextBlock.setPlan(currentNode);
 
     masterPlan.addConnect(channel);
 
-    return currentBlock;
+    return nextBlock;
+  }
+
+  private ExecutionBlock buildNoPartitionedStorePlan(GlobalPlanContext context,
+                                                     StoreTableNode currentNode,
+                                                     ExecutionBlock childBlock) {
+    if (hasUnionChild(currentNode)) { // when the below is union
+      return buildShuffleAndStorePlanNoPartitionedTableWithUnion(context, currentNode, childBlock);
+    } else {
+      currentNode.setChild(childBlock.getPlan());
+      currentNode.setInSchema(childBlock.getPlan().getOutSchema());
+      childBlock.setPlan(currentNode);
+      return childBlock;
+    }
+  }
+
+  private void setShuffleKeysFromPartitionedTableStore(StoreTableNode node, DataChannel channel) {
+    Preconditions.checkState(node.hasTargetTable(), "A target table must be a partitioned table.");
+    PartitionMethodDesc partitionMethod = node.getPartitionMethod();
+
+    if (node.getType() == NodeType.INSERT) {
+      InsertNode insertNode = (InsertNode) node;
+      channel.setSchema(((InsertNode)node).getProjectedSchema());
+      Column [] shuffleKeys = new Column[partitionMethod.getExpressionSchema().getColumnNum()];
+      int i = 0;
+      for (Column column : partitionMethod.getExpressionSchema().getColumns()) {
+        int id = insertNode.getTableSchema().getColumnId(column.getQualifiedName());
+        shuffleKeys[i++] = insertNode.getProjectedSchema().getColumn(id);
+      }
+      channel.setShuffleKeys(shuffleKeys);
+    } else {
+      channel.setShuffleKeys(partitionMethod.getExpressionSchema().toArray());
+    }
+    channel.setShuffleType(HASH_SHUFFLE);
+    channel.setShuffleOutputNum(32);
   }
 
   public class DistributedPlannerVisitor extends BasicLogicalPlanVisitor<GlobalPlanContext, LogicalNode> {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
index aacf588..09ab5b7 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
@@ -22,17 +22,15 @@ import com.google.common.collect.Maps;
 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.TajoTestingCluster;
-import org.apache.tajo.TpchTestBase;
 import org.apache.tajo.catalog.CatalogService;
 import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.catalog.partition.PartitionMethodDesc;
 import org.apache.tajo.catalog.proto.CatalogProtos;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import java.io.IOException;
 import java.sql.ResultSet;
 import java.util.Map;
 
@@ -44,36 +42,23 @@ import static org.junit.Assert.assertTrue;
  * Test CREATE TABLE AS SELECT statements
  */
 @Category(IntegrationTest.class)
-public class TestCTASQuery {
-  private static TpchTestBase tpch;
-  public TestCTASQuery() throws IOException {
-    super();
-  }
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    tpch = TpchTestBase.getInstance();
-  }
+public class TestCTASQuery extends QueryTestCaseBase {
 
   @Test
   public final void testCtasWithoutTableDefinition() throws Exception {
-    String tableName ="testCtasWithoutTableDefinition";
-    tpch.execute(
-        "create table " + tableName
-            + " partition by column(key float8) "
-            + " as select l_orderkey as col1, l_partkey as col2, l_quantity as key from lineitem");
+    ResultSet res = executeQuery();
 
-    TajoTestingCluster cluster = tpch.getTestingCluster();
-    CatalogService catalog = cluster.getMaster().getCatalog();
-    TableDesc desc = catalog.getTableDesc(tableName);
-    assertTrue(catalog.existsTable(tableName));
+    res.close();
+    CatalogService catalog = testingCluster.getTestingCluster().getMaster().getCatalog();
+    TableDesc desc = catalog.getTableDesc("testCtasWithoutTableDefinition");
+    assertTrue(catalog.existsTable("testCtasWithoutTableDefinition"));
 
     assertTrue(desc.getSchema().contains("testCtasWithoutTableDefinition.col1"));
     PartitionMethodDesc partitionDesc = desc.getPartitionMethod();
     assertEquals(partitionDesc.getPartitionType(), CatalogProtos.PartitionType.COLUMN);
     assertEquals("key", partitionDesc.getExpressionSchema().getColumns().get(0).getColumnName());
 
-    FileSystem fs = FileSystem.get(tpch.getTestingCluster().getConfiguration());
+    FileSystem fs = FileSystem.get(testingCluster.getTestingCluster().getConfiguration());
     Path path = desc.getPath();
     assertTrue(fs.isDirectory(path));
     assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=17.0")));
@@ -83,40 +68,36 @@ public class TestCTASQuery {
     assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=49.0")));
     assertEquals(5, desc.getStats().getNumRows().intValue());
 
-    ResultSet res = tpch.execute(
-        "select distinct * from " + tableName + " where (key = 45.0 or key = 38.0)");
+    ResultSet res2 = executeQuery("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(res.next()) {
-      assertEquals(resultRows1.get(res.getDouble(3))[0], res.getInt(1));
-      assertEquals(resultRows1.get(res.getDouble(3))[1], res.getInt(2));
+    while(res2.next()) {
+      assertEquals(resultRows1.get(res2.getDouble(3))[0], res2.getInt(1));
+      assertEquals(resultRows1.get(res2.getDouble(3))[1], res2.getInt(2));
       i++;
     }
-    res.close();
+    res2.close();
     assertEquals(2, i);
   }
 
   @Test
   public final void testCtasWithColumnedPartition() throws Exception {
-    String tableName ="testCtasWithColumnedPartition";
-    tpch.execute(
-        "create table " + tableName
-            + " (col1 int4, col2 int4) partition by column(key float8) "
-            + " as select l_orderkey as col1, l_partkey as col2, l_quantity as key from lineitem");
+    ResultSet res = executeQuery();
+    res.close();
 
-    TajoTestingCluster cluster = tpch.getTestingCluster();
+    TajoTestingCluster cluster = testingCluster.getTestingCluster();
     CatalogService catalog = cluster.getMaster().getCatalog();
-    TableDesc desc = catalog.getTableDesc(tableName);
-    assertTrue(catalog.existsTable(tableName));
+    TableDesc desc = catalog.getTableDesc("testCtasWithColumnedPartition");
+    assertTrue(catalog.existsTable("testCtasWithColumnedPartition"));
     PartitionMethodDesc partitionDesc = desc.getPartitionMethod();
     assertEquals(partitionDesc.getPartitionType(), CatalogProtos.PartitionType.COLUMN);
     assertEquals("key", partitionDesc.getExpressionSchema().getColumns().get(0).getColumnName());
 
-    FileSystem fs = FileSystem.get(tpch.getTestingCluster().getConfiguration());
+    FileSystem fs = FileSystem.get(cluster.getConfiguration());
     Path path = desc.getPath();
     assertTrue(fs.isDirectory(path));
     assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=17.0")));
@@ -126,21 +107,59 @@ public class TestCTASQuery {
     assertTrue(fs.isDirectory(new Path(path.toUri() + "/key=49.0")));
     assertEquals(5, desc.getStats().getNumRows().intValue());
 
-    ResultSet res = tpch.execute(
-        "select distinct * from " + tableName + " where (key = 45.0 or key = 38.0)");
+    ResultSet res2 = executeQuery("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(res.next()) {
-      assertEquals(resultRows1.get(res.getDouble(3))[0], res.getInt(1));
-      assertEquals(resultRows1.get(res.getDouble(3))[1], res.getInt(2));
+    while(res2.next()) {
+      assertEquals(resultRows1.get(res2.getDouble(3))[0], res2.getInt(1));
+      assertEquals(resultRows1.get(res2.getDouble(3))[1], res2.getInt(2));
       i++;
     }
-    res.close();
+    res2.close();
     assertEquals(2, i);
   }
 
+  @Test
+  public final void testCtasWithGroupby() throws Exception {
+    ResultSet res = executeQuery("CtasWithGroupby.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    assertResultSet(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithOrderby() throws Exception {
+    ResultSet res = executeQuery("CtasWithOrderby.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    assertResultSet(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithLimit() throws Exception {
+    ResultSet res = executeQuery("CtasWithLimit.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    assertResultSet(res2);
+    res2.close();
+  }
+
+  @Test
+  public final void testCtasWithUnion() throws Exception {
+    ResultSet res = executeQuery("CtasWithUnion.sql");
+    res.close();
+
+    ResultSet res2 = executeQuery();
+    resultSetToString(res2);
+    res2.close();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
index a17a9f5..1e021b3 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
@@ -88,7 +88,24 @@ public class TestSelectQuery extends QueryTestCaseBase {
   }
 
   @Test
-  public final void testSelectAsterik() throws Exception {
+  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);

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql
new file mode 100644
index 0000000..7c3895e
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithGroupby.sql
@@ -0,0 +1,2 @@
+create table testCtasWithGroupby (col1 int4, col2 int4) 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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql
new file mode 100644
index 0000000..9c99a66
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithLimit.sql
@@ -0,0 +1,13 @@
+create table testCtasWithLimit (col1 int4, col2 int4) 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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql
new file mode 100644
index 0000000..e9ab88d
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithOrderby.sql
@@ -0,0 +1,11 @@
+create table testCtasWithOrderby (col1 int4, col2 int4) 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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql
new file mode 100644
index 0000000..c9d6888
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/CtasWithUnion.sql
@@ -0,0 +1,35 @@
+create table testCtasWithUnion (col1 int4, col2 int4) 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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/check1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/check1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/check1.sql
new file mode 100644
index 0000000..3fb90bb
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/check2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/check2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/check2.sql
new file mode 100644
index 0000000..1b354b7
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql
new file mode 100644
index 0000000..d5f89d6
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithColumnedPartition.sql
@@ -0,0 +1,2 @@
+create table testCtasWithColumnedPartition (col1 int4, col2 int4) 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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithGroupby.sql
new file mode 100644
index 0000000..bf16e63
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithLimit.sql
new file mode 100644
index 0000000..fa0fbd7
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithOrderby.sql
new file mode 100644
index 0000000..7013b39
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithUnion.sql
new file mode 100644
index 0000000..933e18a
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestCTASQuery/testCtasWithoutTableDefinition.sql
new file mode 100644
index 0000000..e30f261
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk1.sql
new file mode 100644
index 0000000..cda515b
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk2.sql
new file mode 100644
index 0000000..71da1f1
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestSelectQuery/testSelectAsterisk3.sql
new file mode 100644
index 0000000..4d75b08
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result
new file mode 100644
index 0000000..fe96e14
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithGroupby.result
@@ -0,0 +1,7 @@
+col1,col2,key
+-------------------------------
+1,0,17.0
+1,0,36.0
+2,0,38.0
+3,0,45.0
+3,0,49.0
\ No newline at end of file

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

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result
new file mode 100644
index 0000000..fe96e14
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithOrderby.result
@@ -0,0 +1,7 @@
+col1,col2,key
+-------------------------------
+1,0,17.0
+1,0,36.0
+2,0,38.0
+3,0,45.0
+3,0,49.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestCTASQuery/testCtasWithUnion.result
new file mode 100644
index 0000000..a6f9853
--- /dev/null
+++ b/tajo-core/tajo-core-backend/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/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterik.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterik.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterik.result
deleted file mode 100644
index ec6b911..0000000
--- a/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterik.result
+++ /dev/null
@@ -1,7 +0,0 @@
-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 
-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
-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,3,6540,2,49.0,46796.47,0.1,0.0,R,F,1993-11-09,1993-12-20,1993-11-24,TAKE BACK RETURN,RAIL, unusual accounts. eve
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk1.result
new file mode 100644
index 0000000..ec6b911
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk1.result
@@ -0,0 +1,7 @@
+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 
+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
+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,3,6540,2,49.0,46796.47,0.1,0.0,R,F,1993-11-09,1993-12-20,1993-11-24,TAKE BACK RETURN,RAIL, unusual accounts. eve
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk2.result
new file mode 100644
index 0000000..2513bc1
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk2.result
@@ -0,0 +1,3 @@
+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
+-------------------------------
+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
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/6aa96fa9/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk3.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk3.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk3.result
new file mode 100644
index 0000000..2513bc1
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestSelectQuery/testSelectAsterisk3.result
@@ -0,0 +1,3 @@
+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
+-------------------------------
+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
\ No newline at end of file