/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.solr.handler.sql;

import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Pair;

import java.util.*;

/**
 * Implementation of {@link org.apache.calcite.rel.core.Aggregate} relational expression in Solr.
 */
class SolrAggregate extends Aggregate implements SolrRel {
  private static final List<SqlAggFunction> SUPPORTED_AGGREGATIONS = Arrays.asList(
      SqlStdOperatorTable.COUNT,
      SqlStdOperatorTable.SUM,
      SqlStdOperatorTable.SUM0,
      SqlStdOperatorTable.MIN,
      SqlStdOperatorTable.MAX,
      SqlStdOperatorTable.AVG
  );

  SolrAggregate(
      RelOptCluster cluster,
      RelTraitSet traitSet,
      RelNode child,
      boolean indicator,
      ImmutableBitSet groupSet,
      List<ImmutableBitSet> groupSets,
      List<AggregateCall> aggCalls) {
    super(cluster, traitSet, child, indicator, groupSet, groupSets, aggCalls);
    assert getConvention() == SolrRel.CONVENTION;
    assert getConvention() == child.getConvention();
  }

  @Override
  public Aggregate copy(RelTraitSet traitSet, RelNode input,
                        boolean indicator, ImmutableBitSet groupSet,
                        List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
    return new SolrAggregate(getCluster(), traitSet, input, indicator, groupSet, groupSets, aggCalls);
  }

  public void implement(Implementor implementor) {
    implementor.visitChild(0, getInput());

    final List<String> inNames = SolrRules.solrFieldNames(getInput().getRowType());


    for(Pair<AggregateCall, String> namedAggCall : getNamedAggCalls()) {


      AggregateCall aggCall = namedAggCall.getKey();

      Pair<String, String> metric = toSolrMetric(implementor, aggCall, inNames);
      implementor.addReverseAggMapping(namedAggCall.getValue(), metric.getKey().toLowerCase()+"("+metric.getValue()+")");
      implementor.addMetricPair(namedAggCall.getValue(), metric.getKey(), metric.getValue());
      if(aggCall.getName() == null) {
        implementor.addFieldMapping(namedAggCall.getValue(),
            aggCall.getAggregation().getName() + "(" + inNames.get(aggCall.getArgList().get(0)) + ")");
      }
    }

    for(int group : getGroupSet()) {
      String inName = inNames.get(group);
      implementor.addBucket(inName);
    }
  }

  private Pair<String, String> toSolrMetric(Implementor implementor, AggregateCall aggCall, List<String> inNames) {
    SqlAggFunction aggregation = aggCall.getAggregation();
    List<Integer> args = aggCall.getArgList();
    switch (args.size()) {
      case 0:
        if (aggregation.equals(SqlStdOperatorTable.COUNT)) {
          return new Pair<>(aggregation.getName(), "*");
        }
      case 1:
        String inName = inNames.get(args.get(0));
        String name = implementor.fieldMappings.getOrDefault(inName, inName);
        if(SUPPORTED_AGGREGATIONS.contains(aggregation)) {
          return new Pair<>(aggregation.getName(), name);
        }
      default:
        throw new AssertionError("Invalid aggregation " + aggregation + " with args " + args + " with names" + inNames);
    }
  }
}

// End SolrAggregate.java

@@ -2947,16 +2947,27 @@
 werCase(
+Locale.ROOT
 )+%22(%22+me

Fix precommit