Extract EliminateCrossJoins optimizer replacement logic to a method
@@ -41,6 +41,7 @@ import java.util.PriorityQueue;
import java.util.Set;
import static com.facebook.presto.sql.planner.plan.SimplePlanRewriter.rewriteWith;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Objects.requireNonNull;
@@ -135,27 +136,13 @@ public class EliminateCrossJoins
.collect(toImmutableList());
}
- private class Rewriter
- extends SimplePlanRewriter<PlanNode>
- {
- private final PlanNodeIdAllocator idAllocator;
- private final JoinGraph graph;
- private final List<Integer> joinOrder;
-
- public Rewriter(PlanNodeIdAllocator idAllocator, JoinGraph graph, List<Integer> joinOrder)
- {
- this.idAllocator = requireNonNull(idAllocator, "idAllocator is null");
- this.graph = requireNonNull(graph, "graph is null");
- this.joinOrder = ImmutableList.copyOf(requireNonNull(joinOrder, "joinOrder is null"));
- checkState(joinOrder.size() >= 2);
- }
-
- @Override
- public PlanNode visitPlan(PlanNode node, RewriteContext<PlanNode> context)
+ public static PlanNode buildJoinTree(List<Symbol> expectedOutputSymbols, JoinGraph graph, List<Integer> joinOrder, PlanNodeIdAllocator idAllocator)
{
- if (!Objects.equals(node.getId(), graph.getRootId())) {
- return context.defaultRewrite(node, context.get());
- }
+ requireNonNull(expectedOutputSymbols, "expectedOutputSymbols is null");
+ requireNonNull(idAllocator, "idAllocator is null");
+ requireNonNull(graph, "graph is null");
+ joinOrder = ImmutableList.copyOf(requireNonNull(joinOrder, "joinOrder is null"));
+ checkArgument(joinOrder.size() >= 2);
PlanNode result = graph.getNode(joinOrder.get(0));
Set<PlanNodeId> alreadyJoinedNodes = new HashSet<>();
@@ -208,16 +195,41 @@ public class EliminateCrossJoins
Assignments.copyOf(graph.getAssignments().get()));
}
- if (!result.getOutputSymbols().equals(node.getOutputSymbols())) {
+ if (!result.getOutputSymbols().equals(expectedOutputSymbols)) {
// Introduce a projection to constrain the outputs to what was originally expected
// Some nodes are sensitive to what's produced (e.g., DistinctLimit node)
result = new ProjectNode(
idAllocator.getNextId(),
result,
- Assignments.identity(node.getOutputSymbols()));
+ Assignments.identity(expectedOutputSymbols));
}
return result;
}
+
+ private class Rewriter
+ extends SimplePlanRewriter<PlanNode>
+ {
+ private final PlanNodeIdAllocator idAllocator;
+ private final JoinGraph graph;
+ private final List<Integer> joinOrder;
+
+ public Rewriter(PlanNodeIdAllocator idAllocator, JoinGraph graph, List<Integer> joinOrder)
+ {
+ this.idAllocator = requireNonNull(idAllocator, "idAllocator is null");
+ this.graph = requireNonNull(graph, "graph is null");
+ this.joinOrder = ImmutableList.copyOf(requireNonNull(joinOrder, "joinOrder is null"));
+ checkState(joinOrder.size() >= 2);
+ }
+
+ @Override
+ public PlanNode visitPlan(PlanNode node, RewriteContext<PlanNode> context)
+ {
+ if (!Objects.equals(node.getId(), graph.getRootId())) {
+ return context.defaultRewrite(node, context.get());
+ }
+
+ return buildJoinTree(node.getOutputSymbols(), graph, joinOrder, idAllocator);
+ }
}
}
