Source:
<code>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()) { 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)) { <START> checkState(preferredProperties.getGlobalProperties().isPresent() && preferredProperties.getGlobalProperties().get().getPartitioningProperties().isPresent()); <END> Partitioning partitioning = getPreferredPartitioning(preferredProperties.getGlobalProperties().get().getPartitioningProperties().get()); child = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), REMOTE, child.getNode(), new PartitioningScheme( partitioning, child.getNode().getOutputSymbols(), node.getHashSymbol())), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }</code><technical_language>modify partitioningRequirement contains merged partitioning requirement. this code insert partitionedExchange if data is partitioning merged requirement. For example, partitioningRequirement={a,b}, mergedPartitioningPreferences={a}, isNodePartitionedOn={a}. similar in other methods</technical_language>

Target:
public PlanWithProperties visitAggregation(AggregationNode node, PreferredProperties parentPreferredProperties) { Set<VariableReferenceExpression> partitioningRequirement = ImmutableSet.copyOf(node.getGroupingKeys()); boolean preferSingleNode = hasSingleNodeExecutionPreference(node, metadata.getFunctionManager()); boolean hasMixedGroupingSets = node.hasEmptyGroupingSet() && node.hasNonEmptyGroupingSet(); PreferredProperties preferredProperties = preferSingleNode ? PreferredProperties.undistributed() : PreferredProperties.any(); if (!node.getGroupingKeys().isEmpty() && !hasMixedGroupingSets) { FeaturesConfig.AggregationPartitioningMergingStrategy aggregationPartitioningMergingStrategy = getAggregationPartitioningMergingStrategy(session); preferredProperties = PreferredProperties.partitionedWithLocal(partitioningRequirement, grouped(node.getGroupingKeys())) .mergeWithParent(parentPreferredProperties, aggregationPartitioningMergingStrategy.isMergingWithParent()); if (aggregationPartitioningMergingStrategy.isAdoptingMergedPreference()) { checkState(preferredProperties.getGlobalProperties().isPresent() && preferredProperties.getGlobalProperties().get().getPartitioningProperties().isPresent()); partitioningRequirement = ImmutableSet.copyOf(preferredProperties.getGlobalProperties().get().getPartitioningProperties().get().getPartitioningColumns()); } } PlanWithProperties child = planChild(node, preferredProperties); if (child.getProperties().isSingleNode()) { return rebaseAndDeriveProperties(node, child); } if (preferSingleNode) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE_STREAMING, child.getNode()), child.getProperties()); } else if (hasMixedGroupingSets || !child.getProperties().isStreamPartitionedOn(partitioningRequirement) && !child.getProperties().isNodePartitionedOn(partitioningRequirement)) { child = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), selectExchangeScopeForPartitionedRemoteExchange(child.getNode(), false), child.getNode(), createPartitioning(partitioningRequirement), node.getHashVariable()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }