use of com.facebook.presto.sql.planner.optimizations.joins.JoinGraph in project presto by prestodb.
the class TestEliminateCrossJoins method testDoNotReorderCrossJoins.
@Test
public void testDoNotReorderCrossJoins() {
PlanNode plan = join(join(values(symbol("a")), values(symbol("b"))), values(symbol("c")), symbol("c"), symbol("b"));
JoinGraph joinGraph = getOnlyElement(JoinGraph.buildFrom(plan));
assertEquals(EliminateCrossJoins.getJoinOrder(joinGraph), ImmutableList.of(0, 1, 2));
}
use of com.facebook.presto.sql.planner.optimizations.joins.JoinGraph in project presto by prestodb.
the class TestEliminateCrossJoins method testDonNotChangeOrderWithoutCrossJoin.
@Test
public void testDonNotChangeOrderWithoutCrossJoin() {
PlanNode plan = join(join(values(symbol("a")), values(symbol("b")), symbol("a"), symbol("b")), values(symbol("c")), symbol("c"), symbol("b"));
JoinGraph joinGraph = getOnlyElement(JoinGraph.buildFrom(plan));
assertEquals(EliminateCrossJoins.getJoinOrder(joinGraph), ImmutableList.of(0, 1, 2));
}
use of com.facebook.presto.sql.planner.optimizations.joins.JoinGraph in project presto by prestodb.
the class EliminateCrossJoins method getJoinOrder.
/**
* Given JoinGraph determine the order of joins between graph nodes
* by traversing JoinGraph. Any graph traversal algorithm could be used
* here (like BFS or DFS), but we use PriorityQueue to preserve
* original JoinOrder as mush as it is possible. PriorityQueue returns
* next nodes to join in order of their occurrence in original Plan.
*/
public static List<Integer> getJoinOrder(JoinGraph graph) {
ImmutableList.Builder<PlanNode> joinOrder = ImmutableList.builder();
Map<PlanNodeId, Integer> priorities = new HashMap<>();
for (int i = 0; i < graph.size(); i++) {
priorities.put(graph.getNode(i).getId(), i);
}
PriorityQueue<PlanNode> nodesToVisit = new PriorityQueue<>(graph.size(), (Comparator<PlanNode>) (node1, node2) -> priorities.get(node1.getId()).compareTo(priorities.get(node2.getId())));
Set<PlanNode> visited = new HashSet<>();
nodesToVisit.add(graph.getNode(0));
while (!nodesToVisit.isEmpty()) {
PlanNode node = nodesToVisit.poll();
if (!visited.contains(node)) {
visited.add(node);
joinOrder.add(node);
for (JoinGraph.Edge edge : graph.getEdges(node)) {
nodesToVisit.add(edge.getTargetNode());
}
}
if (nodesToVisit.isEmpty() && visited.size() < graph.size()) {
// disconnected graph, find new starting point
Optional<PlanNode> firstNotVisitedNode = graph.getNodes().stream().filter(graphNode -> !visited.contains(graphNode)).findFirst();
if (firstNotVisitedNode.isPresent()) {
nodesToVisit.add(firstNotVisitedNode.get());
}
}
}
checkState(visited.size() == graph.size());
return joinOrder.build().stream().map(node -> priorities.get(node.getId())).collect(toImmutableList());
}
use of com.facebook.presto.sql.planner.optimizations.joins.JoinGraph in project presto by prestodb.
the class EliminateCrossJoins method optimize.
@Override
public PlanNode optimize(PlanNode plan, Session session, Map<Symbol, Type> types, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator) {
if (!SystemSessionProperties.isJoinReorderingEnabled(session)) {
return plan;
}
List<JoinGraph> joinGraphs = JoinGraph.buildFrom(plan);
for (int i = joinGraphs.size() - 1; i >= 0; i--) {
JoinGraph graph = joinGraphs.get(i);
List<Integer> joinOrder = getJoinOrder(graph);
if (isOriginalOrder(joinOrder)) {
continue;
}
plan = rewriteWith(new Rewriter(idAllocator, graph, joinOrder), plan);
}
return plan;
}
use of com.facebook.presto.sql.planner.optimizations.joins.JoinGraph in project presto by prestodb.
the class TestEliminateCrossJoins method testJoinOrder.
@Test
public void testJoinOrder() {
PlanNode plan = join(join(values(symbol("a")), values(symbol("b"))), values(symbol("c")), symbol("a"), symbol("c"), symbol("c"), symbol("b"));
JoinGraph joinGraph = getOnlyElement(JoinGraph.buildFrom(plan));
assertEquals(EliminateCrossJoins.getJoinOrder(joinGraph), ImmutableList.of(0, 2, 1));
}
Aggregations