remove some code

This commit is contained in:
Alexander Kuzmenkov 2020-06-16 13:44:23 +03:00
parent 7cc54fd4f1
commit be008cd186
2 changed files with 118 additions and 157 deletions

View File

@ -18,35 +18,6 @@ namespace ErrorCodes
namespace namespace
{ {
template <bool overflow, bool tuple_argument>
struct SumMap
{
template <typename T>
using F = AggregateFunctionSumMap<T, overflow, tuple_argument>;
};
template <bool overflow, bool tuple_argument>
struct SumMapFiltered
{
template <typename T>
using F = AggregateFunctionSumMapFiltered<T, overflow, tuple_argument>;
};
template <bool tuple_argument>
struct MinMap
{
template <typename T>
using F = AggregateFunctionMinMap<T, tuple_argument>;
};
template <bool tuple_argument>
struct MaxMap
{
template <typename T>
using F = AggregateFunctionMaxMap<T, tuple_argument>;
};
auto parseArguments(const std::string & name, const DataTypes & arguments) auto parseArguments(const std::string & name, const DataTypes & arguments)
{ {
DataTypes args; DataTypes args;
@ -99,97 +70,32 @@ auto parseArguments(const std::string & name, const DataTypes & arguments)
tuple_argument}; tuple_argument};
} }
template <bool overflow> // This function instantiates a particular overload of the sumMap family of
AggregateFunctionPtr createAggregateFunctionSumMap(const std::string & name, const DataTypes & arguments, const Array & params) // functions.
// The template parameter MappedFunction<bool template_argument> is an aggregate
// function template that allows to choose the aggregate function variant that
// accepts either normal arguments or tuple argument.
template<template <bool tuple_argument> typename MappedFunction>
AggregateFunctionPtr createAggregateFunctionMap(const std::string & name, const DataTypes & arguments, const Array & params)
{ {
assertNoParameters(name, params);
auto [keys_type, values_types, tuple_argument] = parseArguments(name,
arguments);
AggregateFunctionPtr res;
if (tuple_argument)
{
res.reset(createWithNumericBasedType<SumMap<overflow, true>::template F>(*keys_type, keys_type, values_types, arguments));
if (!res)
res.reset(createWithDecimalType<SumMap<overflow, true>::template F>(*keys_type, keys_type, values_types, arguments));
if (!res)
res.reset(createWithStringType<SumMap<overflow, true>::template F>(*keys_type, keys_type, values_types, arguments));
}
else
{
res.reset(createWithNumericBasedType<SumMap<overflow, false>::template F>(*keys_type, keys_type, values_types, arguments));
if (!res)
res.reset(createWithDecimalType<SumMap<overflow, false>::template F>(*keys_type, keys_type, values_types, arguments));
if (!res)
res.reset(createWithStringType<SumMap<overflow, false>::template F>(*keys_type, keys_type, values_types, arguments));
}
if (!res)
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
return res;
}
template <bool overflow>
AggregateFunctionPtr createAggregateFunctionSumMapFiltered(const std::string & name, const DataTypes & arguments, const Array & params)
{
if (params.size() != 1)
throw Exception("Aggregate function " + name + " requires exactly one parameter of Array type.",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
Array keys_to_keep;
if (!params.front().tryGet<Array>(keys_to_keep))
throw Exception("Aggregate function " + name + " requires an Array as parameter.",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto [keys_type, values_types, tuple_argument] = parseArguments(name,
arguments);
AggregateFunctionPtr res;
if (tuple_argument)
{
res.reset(createWithNumericBasedType<SumMapFiltered<overflow, true>::template F>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
if (!res)
res.reset(createWithDecimalType<SumMapFiltered<overflow, true>::template F>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
if (!res)
res.reset(createWithStringType<SumMapFiltered<overflow, true>::template F>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
}
else
{
res.reset(createWithNumericBasedType<SumMapFiltered<overflow, false>::template F>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
if (!res)
res.reset(createWithDecimalType<SumMapFiltered<overflow, false>::template F>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
if (!res)
res.reset(createWithStringType<SumMapFiltered<overflow, false>::template F>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
}
if (!res)
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
return res;
}
AggregateFunctionPtr createAggregateFunctionMinMap(const std::string & name, const DataTypes & arguments, const Array & params)
{
assertNoParameters(name, params);
auto [keys_type, values_types, tuple_argument] = parseArguments(name, arguments); auto [keys_type, values_types, tuple_argument] = parseArguments(name, arguments);
AggregateFunctionPtr res; AggregateFunctionPtr res;
if (tuple_argument) if (tuple_argument)
{ {
res.reset(createWithNumericBasedType<MinMap<true>::template F>(*keys_type, keys_type, values_types, arguments)); res.reset(createWithNumericBasedType<MappedFunction<true>::template F>(*keys_type, keys_type, values_types, arguments, params));
if (!res) if (!res)
res.reset(createWithDecimalType<MinMap<true>::template F>(*keys_type, keys_type, values_types, arguments)); res.reset(createWithDecimalType<MappedFunction<true>::template F>(*keys_type, keys_type, values_types, arguments, params));
if (!res) if (!res)
res.reset(createWithStringType<MinMap<true>::template F>(*keys_type, keys_type, values_types, arguments)); res.reset(createWithStringType<MappedFunction<true>::template F>(*keys_type, keys_type, values_types, arguments, params));
} }
else else
{ {
res.reset(createWithNumericBasedType<MinMap<false>::template F>(*keys_type, keys_type, values_types, arguments)); res.reset(createWithNumericBasedType<MappedFunction<false>::template F>(*keys_type, keys_type, values_types, arguments, params));
if (!res) if (!res)
res.reset(createWithDecimalType<MinMap<false>::template F>(*keys_type, keys_type, values_types, arguments)); res.reset(createWithDecimalType<MappedFunction<false>::template F>(*keys_type, keys_type, values_types, arguments, params));
if (!res) if (!res)
res.reset(createWithStringType<MinMap<false>::template F>(*keys_type, keys_type, values_types, arguments)); res.reset(createWithStringType<MappedFunction<false>::template F>(*keys_type, keys_type, values_types, arguments, params));
} }
if (!res) if (!res)
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -197,45 +103,66 @@ AggregateFunctionPtr createAggregateFunctionMinMap(const std::string & name, con
return res; return res;
} }
AggregateFunctionPtr createAggregateFunctionMaxMap(const std::string & name, const DataTypes & arguments, const Array & params) // This template chooses the sumMap variant with given filtering and overflow
// handling.
template <bool filtered, bool overflow>
struct SumMapVariants
{ {
assertNoParameters(name, params); // SumMapVariants chooses the `overflow` and `filtered` parameters of the
// aggregate functions. The `tuple_argument` and the value type `T` are left
auto [keys_type, values_types, tuple_argument] = parseArguments(name, arguments); // as free parameters.
// DispatchOnTupleArgument chooses `tuple_argument`, and the value type `T`
AggregateFunctionPtr res; // is left free.
if (tuple_argument) template <bool tuple_argument>
struct DispatchOnTupleArgument
{ {
res.reset(createWithNumericBasedType<MaxMap<true>::template F>(*keys_type, keys_type, values_types, arguments)); template <typename T>
if (!res) using F = std::conditional_t<filtered,
res.reset(createWithDecimalType<MaxMap<true>::template F>(*keys_type, keys_type, values_types, arguments)); AggregateFunctionSumMapFiltered<T, overflow, tuple_argument>,
if (!res) AggregateFunctionSumMap<T, overflow, tuple_argument>>;
res.reset(createWithStringType<MaxMap<true>::template F>(*keys_type, keys_type, values_types, arguments)); };
} };
else
{
res.reset(createWithNumericBasedType<MaxMap<false>::template F>(*keys_type, keys_type, values_types, arguments));
if (!res)
res.reset(createWithDecimalType<MaxMap<false>::template F>(*keys_type, keys_type, values_types, arguments));
if (!res)
res.reset(createWithStringType<MaxMap<false>::template F>(*keys_type, keys_type, values_types, arguments));
}
if (!res)
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
return res; // This template gives an aggregate function template that is narrowed
} // to accept either tuple argumen or normal argumens.
template <bool tuple_argument>
struct MinMapDispatchOnTupleArgument
{
template <typename T>
using F = AggregateFunctionMinMap<T, tuple_argument>;
};
// This template gives an aggregate function template that is narrowed
// to accept either tuple argumen or normal argumens.
template <bool tuple_argument>
struct MaxMapDispatchOnTupleArgument
{
template <typename T>
using F = AggregateFunctionMaxMap<T, tuple_argument>;
};
} }
void registerAggregateFunctionSumMap(AggregateFunctionFactory & factory) void registerAggregateFunctionSumMap(AggregateFunctionFactory & factory)
{ {
factory.registerFunction("sumMap", createAggregateFunctionSumMap<false /*overflow*/>); factory.registerFunction("sumMap", createAggregateFunctionMap<
factory.registerFunction("sumMapWithOverflow", createAggregateFunctionSumMap<true /*overflow*/>); SumMapVariants<false, false>::DispatchOnTupleArgument>);
factory.registerFunction("sumMapFiltered", createAggregateFunctionSumMapFiltered<false /*overflow*/>);
factory.registerFunction("sumMapFilteredWithOverflow", createAggregateFunctionSumMapFiltered<true /*overflow*/>); factory.registerFunction("sumMapWithOverflow", createAggregateFunctionMap<
factory.registerFunction("minMap", createAggregateFunctionMinMap); SumMapVariants<false, true>::DispatchOnTupleArgument>);
factory.registerFunction("maxMap", createAggregateFunctionMaxMap);
factory.registerFunction("sumMapFiltered", createAggregateFunctionMap<
SumMapVariants<true, false>::DispatchOnTupleArgument>);
factory.registerFunction("sumMapFilteredWithOverflow",
createAggregateFunctionMap<
SumMapVariants<true, true>::DispatchOnTupleArgument>);
factory.registerFunction("minMap",
createAggregateFunctionMap<MinMapDispatchOnTupleArgument>);
factory.registerFunction("maxMap",
createAggregateFunctionMap<MaxMapDispatchOnTupleArgument>);
} }
} }

View File

@ -25,6 +25,7 @@ namespace ErrorCodes
{ {
extern const int BAD_ARGUMENTS; extern const int BAD_ARGUMENTS;
extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
} }
template <typename T> template <typename T>
@ -62,11 +63,14 @@ private:
DataTypes values_types; DataTypes values_types;
public: public:
AggregateFunctionMapBase( using Base = IAggregateFunctionDataHelper<
const DataTypePtr & keys_type_, const DataTypes & values_types_, AggregateFunctionMapData<NearestFieldType<T>>, Derived>;
const DataTypes & argument_types_, const Array & params_)
: IAggregateFunctionDataHelper<AggregateFunctionMapData<NearestFieldType<T>>, Derived>(argument_types_, params_) AggregateFunctionMapBase(const DataTypePtr & keys_type_,
, keys_type(keys_type_), values_types(values_types_) {} const DataTypes & values_types_, const DataTypes & argument_types_)
: Base(argument_types_, {} /* parameters */), keys_type(keys_type_),
values_types(values_types_)
{}
DataTypePtr getReturnType() const override DataTypePtr getReturnType() const override
{ {
@ -312,9 +316,15 @@ private:
using Base = AggregateFunctionMapBase<T, Self, FieldVisitorSum, overflow, tuple_argument>; using Base = AggregateFunctionMapBase<T, Self, FieldVisitorSum, overflow, tuple_argument>;
public: public:
AggregateFunctionSumMap(const DataTypePtr & keys_type_, DataTypes & values_types_, const DataTypes & argument_types_) AggregateFunctionSumMap(const DataTypePtr & keys_type_,
: Base{keys_type_, values_types_, argument_types_, {}} DataTypes & values_types_, const DataTypes & argument_types_,
{} const Array & params_)
: Base{keys_type_, values_types_, argument_types_}
{
// The constructor accepts parameters to have a uniform interface with
// sumMapFiltered, but this function doesn't have any parameters.
assertNoParameters(getName(), params_);
}
String getName() const override { return "sumMap"; } String getName() const override { return "sumMap"; }
@ -336,11 +346,22 @@ private:
std::unordered_set<T> keys_to_keep; std::unordered_set<T> keys_to_keep;
public: public:
AggregateFunctionSumMapFiltered( AggregateFunctionSumMapFiltered(const DataTypePtr & keys_type_,
const DataTypePtr & keys_type_, const DataTypes & values_types_, const Array & keys_to_keep_, const DataTypes & values_types_, const DataTypes & argument_types_,
const DataTypes & argument_types_, const Array & params_) const Array & params_)
: Base{keys_type_, values_types_, argument_types_, params_} : Base{keys_type_, values_types_, argument_types_}
{ {
if (params_.size() != 1)
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"Aggregate function '{}' requires exactly one parameter "
"of Array type", getName());
Array keys_to_keep_;
if (!params_.front().tryGet<Array>(keys_to_keep_))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
"Aggregate function {} requires an Array as a parameter",
getName());
keys_to_keep.reserve(keys_to_keep_.size()); keys_to_keep.reserve(keys_to_keep_.size());
for (const Field & f : keys_to_keep_) for (const Field & f : keys_to_keep_)
{ {
@ -348,7 +369,8 @@ public:
} }
} }
String getName() const override { return "sumMapFiltered"; } String getName() const override
{ return overflow ? "sumMapFilteredWithOverflow" : "sumMapFiltered"; }
bool keepKey(const T & key) const { return keys_to_keep.count(key); } bool keepKey(const T & key) const { return keys_to_keep.count(key); }
}; };
@ -362,9 +384,15 @@ private:
using Base = AggregateFunctionMapBase<T, Self, FieldVisitorMin, true, tuple_argument>; using Base = AggregateFunctionMapBase<T, Self, FieldVisitorMin, true, tuple_argument>;
public: public:
AggregateFunctionMinMap(const DataTypePtr & keys_type_, DataTypes & values_types_, const DataTypes & argument_types_) AggregateFunctionMinMap(const DataTypePtr & keys_type_,
: Base{keys_type_, values_types_, argument_types_, {}} DataTypes & values_types_, const DataTypes & argument_types_,
{} const Array & params_)
: Base{keys_type_, values_types_, argument_types_}
{
// The constructor accepts parameters to have a uniform interface with
// sumMapFiltered, but this function doesn't have any parameters.
assertNoParameters(getName(), params_);
}
String getName() const override { return "minMap"; } String getName() const override { return "minMap"; }
@ -380,9 +408,15 @@ private:
using Base = AggregateFunctionMapBase<T, Self, FieldVisitorMax, true, tuple_argument>; using Base = AggregateFunctionMapBase<T, Self, FieldVisitorMax, true, tuple_argument>;
public: public:
AggregateFunctionMaxMap(const DataTypePtr & keys_type_, DataTypes & values_types_, const DataTypes & argument_types_) AggregateFunctionMaxMap(const DataTypePtr & keys_type_,
: Base{keys_type_, values_types_, argument_types_, {}} DataTypes & values_types_, const DataTypes & argument_types_,
{} const Array & params_)
: Base{keys_type_, values_types_, argument_types_}
{
// The constructor accepts parameters to have a uniform interface with
// sumMapFiltered, but this function doesn't have any parameters.
assertNoParameters(getName(), params_);
}
String getName() const override { return "maxMap"; } String getName() const override { return "maxMap"; }