Source:
<code>public Result apply(AggregationNode aggregation, Captures captures, Context context) { JoinNode join = captures.get(JOIN); if (join.getFilter().isPresent() || !(join.getType() == JoinNode.Type.LEFT || join.getType() == JoinNode.Type.RIGHT) || !groupsOnAllOuterTableColumns(aggregation, context.getLookup().resolve(getOuterTable(join))) || !isDistinct(context.getLookup().resolve(getOuterTable(join)), context.getLookup()::resolve)) { return Result.empty(); } List<Symbol> groupingKeys = join.getCriteria().stream() .map(join.getType() == JoinNode.Type.RIGHT ? JoinNode.EquiJoinClause::getLeft : JoinNode.EquiJoinClause::getRight) .collect(toImmutableList()); AggregationNode rewrittenAggregation = new AggregationNode( aggregation.getId(), getInnerTable(join), aggregation.getAggregations(), ImmutableList.of(groupingKeys), ImmutableList.of(), aggregation.getStep(), aggregation.getHashSymbol(), aggregation.getGroupIdSymbol()); JoinNode rewrittenJoin; if (join.getType() == JoinNode.Type.LEFT) { rewrittenJoin = new JoinNode( join.getId(), join.getType(), join.getLeft(), rewrittenAggregation, join.getCriteria(), ImmutableList.<Symbol>builder() .addAll(join.getLeft().getOutputSymbols()) .addAll(rewrittenAggregation.getAggregations().keySet()) .build(), join.getFilter(), join.getLeftHashSymbol(), join.getRightHashSymbol(), join.getDistributionType()); } else { rewrittenJoin = new JoinNode( join.getId(), join.getType(), rewrittenAggregation, join.getRight(), join.getCriteria(), ImmutableList.<Symbol>builder() .addAll(rewrittenAggregation.getAggregations().keySet()) .addAll(join.getRight().getOutputSymbols()) .build(), join.getFilter(), join.getLeftHashSymbol(), join.getRightHashSymbol(), join.getDistributionType()); <START> } <END> PlanNode resultNode = coalesceWithNullAggregation(rewrittenAggregation, rewrittenJoin, context.getSymbolAllocator(), context.getIdAllocator(), context.getLookup()); if(resultNode == null) { return Result.empty(); } return Result.ofPlanNode(resultNode); }</code><technical_language>commit message is long, wraps in github, please follow <LINK_0></technical_language>

Target:
public Result apply(AggregationNode aggregation, Captures captures, Context context) { JoinNode join = captures.get(JOIN); if (join.getFilter().isPresent() || !(join.getType() == JoinNode.Type.LEFT || join.getType() == JoinNode.Type.RIGHT) || !groupsOnAllOuterTableColumns(aggregation, context.getLookup().resolve(getOuterTable(join))) || !isDistinct(context.getLookup().resolve(getOuterTable(join)), context.getLookup()::resolve)) { return Result.empty(); } List<Symbol> groupingKeys = join.getCriteria().stream() .map(join.getType() == JoinNode.Type.RIGHT ? JoinNode.EquiJoinClause::getLeft : JoinNode.EquiJoinClause::getRight) .collect(toImmutableList()); AggregationNode rewrittenAggregation = new AggregationNode( aggregation.getId(), getInnerTable(join), aggregation.getAggregations(), ImmutableList.of(groupingKeys), ImmutableList.of(), aggregation.getStep(), aggregation.getHashSymbol(), aggregation.getGroupIdSymbol()); JoinNode rewrittenJoin; if (join.getType() == JoinNode.Type.LEFT) { rewrittenJoin = new JoinNode( join.getId(), join.getType(), join.getLeft(), rewrittenAggregation, join.getCriteria(), ImmutableList.<Symbol>builder() .addAll(join.getLeft().getOutputSymbols()) .addAll(rewrittenAggregation.getAggregations().keySet()) .build(), join.getFilter(), join.getLeftHashSymbol(), join.getRightHashSymbol(), join.getDistributionType()); } else { rewrittenJoin = new JoinNode( join.getId(), join.getType(), rewrittenAggregation, join.getRight(), join.getCriteria(), ImmutableList.<Symbol>builder() .addAll(rewrittenAggregation.getAggregations().keySet()) .addAll(join.getRight().getOutputSymbols()) .build(), join.getFilter(), join.getLeftHashSymbol(), join.getRightHashSymbol(), join.getDistributionType()); } Optional<PlanNode> resultNode = coalesceWithNullAggregation(rewrittenAggregation, rewrittenJoin, context.getSymbolAllocator(), context.getIdAllocator(), context.getLookup()); if (!resultNode.isPresent()) { return Result.empty(); } return Result.ofPlanNode(resultNode.get()); }