#include #include #include #include #include #include #include "registerAggregateFunctions.h" namespace DB { namespace { struct WithOverflowPolicy { /// Overflow, meaning that the returned type is the same as the input type. static DataTypePtr promoteType(const DataTypePtr & data_type) { return data_type; } }; struct WithoutOverflowPolicy { /// No overflow, meaning we promote the types if necessary. static DataTypePtr promoteType(const DataTypePtr & data_type) { if (!data_type->canBePromoted()) throw Exception{"Values to be summed are expected to be Numeric, Float or Decimal.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; return data_type->promoteNumericType(); } }; template using SumMapWithOverflow = AggregateFunctionSumMap; template using SumMapWithoutOverflow = AggregateFunctionSumMap; template using SumMapFilteredWithOverflow = AggregateFunctionSumMapFiltered; template using SumMapFilteredWithoutOverflow = AggregateFunctionSumMapFiltered; using SumMapArgs = std::pair; SumMapArgs parseArguments(const std::string & name, const DataTypes & arguments) { if (arguments.size() < 2) throw Exception("Aggregate function " + name + " requires at least two arguments of Array type.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); const auto * array_type = checkAndGetDataType(arguments[0].get()); if (!array_type) throw Exception("First argument for function " + name + " must be an array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); DataTypePtr keys_type = array_type->getNestedType(); DataTypes values_types; values_types.reserve(arguments.size() - 1); for (size_t i = 1; i < arguments.size(); ++i) { array_type = checkAndGetDataType(arguments[i].get()); if (!array_type) throw Exception("Argument #" + toString(i) + " for function " + name + " must be an array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); values_types.push_back(array_type->getNestedType()); } return {std::move(keys_type), std::move(values_types)}; } template