presto-main/src/main/java/io/prestosql/sql/planner/optimizations/OptimizeMixedDistinctAggregations.java/Optimizer/createProjectNode
class Optimizer:        private ProjectNode createProjectNode(
                AggregationNode source,
                AggregateInfo aggregateInfo,
                Symbol distinctSymbol,
                Symbol groupSymbol,
                List<Symbol> groupBySymbols,
                Map<Symbol, Symbol> aggregationOutputSymbolsMap)
        {
            Assignments.Builder outputSymbols = Assignments.builder();
            ImmutableMap.Builder<Symbol, Symbol> outputNonDistinctAggregateSymbols = ImmutableMap.builder();
            for (Symbol symbol : source.getOutputSymbols()) {
                if (distinctSymbol.equals(symbol)) {
                    Symbol newSymbol = symbolAllocator.newSymbol("expr", symbolAllocator.getTypes().get(symbol));
                    aggregateInfo.setNewDistinctAggregateSymbol(newSymbol);

                    Expression expression = createIfExpression(
                            groupSymbol.toSymbolReference(),
                            new Cast(new LongLiteral("1"), toSqlType(BIGINT)), // TODO: this should use GROUPING() when that's available instead of relying on specific group numbering
                            ComparisonExpression.Operator.EQUAL,
                            symbol.toSymbolReference(),
                            symbolAllocator.getTypes().get(symbol));
                    outputSymbols.put(newSymbol, expression);
                }
                else if (aggregationOutputSymbolsMap.containsKey(symbol)) {
                    Symbol newSymbol = symbolAllocator.newSymbol("expr", symbolAllocator.getTypes().get(symbol));
                    // key of outputNonDistinctAggregateSymbols is key of an aggregation in AggrNode above, it will now aggregate on this Map's value
                    outputNonDistinctAggregateSymbols.put(aggregationOutputSymbolsMap.get(symbol), newSymbol);
                    Expression expression = createIfExpression(
                            groupSymbol.toSymbolReference(),
                            new Cast(new LongLiteral("0"), toSqlType(BIGINT)), // TODO: this should use GROUPING() when that's available instead of relying on specific group numbering
                            ComparisonExpression.Operator.EQUAL,
                            symbol.toSymbolReference(),
                            symbolAllocator.getTypes().get(symbol));
                    outputSymbols.put(newSymbol, expression);
                }

                // A symbol can appear both in groupBy and distinct/non-distinct aggregation
                if (groupBySymbols.contains(symbol)) {
                    Expression expression = symbol.toSymbolReference();
                    outputSymbols.put(symbol, expression);
                }
            }

            // add null assignment for mask
            // unused mask will be removed by PruneUnreferencedOutputs
            outputSymbols.put(aggregateInfo.getMask(), new NullLiteral());

            aggregateInfo.setNewNonDistinctAggregateSymbols(outputNonDistinctAggregateSymbols.build());

            return new ProjectNode(idAllocator.getNextId(), source, outputSymbols.build());
        }