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
13namespace DB
14{
15
16namespace 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
26DataTypePtr 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
33DataTypePtr 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
56DataTypePtr 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
81void 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
104void 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
118void 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
129void 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
137const 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
160DataTypeFactory::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
183DataTypeFactory::~DataTypeFactory()
184{}
185
186DataTypeFactory & DataTypeFactory::instance()
187{
188 static DataTypeFactory ret;
189 return ret;
190}
191
192}
193