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