Skip to content

Commit

Permalink
Merge pull request ClickHouse#35563 from ClickHouse/backport/22.3/35534
Browse files Browse the repository at this point in the history
Backport ClickHouse#35534 to 22.3: Fix cast into IPv4, IPv6 address in IN section
  • Loading branch information
kitaisreal authored Mar 24, 2022
2 parents 90c8cd0 + f3e2ad1 commit 9a38aef
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
21 changes: 11 additions & 10 deletions src/Functions/FunctionsConversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -2697,13 +2697,10 @@ class FunctionCast final : public FunctionCastBase
return createWrapper<ToDataType>(from_type, to_type, requested_result_is_nullable);
}

WrapperType createUInt8ToUInt8Wrapper(const DataTypePtr from_type, const DataTypePtr to_type) const
WrapperType createUInt8ToBoolWrapper(const DataTypePtr from_type, const DataTypePtr to_type) const
{
return [from_type, to_type] (ColumnsWithTypeAndName & arguments, const DataTypePtr &, const ColumnNullable *, size_t /*input_rows_count*/) -> ColumnPtr
{
if (isBool(from_type) || !isBool(to_type))
return arguments.front().column;

/// Special case when we convert UInt8 column to Bool column.
/// both columns have type UInt8, but we shouldn't use identity wrapper,
/// because Bool column can contain only 0 and 1.
Expand Down Expand Up @@ -3500,15 +3497,19 @@ class FunctionCast final : public FunctionCastBase
/// 'requested_result_is_nullable' is true if CAST to Nullable type is requested.
WrapperType prepareImpl(const DataTypePtr & from_type, const DataTypePtr & to_type, bool requested_result_is_nullable) const
{
bool convert_to_ipv6 = to_type->getCustomName() && to_type->getCustomName()->getName() == "IPv6";
if (isUInt8(from_type) && isBool(to_type))
return createUInt8ToBoolWrapper(from_type, to_type);

if (from_type->equals(*to_type) && !convert_to_ipv6)
{
if (isUInt8(from_type))
return createUInt8ToUInt8Wrapper(from_type, to_type);
/// We can cast IPv6 into IPv6, IPv4 into IPv4, but we should not allow to cast FixedString(16) into IPv6 as part of identity cast
bool safe_convert_custom_types = true;

if (const auto * to_type_custom_name = to_type->getCustomName())
safe_convert_custom_types = from_type->getCustomName() && from_type->getCustomName()->getName() == to_type_custom_name->getName();
else if (const auto * from_type_custom_name = from_type->getCustomName())
safe_convert_custom_types = to_type->getCustomName() && from_type_custom_name->getName() == to_type->getCustomName()->getName();

if (from_type->equals(*to_type) && safe_convert_custom_types)
return createIdentityWrapper(from_type);
}
else if (WhichDataType(from_type).isNothing())
return createNothingWrapper(to_type.get());

Expand Down
2 changes: 2 additions & 0 deletions tests/queries/0_stateless/02243_in_ip_address.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0
0
9 changes: 9 additions & 0 deletions tests/queries/0_stateless/02243_in_ip_address.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table (id UInt64, value_ipv4 IPv4, value_ipv6 IPv6) ENGINE=MergeTree ORDER BY id;

INSERT INTO test_table VALUES (0, '127.0.0.1', '127.0.0.1');

SELECT id FROM test_table WHERE value_ipv4 IN (SELECT value_ipv4 FROM test_table);
SELECT id FROM test_table WHERE value_ipv6 IN (SELECT value_ipv6 FROM test_table);

DROP TABLE test_table;

0 comments on commit 9a38aef

Please sign in to comment.