@Override public Map<PlanNodeId, SplitSource> visitSpatialJoin(SpatialJoinNode node, Void context) { Map<PlanNodeId, SplitSource> leftSplits = node.getLeft().accept(this, context); Map<PlanNodeId, SplitSource> rightSplits = node.getRight().accept(this, context); return ImmutableMap.<PlanNodeId, SplitSource>builder() .putAll(leftSplits) .putAll(rightSplits) .build(); }
@Override public PlanNode visitSpatialJoin(SpatialJoinNode node, RewriteContext<Set<Symbol>> context) { Set<Symbol> requiredInputs = ImmutableSet.<Symbol>builder() .addAll(SymbolsExtractor.extractUnique(node.getFilter())) .addAll(context.get()) .build(); ImmutableSet.Builder<Symbol> leftInputs = ImmutableSet.builder(); node.getLeftPartitionSymbol().map(leftInputs::add); ImmutableSet.Builder<Symbol> rightInputs = ImmutableSet.builder(); node.getRightPartitionSymbol().map(rightInputs::add); PlanNode left = context.rewrite(node.getLeft(), leftInputs.addAll(requiredInputs).build()); PlanNode right = context.rewrite(node.getRight(), rightInputs.addAll(requiredInputs).build()); List<Symbol> outputSymbols = node.getOutputSymbols().stream() .filter(context.get()::contains) .distinct() .collect(toImmutableList()); return new SpatialJoinNode(node.getId(), node.getType(), left, right, outputSymbols, node.getFilter(), node.getLeftPartitionSymbol(), node.getRightPartitionSymbol(), node.getKdbTree()); }
@Override public PlanNode visitSpatialJoin(SpatialJoinNode node, RewriteContext<Void> context) { PlanNode left = context.rewrite(node.getLeft()); PlanNode right = context.rewrite(node.getRight()); return new SpatialJoinNode(node.getId(), node.getType(), left, right, canonicalizeAndDistinct(node.getOutputSymbols()), canonicalize(node.getFilter()), canonicalize(node.getLeftPartitionSymbol()), canonicalize(node.getRightPartitionSymbol()), node.getKdbTree()); }
@Override public Set<PlanFragmentId> visitSpatialJoin(SpatialJoinNode node, PlanFragmentId currentFragmentId) { return processJoin(node.getRight(), node.getLeft(), currentFragmentId); }
node = new SpatialJoinNode(node.getId(), SpatialJoinNode.Type.INNER, node.getLeft(), node.getRight(), node.getOutputSymbols(), node.getFilter(), node.getLeftPartitionSymbol(), node.getRightPartitionSymbol(), node.getKdbTree()); Expression leftEffectivePredicate = effectivePredicateExtractor.extract(node.getLeft()); Expression rightEffectivePredicate = effectivePredicateExtractor.extract(node.getRight()); Expression joinPredicate = node.getFilter(); rightEffectivePredicate, joinPredicate, node.getLeft().getOutputSymbols()); leftPredicate = innerJoinPushDownResult.getLeftPredicate(); rightPredicate = innerJoinPushDownResult.getRightPredicate(); rightEffectivePredicate, joinPredicate, node.getLeft().getOutputSymbols()); leftPredicate = leftOuterJoinPushDownResult.getOuterJoinPredicate(); rightPredicate = leftOuterJoinPushDownResult.getInnerJoinPredicate(); PlanNode leftSource = context.rewrite(node.getLeft(), leftPredicate); PlanNode rightSource = context.rewrite(node.getRight(), rightPredicate); if (leftSource != node.getLeft() || rightSource != node.getRight() || !areExpressionsEquivalent(newJoinPredicate, joinPredicate)) { leftProjections.putAll(node.getLeft() .getOutputSymbols().stream() .collect(Collectors.toMap(key -> key, Symbol::toSymbolReference)));
@Override public PlanNodeCostEstimate visitSpatialJoin(SpatialJoinNode node, Void context) { return calculateJoinExchangeCost( node.getLeft(), node.getRight(), stats, types, node.getDistributionType() == SpatialJoinNode.DistributionType.REPLICATED, taskCountEstimator.estimateSourceDistributedTaskCount()); }
PlanWithProperties left = node.getLeft().accept(this, PreferredProperties.any()); PlanWithProperties right = node.getRight().accept(this, PreferredProperties.any());
@Override public PlanNodeCostEstimate visitSpatialJoin(SpatialJoinNode node, Void context) { return calculateJoinCost( node, node.getLeft(), node.getRight(), node.getDistributionType() == SpatialJoinNode.DistributionType.REPLICATED); }
@Override public Void visitSpatialJoin(SpatialJoinNode node, Void context) { node.getRight().accept(this, context); node.getLeft().accept(this, context); return null; }
@Override public Void visitSpatialJoin(SpatialJoinNode node, Consumer<PlanNodeId> schedulingOrder) { node.getRight().accept(this, schedulingOrder); node.getLeft().accept(this, schedulingOrder); return null; }
@Override public Void visitSpatialJoin(SpatialJoinNode node, Set<Symbol> boundSymbols) { node.getLeft().accept(this, boundSymbols); node.getRight().accept(this, boundSymbols); Set<Symbol> leftInputs = createInputs(node.getLeft(), boundSymbols); Set<Symbol> rightInputs = createInputs(node.getRight(), boundSymbols); Set<Symbol> allInputs = ImmutableSet.<Symbol>builder() .addAll(leftInputs) .addAll(rightInputs) .build(); Set<Symbol> predicateSymbols = SymbolsExtractor.extractUnique(node.getFilter()); checkArgument( allInputs.containsAll(predicateSymbols), "Symbol from filter (%s) not in sources (%s)", predicateSymbols, allInputs); checkLeftOutputSymbolsBeforeRight(node.getLeft().getOutputSymbols(), node.getOutputSymbols()); return null; }
@Override public PlanWithProperties visitSpatialJoin(SpatialJoinNode node, StreamPreferredProperties parentPreferences) { PlanWithProperties probe = planAndEnforce( node.getLeft(), defaultParallelism(session), parentPreferences.constrainTo(node.getLeft().getOutputSymbols()) .withDefaultParallelism(session)); PlanWithProperties build = planAndEnforce(node.getRight(), singleStream(), singleStream()); return rebaseAndDeriveProperties(node, ImmutableList.of(probe, build)); }
SymbolReference secondSymbol = (SymbolReference) arguments.get(1); PlanNode probeNode = node.getLeft(); Set<SymbolReference> probeSymbols = getSymbolReferences(probeNode.getOutputSymbols());
@Override protected Optional<PlanNodeStatsEstimate> doCalculate(SpatialJoinNode node, StatsProvider sourceStats, Lookup lookup, Session session, TypeProvider types) { PlanNodeStatsEstimate leftStats = sourceStats.getStats(node.getLeft()); PlanNodeStatsEstimate rightStats = sourceStats.getStats(node.getRight()); PlanNodeStatsEstimate crossJoinStats = crossJoinStats(node, leftStats, rightStats); switch (node.getType()) { case INNER: return Optional.of(statsCalculator.filterStats(crossJoinStats, node.getFilter(), session, types)); case LEFT: return Optional.of(PlanNodeStatsEstimate.unknown()); default: throw new IllegalArgumentException("Unknown spatial join type: " + node.getType()); } }
@Override public Expression visitSpatialJoin(SpatialJoinNode node, Void context) { Expression leftPredicate = node.getLeft().accept(this, context); Expression rightPredicate = node.getRight().accept(this, context); switch (node.getType()) { case INNER: return combineConjuncts(ImmutableList.<Expression>builder() .add(pullExpressionThroughSymbols(leftPredicate, node.getOutputSymbols())) .add(pullExpressionThroughSymbols(rightPredicate, node.getOutputSymbols())) .build()); case LEFT: return combineConjuncts(ImmutableList.<Expression>builder() .add(pullExpressionThroughSymbols(leftPredicate, node.getOutputSymbols())) .addAll(pullNullableConjunctsThroughOuterJoin(extractConjuncts(rightPredicate), node.getOutputSymbols(), node.getRight().getOutputSymbols()::contains)) .build()); default: throw new IllegalArgumentException("Unsupported spatial join type: " + node.getType()); } }
@Override public Void visitSpatialJoin(SpatialJoinNode node, Void context) { printNode(node, node.getType().getJoinLabel(), node.getFilter().toString(), NODE_COLORS.get(NodeType.JOIN)); node.getLeft().accept(this, context); node.getRight().accept(this, context); return null; }
private PlanNodeStatsEstimate crossJoinStats(SpatialJoinNode node, PlanNodeStatsEstimate leftStats, PlanNodeStatsEstimate rightStats) { PlanNodeStatsEstimate.Builder builder = PlanNodeStatsEstimate.builder() .setOutputRowCount(leftStats.getOutputRowCount() * rightStats.getOutputRowCount()); node.getLeft().getOutputSymbols().forEach(symbol -> builder.addSymbolStatistics(symbol, leftStats.getSymbolStatistics(symbol))); node.getRight().getOutputSymbols().forEach(symbol -> builder.addSymbolStatistics(symbol, rightStats.getSymbolStatistics(symbol))); return builder.build(); }
@Override public PlanWithProperties visitSpatialJoin(SpatialJoinNode node, HashComputationSet parentPreference) { PlanWithProperties left = planAndEnforce(node.getLeft(), new HashComputationSet(), true, new HashComputationSet()); PlanWithProperties right = planAndEnforce(node.getRight(), new HashComputationSet(), true, new HashComputationSet()); verify(left.getHashSymbols().isEmpty(), "probe side of the spatial join should not include hash symbols"); verify(right.getHashSymbols().isEmpty(), "build side of the spatial join should not include hash symbols"); return new PlanWithProperties( replaceChildren(node, ImmutableList.of(left.getNode(), right.getNode())), ImmutableMap.of()); }
@Override public Void visitSpatialJoin(SpatialJoinNode node, Integer indent) { print(indent, "- %s[%s] => [%s]", node.getType().getJoinLabel(), node.getFilter(), formatOutputs(node.getOutputSymbols())); print(indent + 2, "Distribution: %s", node.getDistributionType()); printPlanNodesStatsAndCost(indent + 2, node); printStats(indent + 2, node.getId()); node.getLeft().accept(this, indent + 1); node.getRight().accept(this, indent + 1); return null; }