presto-main/src/main/java/io/prestosql/sql/planner/optimizations/ScalarAggregationToJoinRewriter.java/ScalarAggregationToJoinRewriter/createAggregationNode
class ScalarAggregationToJoinRewriter:    private Optional<AggregationNode> createAggregationNode(
            AggregationNode scalarAggregation,
            JoinNode leftOuterJoin,
            Symbol nonNullableAggregationSourceSymbol)
    {
        FunctionId countFunctionId = metadata.resolveFunction(QualifiedName.of("count"), ImmutableList.of()).getFunctionId();
        ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder();
        for (Map.Entry<Symbol, Aggregation> entry : scalarAggregation.getAggregations().entrySet()) {
            Aggregation aggregation = entry.getValue();
            Symbol symbol = entry.getKey();
            // Only count() and count(*) require rewriting to count(non_null) in order to preserve the row count. count(argument) shouldn't be rewritten.
            if (aggregation.getResolvedFunction().getFunctionId().equals(countFunctionId)) {
                List<Type> scalarAggregationSourceTypes = ImmutableList.of(
                        symbolAllocator.getTypes().get(nonNullableAggregationSourceSymbol));
                aggregations.put(symbol, new Aggregation(
                        metadata.resolveFunction(QualifiedName.of("count"), fromTypes(scalarAggregationSourceTypes)),
                        ImmutableList.of(nonNullableAggregationSourceSymbol.toSymbolReference()),
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        aggregation.getMask()));
            }
            else {
                aggregations.put(symbol, aggregation);
            }
        }

        return Optional.of(new AggregationNode(
                idAllocator.getNextId(),
                leftOuterJoin,
                aggregations.build(),
                singleGroupingSet(leftOuterJoin.getLeft().getOutputSymbols()),
                ImmutableList.of(),
                scalarAggregation.getStep(),
                scalarAggregation.getHashSymbol(),
                Optional.empty()));
    }