Source:
public Result apply(AggregationNode aggregationNode, Captures captures, Context context) { ExchangeNode exchangeNode = captures.get(EXCHANGE_NODE); boolean decomposable = aggregationNode.isDecomposable(functionRegistry); if (aggregationNode.getStep().equals(SINGLE) && aggregationNode.hasEmptyGroupingSet() && aggregationNode.hasNonEmptyGroupingSet() && exchangeNode.getType() == REPARTITION) { checkState( decomposable, "Distributed aggregation with empty grouping set requires partial but functions are not decomposable"); return Result.ofPlanNode(split(aggregationNode, context)); } if (!decomposable || !SystemSessionProperties.preferPartialAggregation(context.getSession())) { return Result.empty(); } if ((exchangeNode.getType() != GATHER && exchangeNode.getType() != REPARTITION) || exchangeNode.getPartitioningScheme().isReplicateNullsAndAny()) { return Result.empty(); } if (exchangeNode.getType() == REPARTITION) { List<Symbol> partitioningColumns = exchangeNode.getPartitioningScheme() .getPartitioning() .getArguments() .stream() .filter(Partitioning.ArgumentBinding::isVariable) .map(Partitioning.ArgumentBinding::getColumn) .collect(Collectors.toList()); if (!aggregationNode.getGroupingKeys().containsAll(partitioningColumns)) { return Result.empty(); } } if (aggregationNode.getHashSymbol().isPresent() || exchangeNode.getPartitioningScheme().getHashColumn().isPresent()) { return Result.empty(); } switch (aggregationNode.getStep()) { case SINGLE: return Result.ofPlanNode(split(aggregationNode, context)); case PARTIAL: return Result.ofPlanNode(pushPartial(aggregationNode, exchangeNode, context)); default: return Result.empty(); } }

Target:
public Result apply(AggregationNode aggregationNode, Captures captures, Context context) { ExchangeNode exchangeNode = captures.get(EXCHANGE_NODE); boolean decomposable = aggregationNode.isDecomposable(functionRegistry); if (aggregationNode.getStep().equals(SINGLE) && aggregationNode.hasEmptyGroupingSet() && aggregationNode.hasNonEmptyGroupingSet() && exchangeNode.getType() == REPARTITION) { checkState( decomposable, "Distributed aggregation with empty grouping set requires partial but functions are not decomposable"); return Result.ofPlanNode(split(aggregationNode, context)); } if (!decomposable || !preferPartialAggregation(context.getSession())) { return Result.empty(); } if ((exchangeNode.getType() != GATHER && exchangeNode.getType() != REPARTITION) || exchangeNode.getPartitioningScheme().isReplicateNullsAndAny()) { return Result.empty(); } if (exchangeNode.getType() == REPARTITION) { List<Symbol> partitioningColumns = exchangeNode.getPartitioningScheme() .getPartitioning() .getArguments() .stream() .filter(Partitioning.ArgumentBinding::isVariable) .map(Partitioning.ArgumentBinding::getColumn) .collect(Collectors.toList()); if (!aggregationNode.getGroupingKeys().containsAll(partitioningColumns)) { return Result.empty(); } } if (aggregationNode.getHashSymbol().isPresent() || exchangeNode.getPartitioningScheme().getHashColumn().isPresent()) { return Result.empty(); } switch (aggregationNode.getStep()) { case SINGLE: return Result.ofPlanNode(split(aggregationNode, context)); case PARTIAL: return Result.ofPlanNode(pushPartial(aggregationNode, exchangeNode, context)); default: return Result.empty(); } }