-
Notifications
You must be signed in to change notification settings - Fork 112
Expand file tree
/
Copy pathregisterDataTypeDateTime.cpp
More file actions
129 lines (103 loc) · 5.44 KB
/
Copy pathregisterDataTypeDateTime.cpp
File metadata and controls
129 lines (103 loc) · 5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <Core/Field.h>
#include <Parsers/IAST.h>
#include <Parsers/ASTLiteral.h>
#include <DataTypes/IDataType.h>
#include <DataTypes/DataTypeDateTime.h>
#include <DataTypes/DataTypeDateTime64.h>
#include <DataTypes/DataTypeFactory.h>
namespace DB
{
namespace ErrorCodes
{
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
}
enum class ArgumentKind
{
Optional,
Mandatory
};
PreformattedMessage getExceptionMessage(
const String & message, size_t argument_index, const char * argument_name,
const std::string & context_data_type_name, Field::Types::Which field_type)
{
return PreformattedMessage::create("Parameter #{} '{}' for {}{}, expected {} literal",
argument_index, argument_name, context_data_type_name, message, field_type);
}
template <typename T, ArgumentKind Kind>
std::conditional_t<Kind == ArgumentKind::Optional, std::optional<T>, T>
getArgument(const ASTPtr & arguments, size_t argument_index, const char * argument_name [[maybe_unused]], const std::string context_data_type_name)
{
using NearestResultType = NearestFieldType<T>;
const auto field_type = Field::TypeToEnum<NearestResultType>::value;
const ASTLiteral * argument = nullptr;
if (!arguments || arguments->children.size() <= argument_index
|| !(argument = arguments->children[argument_index]->as<ASTLiteral>())
|| argument->value.getType() != field_type)
{
if constexpr (Kind == ArgumentKind::Optional)
return {};
else
{
if (argument && argument->value.getType() != field_type)
throw Exception(getExceptionMessage(fmt::format(" has wrong type: {}", argument->value.getTypeName()),
argument_index, argument_name, context_data_type_name, field_type), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
else
throw Exception(getExceptionMessage(" is missing", argument_index, argument_name, context_data_type_name, field_type),
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
}
}
return argument->value.get<NearestResultType>();
}
static DataTypePtr create(const ASTPtr & arguments/* proton: starts */, [[maybe_unused]] bool compatible_with_clickhouse/* proton: ends */)
{
if (!arguments || arguments->children.empty())
return std::make_shared<DataTypeDateTime>();
const auto scale = getArgument<UInt64, ArgumentKind::Optional>(arguments, 0, "scale", "datetime");
const auto timezone = getArgument<String, ArgumentKind::Optional>(arguments, !!scale, "timezone", "datetime");
if (!scale && !timezone)
throw Exception(getExceptionMessage(" has wrong type: ", 0, "scale", "DateTime", Field::Types::Which::UInt64),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
/// If scale is defined, the data type is DateTime when scale = 0 otherwise the data type is DateTime64
if (scale && scale.value() != 0)
return std::make_shared<DataTypeDateTime64>(scale.value(), timezone.value_or(String{}));
return std::make_shared<DataTypeDateTime>(timezone.value_or(String{}));
}
static DataTypePtr create32(const ASTPtr & arguments, [[maybe_unused]] bool compatible_with_clickhouse = false) /// proton: updated
{
if (!arguments || arguments->children.empty())
return std::make_shared<DataTypeDateTime>();
if (arguments->children.size() != 1)
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"The datetime32 data type can optionally have only one argument - time zone name");
const auto * argument = arguments->children[0]->as<ASTLiteral>();
if (argument && argument->value.getType() == Field::Types::Which::UInt64)
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
"The datetime32 data type does not support precision. Use datetime64 for fractional seconds");
const auto timezone = getArgument<String, ArgumentKind::Mandatory>(arguments, 0, "timezone", "datetime32");
return std::make_shared<DataTypeDateTime>(timezone);
}
static DataTypePtr create64(const ASTPtr & arguments, [[maybe_unused]] bool compatible_with_clickhouse = false) /// proton: updated
{
if (!arguments || arguments->children.empty())
return std::make_shared<DataTypeDateTime64>(DataTypeDateTime64::default_scale);
if (arguments->children.size() > 2)
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"The datetime64 data type can optionally have two argument - scale and time zone name");
const auto scale = getArgument<UInt64, ArgumentKind::Mandatory>(arguments, 0, "scale", "datetime64");
const auto timezone = getArgument<String, ArgumentKind::Optional>(arguments, 1, "timezone", "datetime64");
return std::make_shared<DataTypeDateTime64>(scale, timezone.value_or(String{}));
}
void registerDataTypeDateTime(DataTypeFactory & factory)
{
factory.registerDataType("datetime", create, DataTypeFactory::CaseInsensitive);
factory.registerDataType("datetime32", create32, DataTypeFactory::CaseInsensitive);
factory.registerDataType("datetime64", create64, DataTypeFactory::CaseInsensitive);
/// factory.registerAlias("TIMESTAMP", "datetime", DataTypeFactory::CaseInsensitive);
/// proton: starts
factory.registerClickHouseAlias("Datetime", "datetime");
factory.registerClickHouseAlias("Datetime32", "datetime32");
factory.registerClickHouseAlias("Datetime64", "datetime64");
/// proton: ends
}
}