/** * 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; import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME; 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); } catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse"); catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME); // 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( CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, tables[i]), tpch.getSchema(tables[i]), m, CommonTestingUtil.getTestDir()); d.setStats(stats); catalog.createTable(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(LocalTajoTestingUtility.createDummySession(), 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"))); } }