| 888 | } |
| 889 | |
| 890 | std::unique_ptr<IDataType::SubstreamData> DataTypeDynamic::getDynamicSubcolumnData(std::string_view subcolumn_name, const SubstreamData & data, size_t initial_array_level, bool throw_if_null) const |
| 891 | { |
| 892 | auto [type_subcolumn_name, subcolumn_nested_name] = splitSubcolumnName(subcolumn_name); |
| 893 | /// Check if requested subcolumn is a valid data type. |
| 894 | auto subcolumn_type = DataTypeFactory::instance().tryGet(String(type_subcolumn_name)); |
| 895 | if (!subcolumn_type) |
| 896 | { |
| 897 | if (throw_if_null) |
| 898 | throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Dynamic type doesn't have subcolumn '{}'", type_subcolumn_name); |
| 899 | return nullptr; |
| 900 | } |
| 901 | |
| 902 | const auto & dynamic_serialization = assert_cast<const SerializationDynamic &>(*removeNamedSerialization(data.serialization)); |
| 903 | auto subcolumn_serialization = dynamic_serialization.createSerializationForType(subcolumn_type); |
| 904 | std::unique_ptr<SubstreamData> res = std::make_unique<SubstreamData>(subcolumn_serialization); |
| 905 | res->type = subcolumn_type; |
| 906 | std::optional<ColumnVariant::Discriminator> discriminator; |
| 907 | ColumnPtr null_map_for_variant_from_shared_variant; |
| 908 | if (data.column) |
| 909 | { |
| 910 | /// If column was provided, we should extract subcolumn from Dynamic column. |
| 911 | const auto & dynamic_column = assert_cast<const ColumnDynamic &>(*data.column); |
| 912 | const auto & variant_info = dynamic_column.getVariantInfo(); |
| 913 | const auto & variant_column = dynamic_column.getVariantColumn(); |
| 914 | const auto & shared_variant = dynamic_column.getSharedVariant(); |
| 915 | /// Check if provided Dynamic column has subcolumn of this type. |
| 916 | String subcolumn_type_name = subcolumn_type->getName(); |
| 917 | auto it = variant_info.variant_name_to_discriminator.find(subcolumn_type_name); |
| 918 | if (it != variant_info.variant_name_to_discriminator.end()) |
| 919 | { |
| 920 | discriminator = it->second; |
| 921 | res->column = variant_column.getVariantPtrByGlobalDiscriminator(*discriminator); |
| 922 | } |
| 923 | /// Otherwise if there is data in shared variant try to find requested type there. |
| 924 | else if (!shared_variant.empty()) |
| 925 | { |
| 926 | /// Create null map for resulting subcolumn to make it Nullable. |
| 927 | auto null_map_column = ColumnUInt8::create(); |
| 928 | NullMap & null_map = assert_cast<ColumnUInt8 &>(*null_map_column).getData(); |
| 929 | null_map.reserve(variant_column.size()); |
| 930 | auto subcolumn = subcolumn_type->createColumn(); |
| 931 | auto shared_variant_local_discr = variant_column.localDiscriminatorByGlobal(dynamic_column.getSharedVariantDiscriminator()); |
| 932 | const auto & local_discriminators = variant_column.getLocalDiscriminators(); |
| 933 | const auto & offsets = variant_column.getOffsets(); |
| 934 | const FormatSettings format_settings; |
| 935 | for (size_t i = 0; i != local_discriminators.size(); ++i) |
| 936 | { |
| 937 | if (local_discriminators[i] == shared_variant_local_discr) |
| 938 | { |
| 939 | auto value = shared_variant.getDataAt(offsets[i]); |
| 940 | ReadBufferFromMemory buf(value); |
| 941 | auto type = decodeDataType(buf); |
| 942 | if (type->getName() == subcolumn_type_name) |
| 943 | { |
| 944 | subcolumn_serialization->deserializeBinary(*subcolumn, buf, format_settings); |
| 945 | null_map.push_back(static_cast<UInt8>(0)); |
| 946 | } |
| 947 | else |
nothing calls this directly
no test coverage detected