/*
* Licensed 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 com.facebook.presto.sql.planner.optimizations;
import com.facebook.presto.SystemSessionProperties;
import com.facebook.presto.sql.planner.assertions.BasePlanTest;
import com.facebook.presto.sql.planner.assertions.PlanMatchPattern;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.testng.annotations.Test;
import java.util.Optional;
import static com.facebook.presto.sql.planner.assertions.PlanMatchPattern.anyTree;
import static com.facebook.presto.sql.planner.assertions.PlanMatchPattern.equiJoinClause;
import static com.facebook.presto.sql.planner.assertions.PlanMatchPattern.filter;
import static com.facebook.presto.sql.planner.assertions.PlanMatchPattern.join;
import static com.facebook.presto.sql.planner.assertions.PlanMatchPattern.tableScan;
import static com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER;
public class TestReorderJoins
extends BasePlanTest
{
private static final PlanMatchPattern ORDERS_TABLESCAN = tableScan("orders", ImmutableMap.of("O_ORDERKEY", "orderkey"));
private static final PlanMatchPattern ORDERS_WITH_SHIPPRIORITY_TABLESCAN = tableScan(
"orders",
ImmutableMap.of("O_ORDERKEY", "orderkey", "O_SHIPPRIORITY", "shippriority"));
private static final PlanMatchPattern SUPPLIER_TABLESCAN = tableScan("supplier", ImmutableMap.of("S_SUPPKEY", "suppkey"));
private static final PlanMatchPattern PART_TABLESCAN = tableScan("part", ImmutableMap.of("P_PARTKEY", "partkey"));
private static final PlanMatchPattern PART_WITH_NAME_TABLESCAN = tableScan("part", ImmutableMap.of("P_PARTKEY", "partkey", "P_NAME", "name"));
private static final PlanMatchPattern LINEITEM_TABLESCAN = tableScan(
"lineitem",
ImmutableMap.of(
"L_PARTKEY", "partkey",
"L_ORDERKEY", "orderkey"));
private static final PlanMatchPattern LINEITEM_WITH_RETURNFLAG_TABLESCAN = tableScan(
"lineitem",
ImmutableMap.of(
"L_PARTKEY", "partkey",
"L_ORDERKEY", "orderkey",
"L_RETURNFLAG", "returnflag"));
private static final PlanMatchPattern LINEITEM_WITH_COMMENT_TABLESCAN = tableScan(
"lineitem",
ImmutableMap.of(
"L_PARTKEY", "partkey",
"L_ORDERKEY", "orderkey",
"L_COMMENT", "comment"));
public TestReorderJoins()
{
super(ImmutableMap.of(SystemSessionProperties.REORDER_JOINS, "true"));
}
@Test
public void testEliminateSimpleCrossJoin()
{
assertPlan("SELECT * FROM part p, orders o, lineitem l WHERE p.partkey = l.partkey AND l.orderkey = o.orderkey",
anyTree(
join(INNER, ImmutableList.of(equiJoinClause("L_ORDERKEY", "O_ORDERKEY")),
anyTree(
join(INNER, ImmutableList.of(equiJoinClause("P_PARTKEY", "L_PARTKEY")),
anyTree(PART_TABLESCAN),
anyTree(LINEITEM_TABLESCAN))),
anyTree(ORDERS_TABLESCAN))));
}
@Test
public void testGiveUpOnCrossJoin()
{
assertPlan("SELECT o.orderkey FROM part p, orders o, lineitem l WHERE l.orderkey = o.orderkey",
anyTree(
join(INNER, ImmutableList.of(equiJoinClause("O_ORDERKEY", "L_ORDERKEY")),
anyTree(
join(INNER, ImmutableList.of(),
tableScan("part"),
anyTree(tableScan("orders", ImmutableMap.of("O_ORDERKEY", "orderkey"))))),
anyTree(tableScan("lineitem", ImmutableMap.of("L_ORDERKEY", "orderkey"))))));
}
@Test
public void testEliminateCrossJoinWithNonEqualityCondition()
{
assertPlan("SELECT o.orderkey FROM part p, orders o, lineitem l " +
"WHERE p.partkey = l.partkey AND l.orderkey = o.orderkey AND p.partkey <> o.orderkey AND p.name < l.comment",
anyTree(
join(INNER, ImmutableList.of(equiJoinClause("L_ORDERKEY", "O_ORDERKEY")),
anyTree(
join(INNER, ImmutableList.of(equiJoinClause("P_PARTKEY", "L_PARTKEY")), Optional.of("P_NAME < cast(L_COMMENT AS varchar(55))"),
anyTree(PART_WITH_NAME_TABLESCAN),
anyTree(filter("L_PARTKEY <> L_ORDERKEY", LINEITEM_WITH_COMMENT_TABLESCAN)))),
anyTree(ORDERS_TABLESCAN))));
}
@Test
public void testEliminateCrossJoinPreserveFilters()
{
assertPlan("SELECT o.orderkey FROM part p, orders o, lineitem l " +
"WHERE p.partkey = l.partkey AND l.orderkey = o.orderkey AND l.returnflag = 'R' AND shippriority >= 10",
anyTree(join(INNER, ImmutableList.of(equiJoinClause("L_ORDERKEY", "O_ORDERKEY")),
anyTree(
join(INNER, ImmutableList.of(equiJoinClause("P_PARTKEY", "L_PARTKEY")),
anyTree(PART_TABLESCAN),
anyTree(filter("L_RETURNFLAG = 'R'", LINEITEM_WITH_RETURNFLAG_TABLESCAN)))),
anyTree(filter("O_SHIPPRIORITY >= 10", ORDERS_WITH_SHIPPRIORITY_TABLESCAN)))));
}
}