Source:
<code>public void onMatch(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelBuilder relBuilder = call.builder(); final List<SqlAggFunction> topAggFunctions = new ArrayList<>(); for (AggregateCall aggregateCall : aggregate.getAggCallList()) { if (aggregateCall.isDistinct()) { return; } if (aggregateCall.getAggregation().equals(HiveGroupingID.INSTANCE)) { return; } if (aggregateCall.filterArg >= 0) { return; } SqlAggFunction aggFunction = HiveRelBuilder.getRollup(aggregateCall.getAggregation()); if (aggFunction == null) { return; } topAggFunctions.add(aggFunction); } final ImmutableBitSet bottomAggregateGroupSet = aggregate.getGroupSet(); if (aggregate.getCluster().getMetadataQuery().areColumnsUnique(aggregate.getInput(), bottomAggregateGroupSet)) { return; } final ImmutableBitSet topAggregateGroupSet = ImmutableBitSet.range(0, bottomAggregateGroupSet.cardinality()); final Map<Integer, Integer> map = new HashMap<>(); bottomAggregateGroupSet.forEach(k -> map.put(k, map.size())); ImmutableList<ImmutableBitSet> topAggregateGroupSets = ImmutableBitSet.ORDERING.immutableSortedCopy( ImmutableBitSet.permute(aggregate.groupSets, map)); final List<AggregateCall> topAggregateCalls = new ArrayList<>(); for (int i = 0; i < aggregate.getAggCallList().size(); i++) { <START> AggregateCall aggregateCall = aggregate.getAggCallList().get(i); <END> topAggregateCalls.add( AggregateCall.create(topAggFunctions.get(i), aggregateCall.isDistinct(), aggregateCall.isApproximate(), ImmutableList.of(topAggregateGroupSet.cardinality() + i), -1, aggregateCall.collation, aggregateCall.type, aggregateCall.name)); } relBuilder.push(aggregate.getInput()) .aggregate(relBuilder.groupKey(bottomAggregateGroupSet), aggregate.getAggCallList()) .aggregate(relBuilder.groupKey(topAggregateGroupSet, topAggregateGroupSets), topAggregateCalls); call.transformTo(relBuilder.build()); }</code><technical_language>Instead of looping agg call list I do this in loop topAggFuctions is created</technical_language>

Target:
public void onMatch(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelBuilder relBuilder = call.builder(); final ImmutableBitSet bottomAggregateGroupSet = aggregate.getGroupSet(); final List<AggregateCall> topAggregateCalls = new ArrayList<>(); for (int i = 0; i < aggregate.getAggCallList().size(); i++) { AggregateCall aggregateCall = aggregate.getAggCallList().get(i); if (aggregateCall.isDistinct()) { return; } if (aggregateCall.getAggregation().equals(HiveGroupingID.INSTANCE)) { return; } if (aggregateCall.filterArg >= 0) { return; } SqlAggFunction aggFunction = HiveRelBuilder.getRollup(aggregateCall.getAggregation()); if (aggFunction == null) { return; } topAggregateCalls.add( AggregateCall.create(aggFunction, aggregateCall.isDistinct(), aggregateCall.isApproximate(), ImmutableList.of(bottomAggregateGroupSet.cardinality() + i), -1, aggregateCall.collation, aggregateCall.type, aggregateCall.name)); } if (aggregate.getCluster().getMetadataQuery().areColumnsUnique(aggregate.getInput(), bottomAggregateGroupSet)) { return; } final ImmutableBitSet topAggregateGroupSet = ImmutableBitSet.range(0, bottomAggregateGroupSet.cardinality()); final Map<Integer, Integer> map = new HashMap<>(); bottomAggregateGroupSet.forEach(k -> map.put(k, map.size())); ImmutableList<ImmutableBitSet> topAggregateGroupSets = ImmutableBitSet.ORDERING.immutableSortedCopy( ImmutableBitSet.permute(aggregate.groupSets, map)); relBuilder.push(aggregate.getInput()) .aggregate(relBuilder.groupKey(bottomAggregateGroupSet), aggregate.getAggCallList()) .aggregate(relBuilder.groupKey(topAggregateGroupSet, topAggregateGroupSets), topAggregateCalls); call.transformTo(relBuilder.build()); }