ClickHouse/src/Functions/FunctionsWindow.h

156 lines
4.5 KiB
C++
Raw Normal View History

2020-01-14 03:08:54 +00:00
#pragma once
2021-11-19 13:09:12 +00:00
#include <base/DateLUT.h>
2021-06-01 03:01:35 +00:00
#include <DataTypes/DataTypeInterval.h>
#include <Functions/IFunction.h>
2020-01-14 03:08:54 +00:00
namespace DB
{
/** Window functions:
*
2020-02-02 03:54:54 +00:00
* TUMBLE(time_attr, interval [, timezone])
2021-05-29 10:29:38 +00:00
*
2020-01-14 03:08:54 +00:00
* TUMBLE_START(window_id)
2021-05-29 10:29:38 +00:00
*
2020-02-02 03:54:54 +00:00
* TUMBLE_START(time_attr, interval [, timezone])
2021-05-29 10:29:38 +00:00
*
2020-01-14 03:08:54 +00:00
* TUMBLE_END(window_id)
2021-05-29 10:29:38 +00:00
*
2020-02-02 03:54:54 +00:00
* TUMBLE_END(time_attr, interval [, timezone])
2021-05-29 10:29:38 +00:00
*
2020-02-02 03:54:54 +00:00
* HOP(time_attr, hop_interval, window_interval [, timezone])
2021-05-29 10:29:38 +00:00
*
2020-01-14 03:08:54 +00:00
* HOP_START(window_id)
2021-05-29 10:29:38 +00:00
*
2020-02-02 03:54:54 +00:00
* HOP_START(time_attr, hop_interval, window_interval [, timezone])
2021-05-29 10:29:38 +00:00
*
2020-01-14 03:08:54 +00:00
* HOP_END(window_id)
2021-05-29 10:29:38 +00:00
*
2020-02-02 03:54:54 +00:00
* HOP_END(time_attr, hop_interval, window_interval [, timezone])
2021-05-29 10:29:38 +00:00
*
2020-01-14 03:08:54 +00:00
*/
2020-01-14 16:24:26 +00:00
enum WindowFunctionName
2020-01-14 03:08:54 +00:00
{
TUMBLE,
TUMBLE_START,
TUMBLE_END,
HOP,
HOP_START,
2020-06-17 15:06:19 +00:00
HOP_END,
WINDOW_ID
2020-01-14 03:08:54 +00:00
};
template <IntervalKind::Kind unit>
struct ToStartOfTransform;
#define TRANSFORM_DATE(INTERVAL_KIND) \
template <> \
struct ToStartOfTransform<IntervalKind::INTERVAL_KIND> \
{ \
2021-05-28 07:36:19 +00:00
static ExtendedDayNum execute(UInt32 t, UInt64 delta, const DateLUTImpl & time_zone) \
2020-01-14 03:08:54 +00:00
{ \
return time_zone.toStartOf##INTERVAL_KIND##Interval(time_zone.toDayNum(t), delta); \
} \
};
TRANSFORM_DATE(Year)
TRANSFORM_DATE(Quarter)
TRANSFORM_DATE(Month)
TRANSFORM_DATE(Week)
#undef TRANSFORM_DATE
2020-07-27 09:32:15 +00:00
template <>
struct ToStartOfTransform<IntervalKind::Day>
{
static UInt32 execute(UInt32 t, UInt64 delta, const DateLUTImpl & time_zone)
{
return time_zone.toStartOfDayInterval(time_zone.toDayNum(t), delta);
}
};
2020-01-14 03:08:54 +00:00
#define TRANSFORM_TIME(INTERVAL_KIND) \
template <> \
struct ToStartOfTransform<IntervalKind::INTERVAL_KIND> \
{ \
static UInt32 execute(UInt32 t, UInt64 delta, const DateLUTImpl & time_zone) \
{ \
return time_zone.toStartOf##INTERVAL_KIND##Interval(t, delta); \
} \
};
TRANSFORM_TIME(Hour)
TRANSFORM_TIME(Minute)
TRANSFORM_TIME(Second)
#undef TRANSFORM_DATE
template <IntervalKind::Kind unit>
struct AddTime;
#define ADD_DATE(INTERVAL_KIND) \
template <> \
struct AddTime<IntervalKind::INTERVAL_KIND> \
{ \
2021-05-28 07:36:19 +00:00
static ExtendedDayNum execute(UInt16 d, UInt64 delta, const DateLUTImpl & time_zone) \
{ \
2021-05-28 07:36:19 +00:00
return time_zone.add##INTERVAL_KIND##s(ExtendedDayNum(d), delta); \
} \
2020-01-14 03:08:54 +00:00
};
ADD_DATE(Year)
ADD_DATE(Quarter)
ADD_DATE(Month)
#undef ADD_DATE
2020-07-27 09:32:15 +00:00
template <>
struct AddTime<IntervalKind::Week>
{
2021-05-28 07:36:19 +00:00
static ExtendedDayNum execute(UInt16 d, UInt64 delta, const DateLUTImpl &) { return ExtendedDayNum(d + 7 * delta);}
};
2020-01-14 03:08:54 +00:00
#define ADD_TIME(INTERVAL_KIND, INTERVAL) \
template <> \
struct AddTime<IntervalKind::INTERVAL_KIND> \
{ \
static UInt32 execute(UInt32 t, Int64 delta, const DateLUTImpl &) { return t + INTERVAL * delta; } \
};
ADD_TIME(Day, 86400)
2020-01-14 03:08:54 +00:00
ADD_TIME(Hour, 3600)
ADD_TIME(Minute, 60)
ADD_TIME(Second, 1)
#undef ADD_TIME
2021-05-29 10:29:38 +00:00
template <WindowFunctionName type>
struct WindowImpl
{
2021-06-01 03:01:35 +00:00
static constexpr auto name = "UNKNOWN";
2021-05-29 10:29:38 +00:00
2021-06-01 03:01:35 +00:00
static DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments, const String & function_name);
2021-05-29 10:29:38 +00:00
2021-06-01 03:01:35 +00:00
static ColumnPtr dispatchForColumns(const ColumnsWithTypeAndName & arguments, const String & function_name);
2020-01-14 03:08:54 +00:00
};
2020-01-14 16:24:26 +00:00
template <WindowFunctionName type>
2020-01-14 03:08:54 +00:00
class FunctionWindow : public IFunction
{
public:
2020-01-14 16:24:26 +00:00
static constexpr auto name = WindowImpl<type>::name;
2021-11-19 13:09:12 +00:00
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionWindow>(); }
2020-01-14 03:08:54 +00:00
String getName() const override { return name; }
2020-02-02 03:54:54 +00:00
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
2020-01-14 03:08:54 +00:00
bool useDefaultImplementationForConstants() const override { return true; }
2020-02-02 03:54:54 +00:00
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2, 3}; }
2021-11-19 13:09:12 +00:00
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo &) const override { return true; }
2020-01-14 03:08:54 +00:00
2021-06-01 03:01:35 +00:00
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override;
2020-01-14 03:08:54 +00:00
2021-06-01 03:01:35 +00:00
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t /*input_rows_count*/) const override;
2020-01-14 03:08:54 +00:00
};
2020-01-14 16:24:26 +00:00
using FunctionTumble = FunctionWindow<TUMBLE>;
using FunctionTumbleStart = FunctionWindow<TUMBLE_START>;
using FunctionTumbleEnd = FunctionWindow<TUMBLE_END>;
using FunctionHop = FunctionWindow<HOP>;
2020-06-17 15:06:19 +00:00
using FunctionWindowId = FunctionWindow<WINDOW_ID>;
2020-01-14 16:24:26 +00:00
using FunctionHopStart = FunctionWindow<HOP_START>;
using FunctionHopEnd = FunctionWindow<HOP_END>;
2020-01-14 03:08:54 +00:00
}