1#include <IO/WriteBufferFromString.h>
2#include <IO/Operators.h>
3#include <Common/typeid_cast.h>
4
5#include <DataTypes/getMostSubtype.h>
6
7#include <DataTypes/DataTypeArray.h>
8#include <DataTypes/DataTypeTuple.h>
9#include <DataTypes/DataTypeNullable.h>
10#include <DataTypes/DataTypeNothing.h>
11#include <DataTypes/DataTypeString.h>
12#include <DataTypes/DataTypeDate.h>
13#include <DataTypes/DataTypesNumber.h>
14
15
16namespace DB
17{
18
19namespace ErrorCodes
20{
21extern const int BAD_ARGUMENTS;
22extern const int NO_COMMON_TYPE;
23}
24
25namespace
26{
27String getExceptionMessagePrefix(const DataTypes & types)
28{
29 WriteBufferFromOwnString res;
30 res << "There is no subtype for types ";
31
32 bool first = true;
33 for (const auto & type : types)
34 {
35 if (!first)
36 res << ", ";
37 first = false;
38
39 res << type->getName();
40 }
41
42 return res.str();
43}
44
45}
46
47
48DataTypePtr getMostSubtype(const DataTypes & types, bool throw_if_result_is_nothing, bool force_support_conversion)
49{
50
51 auto getNothingOrThrow = [throw_if_result_is_nothing, & types](const std::string & reason)
52 {
53 if (throw_if_result_is_nothing)
54 throw Exception(getExceptionMessagePrefix(types) + reason, ErrorCodes::NO_COMMON_TYPE);
55 return std::make_shared<DataTypeNothing>();
56 };
57
58 /// Trivial cases
59
60 if (types.empty())
61 {
62 if (throw_if_result_is_nothing)
63 throw Exception("There is no common type for empty type list", ErrorCodes::NO_COMMON_TYPE);
64 return std::make_shared<DataTypeNothing>();
65 }
66
67 if (types.size() == 1)
68 {
69 if (throw_if_result_is_nothing && typeid_cast<const DataTypeNothing *>(types[0].get()))
70 throw Exception("There is no common type for type Nothing", ErrorCodes::NO_COMMON_TYPE);
71 return types[0];
72 }
73
74 /// All types are equal
75 {
76 bool all_equal = true;
77 for (size_t i = 1, size = types.size(); i < size; ++i)
78 {
79 if (!types[i]->equals(*types[0]))
80 {
81 all_equal = false;
82 break;
83 }
84 }
85
86 if (all_equal)
87 return types[0];
88 }
89
90 /// Recursive rules
91
92 /// If there are Nothing types, result is Nothing
93 {
94 for (const auto & type : types)
95 if (typeid_cast<const DataTypeNothing *>(type.get()))
96 return getNothingOrThrow(" because some of them are Nothing");
97 }
98
99 /// For Arrays
100 {
101 bool have_array = false;
102 bool all_arrays = true;
103
104 DataTypes nested_types;
105 nested_types.reserve(types.size());
106
107 for (const auto & type : types)
108 {
109 if (const auto type_array = typeid_cast<const DataTypeArray *>(type.get()))
110 {
111 have_array = true;
112 nested_types.emplace_back(type_array->getNestedType());
113 }
114 else
115 all_arrays = false;
116 }
117
118 if (have_array)
119 {
120 if (!all_arrays)
121 return getNothingOrThrow(" because some of them are Array and some of them are not");
122
123 return std::make_shared<DataTypeArray>(getMostSubtype(nested_types, false, force_support_conversion));
124 }
125 }
126
127 /// For tuples
128 {
129 bool have_tuple = false;
130 bool all_tuples = true;
131 size_t tuple_size = 0;
132
133 std::vector<DataTypes> nested_types;
134
135 for (const auto & type : types)
136 {
137 if (const auto type_tuple = typeid_cast<const DataTypeTuple *>(type.get()))
138 {
139 if (!have_tuple)
140 {
141 tuple_size = type_tuple->getElements().size();
142 nested_types.resize(tuple_size);
143 for (size_t elem_idx = 0; elem_idx < tuple_size; ++elem_idx)
144 nested_types[elem_idx].reserve(types.size());
145 }
146 else if (tuple_size != type_tuple->getElements().size())
147 return getNothingOrThrow(" because Tuples have different sizes");
148
149 have_tuple = true;
150
151 for (size_t elem_idx = 0; elem_idx < tuple_size; ++elem_idx)
152 nested_types[elem_idx].emplace_back(type_tuple->getElements()[elem_idx]);
153 }
154 else
155 all_tuples = false;
156 }
157
158 if (have_tuple)
159 {
160 if (!all_tuples)
161 return getNothingOrThrow(" because some of them are Tuple and some of them are not");
162
163 DataTypes common_tuple_types(tuple_size);
164 for (size_t elem_idx = 0; elem_idx < tuple_size; ++elem_idx)
165 common_tuple_types[elem_idx] =
166 getMostSubtype(nested_types[elem_idx], throw_if_result_is_nothing, force_support_conversion);
167
168 return std::make_shared<DataTypeTuple>(common_tuple_types);
169 }
170 }
171
172 /// For Nullable
173 {
174 bool all_nullable = true;
175 bool have_nullable = false;
176
177 DataTypes nested_types;
178 nested_types.reserve(types.size());
179
180 for (const auto & type : types)
181 {
182 if (const auto type_nullable = typeid_cast<const DataTypeNullable *>(type.get()))
183 {
184 have_nullable = true;
185 nested_types.emplace_back(type_nullable->getNestedType());
186 }
187 else
188 {
189 all_nullable = false;
190 nested_types.emplace_back(type);
191 }
192 }
193
194 if (have_nullable)
195 {
196 if (all_nullable || force_support_conversion)
197 return std::make_shared<DataTypeNullable>(getMostSubtype(nested_types, false, force_support_conversion));
198
199 return getMostSubtype(nested_types, throw_if_result_is_nothing, force_support_conversion);
200 }
201 }
202
203 /// Non-recursive rules
204
205 /// For String and FixedString, the common type is FixedString.
206 /// For different FixedStrings, the common type is Nothing.
207 /// No other types are compatible with Strings. TODO Enums?
208 {
209 bool have_string = false;
210 bool all_strings = true;
211
212 DataTypePtr fixed_string_type = nullptr;
213
214 for (const auto & type : types)
215 {
216 if (isFixedString(type))
217 {
218 have_string = true;
219 if (!fixed_string_type)
220 fixed_string_type = type;
221 else if (!type->equals(*fixed_string_type))
222 return getNothingOrThrow(" because some of them are FixedStrings with different length");
223 }
224 else if (isString(type))
225 have_string = true;
226 else
227 all_strings = false;
228 }
229
230 if (have_string)
231 {
232 if (!all_strings)
233 return getNothingOrThrow(" because some of them are String/FixedString and some of them are not");
234
235 return fixed_string_type ? fixed_string_type : std::make_shared<DataTypeString>();
236 }
237 }
238
239 /// For Date and DateTime, the common type is Date. No other types are compatible.
240 {
241 bool have_date_or_datetime = false;
242 bool all_date_or_datetime = true;
243
244 for (const auto & type : types)
245 {
246 if (isDateOrDateTime(type))
247 have_date_or_datetime = true;
248 else
249 all_date_or_datetime = false;
250 }
251
252 if (have_date_or_datetime)
253 {
254 if (!all_date_or_datetime)
255 return getNothingOrThrow(" because some of them are Date/DateTime and some of them are not");
256
257 return std::make_shared<DataTypeDate>();
258 }
259 }
260
261 /// For numeric types, the most complicated part.
262 {
263 bool all_numbers = true;
264
265 size_t min_bits_of_signed_integer = 0;
266 size_t min_bits_of_unsigned_integer = 0;
267 size_t min_mantissa_bits_of_floating = 0;
268
269 auto minimize = [](size_t & what, size_t value)
270 {
271 if (what == 0 || value < what)
272 what = value;
273 };
274
275 for (const auto & type : types)
276 {
277 if (typeid_cast<const DataTypeUInt8 *>(type.get()))
278 minimize(min_bits_of_unsigned_integer, 8);
279 else if (typeid_cast<const DataTypeUInt16 *>(type.get()))
280 minimize(min_bits_of_unsigned_integer, 16);
281 else if (typeid_cast<const DataTypeUInt32 *>(type.get()))
282 minimize(min_bits_of_unsigned_integer, 32);
283 else if (typeid_cast<const DataTypeUInt64 *>(type.get()))
284 minimize(min_bits_of_unsigned_integer, 64);
285 else if (typeid_cast<const DataTypeInt8 *>(type.get()))
286 minimize(min_bits_of_signed_integer, 8);
287 else if (typeid_cast<const DataTypeInt16 *>(type.get()))
288 minimize(min_bits_of_signed_integer, 16);
289 else if (typeid_cast<const DataTypeInt32 *>(type.get()))
290 minimize(min_bits_of_signed_integer, 32);
291 else if (typeid_cast<const DataTypeInt64 *>(type.get()))
292 minimize(min_bits_of_signed_integer, 64);
293 else if (typeid_cast<const DataTypeFloat32 *>(type.get()))
294 minimize(min_mantissa_bits_of_floating, 24);
295 else if (typeid_cast<const DataTypeFloat64 *>(type.get()))
296 minimize(min_mantissa_bits_of_floating, 53);
297 else
298 all_numbers = false;
299 }
300
301 if (min_bits_of_signed_integer || min_bits_of_unsigned_integer || min_mantissa_bits_of_floating)
302 {
303 if (!all_numbers)
304 return getNothingOrThrow(" because some of them are numbers and some of them are not");
305
306 /// If the result must be floating.
307 if (!min_bits_of_signed_integer && !min_bits_of_unsigned_integer)
308 {
309 if (min_mantissa_bits_of_floating <= 24)
310 return std::make_shared<DataTypeFloat32>();
311 else if (min_mantissa_bits_of_floating <= 53)
312 return std::make_shared<DataTypeFloat64>();
313 else
314 throw Exception("Logical error: " + getExceptionMessagePrefix(types)
315 + " but as all data types are floats, we must have found maximum float type", ErrorCodes::NO_COMMON_TYPE);
316 }
317
318 /// If there are signed and unsigned types of same bit-width, the result must be unsigned number.
319 if (min_bits_of_unsigned_integer &&
320 (min_bits_of_signed_integer == 0 || min_bits_of_unsigned_integer <= min_bits_of_signed_integer))
321 {
322 if (min_bits_of_unsigned_integer <= 8)
323 return std::make_shared<DataTypeUInt8>();
324 else if (min_bits_of_unsigned_integer <= 16)
325 return std::make_shared<DataTypeUInt16>();
326 else if (min_bits_of_unsigned_integer <= 32)
327 return std::make_shared<DataTypeUInt32>();
328 else if (min_bits_of_unsigned_integer <= 64)
329 return std::make_shared<DataTypeUInt64>();
330 else
331 throw Exception("Logical error: " + getExceptionMessagePrefix(types)
332 + " but as all data types are integers, we must have found maximum unsigned integer type", ErrorCodes::NO_COMMON_TYPE);
333 }
334
335 /// All signed.
336 {
337 if (min_bits_of_signed_integer <= 8)
338 return std::make_shared<DataTypeInt8>();
339 else if (min_bits_of_signed_integer <= 16)
340 return std::make_shared<DataTypeInt16>();
341 else if (min_bits_of_signed_integer <= 32)
342 return std::make_shared<DataTypeInt32>();
343 else if (min_bits_of_signed_integer <= 64)
344 return std::make_shared<DataTypeInt64>();
345 else
346 throw Exception("Logical error: " + getExceptionMessagePrefix(types)
347 + " but as all data types are integers, we must have found maximum signed integer type", ErrorCodes::NO_COMMON_TYPE);
348 }
349 }
350 }
351
352 /// All other data types (UUID, AggregateFunction, Enum...) are compatible only if they are the same (checked in trivial cases).
353 return getNothingOrThrow("");
354}
355
356}
357