private List<JoinEnumerationResult> getPossibleJoinNodes(JoinNode joinNode, DistributionType distributionType) { return ImmutableList.of( createJoinEnumerationResult(joinNode.withDistributionType(distributionType)), createJoinEnumerationResult(joinNode.flipChildren().withDistributionType(distributionType))); }
private PlanNode getCostBasedJoin(JoinNode joinNode, Context context) { List<PlanNodeWithCost> possibleJoinNodes = new ArrayList<>(); addJoinsWithDifferentDistributions(joinNode, possibleJoinNodes, context); addJoinsWithDifferentDistributions(joinNode.flipChildren(), possibleJoinNodes, context); if (possibleJoinNodes.stream().anyMatch(result -> result.getCost().hasUnknownComponents()) || possibleJoinNodes.isEmpty()) { return getSyntacticOrderJoin(joinNode, context, AUTOMATIC); } // Using Ordering to facilitate rule determinism Ordering<PlanNodeWithCost> planNodeOrderings = costComparator.forSession(context.getSession()).onResultOf(PlanNodeWithCost::getCost); return planNodeOrderings.min(possibleJoinNodes).getPlanNode(); }
private JoinEnumerationResult setJoinNodeProperties(JoinNode joinNode) { // TODO avoid stat (but not cost) recalculation for all considered (distribution,flip) pairs, since resulting relation is the same in all case if (isAtMostScalar(joinNode.getRight(), lookup)) { return createJoinEnumerationResult(joinNode.withDistributionType(REPLICATED)); } if (isAtMostScalar(joinNode.getLeft(), lookup)) { return createJoinEnumerationResult(joinNode.flipChildren().withDistributionType(REPLICATED)); } List<JoinEnumerationResult> possibleJoinNodes = getPossibleJoinNodes(joinNode, getJoinDistributionType(session)); verify(!possibleJoinNodes.isEmpty(), "possibleJoinNodes is empty"); if (possibleJoinNodes.stream().anyMatch(UNKNOWN_COST_RESULT::equals)) { return UNKNOWN_COST_RESULT; } return resultComparator.min(possibleJoinNodes); }