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:30:21 UTC

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

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));
+  }
+}