| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.tajo.master; |
| |
| import org.apache.tajo.LocalTajoTestingUtility; |
| import org.apache.tajo.TajoTestingCluster; |
| import org.apache.tajo.algebra.Expr; |
| import org.apache.tajo.benchmark.TPCH; |
| import org.apache.tajo.catalog.*; |
| import org.apache.tajo.catalog.proto.CatalogProtos; |
| import org.apache.tajo.catalog.statistics.TableStats; |
| import org.apache.tajo.engine.parser.SQLAnalyzer; |
| import org.apache.tajo.engine.planner.LogicalOptimizer; |
| import org.apache.tajo.engine.planner.LogicalPlan; |
| import org.apache.tajo.engine.planner.LogicalPlanner; |
| import org.apache.tajo.engine.planner.PlanningException; |
| import org.apache.tajo.engine.planner.global.GlobalPlanner; |
| import org.apache.tajo.engine.planner.global.MasterPlan; |
| import org.apache.tajo.engine.query.QueryContext; |
| import org.apache.tajo.util.CommonTestingUtil; |
| import org.apache.tajo.util.FileUtil; |
| import org.junit.AfterClass; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import java.io.File; |
| import java.io.IOException; |
| |
| public class TestGlobalPlanner { |
| |
| private static TajoTestingCluster util; |
| private static CatalogService catalog; |
| private static SQLAnalyzer sqlAnalyzer; |
| private static LogicalPlanner planner; |
| private static LogicalOptimizer optimizer; |
| private static TPCH tpch; |
| private static GlobalPlanner globalPlanner; |
| |
| @BeforeClass |
| public static void setUp() throws Exception { |
| util = new TajoTestingCluster(); |
| util.startCatalogCluster(); |
| catalog = util.getMiniCatalogCluster().getCatalog(); |
| for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) { |
| catalog.createFunction(funcDesc); |
| } |
| |
| // TPC-H Schema for Complex Queries |
| String [] tables = { |
| "part", "supplier", "partsupp", "nation", "region", "lineitem", "orders", "customer" |
| }; |
| int [] volumes = { |
| 100, 200, 50, 5, 5, 800, 300, 100 |
| }; |
| tpch = new TPCH(); |
| tpch.loadSchemas(); |
| tpch.loadOutSchema(); |
| for (int i = 0; i < tables.length; i++) { |
| TableMeta m = CatalogUtil.newTableMeta(CatalogProtos.StoreType.CSV); |
| TableStats stats = new TableStats(); |
| stats.setNumBytes(volumes[i]); |
| TableDesc d = CatalogUtil.newTableDesc(tables[i], tpch.getSchema(tables[i]), m, CommonTestingUtil.getTestDir()); |
| d.setStats(stats); |
| catalog.addTable(d); |
| } |
| |
| sqlAnalyzer = new SQLAnalyzer(); |
| planner = new LogicalPlanner(catalog); |
| optimizer = new LogicalOptimizer(util.getConfiguration()); |
| globalPlanner = new GlobalPlanner(util.getConfiguration(), catalog); |
| } |
| |
| @AfterClass |
| public static void tearDown() { |
| util.shutdownCatalogCluster(); |
| } |
| |
| private MasterPlan buildPlan(String sql) throws PlanningException, IOException { |
| Expr expr = sqlAnalyzer.parse(sql); |
| LogicalPlan plan = planner.createPlan(expr); |
| optimizer.optimize(plan); |
| QueryContext context = new QueryContext(); |
| MasterPlan masterPlan = new MasterPlan(LocalTajoTestingUtility.newQueryId(), context, plan); |
| globalPlanner.build(masterPlan); |
| return masterPlan; |
| } |
| |
| @Test |
| public void testSelectDistinct() throws Exception { |
| buildPlan("select distinct l_orderkey from lineitem"); |
| } |
| |
| @Test |
| public void testSortAfterGroupBy() throws Exception { |
| buildPlan("select max(l_quantity) as max_quantity, l_orderkey from lineitem group by l_orderkey order by max_quantity"); |
| } |
| |
| @Test |
| public void testSortLimit() throws Exception { |
| buildPlan("select max(l_quantity) as max_quantity, l_orderkey from lineitem group by l_orderkey order by max_quantity limit 3"); |
| } |
| |
| @Test |
| public void testJoin() throws Exception { |
| buildPlan("select n_name, r_name, n_regionkey, r_regionkey from nation, region"); |
| } |
| |
| @Test |
| public void testUnion() throws IOException, PlanningException { |
| buildPlan("select o_custkey as num from orders union select c_custkey as num from customer union select p_partkey as num from part"); |
| } |
| |
| @Test |
| public void testSubQuery() throws IOException, PlanningException { |
| buildPlan("select l.l_orderkey from (select * from lineitem) l"); |
| } |
| |
| @Test |
| public void testSubQueryJoin() throws IOException, PlanningException { |
| buildPlan("select l.l_orderkey from (select * from lineitem) l join (select * from orders) o on l.l_orderkey = o.o_orderkey"); |
| } |
| |
| @Test |
| public void testSubQueryGroupBy() throws IOException, PlanningException { |
| buildPlan("select sum(l_extendedprice*l_discount) as revenue from (select * from lineitem) as l"); |
| } |
| |
| @Test |
| public void testSubQueryGroupBy2() throws IOException, PlanningException { |
| buildPlan("select l_orderkey, sum(l_extendedprice*l_discount) as revenue from (select * from lineitem) as l group by l_orderkey"); |
| } |
| |
| @Test |
| public void testSubQuerySortAfterGroup() throws IOException, PlanningException { |
| buildPlan("select l_orderkey, sum(l_extendedprice*l_discount) as revenue from (select * from lineitem) as l group by l_orderkey order by l_orderkey"); |
| } |
| |
| @Test |
| public void testSubQuerySortAfterGroupMultiBlocks() throws IOException, PlanningException { |
| buildPlan( |
| "select l_orderkey, revenue from (" + |
| "select l_orderkey, sum(l_extendedprice*l_discount) as revenue from lineitem group by l_orderkey" |
| +") l1" |
| |
| ); |
| } |
| |
| @Test |
| public void testSubQuerySortAfterGroupMultiBlocks2() throws IOException, PlanningException { |
| buildPlan( |
| "select l_orderkey, revenue from (" + |
| "select l_orderkey, revenue from (" + |
| "select l_orderkey, sum(l_extendedprice*l_discount) as revenue from lineitem group by l_orderkey" |
| +") l1" + |
| ") l2 order by l_orderkey" |
| |
| ); |
| } |
| |
| @Test |
| public void testComplexUnion1() throws Exception { |
| buildPlan(FileUtil.readTextFile(new File("src/test/resources/queries/default/complex_union_1.sql"))); |
| } |
| |
| @Test |
| public void testComplexUnion2() throws Exception { |
| buildPlan(FileUtil.readTextFile(new File("src/test/resources/queries/default/complex_union_2.sql"))); |
| } |
| |
| @Test |
| public void testUnionGroupBy1() throws Exception { |
| buildPlan("select l_orderkey, sum(l_extendedprice*l_discount) as revenue from (" + |
| "select * from lineitem " + |
| "union " + |
| "select * from lineitem ) l group by l_orderkey"); |
| } |
| |
| @Test |
| public void testTPCH_Q5() throws Exception { |
| buildPlan(FileUtil.readTextFile(new File("benchmark/tpch/q5.sql"))); |
| } |
| } |