| 1599 | } |
| 1600 | |
| 1601 | FunctionCast::WrapperType FunctionCast::createColumnToVariantWrapper(const DataTypePtr & from_type, const DataTypeVariant & to_variant) const |
| 1602 | { |
| 1603 | /// We allow converting NULL to Variant(...) as Variant can store NULLs. |
| 1604 | if (from_type->onlyNull()) |
| 1605 | { |
| 1606 | return [](ColumnsWithTypeAndName &, const DataTypePtr & result_type, const ColumnNullable *, size_t input_rows_count) -> ColumnPtr |
| 1607 | { |
| 1608 | auto result_column = result_type->createColumn(); |
| 1609 | result_column->insertManyDefaults(input_rows_count); |
| 1610 | return result_column; |
| 1611 | }; |
| 1612 | } |
| 1613 | |
| 1614 | auto from_nested_type = removeNullableOrLowCardinalityNullable(from_type); |
| 1615 | auto variant_discr_opt = to_variant.tryGetVariantDiscriminator(from_nested_type->getName()); |
| 1616 | /// Cast String to Variant through parsing if it's not Variant(String). |
| 1617 | if (settings.cast_string_to_variant_use_inference && isStringOrFixedString(removeNullable(removeLowCardinality(from_type))) && (!variant_discr_opt || to_variant.getVariants().size() > 1)) |
| 1618 | return createStringToVariantWrapper(); |
| 1619 | |
| 1620 | if (!variant_discr_opt) |
| 1621 | throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert type {} to {}. Conversion to Variant allowed only for types from this Variant", from_type->getName(), to_variant.getName()); |
| 1622 | |
| 1623 | /// We resolve the destination variant type by name, but two distinct types can share the same name. |
| 1624 | /// AggregateFunction has a hidden state representation (Aggregation vs Window) that is not encoded |
| 1625 | /// in its name, since it is not a user-facing difference but an internal implementation detail. |
| 1626 | /// So when DataTypeVariant is constructed from two AggregateFunction(f, ...) types that differ only |
| 1627 | /// in state representation, its constructor collapses them by name to a single variant type. |
| 1628 | /// If our source column carries the other state representation, we must cast it to the destination |
| 1629 | /// variant type before storing it as a subcolumn, otherwise serialization would interpret the bytes |
| 1630 | /// using the wrong layout and crash. |
| 1631 | const auto & target_variant_type = to_variant.getVariants()[*variant_discr_opt]; |
| 1632 | const auto * from_agg_type = typeid_cast<const DataTypeAggregateFunction *>(from_nested_type.get()); |
| 1633 | const auto * target_variant_agg_type = typeid_cast<const DataTypeAggregateFunction *>(target_variant_type.get()); |
| 1634 | WrapperType to_target_variant_type_cast; |
| 1635 | if (from_agg_type && target_variant_agg_type && from_agg_type->equalsIgnoringVariant(*target_variant_type) |
| 1636 | && !from_nested_type->equals(*target_variant_type)) |
| 1637 | { |
| 1638 | to_target_variant_type_cast = prepareUnpackDictionaries(from_nested_type, target_variant_type); |
| 1639 | } |
| 1640 | |
| 1641 | return [variant_discr = *variant_discr_opt, |
| 1642 | cast_to_variant_type_wrapper = std::move(to_target_variant_type_cast), |
| 1643 | target_variant_type, |
| 1644 | unwrapped_from_type = from_nested_type] |
| 1645 | (ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const ColumnNullable *, size_t) -> ColumnPtr |
| 1646 | { |
| 1647 | const auto & result_variant_type = assert_cast<const DataTypeVariant &>(*result_type); |
| 1648 | const auto & variant_types = result_variant_type.getVariants(); |
| 1649 | |
| 1650 | auto cast_to_variant_type_if_needed = [&](const ColumnPtr & col) -> ColumnPtr |
| 1651 | { |
| 1652 | if (!cast_to_variant_type_wrapper) |
| 1653 | return col; |
| 1654 | ColumnsWithTypeAndName args = {{col, unwrapped_from_type, ""}}; |
| 1655 | return cast_to_variant_type_wrapper(args, target_variant_type, nullptr, col->size()); |
| 1656 | }; |
| 1657 | |
| 1658 | if (const ColumnNullable * col_nullable = typeid_cast<const ColumnNullable *>(arguments.front().column.get())) |
nothing calls this directly
no test coverage detected