| 315 | } |
| 316 | |
| 317 | static DataTypePtr getLeastCommonTypeForObject(const DataTypes & types, bool check_ambiguous_paths) |
| 318 | { |
| 319 | /// Types of subcolumns by path from all tuples. |
| 320 | std::unordered_map<PathInData, DataTypes, PathInData::Hash> subcolumns_types; |
| 321 | |
| 322 | /// First we flatten tuples, then get common type for paths |
| 323 | /// and finally unflatten paths and create new tuple type. |
| 324 | for (const auto & type : types) |
| 325 | { |
| 326 | const auto * type_tuple = typeid_cast<const DataTypeTuple *>(type.get()); |
| 327 | if (!type_tuple) |
| 328 | throw Exception(ErrorCodes::LOGICAL_ERROR, |
| 329 | "Least common type for object can be deduced only from tuples, but {} given", type->getName()); |
| 330 | |
| 331 | auto [tuple_paths, tuple_types] = flattenTuple(type); |
| 332 | assert(tuple_paths.size() == tuple_types.size()); |
| 333 | |
| 334 | for (size_t i = 0; i < tuple_paths.size(); ++i) |
| 335 | subcolumns_types[tuple_paths[i]].push_back(tuple_types[i]); |
| 336 | } |
| 337 | |
| 338 | PathsInData tuple_paths; |
| 339 | DataTypes tuple_types; |
| 340 | |
| 341 | /// Get the least common type for all paths. |
| 342 | for (const auto & [key, subtypes] : subcolumns_types) |
| 343 | { |
| 344 | assert(!subtypes.empty()); |
| 345 | if (key.getPath() == ColumnObject::COLUMN_NAME_DUMMY) |
| 346 | continue; |
| 347 | |
| 348 | size_t first_dim = getNumberOfDimensions(*subtypes[0]); |
| 349 | for (size_t i = 1; i < subtypes.size(); ++i) |
| 350 | if (first_dim != getNumberOfDimensions(*subtypes[i])) |
| 351 | throw Exception(ErrorCodes::TYPE_MISMATCH, |
| 352 | "Uncompatible types of subcolumn '{}': {} and {}", |
| 353 | key.getPath(), subtypes[0]->getName(), subtypes[i]->getName()); |
| 354 | |
| 355 | tuple_paths.emplace_back(key); |
| 356 | tuple_types.emplace_back(getLeastSupertypeOrString(subtypes)); |
| 357 | } |
| 358 | |
| 359 | if (tuple_paths.empty()) |
| 360 | { |
| 361 | tuple_paths.emplace_back(ColumnObject::COLUMN_NAME_DUMMY); |
| 362 | tuple_types.emplace_back(std::make_shared<DataTypeUInt8>()); |
| 363 | } |
| 364 | |
| 365 | if (check_ambiguous_paths) |
| 366 | checkObjectHasNoAmbiguousPaths(tuple_paths); |
| 367 | |
| 368 | return unflattenTuple(tuple_paths, tuple_types); |
| 369 | } |
| 370 | |
| 371 | static DataTypePtr getLeastCommonTypeForDynamicColumnsImpl( |
| 372 | const DataTypePtr & type_in_storage, const DataTypes & concrete_types, bool check_ambiguos_paths); |
no test coverage detected