Resolves a dynamic subcolumn like `map['key']` by parsing the key from the subcolumn name, creating a `SerializationMapKeyValue` that knows how to read only the relevant bucket, and optionally pre-extracting the values from an existing column. The subcolumn name must start with "key_" followed by the text-serialized key value.
| 185 | /// and optionally pre-extracting the values from an existing column. |
| 186 | /// The subcolumn name must start with "key_" followed by the text-serialized key value. |
| 187 | std::unique_ptr<IDataType::SubstreamData> DataTypeMap::getDynamicSubcolumnData(std::string_view subcolumn_name, const SubstreamData & data, size_t /*initial_array_level*/, bool throw_if_null) const |
| 188 | { |
| 189 | /// Only subcolumns of the form "key_<serialized_key>" are supported. |
| 190 | if (!subcolumn_name.starts_with(KEY_SUBCOLUMN_PREFIX)) |
| 191 | { |
| 192 | if (throw_if_null) |
| 193 | throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Type {} doesn't have subcolumn {}", getName(), subcolumn_name); |
| 194 | return nullptr; |
| 195 | } |
| 196 | |
| 197 | /// Parse the key value from the subcolumn name. |
| 198 | std::string_view key_string = subcolumn_name.substr(KEY_SUBCOLUMN_PREFIX.size()); |
| 199 | auto key_column = key_type->createColumn(); |
| 200 | auto key_serialization = key_type->getDefaultSerialization(); |
| 201 | ReadBufferFromString buf(key_string); |
| 202 | try |
| 203 | { |
| 204 | key_serialization->deserializeWholeText(*key_column, buf, FormatSettings{}); |
| 205 | } |
| 206 | catch (...) |
| 207 | { |
| 208 | if (throw_if_null) |
| 209 | throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Type {} doesn't have subcolumn {}", getName(), subcolumn_name); |
| 210 | return nullptr; |
| 211 | } |
| 212 | |
| 213 | /// Create a serialization that reads only the bucket containing the requested key. |
| 214 | const auto & map_serialization = assert_cast<const SerializationMap &>(*removeNamedSerialization(data.serialization)); |
| 215 | auto key_value_serialization = SerializationMapKeyValue::create( |
| 216 | map_serialization.getValueSerialization(), |
| 217 | map_serialization.getNestedSerialization(), |
| 218 | map_serialization.getMapSerializationVersion(), |
| 219 | key_column->getPtr(), |
| 220 | nested); |
| 221 | std::unique_ptr<SubstreamData> res = std::make_unique<SubstreamData>(key_value_serialization); |
| 222 | res->type = value_type; |
| 223 | |
| 224 | /// If a column is available, pre-extract the values for the requested key. |
| 225 | if (data.column) |
| 226 | { |
| 227 | const auto & column_map = assert_cast<const ColumnMap &>(*data.column); |
| 228 | auto value_column = value_type->createColumn(); |
| 229 | extractKeyValueFromMap(*column_map.getNestedColumnPtr(), *key_column->getPtr(), *value_column, 0, data.column->size()); |
| 230 | res->column = std::move(value_column); |
| 231 | } |
| 232 | |
| 233 | return res; |
| 234 | } |
| 235 | |
| 236 | static DataTypePtr create(const ASTPtr & arguments) |
| 237 | { |
nothing calls this directly
no test coverage detected