| 40 | } |
| 41 | |
| 42 | ColumnPtr tryGetSubcolumnFromBlock(const Block & block, const DataTypePtr & requested_column_type, const NameAndTypePair & requested_subcolumn) |
| 43 | { |
| 44 | const auto * elem = block.findByName(requested_subcolumn.getNameInStorage()); |
| 45 | if (!elem) |
| 46 | return nullptr; |
| 47 | |
| 48 | auto subcolumn_name = requested_subcolumn.getSubcolumnName(); |
| 49 | /// If requested subcolumn is dynamic, we should first perform cast and then |
| 50 | /// extract the subcolumn, because the data of dynamic subcolumn can change after cast. |
| 51 | if ((elem->type->hasDynamicStructure() || requested_column_type->hasDynamicStructure()) && !elem->type->equals(*requested_column_type)) |
| 52 | { |
| 53 | auto cast_column = castColumn({elem->column->decompress(), elem->type, ""}, requested_column_type); |
| 54 | auto elem_column = requested_column_type->tryGetSubcolumn(subcolumn_name, cast_column); |
| 55 | auto elem_type = requested_column_type->tryGetSubcolumnType(subcolumn_name); |
| 56 | |
| 57 | if (!elem_type || !elem_column) |
| 58 | return nullptr; |
| 59 | |
| 60 | return elem_column; |
| 61 | } |
| 62 | |
| 63 | auto elem_column = elem->type->tryGetSubcolumn(subcolumn_name, elem->column->decompress()); |
| 64 | auto elem_type = elem->type->tryGetSubcolumnType(subcolumn_name); |
| 65 | |
| 66 | if (!elem_type || !elem_column) |
| 67 | return nullptr; |
| 68 | |
| 69 | return castColumn({elem_column, elem_type, ""}, requested_subcolumn.type); |
| 70 | } |
| 71 | |
| 72 | ColumnPtr getColumnFromBlock(const Block & block, const NameAndTypePair & requested_column) |
| 73 | { |
no test coverage detected