private static boolean meetsPartitioningRequirements(PreferredProperties preferred, ActualProperties actual) { if (!preferred.getGlobalProperties().isPresent()) { return true; } PreferredProperties.Global preferredGlobal = preferred.getGlobalProperties().get(); if (!preferredGlobal.isDistributed()) { return actual.isSingleNode(); } if (!preferredGlobal.getPartitioningProperties().isPresent()) { return !actual.isSingleNode(); } return actual.isStreamPartitionedOn(preferredGlobal.getPartitioningProperties().get().getPartitioningColumns()); }
private boolean shouldRepartitionForIndexJoin(List<Symbol> joinColumns, PreferredProperties parentPreferredProperties, ActualProperties probeProperties) { // See if distributed index joins are enabled if (!distributedIndexJoins) { return false; } // No point in repartitioning if the plan is not distributed if (probeProperties.isSingleNode()) { return false; } Optional<PreferredProperties.PartitioningProperties> parentPartitioningPreferences = parentPreferredProperties.getGlobalProperties() .flatMap(PreferredProperties.Global::getPartitioningProperties); // Disable repartitioning if it would disrupt a parent's partitioning preference when streaming is enabled boolean parentAlreadyPartitionedOnChild = parentPartitioningPreferences .map(partitioning -> probeProperties.isStreamPartitionedOn(partitioning.getPartitioningColumns())) .orElse(false); if (preferStreamingOperators && parentAlreadyPartitionedOnChild) { return false; } // Otherwise, repartition if we need to align with the join columns if (!probeProperties.isStreamPartitionedOn(joinColumns)) { return true; } // If we are already partitioned on the join columns because the data has been forced effectively into one stream, // then we should repartition if that would make a difference (from the single stream state). return probeProperties.isEffectivelySingleStream() && probeProperties.isStreamRepartitionEffective(joinColumns); }
@Override public PlanWithProperties visitJoin(JoinNode node, PreferredProperties preferredProperties) { List<Symbol> leftSymbols = node.getCriteria().stream() .map(JoinNode.EquiJoinClause::getLeft) .collect(toImmutableList()); List<Symbol> rightSymbols = node.getCriteria().stream() .map(JoinNode.EquiJoinClause::getRight) .collect(toImmutableList()); JoinNode.DistributionType distributionType = node.getDistributionType().orElseThrow(() -> new IllegalArgumentException("distributionType not yet set")); if (distributionType == JoinNode.DistributionType.REPLICATED) { PlanWithProperties left = node.getLeft().accept(this, PreferredProperties.any()); // use partitioned join if probe side is naturally partitioned on join symbols (e.g: because of aggregation) if (!node.getCriteria().isEmpty() && left.getProperties().isNodePartitionedOn(leftSymbols) && !left.getProperties().isSingleNode()) { return planPartitionedJoin(node, leftSymbols, rightSymbols, left); } return planReplicatedJoin(node, left); } else { return planPartitionedJoin(node, leftSymbols, rightSymbols); } }
checkArgument(forceSingleNode || globalProperties.isSingleNode(), "Final aggregation with default value not separated from partial aggregation by remote hash exchange");
@Override public ActualProperties visitTableWriter(TableWriterNode node, List<ActualProperties> inputProperties) { ActualProperties properties = Iterables.getOnlyElement(inputProperties); if (properties.isCoordinatorOnly()) { return ActualProperties.builder() .global(coordinatorSingleStreamPartition()) .build(); } return ActualProperties.builder() .global(properties.isSingleNode() ? singleStreamPartition() : arbitraryPartition()) .build(); }
@Override public PlanWithProperties visitEnforceSingleRow(EnforceSingleRowNode node, PreferredProperties preferredProperties) { PlanWithProperties child = planChild(node, PreferredProperties.any()); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitTopN(TopNNode node, PreferredProperties preferredProperties) { PlanWithProperties child; switch (node.getStep()) { case SINGLE: case FINAL: child = planChild(node, PreferredProperties.undistributed()); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()), child.getProperties()); } break; case PARTIAL: child = planChild(node, PreferredProperties.any()); break; default: throw new UnsupportedOperationException(format("Unsupported step for TopN [%s]", node.getStep())); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitOutput(OutputNode node, PreferredProperties preferredProperties) { PlanWithProperties child = planChild(node, PreferredProperties.undistributed()); if (!child.getProperties().isSingleNode() && isForceSingleNodeOutput(session)) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
PlanWithProperties child = node.getSources().get(i).accept(this, PreferredProperties.any()); plannedChildren.add(child); if (child.getProperties().isSingleNode()) { unpartitionedChildren.add(child.getNode()); unpartitionedOutputLayouts.add(node.sourceOutputLayout(i));
if (left.getProperties().isSingleNode()) { if (!right.getProperties().isSingleNode()) { right = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, right.getNode()),
private PlanWithProperties planReplicatedJoin(JoinNode node, PlanWithProperties left) { // Broadcast Join PlanWithProperties right = node.getRight().accept(this, PreferredProperties.any()); if (left.getProperties().isSingleNode()) { if (!right.getProperties().isSingleNode() || (!isColocatedJoinEnabled(session) && hasMultipleSources(left.getNode(), right.getNode()))) { right = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, right.getNode()), right.getProperties()); } } else { right = withDerivedProperties( replicatedExchange(idAllocator.getNextId(), REMOTE, right.getNode()), right.getProperties()); } return buildJoin(node, left, right, JoinNode.DistributionType.REPLICATED); }
if (child.getProperties().isSingleNode()) { if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()),
@Override public PlanWithProperties visitDistinctLimit(DistinctLimitNode node, PreferredProperties preferredProperties) { PlanWithProperties child = planChild(node, PreferredProperties.any()); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange( idAllocator.getNextId(), REMOTE, new DistinctLimitNode(idAllocator.getNextId(), child.getNode(), node.getLimit(), true, node.getDistinctSymbols(), node.getHashSymbol())), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
.global(probeProperties.isSingleNode() ? singleStreamPartition() : arbitraryPartition()) .unordered(unordered) .build();
@Override public PlanWithProperties visitMarkDistinct(MarkDistinctNode node, PreferredProperties preferredProperties) { PreferredProperties preferredChildProperties = PreferredProperties.partitionedWithLocal(ImmutableSet.copyOf(node.getDistinctSymbols()), grouped(node.getDistinctSymbols())) .mergeWithParent(preferredProperties); PlanWithProperties child = node.getSource().accept(this, preferredChildProperties); if (child.getProperties().isSingleNode() || !child.getProperties().isStreamPartitionedOn(node.getDistinctSymbols())) { child = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), REMOTE, child.getNode(), node.getDistinctSymbols(), node.getHashSymbol()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitLimit(LimitNode node, PreferredProperties preferredProperties) { PlanWithProperties child = planChild(node, PreferredProperties.any()); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( new LimitNode(idAllocator.getNextId(), child.getNode(), node.getCount(), true), child.getProperties()); child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
if (source.getProperties().isNodePartitionedOn(sourceSymbols) && !source.getProperties().isSingleNode()) { Partitioning filteringPartitioning = source.getProperties().translate(createTranslator(sourceToFiltering)).getNodePartitioning().get(); filteringSource = node.getFilteringSource().accept(this, PreferredProperties.partitionedWithNullsAndAnyReplicated(filteringPartitioning)); filteringSource = node.getFilteringSource().accept(this, PreferredProperties.partitionedWithNullsAndAnyReplicated(ImmutableSet.copyOf(filteringSourceSymbols))); if (filteringSource.getProperties().isNodePartitionedOn(filteringSourceSymbols, true) && !filteringSource.getProperties().isSingleNode()) { Partitioning sourcePartitioning = filteringSource.getProperties().translate(createTranslator(filteringToSource)).getNodePartitioning().get(); source = withDerivedProperties( if (source.getProperties().isSingleNode()) { if (!filteringSource.getProperties().isSingleNode() || (!isColocatedJoinEnabled(session) && hasMultipleSources(source.getNode(), filteringSource.getNode()))) { filteringSource = withDerivedProperties(
@Override public PlanWithProperties visitAggregation(AggregationNode node, PreferredProperties parentPreferredProperties) { Set<Symbol> partitioningRequirement = ImmutableSet.copyOf(node.getGroupingKeys()); boolean preferSingleNode = node.hasSingleNodeExecutionPreference(metadata.getFunctionRegistry()); PreferredProperties preferredProperties = preferSingleNode ? PreferredProperties.undistributed() : PreferredProperties.any(); if (!node.getGroupingKeys().isEmpty()) { preferredProperties = PreferredProperties.partitionedWithLocal(partitioningRequirement, grouped(node.getGroupingKeys())) .mergeWithParent(parentPreferredProperties); } PlanWithProperties child = planChild(node, preferredProperties); if (child.getProperties().isSingleNode()) { // If already unpartitioned, just drop the single aggregation back on return rebaseAndDeriveProperties(node, child); } if (preferSingleNode) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()), child.getProperties()); } else if (!child.getProperties().isStreamPartitionedOn(partitioningRequirement) && !child.getProperties().isNodePartitionedOn(partitioningRequirement)) { child = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), REMOTE, child.getNode(), node.getGroupingKeys(), node.getHashSymbol()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
PlanWithProperties child = planChild(node, PreferredProperties.undistributed()); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()),
if (left.getProperties().isNodePartitionedOn(leftSymbols) && !left.getProperties().isSingleNode()) { Partitioning rightPartitioning = left.getProperties().translate(createTranslator(leftToRight)).getNodePartitioning().get(); right = node.getRight().accept(this, PreferredProperties.partitioned(rightPartitioning)); right = node.getRight().accept(this, PreferredProperties.partitioned(ImmutableSet.copyOf(rightSymbols))); if (right.getProperties().isNodePartitionedOn(rightSymbols) && !right.getProperties().isSingleNode()) { Partitioning leftPartitioning = right.getProperties().translate(createTranslator(rightToLeft)).getNodePartitioning().get(); left = withDerivedProperties(