ClickHouse

Форк
0
/
toTimezone.cpp 
139 строк · 4.7 Кб
1
#include <DataTypes/DataTypeDateTime.h>
2
#include <DataTypes/DataTypeDateTime64.h>
3

4
#include <Functions/IFunction.h>
5
#include <Functions/FunctionFactory.h>
6
#include <Functions/extractTimeZoneFromFunctionArguments.h>
7

8
#include <Interpreters/Context.h>
9

10
#include <IO/WriteHelpers.h>
11
#include <Common/assert_cast.h>
12

13
namespace DB
14
{
15
namespace ErrorCodes
16
{
17
    extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
18
    extern const int ILLEGAL_TYPE_OF_ARGUMENT;
19
}
20

21
namespace
22
{
23
class ExecutableFunctionToTimeZone : public IExecutableFunction
24
{
25
public:
26
    explicit ExecutableFunctionToTimeZone() = default;
27

28
    String getName() const override { return "toTimezone"; }
29

30
    ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t /*input_rows_count*/) const override
31
    {
32
        return arguments[0].column;
33
    }
34
};
35

36
class FunctionBaseToTimeZone : public IFunctionBase
37
{
38
public:
39
    FunctionBaseToTimeZone(
40
        bool is_constant_timezone_,
41
        DataTypes argument_types_,
42
        DataTypePtr return_type_)
43
        : is_constant_timezone(is_constant_timezone_)
44
        , argument_types(std::move(argument_types_))
45
        , return_type(std::move(return_type_)) {}
46

47
    String getName() const override { return "toTimezone"; }
48

49
    bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
50

51
    const DataTypes & getArgumentTypes() const override
52
    {
53
        return argument_types;
54
    }
55

56
    const DataTypePtr & getResultType() const override
57
    {
58
        return return_type;
59
    }
60

61
    ExecutableFunctionPtr prepare(const ColumnsWithTypeAndName & /*arguments*/) const override
62
    {
63
        return std::make_unique<ExecutableFunctionToTimeZone>();
64
    }
65

66
    bool hasInformationAboutMonotonicity() const override { return is_constant_timezone; }
67

68
    Monotonicity getMonotonicityForRange(const IDataType & /*type*/, const Field & /*left*/, const Field & /*right*/) const override
69
    {
70
        const bool b = is_constant_timezone;
71
        return { .is_monotonic = b, .is_positive = b, .is_always_monotonic = b, .is_strict = b };
72
    }
73

74
private:
75
    bool is_constant_timezone;
76
    DataTypes argument_types;
77
    DataTypePtr return_type;
78
};
79

80
/// Just changes time zone information for data type. The calculation is free.
81
class ToTimeZoneOverloadResolver : public IFunctionOverloadResolver
82
{
83
public:
84
    static constexpr auto name = "toTimezone";
85

86
    String getName() const override { return name; }
87

88
    size_t getNumberOfArguments() const override { return 2; }
89
    static FunctionOverloadResolverPtr create(ContextPtr context) { return std::make_unique<ToTimeZoneOverloadResolver>(context); }
90
    explicit ToTimeZoneOverloadResolver(ContextPtr context)
91
        : allow_nonconst_timezone_arguments(context->getSettings().allow_nonconst_timezone_arguments)
92
    {}
93

94
    DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
95
    {
96
        if (arguments.size() != 2)
97
            throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
98
                "Number of arguments for function {} doesn't match: passed {}, should be 2",
99
                getName(), arguments.size());
100

101
        const auto which_type = WhichDataType(arguments[0].type);
102
        if (!which_type.isDateTime() && !which_type.isDateTime64())
103
            throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type {} of argument of function {}. "
104
                "Should be DateTime or DateTime64", arguments[0].type->getName(), getName());
105

106
        String time_zone_name = extractTimeZoneNameFromFunctionArguments(arguments, 1, 0, allow_nonconst_timezone_arguments);
107

108
        if (which_type.isDateTime())
109
            return std::make_shared<DataTypeDateTime>(time_zone_name);
110

111
        const auto * date_time64 = assert_cast<const DataTypeDateTime64 *>(arguments[0].type.get());
112
        return std::make_shared<DataTypeDateTime64>(date_time64->getScale(), time_zone_name);
113
    }
114

115
    FunctionBasePtr buildImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) const override
116
    {
117
        bool is_constant_timezone = false;
118
        if (arguments[1].column)
119
            is_constant_timezone = isColumnConst(*arguments[1].column);
120

121
        DataTypes data_types(arguments.size());
122
        for (size_t i = 0; i < arguments.size(); ++i)
123
            data_types[i] = arguments[i].type;
124

125
        return std::make_unique<FunctionBaseToTimeZone>(is_constant_timezone, data_types, result_type);
126
    }
127
private:
128
    const bool allow_nonconst_timezone_arguments;
129
};
130

131
}
132

133
REGISTER_FUNCTION(ToTimeZone)
134
{
135
    factory.registerFunction<ToTimeZoneOverloadResolver>();
136
    factory.registerAlias("toTimeZone", "toTimezone");
137
}
138

139
}
140

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.