dbms: development [#CONV-2944].

This commit is contained in:
Alexey Milovidov 2011-09-19 03:40:05 +00:00
parent 4164a38d79
commit 5c7ea6af1f
6 changed files with 249 additions and 0 deletions

View File

@ -0,0 +1,60 @@
#pragma once
#include <DB/IO/WriteHelpers.h>
#include <DB/IO/ReadHelpers.h>
#include <DB/DataTypes/DataTypesNumberVariable.h>
#include <DB/AggregateFunctions/INullaryAggregateFunction.h>
namespace DB
{
/// Просто считает, сколько раз её вызвали
class AggregateFunctionCount : public INullaryAggregateFunction
{
private:
UInt64 count;
public:
AggregateFunctionCount() : count(0) {}
String getName() const { return "count"; }
AggregateFunctionPtr cloneEmpty() const
{
return new AggregateFunctionCount;
}
DataTypePtr getReturnType() const
{
return new DataTypeVarUInt;
}
void addZero() { ++count; }
void merge(const IAggregateFunction & rhs)
{
count += static_cast<const AggregateFunctionCount &>(rhs).count;
}
void serialize(WriteBuffer & buf) const
{
writeVarUInt(count, buf);
}
void deserializeMerge(ReadBuffer & buf)
{
UInt64 tmp;
readVarUInt(tmp, buf);
count += tmp;
}
Field getResult() const
{
return count;
}
};
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <Poco/RegularExpression.h>
#include <DB/AggregateFunctions/IAggregateFunction.h>
namespace DB
{
/** Позволяет создать агрегатную функцию по её имени.
*/
class AggregateFunctionFactory
{
public:
AggregateFunctionFactory();
AggregateFunctionPtr get(const String & name) const;
AggregateFunctionPtr tryGet(const String & name) const;
private:
typedef std::map<String, AggregateFunctionPtr> NonParametricAggregateFunctions;
NonParametricAggregateFunctions non_parametric_aggregate_functions;
};
using Poco::SharedPtr;
typedef SharedPtr<AggregateFunctionFactory> AggregateFunctionFactoryPtr;
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <Poco/SharedPtr.h>
#include <DB/Core/Row.h>
#include <DB/DataTypes/IDataType.h>
namespace DB
{
/** Интерфейс для агрегатных функций.
* Агрегатные функции аккумулируют значения, которые в них передают, держа в себе некоторое состояние.
*/
class IAggregateFunction
{
public:
/// Получить основное имя функции.
virtual String getName() const = 0;
/// Создать новую агрегатную функцию того же типа.
virtual SharedPtr<IAggregateFunction> cloneEmpty() const = 0;
/** Указать типы аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
* Необходимо вызывать перед остальными вызовами.
*/
virtual void setArguments(const DataTypes & arguments) = 0;
/// Получить тип результата.
virtual DataTypePtr getReturnType() const = 0;
/// Добавить значение.
virtual void add(const Row & row) = 0;
/// Объединить состояние с другой агрегатной функцией.
virtual void merge(const IAggregateFunction & rhs) = 0;
/// Сериализовать состояние (например, для передачи по сети).
virtual void serialize(WriteBuffer & buf) const = 0;
/// Десериализовать состояние и объединить своё состояние с ним.
virtual void deserializeMerge(ReadBuffer & buf) = 0;
/// Получить результат
virtual Field getResult() const = 0;
};
using Poco::SharedPtr;
typedef SharedPtr<IAggregateFunction> AggregateFunctionPtr;
typedef std::vector<AggregateFunctionPtr> AggregateFunctions;
template <> struct TypeName<AggregateFunctionPtr> { static std::string get() { return "AggregateFunctionPtr"; } };
template <> struct NearestFieldType<AggregateFunctionPtr> { typedef AggregateFunctionPtr Type; };
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <DB/AggregateFunctions/IAggregateFunction.h>
namespace DB
{
/** Интерфейс для ноль-арных агрегатных функций. Это, например, агрегатная функция count.
*/
class INullaryAggregateFunction : public IAggregateFunction
{
public:
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
void setArguments(const DataTypes & arguments)
{
if (arguments.size() != 0)
throw Exception("Passed " + Poco::NumberFormatter::format(arguments.size()) + " arguments to nullary aggregate function " + getName(),
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
}
/// Добавить значение.
void add(const Row & row)
{
addZero();
}
virtual void addZero() = 0;
};
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <DB/AggregateFunctions/IAggregateFunction.h>
namespace DB
{
/** Интерфейс для агрегатных функций, принимающих одно значение. Это почти все агрегатные функции.
*/
class IUnaryAggregateFunction : public IAggregateFunction
{
public:
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
void setArguments(const DataTypes & arguments)
{
if (arguments.size() != 1)
throw Exception("Passed " + Poco::NumberFormatter::format(arguments.size()) + " arguments to unary aggregate function " + getName(),
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
}
/// Добавить значение.
void add(const Row & row)
{
addOne(row[0]);
}
virtual void addOne(const Field & value) = 0;
};
}

View File

@ -0,0 +1,39 @@
#include <boost/assign/list_inserter.hpp>
#include <DB/AggregateFunctions/AggregateFunctionCount.h>
#include <DB/AggregateFunctions/AggregateFunctionFactory.h>
namespace DB
{
AggregateFunctionFactory::AggregateFunctionFactory()
{
boost::assign::insert(non_parametric_aggregate_functions)
("count", new AggregateFunctionCount)
;
}
AggregateFunctionPtr AggregateFunctionFactory::get(const String & name) const
{
NonParametricAggregateFunctions::const_iterator it = non_parametric_aggregate_functions.find(name);
if (it != non_parametric_aggregate_functions.end())
return it->second->cloneEmpty();
throw Exception("Unknown aggregate function " + name, ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION);
}
AggregateFunctionPtr AggregateFunctionFactory::tryGet(const String & name) const
{
NonParametricAggregateFunctions::const_iterator it = non_parametric_aggregate_functions.find(name);
if (it != non_parametric_aggregate_functions.end())
return it->second->cloneEmpty();
return NULL;
}
}