private RexNode reduceAvg(
      Aggregate oldAggRel,
      AggregateCall oldCall,
      List<AggregateCall> newCalls,
      Map<AggregateCall, RexNode> aggCallMapping,
      List<RexNode> inputExprs) {
    final int nGroups = oldAggRel.getGroupCount();
    final RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
    final RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory();

    Preconditions.checkState(oldCall.getArgList().size() == 1);
    // We compute SUM with either BIGINT, DOUBLE, or DECIMAL
    final RexNode arg = getAvgInput(inputExprs.get(oldCall.getArgList().get(0)), rexBuilder, typeFactory);
    final List<Integer> argIndices = Collections.singletonList(lookupOrAdd(inputExprs, arg));
    final RelDataType sumReturnType = getSumReturnType(
        rexBuilder.getTypeFactory(), arg.getType());
    final AggregateCall sumCall =
        AggregateCall.create(
            new HiveSqlSumAggFunction(
                oldCall.isDistinct(),
                ReturnTypes.explicit(sumReturnType),
                oldCall.getAggregation().getOperandTypeInference(),
                oldCall.getAggregation().getOperandTypeChecker()), //SqlStdOperatorTable.SUM,
            oldCall.isDistinct(),
            oldCall.isApproximate(),
            oldCall.ignoreNulls(),
            argIndices,
            oldCall.filterArg,
            oldCall.getCollation(),
            sumReturnType,
            null);
    // The denominator of AVG is always BIGINT
    final RelDataType countRetType = typeFactory.createTypeWithNullability(
        typeFactory.createSqlType(SqlTypeName.BIGINT), true);
    final AggregateCall countCall =
        AggregateCall.create(
            new HiveSqlCountAggFunction(
                oldCall.isDistinct(),
                ReturnTypes.explicit(countRetType),
                oldCall.getAggregation().getOperandTypeInference(),
                oldCall.getAggregation().getOperandTypeChecker()), //SqlStdOperatorTable.COUNT,
            oldCall.isDistinct(),
            oldCall.isApproximate(),
            oldCall.ignoreNulls(),
            // We need to use the cast argument here to apply the same null-check as SUM
            argIndices,
            oldCall.filterArg,
            oldCall.getCollation(),
            countRetType,
            null);

    // NOTE:  these references are with respect to the output
    // of newAggRel
    RexNode numeratorRef =
        rexBuilder.addAggCall(sumCall,
            nGroups,
            newCalls,
            aggCallMapping,
            ImmutableList.of(arg.getType()));
    final RexNode denominatorRef =
        rexBuilder.addAggCall(countCall,
            nGroups,
            newCalls,
            aggCallMapping,
            ImmutableList.of(arg.getType()));

    if (numeratorRef.getType().getSqlTypeName() != SqlTypeName.DECIMAL) {
      // If type is not decimal, we enforce the same type as the avg to comply with
      // Hive semantics
      numeratorRef = rexBuilder.ensureType(oldCall.getType(), numeratorRef, true);
    }
    final RexNode divideRef =
        rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
    return rexBuilder.makeCast(oldCall.getType(), divideRef);
  }
Reduces all calls to SUM0, AVG, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP in
the aggregates list to.

<p>It handles newly generated common subexpressions since this was done
at the sql2rel stage.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveAggregateReduceFunctionsRule.java