1#include <unordered_set>
2
3#include <IO/WriteBufferFromString.h>
4#include <IO/Operators.h>
5#include <Common/typeid_cast.h>
6
7#include <DataTypes/getLeastSupertype.h>
8
9#include <DataTypes/DataTypeArray.h>
10#include <DataTypes/DataTypeTuple.h>
11#include <DataTypes/DataTypeNullable.h>
12#include <DataTypes/DataTypeNothing.h>
13#include <DataTypes/DataTypeString.h>
14#include <DataTypes/DataTypeDateTime.h>
15#include <DataTypes/DataTypeDateTime64.h>
16#include <DataTypes/DataTypesNumber.h>
17#include <DataTypes/DataTypesDecimal.h>
18
19
20namespace DB
21{
22
23namespace ErrorCodes
24{
25 extern const int BAD_ARGUMENTS;
26 extern const int NO_COMMON_TYPE;
27}
28
29namespace
30{
31 String getExceptionMessagePrefix(const DataTypes & types)
32 {
33 WriteBufferFromOwnString res;
34 res << "There is no supertype for types ";
35
36 bool first = true;
37 for (const auto & type : types)
38 {
39 if (!first)
40 res << ", ";
41 first = false;
42
43 res << type->getName();
44 }
45
46 return res.str();
47 }
48}
49
50
51DataTypePtr getLeastSupertype(const DataTypes & types)
52{
53 /// Trivial cases
54
55 if (types.empty())
56 return std::make_shared<DataTypeNothing>();
57
58 if (types.size() == 1)
59 return types[0];
60
61 /// All types are equal
62 {
63 bool all_equal = true;
64 for (size_t i = 1, size = types.size(); i < size; ++i)
65 {
66 if (!types[i]->equals(*types[0]))
67 {
68 all_equal = false;
69 break;
70 }
71 }
72
73 if (all_equal)
74 return types[0];
75 }
76
77 /// Recursive rules
78
79 /// If there are Nothing types, skip them
80 {
81 DataTypes non_nothing_types;
82 non_nothing_types.reserve(types.size());
83
84 for (const auto & type : types)
85 if (!typeid_cast<const DataTypeNothing *>(type.get()))
86 non_nothing_types.emplace_back(type);
87
88 if (non_nothing_types.size() < types.size())
89 return getLeastSupertype(non_nothing_types);
90 }
91
92 /// For Arrays
93 {
94 bool have_array = false;
95 bool all_arrays = true;
96
97 DataTypes nested_types;
98 nested_types.reserve(types.size());
99
100 for (const auto & type : types)
101 {
102 if (const DataTypeArray * type_array = typeid_cast<const DataTypeArray *>(type.get()))
103 {
104 have_array = true;
105 nested_types.emplace_back(type_array->getNestedType());
106 }
107 else
108 all_arrays = false;
109 }
110
111 if (have_array)
112 {
113 if (!all_arrays)
114 throw Exception(getExceptionMessagePrefix(types) + " because some of them are Array and some of them are not", ErrorCodes::NO_COMMON_TYPE);
115
116 return std::make_shared<DataTypeArray>(getLeastSupertype(nested_types));
117 }
118 }
119
120 /// For tuples
121 {
122 bool have_tuple = false;
123 bool all_tuples = true;
124 size_t tuple_size = 0;
125
126 std::vector<DataTypes> nested_types;
127
128 for (const auto & type : types)
129 {
130 if (const DataTypeTuple * type_tuple = typeid_cast<const DataTypeTuple *>(type.get()))
131 {
132 if (!have_tuple)
133 {
134 tuple_size = type_tuple->getElements().size();
135 nested_types.resize(tuple_size);
136 for (size_t elem_idx = 0; elem_idx < tuple_size; ++elem_idx)
137 nested_types[elem_idx].reserve(types.size());
138 }
139 else if (tuple_size != type_tuple->getElements().size())
140 throw Exception(getExceptionMessagePrefix(types) + " because Tuples have different sizes", ErrorCodes::NO_COMMON_TYPE);
141
142 have_tuple = true;
143
144 for (size_t elem_idx = 0; elem_idx < tuple_size; ++elem_idx)
145 nested_types[elem_idx].emplace_back(type_tuple->getElements()[elem_idx]);
146 }
147 else
148 all_tuples = false;
149 }
150
151 if (have_tuple)
152 {
153 if (!all_tuples)
154 throw Exception(getExceptionMessagePrefix(types) + " because some of them are Tuple and some of them are not", ErrorCodes::NO_COMMON_TYPE);
155
156 DataTypes common_tuple_types(tuple_size);
157 for (size_t elem_idx = 0; elem_idx < tuple_size; ++elem_idx)
158 common_tuple_types[elem_idx] = getLeastSupertype(nested_types[elem_idx]);
159
160 return std::make_shared<DataTypeTuple>(common_tuple_types);
161 }
162 }
163
164 /// For Nullable
165 {
166 bool have_nullable = false;
167
168 DataTypes nested_types;
169 nested_types.reserve(types.size());
170
171 for (const auto & type : types)
172 {
173 if (const DataTypeNullable * type_nullable = typeid_cast<const DataTypeNullable *>(type.get()))
174 {
175 have_nullable = true;
176
177 if (!type_nullable->onlyNull())
178 nested_types.emplace_back(type_nullable->getNestedType());
179 }
180 else
181 nested_types.emplace_back(type);
182 }
183
184 if (have_nullable)
185 {
186 return std::make_shared<DataTypeNullable>(getLeastSupertype(nested_types));
187 }
188 }
189
190 /// Non-recursive rules
191
192 std::unordered_set<TypeIndex> type_ids;
193 for (const auto & type : types)
194 type_ids.insert(type->getTypeId());
195
196 /// For String and FixedString, or for different FixedStrings, the common type is String.
197 /// No other types are compatible with Strings. TODO Enums?
198 {
199 UInt32 have_string = type_ids.count(TypeIndex::String);
200 UInt32 have_fixed_string = type_ids.count(TypeIndex::FixedString);
201
202 if (have_string || have_fixed_string)
203 {
204 bool all_strings = type_ids.size() == (have_string + have_fixed_string);
205 if (!all_strings)
206 throw Exception(getExceptionMessagePrefix(types) + " because some of them are String/FixedString and some of them are not", ErrorCodes::NO_COMMON_TYPE);
207
208 return std::make_shared<DataTypeString>();
209 }
210 }
211
212 /// For Date and DateTime, the common type is DateTime. No other types are compatible.
213 {
214 UInt32 have_date = type_ids.count(TypeIndex::Date);
215 UInt32 have_datetime = type_ids.count(TypeIndex::DateTime);
216 UInt32 have_datetime64 = type_ids.count(TypeIndex::DateTime64);
217
218 if (have_date || have_datetime || have_datetime64)
219 {
220 bool all_date_or_datetime = type_ids.size() == (have_date + have_datetime + have_datetime64);
221 if (!all_date_or_datetime)
222 throw Exception(getExceptionMessagePrefix(types) + " because some of them are Date/DateTime and some of them are not", ErrorCodes::NO_COMMON_TYPE);
223
224 if (have_datetime64 == 0)
225 {
226 return std::make_shared<DataTypeDateTime>();
227 }
228
229 // When DateTime64 involved, make sure that supertype has whole-part precision
230 // big enough to hold max whole-value of any type from `types`.
231 // That would sacrifice scale when comparing DateTime64 of different scales.
232
233 UInt32 max_datetime64_whole_precision = 0;
234 for (const auto & t : types)
235 {
236 if (auto dt64 = typeid_cast<const DataTypeDateTime64 *>(t.get()))
237 {
238 const auto whole_precision = dt64->getPrecision() - dt64->getScale();
239 max_datetime64_whole_precision = std::max(whole_precision, max_datetime64_whole_precision);
240 }
241 }
242
243 UInt32 least_decimal_precision = 0;
244 if (have_datetime)
245 {
246 least_decimal_precision = leastDecimalPrecisionFor(TypeIndex::UInt32);
247 }
248 else if (have_date)
249 {
250 least_decimal_precision = leastDecimalPrecisionFor(TypeIndex::UInt16);
251 }
252 max_datetime64_whole_precision = std::max(least_decimal_precision, max_datetime64_whole_precision);
253
254 const UInt32 scale = DataTypeDateTime64::maxPrecision() - max_datetime64_whole_precision;
255 return std::make_shared<DataTypeDateTime64>(scale);
256 }
257 }
258
259 /// Decimals
260 {
261 UInt32 have_decimal32 = type_ids.count(TypeIndex::Decimal32);
262 UInt32 have_decimal64 = type_ids.count(TypeIndex::Decimal64);
263 UInt32 have_decimal128 = type_ids.count(TypeIndex::Decimal128);
264
265 if (have_decimal32 || have_decimal64 || have_decimal128)
266 {
267 UInt32 num_supported = have_decimal32 + have_decimal64 + have_decimal128;
268
269 std::vector<TypeIndex> int_ids = {TypeIndex::Int8, TypeIndex::UInt8, TypeIndex::Int16, TypeIndex::UInt16,
270 TypeIndex::Int32, TypeIndex::UInt32, TypeIndex::Int64, TypeIndex::UInt64};
271 std::vector<UInt32> num_ints(int_ids.size(), 0);
272
273 TypeIndex max_int = TypeIndex::Nothing;
274 for (size_t i = 0; i < int_ids.size(); ++i)
275 {
276 UInt32 num = type_ids.count(int_ids[i]);
277 num_ints[i] = num;
278 num_supported += num;
279 if (num)
280 max_int = int_ids[i];
281 }
282
283 if (num_supported != type_ids.size())
284 throw Exception(getExceptionMessagePrefix(types) + " because some of them have no lossless convertion to Decimal",
285 ErrorCodes::NO_COMMON_TYPE);
286
287 UInt32 max_scale = 0;
288 for (const auto & type : types)
289 {
290 UInt32 scale = getDecimalScale(*type, 0);
291 if (scale > max_scale)
292 max_scale = scale;
293 }
294
295 UInt32 min_precision = max_scale + leastDecimalPrecisionFor(max_int);
296
297 /// special cases Int32 -> Dec32, Int64 -> Dec64
298 if (max_scale == 0)
299 {
300 if (max_int == TypeIndex::Int32)
301 min_precision = DataTypeDecimal<Decimal32>::maxPrecision();
302 else if (max_int == TypeIndex::Int64)
303 min_precision = DataTypeDecimal<Decimal64>::maxPrecision();
304 }
305
306 if (min_precision > DataTypeDecimal<Decimal128>::maxPrecision())
307 throw Exception(getExceptionMessagePrefix(types) + " because the least supertype is Decimal("
308 + toString(min_precision) + ',' + toString(max_scale) + ')',
309 ErrorCodes::NO_COMMON_TYPE);
310
311 if (have_decimal128 || min_precision > DataTypeDecimal<Decimal64>::maxPrecision())
312 return std::make_shared<DataTypeDecimal<Decimal128>>(DataTypeDecimal<Decimal128>::maxPrecision(), max_scale);
313 if (have_decimal64 || min_precision > DataTypeDecimal<Decimal32>::maxPrecision())
314 return std::make_shared<DataTypeDecimal<Decimal64>>(DataTypeDecimal<Decimal64>::maxPrecision(), max_scale);
315 return std::make_shared<DataTypeDecimal<Decimal32>>(DataTypeDecimal<Decimal32>::maxPrecision(), max_scale);
316 }
317 }
318
319 /// For numeric types, the most complicated part.
320 {
321 bool all_numbers = true;
322
323 size_t max_bits_of_signed_integer = 0;
324 size_t max_bits_of_unsigned_integer = 0;
325 size_t max_mantissa_bits_of_floating = 0;
326
327 auto maximize = [](size_t & what, size_t value)
328 {
329 if (value > what)
330 what = value;
331 };
332
333 for (const auto & type : types)
334 {
335 if (typeid_cast<const DataTypeUInt8 *>(type.get()))
336 maximize(max_bits_of_unsigned_integer, 8);
337 else if (typeid_cast<const DataTypeUInt16 *>(type.get()))
338 maximize(max_bits_of_unsigned_integer, 16);
339 else if (typeid_cast<const DataTypeUInt32 *>(type.get()))
340 maximize(max_bits_of_unsigned_integer, 32);
341 else if (typeid_cast<const DataTypeUInt64 *>(type.get()))
342 maximize(max_bits_of_unsigned_integer, 64);
343 else if (typeid_cast<const DataTypeInt8 *>(type.get()))
344 maximize(max_bits_of_signed_integer, 8);
345 else if (typeid_cast<const DataTypeInt16 *>(type.get()))
346 maximize(max_bits_of_signed_integer, 16);
347 else if (typeid_cast<const DataTypeInt32 *>(type.get()))
348 maximize(max_bits_of_signed_integer, 32);
349 else if (typeid_cast<const DataTypeInt64 *>(type.get()))
350 maximize(max_bits_of_signed_integer, 64);
351 else if (typeid_cast<const DataTypeFloat32 *>(type.get()))
352 maximize(max_mantissa_bits_of_floating, 24);
353 else if (typeid_cast<const DataTypeFloat64 *>(type.get()))
354 maximize(max_mantissa_bits_of_floating, 53);
355 else
356 all_numbers = false;
357 }
358
359 if (max_bits_of_signed_integer || max_bits_of_unsigned_integer || max_mantissa_bits_of_floating)
360 {
361 if (!all_numbers)
362 throw Exception(getExceptionMessagePrefix(types) + " because some of them are numbers and some of them are not", ErrorCodes::NO_COMMON_TYPE);
363
364 /// If there are signed and unsigned types of same bit-width, the result must be signed number with at least one more bit.
365 /// Example, common of Int32, UInt32 = Int64.
366
367 size_t min_bit_width_of_integer = std::max(max_bits_of_signed_integer, max_bits_of_unsigned_integer);
368
369 /// If unsigned is not covered by signed.
370 if (max_bits_of_signed_integer && max_bits_of_unsigned_integer >= max_bits_of_signed_integer)
371 ++min_bit_width_of_integer;
372
373 /// If the result must be floating.
374 if (max_mantissa_bits_of_floating)
375 {
376 size_t min_mantissa_bits = std::max(min_bit_width_of_integer, max_mantissa_bits_of_floating);
377 if (min_mantissa_bits <= 24)
378 return std::make_shared<DataTypeFloat32>();
379 else if (min_mantissa_bits <= 53)
380 return std::make_shared<DataTypeFloat64>();
381 else
382 throw Exception(getExceptionMessagePrefix(types)
383 + " because some of them are integers and some are floating point,"
384 " but there is no floating point type, that can exactly represent all required integers", ErrorCodes::NO_COMMON_TYPE);
385 }
386
387 /// If the result must be signed integer.
388 if (max_bits_of_signed_integer)
389 {
390 if (min_bit_width_of_integer <= 8)
391 return std::make_shared<DataTypeInt8>();
392 else if (min_bit_width_of_integer <= 16)
393 return std::make_shared<DataTypeInt16>();
394 else if (min_bit_width_of_integer <= 32)
395 return std::make_shared<DataTypeInt32>();
396 else if (min_bit_width_of_integer <= 64)
397 return std::make_shared<DataTypeInt64>();
398 else
399 throw Exception(getExceptionMessagePrefix(types)
400 + " because some of them are signed integers and some are unsigned integers,"
401 " but there is no signed integer type, that can exactly represent all required unsigned integer values", ErrorCodes::NO_COMMON_TYPE);
402 }
403
404 /// All unsigned.
405 {
406 if (min_bit_width_of_integer <= 8)
407 return std::make_shared<DataTypeUInt8>();
408 else if (min_bit_width_of_integer <= 16)
409 return std::make_shared<DataTypeUInt16>();
410 else if (min_bit_width_of_integer <= 32)
411 return std::make_shared<DataTypeUInt32>();
412 else if (min_bit_width_of_integer <= 64)
413 return std::make_shared<DataTypeUInt64>();
414 else
415 throw Exception("Logical error: " + getExceptionMessagePrefix(types)
416 + " but as all data types are unsigned integers, we must have found maximum unsigned integer type", ErrorCodes::NO_COMMON_TYPE);
417 }
418 }
419 }
420
421 /// All other data types (UUID, AggregateFunction, Enum...) are compatible only if they are the same (checked in trivial cases).
422 throw Exception(getExceptionMessagePrefix(types), ErrorCodes::NO_COMMON_TYPE);
423}
424
425}
426