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

Method createColumnToVariantWrapper

src/Functions/FunctionsConversion.cpp:1601–1741  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1599}
1600
1601FunctionCast::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()))

Callers

nothing calls this directly

Calls 15

removeLowCardinalityFunction · 0.85
equalsIgnoringVariantMethod · 0.80
getIndexesMethod · 0.80
getNullValueIndexMethod · 0.80
resize_fillMethod · 0.80
createFunction · 0.70
removeNullableFunction · 0.50
ExceptionClass · 0.50

Tested by

no test coverage detected