BuiltinAggregateFunctions.java

// 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.doris.catalog;

import org.apache.doris.nereids.trees.expressions.functions.agg.AIAgg;
import org.apache.doris.nereids.trees.expressions.functions.agg.AnyValue;
import org.apache.doris.nereids.trees.expressions.functions.agg.ArrayAgg;
import org.apache.doris.nereids.trees.expressions.functions.agg.Avg;
import org.apache.doris.nereids.trees.expressions.functions.agg.AvgWeighted;
import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapAgg;
import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapIntersect;
import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapUnion;
import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapUnionCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapUnionInt;
import org.apache.doris.nereids.trees.expressions.functions.agg.BoolAnd;
import org.apache.doris.nereids.trees.expressions.functions.agg.BoolOr;
import org.apache.doris.nereids.trees.expressions.functions.agg.BoolXor;
import org.apache.doris.nereids.trees.expressions.functions.agg.CollectList;
import org.apache.doris.nereids.trees.expressions.functions.agg.CollectSet;
import org.apache.doris.nereids.trees.expressions.functions.agg.Corr;
import org.apache.doris.nereids.trees.expressions.functions.agg.CorrWelford;
import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
import org.apache.doris.nereids.trees.expressions.functions.agg.CountByEnum;
import org.apache.doris.nereids.trees.expressions.functions.agg.Covar;
import org.apache.doris.nereids.trees.expressions.functions.agg.CovarSamp;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupArrayIntersect;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupArrayUnion;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupBitAnd;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupBitOr;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupBitXor;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupBitmapXor;
import org.apache.doris.nereids.trees.expressions.functions.agg.GroupConcat;
import org.apache.doris.nereids.trees.expressions.functions.agg.Histogram;
import org.apache.doris.nereids.trees.expressions.functions.agg.HllUnion;
import org.apache.doris.nereids.trees.expressions.functions.agg.HllUnionAgg;
import org.apache.doris.nereids.trees.expressions.functions.agg.IntersectCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.Kurt;
import org.apache.doris.nereids.trees.expressions.functions.agg.LinearHistogram;
import org.apache.doris.nereids.trees.expressions.functions.agg.MapAgg;
import org.apache.doris.nereids.trees.expressions.functions.agg.MapAggV2;
import org.apache.doris.nereids.trees.expressions.functions.agg.Max;
import org.apache.doris.nereids.trees.expressions.functions.agg.MaxBy;
import org.apache.doris.nereids.trees.expressions.functions.agg.Median;
import org.apache.doris.nereids.trees.expressions.functions.agg.Min;
import org.apache.doris.nereids.trees.expressions.functions.agg.MinBy;
import org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctGroupConcat;
import org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctSum;
import org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctSum0;
import org.apache.doris.nereids.trees.expressions.functions.agg.Ndv;
import org.apache.doris.nereids.trees.expressions.functions.agg.NotNullableAggregateFunction;
import org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapExprCalculate;
import org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapExprCalculateCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapIntersect;
import org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapIntersectCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapUnionCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.Percentile;
import org.apache.doris.nereids.trees.expressions.functions.agg.PercentileApprox;
import org.apache.doris.nereids.trees.expressions.functions.agg.PercentileApproxWeighted;
import org.apache.doris.nereids.trees.expressions.functions.agg.PercentileArray;
import org.apache.doris.nereids.trees.expressions.functions.agg.PercentileReservoir;
import org.apache.doris.nereids.trees.expressions.functions.agg.QuantileUnion;
import org.apache.doris.nereids.trees.expressions.functions.agg.RegrIntercept;
import org.apache.doris.nereids.trees.expressions.functions.agg.RegrSlope;
import org.apache.doris.nereids.trees.expressions.functions.agg.Retention;
import org.apache.doris.nereids.trees.expressions.functions.agg.Sem;
import org.apache.doris.nereids.trees.expressions.functions.agg.SequenceCount;
import org.apache.doris.nereids.trees.expressions.functions.agg.SequenceMatch;
import org.apache.doris.nereids.trees.expressions.functions.agg.Skew;
import org.apache.doris.nereids.trees.expressions.functions.agg.Stddev;
import org.apache.doris.nereids.trees.expressions.functions.agg.StddevSamp;
import org.apache.doris.nereids.trees.expressions.functions.agg.Sum;
import org.apache.doris.nereids.trees.expressions.functions.agg.Sum0;
import org.apache.doris.nereids.trees.expressions.functions.agg.TopN;
import org.apache.doris.nereids.trees.expressions.functions.agg.TopNArray;
import org.apache.doris.nereids.trees.expressions.functions.agg.TopNWeighted;
import org.apache.doris.nereids.trees.expressions.functions.agg.Variance;
import org.apache.doris.nereids.trees.expressions.functions.agg.VarianceSamp;
import org.apache.doris.nereids.trees.expressions.functions.agg.WindowFunnel;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;

import java.util.List;
import java.util.Map;

/**
 * Builtin aggregate functions.
 * <p>
 * Note: Please ensure that this class only has some lists and no procedural code.
 * It helps to be clear and concise.
 */
public class BuiltinAggregateFunctions implements FunctionHelper {
    public final List<AggregateFunc> aggregateFunctions;
    public final Map<String, Boolean> aggFuncNameNullableMap;

    public static final BuiltinAggregateFunctions INSTANCE = new BuiltinAggregateFunctions();

    private BuiltinAggregateFunctions() {
        aggregateFunctions = ImmutableList.of(
                agg(AIAgg.class, "ai_agg"),
                agg(AnyValue.class, "any", "any_value"),
                agg(ArrayAgg.class, "array_agg"),
                agg(Avg.class, "avg"),
                agg(AvgWeighted.class, "avg_weighted"),
                agg(BitmapAgg.class, "bitmap_agg"),
                agg(BitmapIntersect.class, "bitmap_intersect"),
                agg(BitmapUnion.class, "bitmap_union"),
                agg(BitmapUnionCount.class, "bitmap_union_count"),
                agg(BitmapUnionInt.class, "bitmap_union_int"),
                agg(BoolOr.class, "bool_or", "boolor_agg"),
                agg(BoolAnd.class, "bool_and", "booland_agg"),
                agg(BoolXor.class, "bool_xor", "boolxor_agg"),
                agg(CollectList.class, "collect_list", "group_array"),
                agg(CollectSet.class, "collect_set", "group_uniq_array"),
                agg(Corr.class, "corr"),
                agg(CorrWelford.class, "corr_welford"),
                agg(Count.class, "count"),
                agg(CountByEnum.class, "count_by_enum"),
                agg(Covar.class, "covar", "covar_pop"),
                agg(CovarSamp.class, "covar_samp"),
                agg(GroupArrayIntersect.class, "group_array_intersect"),
                agg(GroupArrayUnion.class, "group_array_union"),
                agg(GroupBitAnd.class, "group_bit_and"),
                agg(GroupBitOr.class, "group_bit_or"),
                agg(GroupBitXor.class, "group_bit_xor"),
                agg(GroupBitmapXor.class, "group_bitmap_xor"),
                agg(GroupConcat.class, "group_concat"),
                agg(Histogram.class, "hist", "histogram"),
                agg(HllUnion.class, "hll_raw_agg", "hll_union"),
                agg(HllUnionAgg.class, "hll_union_agg"),
                agg(IntersectCount.class, "intersect_count"),
                agg(Kurt.class, "kurt", "kurt_pop", "kurtosis"),
                agg(LinearHistogram.class, "linear_histogram"),
                agg(MapAgg.class, "map_agg_v1"),
                agg(MapAggV2.class, "map_agg_v2", "map_agg"),
                agg(Max.class, "max"),
                agg(MaxBy.class, "max_by"),
                agg(Median.class, "median"),
                agg(Min.class, "min"),
                agg(MinBy.class, "min_by"),
                agg(MultiDistinctCount.class, "multi_distinct_count"),
                agg(MultiDistinctGroupConcat.class, "multi_distinct_group_concat"),
                agg(MultiDistinctSum.class, "multi_distinct_sum"),
                agg(MultiDistinctSum0.class, "multi_distinct_sum0"),
                agg(Ndv.class, "approx_count_distinct", "ndv"),
                agg(OrthogonalBitmapExprCalculate.class, "orthogonal_bitmap_expr_calculate"),
                agg(OrthogonalBitmapExprCalculateCount.class, "orthogonal_bitmap_expr_calculate_count"),
                agg(OrthogonalBitmapIntersect.class, "orthogonal_bitmap_intersect"),
                agg(OrthogonalBitmapIntersectCount.class, "orthogonal_bitmap_intersect_count"),
                agg(OrthogonalBitmapUnionCount.class, "orthogonal_bitmap_union_count"),
                agg(Percentile.class, "percentile", "percentile_cont"),
                agg(PercentileReservoir.class, "percentile_reservoir"),
                agg(PercentileApprox.class, "percentile_approx"),
                agg(PercentileApproxWeighted.class, "percentile_approx_weighted"),
                agg(PercentileArray.class, "percentile_array"),
                agg(QuantileUnion.class, "quantile_union"),
                agg(RegrIntercept.class, "regr_intercept"),
                agg(RegrSlope.class, "regr_slope"),
                agg(Retention.class, "retention"),
                agg(Sem.class, "sem"),
                agg(SequenceCount.class, "sequence_count"),
                agg(SequenceMatch.class, "sequence_match"),
                agg(Skew.class, "skew", "skew_pop", "skewness"),
                agg(Stddev.class, "stddev_pop", "stddev", "std"),
                agg(StddevSamp.class, "stddev_samp"),
                agg(Sum.class, "sum"),
                agg(Sum0.class, "sum0"),
                agg(TopN.class, "topn"),
                agg(TopNArray.class, "topn_array"),
                agg(TopNWeighted.class, "topn_weighted"),
                agg(Variance.class, "var_pop", "variance_pop", "variance"),
                agg(VarianceSamp.class, "var_samp", "variance_samp"),
                agg(WindowFunnel.class, "window_funnel")
        );

        ImmutableMap.Builder<String, Boolean> aggFuncNameNullableMapBuilder
                = ImmutableSortedMap.<String, Boolean>orderedBy(String.CASE_INSENSITIVE_ORDER);
        for (AggregateFunc aggregateFunc : aggregateFunctions) {
            for (String name : aggregateFunc.names) {
                boolean resultNullable = !(NotNullableAggregateFunction.class
                        .isAssignableFrom(aggregateFunc.functionClass));
                aggFuncNameNullableMapBuilder.put(name, resultNullable);
            }
        }
        aggFuncNameNullableMap = aggFuncNameNullableMapBuilder.build();
    }
}