code: private Optional<PlanNode> coalesceWithNullAggregation(AggregationNode aggregationNode, PlanNode outerJoin, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator, Lookup lookup)
      {
          // Create an aggregation node over a row of nulls.
          Optional<MappedAggregationInfo> aggregationOverNullInfoResultNode = createAggregationOverNull(
                  aggregationNode,
                  symbolAllocator,
                  idAllocator,
                  lookup);
  
          if (!aggregationOverNullInfoResultNode.isPresent()) {
              return Optional.empty();
          }
  
          MappedAggregationInfo aggregationOverNullInfo = aggregationOverNullInfoResultNode.get();
  
          AggregationNode aggregationOverNull = aggregationOverNullInfo.getAggregation();
          Map<Symbol, Symbol> sourceAggregationToOverNullMapping = aggregationOverNullInfo.getSymbolMapping();
  
          // Do a cross join with the aggregation over null
          JoinNode crossJoin = new JoinNode(
                  idAllocator.getNextId(),
                  JoinNode.Type.INNER,
                  outerJoin,
                  aggregationOverNull,
                  ImmutableList.of(),
                  ImmutableList.<Symbol>builder()
                          .addAll(outerJoin.getOutputSymbols())
                          .addAll(aggregationOverNull.getOutputSymbols())
                          .build(),
                  Optional.empty(),
                  Optional.empty(),
                  Optional.empty(),
                  Optional.empty());
  
          // Add coalesce expressions for all aggregation functions
          Assignments.Builder assignmentsBuilder = Assignments.builder();
          for (Symbol symbol : outerJoin.getOutputSymbols()) {
              if (aggregationNode.getAggregations().containsKey(symbol)) {
                  assignmentsBuilder.put(symbol, new CoalesceExpression(symbol.toSymbolReference(), sourceAggregationToOverNullMapping.get(symbol).toSymbolReference()));
              }
              else {
                  assignmentsBuilder.put(symbol, symbol.toSymbolReference());
              }
          }
          return Optional.of(new ProjectNode(idAllocator.getNextId(), crossJoin, assignmentsBuilder.build()));
      }
docs: null row.