presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementFilteredAggregations.java/ImplementFilteredAggregations/apply
class ImplementFilteredAggregations:    @Override
    public Result apply(AggregationNode aggregationNode, Captures captures, Context context)
    {
        Assignments.Builder newAssignments = Assignments.builder();
        ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder();
        ImmutableList.Builder<Expression> maskSymbols = ImmutableList.builder();
        boolean aggregateWithoutFilterPresent = false;

        for (Map.Entry<Symbol, Aggregation> entry : aggregationNode.getAggregations().entrySet()) {
            Symbol output = entry.getKey();

            // strip the filters
            Aggregation aggregation = entry.getValue();
            Optional<Symbol> mask = aggregation.getMask();

            if (aggregation.getFilter().isPresent()) {
                Symbol filter = aggregation.getFilter().get();
                Symbol symbol = context.getSymbolAllocator().newSymbol(filter.getName(), BOOLEAN);
                verify(!mask.isPresent(), "Expected aggregation without mask symbols, see Rule pattern");
                newAssignments.put(symbol, new SymbolReference(filter.getName()));
                mask = Optional.of(symbol);

                maskSymbols.add(symbol.toSymbolReference());
            }
            else {
                aggregateWithoutFilterPresent = true;
            }

            aggregations.put(output, new Aggregation(
                    aggregation.getResolvedFunction(),
                    aggregation.getArguments(),
                    aggregation.isDistinct(),
                    Optional.empty(),
                    aggregation.getOrderingScheme(),
                    mask));
        }

        Expression predicate = TRUE_LITERAL;
        if (!aggregationNode.hasNonEmptyGroupingSet() && !aggregateWithoutFilterPresent) {
            predicate = combineDisjunctsWithDefault(metadata, maskSymbols.build(), TRUE_LITERAL);
        }

        // identity projection for all existing inputs
        newAssignments.putIdentities(aggregationNode.getSource().getOutputSymbols());

        return Result.ofPlanNode(
                new AggregationNode(
                        context.getIdAllocator().getNextId(),
                        new FilterNode(
                                context.getIdAllocator().getNextId(),
                                new ProjectNode(
                                        context.getIdAllocator().getNextId(),
                                        aggregationNode.getSource(),
                                        newAssignments.build()),
                                predicate),
                        aggregations.build(),
                        aggregationNode.getGroupingSets(),
                        ImmutableList.of(),
                        aggregationNode.getStep(),
                        aggregationNode.getHashSymbol(),
                        aggregationNode.getGroupIdSymbol()));
    }