mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #8424 from ClickHouse/arg-min-max-simplification
Simplification of "use arena" property of min/max/any/argMin... aggregate functions
This commit is contained in:
commit
2934c09796
@ -24,11 +24,16 @@ struct AggregateFunctionArgMinMaxData
|
|||||||
|
|
||||||
ResultData result; // the argument at which the minimum/maximum value is reached.
|
ResultData result; // the argument at which the minimum/maximum value is reached.
|
||||||
ValueData value; // value for which the minimum/maximum is calculated.
|
ValueData value; // value for which the minimum/maximum is calculated.
|
||||||
|
|
||||||
|
static bool allocatesMemoryInArena()
|
||||||
|
{
|
||||||
|
return ResultData::allocatesMemoryInArena() || ValueData::allocatesMemoryInArena();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns the first arg value found for the minimum/maximum value. Example: argMax(arg, value).
|
/// Returns the first arg value found for the minimum/maximum value. Example: argMax(arg, value).
|
||||||
template <typename Data, bool AllocatesMemoryInArena>
|
template <typename Data>
|
||||||
class AggregateFunctionArgMinMax final : public IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data, AllocatesMemoryInArena>>
|
class AggregateFunctionArgMinMax final : public IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const DataTypePtr & type_res;
|
const DataTypePtr & type_res;
|
||||||
@ -36,7 +41,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionArgMinMax(const DataTypePtr & type_res_, const DataTypePtr & type_val_)
|
AggregateFunctionArgMinMax(const DataTypePtr & type_res_, const DataTypePtr & type_val_)
|
||||||
: IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data, AllocatesMemoryInArena>>({type_res_, type_val_}, {}),
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data>>({type_res_, type_val_}, {}),
|
||||||
type_res(this->argument_types[0]), type_val(this->argument_types[1])
|
type_res(this->argument_types[0]), type_val(this->argument_types[1])
|
||||||
{
|
{
|
||||||
if (!type_val->isComparable())
|
if (!type_val->isComparable())
|
||||||
@ -77,7 +82,7 @@ public:
|
|||||||
|
|
||||||
bool allocatesMemoryInArena() const override
|
bool allocatesMemoryInArena() const override
|
||||||
{
|
{
|
||||||
return AllocatesMemoryInArena;
|
return Data::allocatesMemoryInArena();
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
|
void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
|
||||||
|
@ -166,6 +166,11 @@ public:
|
|||||||
{
|
{
|
||||||
return has() && assert_cast<const ColVecType &>(column).getData()[row_num] == value;
|
return has() && assert_cast<const ColVecType &>(column).getData()[row_num] == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool allocatesMemoryInArena()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -384,6 +389,11 @@ public:
|
|||||||
{
|
{
|
||||||
return has() && assert_cast<const ColumnString &>(column).getDataAtWithTerminatingZero(row_num) == getStringRef();
|
return has() && assert_cast<const ColumnString &>(column).getDataAtWithTerminatingZero(row_num) == getStringRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool allocatesMemoryInArena()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
@ -555,6 +565,11 @@ public:
|
|||||||
{
|
{
|
||||||
return has() && to.value == value;
|
return has() && to.value == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool allocatesMemoryInArena()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -675,15 +690,15 @@ struct AggregateFunctionAnyHeavyData : Data
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename Data, bool use_arena>
|
template <typename Data>
|
||||||
class AggregateFunctionsSingleValue final : public IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data, use_arena>>
|
class AggregateFunctionsSingleValue final : public IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
DataTypePtr & type;
|
DataTypePtr & type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionsSingleValue(const DataTypePtr & type_)
|
AggregateFunctionsSingleValue(const DataTypePtr & type_)
|
||||||
: IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data, use_arena>>({type_}, {})
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data>>({type_}, {})
|
||||||
, type(this->argument_types[0])
|
, type(this->argument_types[0])
|
||||||
{
|
{
|
||||||
if (StringRef(Data::name()) == StringRef("min")
|
if (StringRef(Data::name()) == StringRef("min")
|
||||||
@ -724,7 +739,7 @@ public:
|
|||||||
|
|
||||||
bool allocatesMemoryInArena() const override
|
bool allocatesMemoryInArena() const override
|
||||||
{
|
{
|
||||||
return use_arena;
|
return Data::allocatesMemoryInArena();
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
|
void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
/// min, max, any, anyLast
|
/// min, max, any, anyLast, anyHeavy, etc...
|
||||||
template <template <typename, bool> class AggregateFunctionTemplate, template <typename> class Data>
|
template <template <typename> class AggregateFunctionTemplate, template <typename> class Data>
|
||||||
static IAggregateFunction * createAggregateFunctionSingleValue(const String & name, const DataTypes & argument_types, const Array & parameters)
|
static IAggregateFunction * createAggregateFunctionSingleValue(const String & name, const DataTypes & argument_types, const Array & parameters)
|
||||||
{
|
{
|
||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
@ -24,26 +24,26 @@ static IAggregateFunction * createAggregateFunctionSingleValue(const String & na
|
|||||||
|
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
#define DISPATCH(TYPE) \
|
#define DISPATCH(TYPE) \
|
||||||
if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE>>, false>(argument_type);
|
if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE>>>(argument_type);
|
||||||
FOR_NUMERIC_TYPES(DISPATCH)
|
FOR_NUMERIC_TYPES(DISPATCH)
|
||||||
#undef DISPATCH
|
#undef DISPATCH
|
||||||
|
|
||||||
if (which.idx == TypeIndex::Date)
|
if (which.idx == TypeIndex::Date)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDate::FieldType>>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDate::FieldType>>>(argument_type);
|
||||||
if (which.idx == TypeIndex::DateTime)
|
if (which.idx == TypeIndex::DateTime)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDateTime::FieldType>>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDateTime::FieldType>>>(argument_type);
|
||||||
if (which.idx == TypeIndex::DateTime64)
|
if (which.idx == TypeIndex::DateTime64)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DateTime64>>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DateTime64>>>(argument_type);
|
||||||
if (which.idx == TypeIndex::Decimal32)
|
if (which.idx == TypeIndex::Decimal32)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal32>>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal32>>>(argument_type);
|
||||||
if (which.idx == TypeIndex::Decimal64)
|
if (which.idx == TypeIndex::Decimal64)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal64>>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal64>>>(argument_type);
|
||||||
if (which.idx == TypeIndex::Decimal128)
|
if (which.idx == TypeIndex::Decimal128)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal128>>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal128>>>(argument_type);
|
||||||
if (which.idx == TypeIndex::String)
|
if (which.idx == TypeIndex::String)
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataString>, true>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataString>>(argument_type);
|
||||||
|
|
||||||
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric>, false>(argument_type);
|
return new AggregateFunctionTemplate<Data<SingleValueDataGeneric>>(argument_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -53,53 +53,28 @@ static IAggregateFunction * createAggregateFunctionArgMinMaxSecond(const DataTyp
|
|||||||
{
|
{
|
||||||
WhichDataType which(val_type);
|
WhichDataType which(val_type);
|
||||||
|
|
||||||
/// If at least one argument is a String, the function can allocate memory in Arena.
|
|
||||||
bool is_res_type_string = WhichDataType(res_type).isString();
|
|
||||||
|
|
||||||
#define DISPATCH(TYPE) \
|
#define DISPATCH(TYPE) \
|
||||||
if (which.idx == TypeIndex::TYPE && !is_res_type_string) \
|
if (which.idx == TypeIndex::TYPE) \
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<TYPE>>>, false>(res_type, val_type); \
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<TYPE>>>>(res_type, val_type); \
|
||||||
if (which.idx == TypeIndex::TYPE && is_res_type_string) \
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<TYPE>>>, true>(res_type, val_type);
|
|
||||||
FOR_NUMERIC_TYPES(DISPATCH)
|
FOR_NUMERIC_TYPES(DISPATCH)
|
||||||
#undef DISPATCH
|
#undef DISPATCH
|
||||||
|
|
||||||
if (!is_res_type_string)
|
if (which.idx == TypeIndex::Date)
|
||||||
{
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDate::FieldType>>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::Date)
|
if (which.idx == TypeIndex::DateTime)
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDate::FieldType>>>, false>(res_type, val_type);
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDateTime::FieldType>>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::DateTime)
|
if (which.idx == TypeIndex::DateTime64)
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDateTime::FieldType>>>, false>(res_type, val_type);
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DateTime64>>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::DateTime64)
|
if (which.idx == TypeIndex::Decimal32)
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DateTime64>>>, false>(res_type, val_type);
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal32>>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::Decimal32)
|
if (which.idx == TypeIndex::Decimal64)
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal32>>>, false>(res_type, val_type);
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal64>>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::Decimal64)
|
if (which.idx == TypeIndex::Decimal128)
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal64>>>, false>(res_type, val_type);
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal128>>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::Decimal128)
|
if (which.idx == TypeIndex::String)
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal128>>>, false>(res_type, val_type);
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataString>>>(res_type, val_type);
|
||||||
if (which.idx == TypeIndex::String)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataString>>, true>(res_type, val_type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (which.idx == TypeIndex::Date)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDate::FieldType>>>, true>(res_type, val_type);
|
|
||||||
if (which.idx == TypeIndex::DateTime)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDateTime::FieldType>>>, true>(res_type, val_type);
|
|
||||||
if (which.idx == TypeIndex::DateTime64)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DateTime64>>>, true>(res_type, val_type);
|
|
||||||
if (which.idx == TypeIndex::Decimal32)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal32>>>, true>(res_type, val_type);
|
|
||||||
if (which.idx == TypeIndex::Decimal64)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal64>>>, true>(res_type, val_type);
|
|
||||||
if (which.idx == TypeIndex::Decimal128)
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal128>>>, true>(res_type, val_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// But generic implementation doesn't allocate memory in Arena.
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataGeneric>>>(res_type, val_type);
|
||||||
|
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataGeneric>>, false>(res_type, val_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class MinMaxData>
|
template <template <typename> class MinMaxData>
|
||||||
|
Loading…
Reference in New Issue
Block a user