MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / getDynamicSubcolumnData

Method getDynamicSubcolumnData

src/DataTypes/DataTypeDynamic.cpp:890–1056  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

888}
889
890std::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

Callers

nothing calls this directly

Tested by

no test coverage detected