2011-09-19 03:40:05 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2011-12-19 08:06:31 +00:00
|
|
|
|
#include <memory>
|
|
|
|
|
|
2011-09-19 03:40:05 +00:00
|
|
|
|
#include <DB/Core/Row.h>
|
|
|
|
|
#include <DB/DataTypes/IDataType.h>
|
2014-06-26 00:58:14 +00:00
|
|
|
|
#include <DB/Common/typeid_cast.h>
|
2016-09-13 13:24:24 +00:00
|
|
|
|
#include <DB/Common/Arena.h>
|
2011-09-19 03:40:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2016-01-11 21:46:36 +00:00
|
|
|
|
namespace ErrorCodes
|
|
|
|
|
{
|
|
|
|
|
extern const int AGGREGATE_FUNCTION_DOESNT_ALLOW_PARAMETERS;
|
|
|
|
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
2016-01-12 02:21:15 +00:00
|
|
|
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
2016-01-19 02:25:07 +00:00
|
|
|
|
extern const int ARGUMENT_OUT_OF_BOUND;
|
2016-01-11 21:46:36 +00:00
|
|
|
|
}
|
2013-02-08 19:34:44 +00:00
|
|
|
|
|
2016-01-11 21:46:36 +00:00
|
|
|
|
using AggregateDataPtr = char *;
|
|
|
|
|
using ConstAggregateDataPtr = const char *;
|
2013-02-08 19:34:44 +00:00
|
|
|
|
|
|
|
|
|
|
2011-09-19 03:40:05 +00:00
|
|
|
|
/** Интерфейс для агрегатных функций.
|
2013-02-08 19:34:44 +00:00
|
|
|
|
* Экземпляры классов с этим интерфейсом не содержат самих данных для агрегации,
|
|
|
|
|
* а содержат лишь метаданные (описание) агрегатной функции,
|
|
|
|
|
* а также методы для создания, удаления и работы с данными.
|
|
|
|
|
* Данные, получающиеся во время агрегации (промежуточные состояния вычислений), хранятся в других объектах
|
|
|
|
|
* (которые могут быть созданы в каком-нибудь пуле),
|
|
|
|
|
* а IAggregateFunction - внешний интерфейс для манипулирования ими.
|
2011-09-19 03:40:05 +00:00
|
|
|
|
*/
|
|
|
|
|
class IAggregateFunction
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/// Получить основное имя функции.
|
|
|
|
|
virtual String getName() const = 0;
|
|
|
|
|
|
|
|
|
|
/** Указать типы аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
|
|
|
|
* Необходимо вызывать перед остальными вызовами.
|
|
|
|
|
*/
|
|
|
|
|
virtual void setArguments(const DataTypes & arguments) = 0;
|
|
|
|
|
|
2012-10-29 02:58:52 +00:00
|
|
|
|
/** Указать параметры - для параметрических агрегатных функций.
|
|
|
|
|
* Если параметры не предусмотрены или переданные параметры недопустимы - кинуть исключение.
|
|
|
|
|
* Если параметры есть - необходимо вызывать перед остальными вызовами, иначе - не вызывать.
|
|
|
|
|
*/
|
2014-03-25 18:16:26 +00:00
|
|
|
|
virtual void setParameters(const Array & params)
|
2012-10-29 02:58:52 +00:00
|
|
|
|
{
|
2014-03-25 18:16:26 +00:00
|
|
|
|
throw Exception("Aggregate function " + getName() + " doesn't allow parameters.",
|
|
|
|
|
ErrorCodes::AGGREGATE_FUNCTION_DOESNT_ALLOW_PARAMETERS);
|
2012-10-29 02:58:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-09-19 03:40:05 +00:00
|
|
|
|
/// Получить тип результата.
|
|
|
|
|
virtual DataTypePtr getReturnType() const = 0;
|
|
|
|
|
|
2013-02-08 19:34:44 +00:00
|
|
|
|
virtual ~IAggregateFunction() {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Функции по работе с данными. */
|
|
|
|
|
|
|
|
|
|
/** Создать пустые данные для агрегации с помощью placement new в заданном месте.
|
2013-02-08 23:41:05 +00:00
|
|
|
|
* Вы должны будете уничтожить их с помощью метода destroy.
|
2013-02-08 19:34:44 +00:00
|
|
|
|
*/
|
|
|
|
|
virtual void create(AggregateDataPtr place) const = 0;
|
|
|
|
|
|
|
|
|
|
/// Уничтожить данные для агрегации.
|
2014-05-23 00:35:14 +00:00
|
|
|
|
virtual void destroy(AggregateDataPtr place) const noexcept = 0;
|
2013-02-08 19:34:44 +00:00
|
|
|
|
|
2013-11-03 23:54:12 +00:00
|
|
|
|
/// Уничтожать данные не обязательно.
|
|
|
|
|
virtual bool hasTrivialDestructor() const = 0;
|
|
|
|
|
|
2013-02-08 19:34:44 +00:00
|
|
|
|
/// Получить sizeof структуры с данными.
|
2013-02-08 23:41:05 +00:00
|
|
|
|
virtual size_t sizeOfData() const = 0;
|
2013-02-08 19:34:44 +00:00
|
|
|
|
|
2013-02-09 02:20:26 +00:00
|
|
|
|
/// Как должна быть выровнена структура с данными. NOTE: Сейчас не используется (структуры с состоянием агрегации кладутся без выравнивания).
|
2013-02-08 23:41:05 +00:00
|
|
|
|
virtual size_t alignOfData() const = 0;
|
2013-02-08 19:34:44 +00:00
|
|
|
|
|
2016-09-22 23:26:08 +00:00
|
|
|
|
/** Adds a value into aggregation data on which place points to.
|
|
|
|
|
* columns points to columns containing arguments of aggregation function.
|
|
|
|
|
* row_num is number of row which should be added.
|
|
|
|
|
* Additional parameter arena should be used instead of standard memory allocator if the addition requires memory allocation.
|
|
|
|
|
*/
|
2016-09-19 22:30:40 +00:00
|
|
|
|
virtual void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena * arena) const = 0;
|
2011-09-19 03:40:05 +00:00
|
|
|
|
|
2016-09-22 23:26:08 +00:00
|
|
|
|
/// Merges state (on which place points to) with other state of current aggregation function.
|
2016-09-23 23:33:17 +00:00
|
|
|
|
virtual void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena * arena) const = 0;
|
2011-09-19 03:40:05 +00:00
|
|
|
|
|
2016-09-22 23:26:08 +00:00
|
|
|
|
/// Serializes state (to transmit it over the network, for example).
|
2013-02-08 19:34:44 +00:00
|
|
|
|
virtual void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const = 0;
|
2011-09-19 03:40:05 +00:00
|
|
|
|
|
2016-09-22 23:26:08 +00:00
|
|
|
|
/// Deserializes state. This function is called only for empty (just created) states.
|
|
|
|
|
virtual void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena * arena) const = 0;
|
2011-09-19 03:40:05 +00:00
|
|
|
|
|
2016-09-26 16:50:13 +00:00
|
|
|
|
/// Returns true if a function requires Arena to handle own states (see add(), merge(), deserialize()).
|
|
|
|
|
virtual bool allocatesMemoryInArena() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-22 23:26:08 +00:00
|
|
|
|
/// Inserts results into a column.
|
2013-06-30 11:38:46 +00:00
|
|
|
|
virtual void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const = 0;
|
2014-05-21 13:27:40 +00:00
|
|
|
|
|
2014-06-03 20:29:04 +00:00
|
|
|
|
/** Возвращает true для агрегатных функций типа -State.
|
|
|
|
|
* Они выполняются как другие агрегатные функции, но не финализируются (возвращают состояние агрегации, которое может быть объединено с другим).
|
|
|
|
|
*/
|
2014-05-30 16:21:30 +00:00
|
|
|
|
virtual bool isState() const { return false; }
|
2015-11-21 19:46:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Внутренний цикл, использующий указатель на функцию, получается лучше, чем использующий виртуальную функцию.
|
|
|
|
|
* Причина в том, что в случае виртуальных функций, GCC 5.1.2 генерирует код,
|
|
|
|
|
* который на каждой итерации цикла заново грузит из памяти в регистр адрес функции (значение по смещению в таблице виртуальных функций).
|
|
|
|
|
* Это даёт падение производительности на простых запросах в районе 12%.
|
|
|
|
|
* После появления более хороших компиляторов, код можно будет убрать.
|
|
|
|
|
*/
|
2016-09-19 22:30:40 +00:00
|
|
|
|
using AddFunc = void (*)(const IAggregateFunction *, AggregateDataPtr, const IColumn **, size_t, Arena *);
|
2015-11-21 19:46:27 +00:00
|
|
|
|
virtual AddFunc getAddressOfAddFunction() const = 0;
|
2013-02-08 19:34:44 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Реализует несколько методов. T - тип структуры с данными для агрегации.
|
|
|
|
|
template <typename T>
|
|
|
|
|
class IAggregateFunctionHelper : public IAggregateFunction
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using Data = T;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2013-02-08 19:34:44 +00:00
|
|
|
|
static Data & data(AggregateDataPtr place) { return *reinterpret_cast<Data*>(place); }
|
2013-02-08 23:41:05 +00:00
|
|
|
|
static const Data & data(ConstAggregateDataPtr place) { return *reinterpret_cast<const Data*>(place); }
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2013-02-08 19:34:44 +00:00
|
|
|
|
public:
|
2015-11-11 02:04:23 +00:00
|
|
|
|
void create(AggregateDataPtr place) const override
|
2013-02-08 19:34:44 +00:00
|
|
|
|
{
|
|
|
|
|
new (place) Data;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-11 02:04:23 +00:00
|
|
|
|
void destroy(AggregateDataPtr place) const noexcept override
|
2013-02-08 19:34:44 +00:00
|
|
|
|
{
|
|
|
|
|
data(place).~Data();
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-11 02:04:23 +00:00
|
|
|
|
bool hasTrivialDestructor() const override
|
2013-11-03 23:54:12 +00:00
|
|
|
|
{
|
|
|
|
|
return __has_trivial_destructor(Data);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-11 02:04:23 +00:00
|
|
|
|
size_t sizeOfData() const override
|
2013-02-08 19:34:44 +00:00
|
|
|
|
{
|
|
|
|
|
return sizeof(Data);
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-09 02:20:26 +00:00
|
|
|
|
/// NOTE: Сейчас не используется (структуры с состоянием агрегации кладутся без выравнивания).
|
2015-11-11 02:04:23 +00:00
|
|
|
|
size_t alignOfData() const override
|
2013-02-08 19:34:44 +00:00
|
|
|
|
{
|
|
|
|
|
return __alignof__(Data);
|
|
|
|
|
}
|
2011-09-19 03:40:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2016-05-28 15:42:22 +00:00
|
|
|
|
using AggregateFunctionPtr = std::shared_ptr<IAggregateFunction>;
|
2011-09-19 03:40:05 +00:00
|
|
|
|
|
|
|
|
|
}
|