// finding relations and filter expressions
JoinGraphContext joinGraphContext = JoinGraphBuilder.buildJoinGraph(plan, block);
// finding join order and restore remain filter order
FoundJoinOrder order = joinOrderAlgorithm.findBestOrder(plan, block,
joinGraphContext.joinGraph, joinGraphContext.relationsForProduct);
JoinNode newJoinNode = order.getOrderedJoin();
JoinNode old = PlannerUtil.findTopNode(block.getRoot(), NodeType.JOIN);
JoinTargetCollector collector = new JoinTargetCollector();
Set<Target> targets = new LinkedHashSet<Target>();
collector.visitJoin(targets, plan, block, old, new Stack<LogicalNode>());
if (targets.size() == 0) {
newJoinNode.setTargets(PlannerUtil.schemaToTargets(old.getOutSchema()));
} else {
newJoinNode.setTargets(targets.toArray(new Target[targets.size()]));
}
PlannerUtil.replaceNode(plan, block.getRoot(), old, newJoinNode);
String optimizedOrder = JoinOrderStringBuilder.buildJoinOrderString(plan, block);
block.addPlanHistory("Non-optimized join order: " + originalOrder + " (cost: " + nonOptimizedJoinCost + ")");
block.addPlanHistory("Optimized join order : " + optimizedOrder + " (cost: " + order.getCost() + ")");
}
}