mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Merge pull request #45024 from ClickHouse/fix-ip-function-cut
Fix cutIPv6 function and IPv4 hashing
This commit is contained in:
commit
1cf5934141
@ -138,6 +138,8 @@ public:
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
if (!checkAndGetDataType<DataTypeIPv6>(arguments[0].get()))
|
||||
{
|
||||
const auto * ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
|
||||
if (!ptr || ptr->getN() != IPV6_BINARY_LENGTH)
|
||||
@ -145,6 +147,7 @@ public:
|
||||
" of argument 1 of function " + getName() +
|
||||
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
||||
if (!WhichDataType(arguments[1]).isUInt8())
|
||||
throw Exception("Illegal type " + arguments[1]->getName() +
|
||||
@ -162,7 +165,7 @@ public:
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; }
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto & col_type_name = arguments[0];
|
||||
const ColumnPtr & column = col_type_name.column;
|
||||
@ -172,11 +175,17 @@ public:
|
||||
const auto & col_ipv4_zeroed_tail_bytes_type = arguments[2];
|
||||
const auto & col_ipv4_zeroed_tail_bytes = col_ipv4_zeroed_tail_bytes_type.column;
|
||||
|
||||
if (const auto * col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
|
||||
{
|
||||
if (col_in->getN() != IPV6_BINARY_LENGTH)
|
||||
const auto * col_in_str = checkAndGetColumn<ColumnFixedString>(column.get());
|
||||
const auto * col_in_ip = checkAndGetColumn<ColumnIPv6>(column.get());
|
||||
|
||||
if (!col_in_str && !col_in_ip)
|
||||
throw Exception("Illegal column " + arguments[0].column->getName()
|
||||
+ " of argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
||||
if (col_in_str && col_in_str->getN() != IPV6_BINARY_LENGTH)
|
||||
throw Exception("Illegal type " + col_type_name.type->getName() +
|
||||
" of column " + col_in->getName() +
|
||||
" of column " + col_in_str->getName() +
|
||||
" argument of function " + getName() +
|
||||
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
@ -205,36 +214,44 @@ public:
|
||||
" of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
|
||||
const auto size = col_in->size();
|
||||
const auto & vec_in = col_in->getChars();
|
||||
|
||||
auto col_res = ColumnString::create();
|
||||
|
||||
ColumnString::Chars & vec_res = col_res->getChars();
|
||||
ColumnString::Offsets & offsets_res = col_res->getOffsets();
|
||||
vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1));
|
||||
offsets_res.resize(size);
|
||||
vec_res.resize(input_rows_count * (IPV6_MAX_TEXT_LENGTH + 1));
|
||||
offsets_res.resize(input_rows_count);
|
||||
|
||||
auto * begin = reinterpret_cast<char *>(vec_res.data());
|
||||
auto * pos = begin;
|
||||
|
||||
for (size_t offset = 0, i = 0; offset < vec_in.size(); offset += IPV6_BINARY_LENGTH, ++i)
|
||||
if (col_in_str)
|
||||
{
|
||||
const auto & vec_in = col_in_str->getChars();
|
||||
|
||||
for (size_t offset = 0, i = 0; i < input_rows_count; offset += IPV6_BINARY_LENGTH, ++i)
|
||||
{
|
||||
const auto * address = &vec_in[offset];
|
||||
UInt8 zeroed_tail_bytes_count = isIPv4Mapped(address) ? ipv4_zeroed_tail_bytes_count : ipv6_zeroed_tail_bytes_count;
|
||||
cutAddress(reinterpret_cast<const unsigned char *>(address), pos, zeroed_tail_bytes_count);
|
||||
offsets_res[i] = pos - begin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto & vec_in = col_in_ip->getData();
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
const auto * address = reinterpret_cast<const UInt8 *>(&vec_in[i]);
|
||||
UInt8 zeroed_tail_bytes_count = isIPv4Mapped(address) ? ipv4_zeroed_tail_bytes_count : ipv6_zeroed_tail_bytes_count;
|
||||
cutAddress(reinterpret_cast<const unsigned char *>(address), pos, zeroed_tail_bytes_count);
|
||||
offsets_res[i] = pos - begin;
|
||||
}
|
||||
}
|
||||
|
||||
vec_res.resize(pos - begin);
|
||||
|
||||
return col_res;
|
||||
}
|
||||
else
|
||||
throw Exception("Illegal column " + arguments[0].column->getName()
|
||||
+ " of argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
||||
private:
|
||||
static bool isIPv4Mapped(const UInt8 * address)
|
||||
|
@ -1136,7 +1136,7 @@ private:
|
||||
else if (which.isInt128()) executeBigIntType<Int128, first>(icolumn, vec_to);
|
||||
else if (which.isInt256()) executeBigIntType<Int256, first>(icolumn, vec_to);
|
||||
else if (which.isUUID()) executeBigIntType<UUID, first>(icolumn, vec_to);
|
||||
else if (which.isIPv4()) executeBigIntType<IPv4, first>(icolumn, vec_to);
|
||||
else if (which.isIPv4()) executeIntType<IPv4, first>(icolumn, vec_to);
|
||||
else if (which.isIPv6()) executeBigIntType<IPv6, first>(icolumn, vec_to);
|
||||
else if (which.isEnum8()) executeIntType<Int8, first>(icolumn, vec_to);
|
||||
else if (which.isEnum16()) executeIntType<Int16, first>(icolumn, vec_to);
|
||||
|
Loading…
Reference in New Issue
Block a user