1 | #include <DataTypes/DataTypeFactory.h> |
2 | #include <DataTypes/DataTypeCustom.h> |
3 | #include <Parsers/parseQuery.h> |
4 | #include <Parsers/ParserCreateQuery.h> |
5 | #include <Parsers/ASTFunction.h> |
6 | #include <Parsers/ASTIdentifier.h> |
7 | #include <Parsers/ASTLiteral.h> |
8 | #include <Common/typeid_cast.h> |
9 | #include <Poco/String.h> |
10 | #include <Common/StringUtils/StringUtils.h> |
11 | #include <IO/WriteHelpers.h> |
12 | |
13 | namespace DB |
14 | { |
15 | |
16 | namespace ErrorCodes |
17 | { |
18 | extern const int LOGICAL_ERROR; |
19 | extern const int UNKNOWN_TYPE; |
20 | extern const int ILLEGAL_SYNTAX_FOR_DATA_TYPE; |
21 | extern const int UNEXPECTED_AST_STRUCTURE; |
22 | extern const int DATA_TYPE_CANNOT_HAVE_ARGUMENTS; |
23 | } |
24 | |
25 | |
26 | DataTypePtr DataTypeFactory::get(const String & full_name) const |
27 | { |
28 | ParserIdentifierWithOptionalParameters parser; |
29 | ASTPtr ast = parseQuery(parser, full_name.data(), full_name.data() + full_name.size(), "data type" , 0); |
30 | return get(ast); |
31 | } |
32 | |
33 | DataTypePtr DataTypeFactory::get(const ASTPtr & ast) const |
34 | { |
35 | if (const auto * func = ast->as<ASTFunction>()) |
36 | { |
37 | if (func->parameters) |
38 | throw Exception("Data type cannot have multiple parenthesed parameters." , ErrorCodes::ILLEGAL_SYNTAX_FOR_DATA_TYPE); |
39 | return get(func->name, func->arguments); |
40 | } |
41 | |
42 | if (const auto * ident = ast->as<ASTIdentifier>()) |
43 | { |
44 | return get(ident->name, {}); |
45 | } |
46 | |
47 | if (const auto * lit = ast->as<ASTLiteral>()) |
48 | { |
49 | if (lit->value.isNull()) |
50 | return get("Null" , {}); |
51 | } |
52 | |
53 | throw Exception("Unexpected AST element for data type." , ErrorCodes::UNEXPECTED_AST_STRUCTURE); |
54 | } |
55 | |
56 | DataTypePtr DataTypeFactory::get(const String & family_name_param, const ASTPtr & parameters) const |
57 | { |
58 | String family_name = getAliasToOrName(family_name_param); |
59 | |
60 | if (endsWith(family_name, "WithDictionary" )) |
61 | { |
62 | ASTPtr low_cardinality_params = std::make_shared<ASTExpressionList>(); |
63 | String param_name = family_name.substr(0, family_name.size() - strlen("WithDictionary" )); |
64 | if (parameters) |
65 | { |
66 | auto func = std::make_shared<ASTFunction>(); |
67 | func->name = param_name; |
68 | func->arguments = parameters; |
69 | low_cardinality_params->children.push_back(func); |
70 | } |
71 | else |
72 | low_cardinality_params->children.push_back(std::make_shared<ASTIdentifier>(param_name)); |
73 | |
74 | return get("LowCardinality" , low_cardinality_params); |
75 | } |
76 | |
77 | return findCreatorByName(family_name)(family_name_param, parameters); |
78 | } |
79 | |
80 | |
81 | void DataTypeFactory::registerDataType(const String & family_name, Creator creator, CaseSensitiveness case_sensitiveness) |
82 | { |
83 | if (creator == nullptr) |
84 | throw Exception("DataTypeFactory: the data type family " + family_name + " has been provided " |
85 | " a null constructor" , ErrorCodes::LOGICAL_ERROR); |
86 | |
87 | String family_name_lowercase = Poco::toLower(family_name); |
88 | |
89 | if (isAlias(family_name) || isAlias(family_name_lowercase)) |
90 | throw Exception("DataTypeFactory: the data type family name '" + family_name + "' is already registered as alias" , |
91 | ErrorCodes::LOGICAL_ERROR); |
92 | |
93 | if (!data_types.emplace(family_name, creator).second) |
94 | throw Exception("DataTypeFactory: the data type family name '" + family_name + "' is not unique" , |
95 | ErrorCodes::LOGICAL_ERROR); |
96 | |
97 | |
98 | if (case_sensitiveness == CaseInsensitive |
99 | && !case_insensitive_data_types.emplace(family_name_lowercase, creator).second) |
100 | throw Exception("DataTypeFactory: the case insensitive data type family name '" + family_name + "' is not unique" , |
101 | ErrorCodes::LOGICAL_ERROR); |
102 | } |
103 | |
104 | void DataTypeFactory::registerSimpleDataType(const String & name, SimpleCreator creator, CaseSensitiveness case_sensitiveness) |
105 | { |
106 | if (creator == nullptr) |
107 | throw Exception("DataTypeFactory: the data type " + name + " has been provided " |
108 | " a null constructor" , ErrorCodes::LOGICAL_ERROR); |
109 | |
110 | registerDataType(name, [name, creator](const String & type_name, const ASTPtr & ast) |
111 | { |
112 | if (ast) |
113 | throw Exception("Data type " + name + " cannot have arguments" , ErrorCodes::DATA_TYPE_CANNOT_HAVE_ARGUMENTS); |
114 | return creator(type_name); |
115 | }, case_sensitiveness); |
116 | } |
117 | |
118 | void DataTypeFactory::registerDataTypeCustom(const String & family_name, CreatorWithCustom creator, CaseSensitiveness case_sensitiveness) |
119 | { |
120 | registerDataType(family_name, [creator](const String & type_name, const ASTPtr & ast) |
121 | { |
122 | auto res = creator(type_name, ast); |
123 | res.first->setCustomization(std::move(res.second)); |
124 | |
125 | return res.first; |
126 | }, case_sensitiveness); |
127 | } |
128 | |
129 | void DataTypeFactory::registerSimpleDataTypeCustom(const String & name, SimpleCreatorWithCustom creator, CaseSensitiveness case_sensitiveness) |
130 | { |
131 | registerDataTypeCustom(name, [creator](const String & type_name, const ASTPtr & /*ast*/) |
132 | { |
133 | return creator(type_name); |
134 | }, case_sensitiveness); |
135 | } |
136 | |
137 | const DataTypeFactory::Creator& DataTypeFactory::findCreatorByName(const String & family_name) const |
138 | { |
139 | { |
140 | DataTypesDictionary::const_iterator it = data_types.find(family_name); |
141 | if (data_types.end() != it) |
142 | return it->second; |
143 | } |
144 | |
145 | String family_name_lowercase = Poco::toLower(family_name); |
146 | |
147 | { |
148 | DataTypesDictionary::const_iterator it = case_insensitive_data_types.find(family_name_lowercase); |
149 | if (case_insensitive_data_types.end() != it) |
150 | return it->second; |
151 | } |
152 | |
153 | auto hints = this->getHints(family_name); |
154 | if (!hints.empty()) |
155 | throw Exception("Unknown data type family: " + family_name + ". Maybe you meant: " + toString(hints), ErrorCodes::UNKNOWN_TYPE); |
156 | else |
157 | throw Exception("Unknown data type family: " + family_name, ErrorCodes::UNKNOWN_TYPE); |
158 | } |
159 | |
160 | DataTypeFactory::DataTypeFactory() |
161 | { |
162 | registerDataTypeNumbers(*this); |
163 | registerDataTypeDecimal(*this); |
164 | registerDataTypeDate(*this); |
165 | registerDataTypeDateTime(*this); |
166 | registerDataTypeDateTime64(*this); |
167 | registerDataTypeString(*this); |
168 | registerDataTypeFixedString(*this); |
169 | registerDataTypeEnum(*this); |
170 | registerDataTypeArray(*this); |
171 | registerDataTypeTuple(*this); |
172 | registerDataTypeNullable(*this); |
173 | registerDataTypeNothing(*this); |
174 | registerDataTypeUUID(*this); |
175 | registerDataTypeAggregateFunction(*this); |
176 | registerDataTypeNested(*this); |
177 | registerDataTypeInterval(*this); |
178 | registerDataTypeLowCardinality(*this); |
179 | registerDataTypeDomainIPv4AndIPv6(*this); |
180 | registerDataTypeDomainSimpleAggregateFunction(*this); |
181 | } |
182 | |
183 | DataTypeFactory::~DataTypeFactory() |
184 | {} |
185 | |
186 | DataTypeFactory & DataTypeFactory::instance() |
187 | { |
188 | static DataTypeFactory ret; |
189 | return ret; |
190 | } |
191 | |
192 | } |
193 | |