mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Merge pull request #16155 from nikitamikhaylov/vladimir-golovchenko-fix-IPvXCIDRToRange
Merging #15856
This commit is contained in:
commit
ef5dd73ae0
@ -1659,7 +1659,7 @@ public:
|
|||||||
if (!isUInt8(second_argument))
|
if (!isUInt8(second_argument))
|
||||||
throw Exception{"Illegal type " + second_argument->getName()
|
throw Exception{"Illegal type " + second_argument->getName()
|
||||||
+ " of second argument of function " + getName()
|
+ " of second argument of function " + getName()
|
||||||
+ ", expected numeric type.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
+ ", expected UInt8", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
||||||
|
|
||||||
DataTypePtr element = DataTypeFactory::instance().get("IPv6");
|
DataTypePtr element = DataTypeFactory::instance().get("IPv6");
|
||||||
return std::make_shared<DataTypeTuple>(DataTypes{element, element});
|
return std::make_shared<DataTypeTuple>(DataTypes{element, element});
|
||||||
@ -1673,19 +1673,21 @@ public:
|
|||||||
const auto & col_type_name_ip = columns[arguments[0]];
|
const auto & col_type_name_ip = columns[arguments[0]];
|
||||||
const ColumnPtr & column_ip = col_type_name_ip.column;
|
const ColumnPtr & column_ip = col_type_name_ip.column;
|
||||||
|
|
||||||
|
const auto col_const_ip_in = checkAndGetColumnConst<ColumnFixedString>(column_ip.get());
|
||||||
const auto col_ip_in = checkAndGetColumn<ColumnFixedString>(column_ip.get());
|
const auto col_ip_in = checkAndGetColumn<ColumnFixedString>(column_ip.get());
|
||||||
|
|
||||||
if (!col_ip_in)
|
if (!col_ip_in && !col_const_ip_in)
|
||||||
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
|
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
|
||||||
+ " of argument of function " + getName(),
|
+ " of argument of function " + getName(),
|
||||||
ErrorCodes::ILLEGAL_COLUMN);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
|
|
||||||
if (col_ip_in->getN() != IPV6_BINARY_LENGTH)
|
if ((col_const_ip_in && col_const_ip_in->getValue<String>().size() != IPV6_BINARY_LENGTH) ||
|
||||||
throw Exception("Illegal type " + col_type_name_ip.type->getName() +
|
(col_ip_in && col_ip_in->getN() != IPV6_BINARY_LENGTH))
|
||||||
" of column " + col_ip_in->getName() +
|
throw Exception("Illegal type " + col_type_name_ip.type->getName() +
|
||||||
" argument of function " + getName() +
|
" of column " + column_ip->getName() +
|
||||||
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
|
" argument of function " + getName() +
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
const auto & col_type_name_cidr = columns[arguments[1]];
|
const auto & col_type_name_cidr = columns[arguments[1]];
|
||||||
const ColumnPtr & column_cidr = col_type_name_cidr.column;
|
const ColumnPtr & column_cidr = col_type_name_cidr.column;
|
||||||
@ -1698,8 +1700,6 @@ public:
|
|||||||
+ " of argument of function " + getName(),
|
+ " of argument of function " + getName(),
|
||||||
ErrorCodes::ILLEGAL_COLUMN);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
|
|
||||||
const auto & vec_in = col_ip_in->getChars();
|
|
||||||
|
|
||||||
auto col_res_lower_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
|
auto col_res_lower_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
|
||||||
auto col_res_upper_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
|
auto col_res_upper_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
|
||||||
|
|
||||||
@ -1711,14 +1711,24 @@ public:
|
|||||||
|
|
||||||
static constexpr UInt8 max_cidr_mask = IPV6_BINARY_LENGTH * 8;
|
static constexpr UInt8 max_cidr_mask = IPV6_BINARY_LENGTH * 8;
|
||||||
|
|
||||||
|
const String col_const_ip_str = col_const_ip_in ? col_const_ip_in->getValue<String>() : "";
|
||||||
|
const UInt8 * col_const_ip_value = col_const_ip_in ? reinterpret_cast<const UInt8 *>(col_const_ip_str.c_str()) : nullptr;
|
||||||
|
|
||||||
for (size_t offset = 0; offset < input_rows_count; ++offset)
|
for (size_t offset = 0; offset < input_rows_count; ++offset)
|
||||||
{
|
{
|
||||||
const size_t offset_ipv6 = offset * IPV6_BINARY_LENGTH;
|
const size_t offset_ipv6 = offset * IPV6_BINARY_LENGTH;
|
||||||
|
|
||||||
|
const UInt8 * ip = col_const_ip_in
|
||||||
|
? col_const_ip_value
|
||||||
|
: &col_ip_in->getChars()[offset_ipv6];
|
||||||
|
|
||||||
UInt8 cidr = col_const_cidr_in
|
UInt8 cidr = col_const_cidr_in
|
||||||
? col_const_cidr_in->getValue<UInt8>()
|
? col_const_cidr_in->getValue<UInt8>()
|
||||||
: col_cidr_in->getData()[offset];
|
: col_cidr_in->getData()[offset];
|
||||||
|
|
||||||
cidr = std::min(cidr, max_cidr_mask);
|
cidr = std::min(cidr, max_cidr_mask);
|
||||||
applyCIDRMask(&vec_in[offset_ipv6], &vec_res_lower_range[offset_ipv6], &vec_res_upper_range[offset_ipv6], cidr);
|
|
||||||
|
applyCIDRMask(ip, &vec_res_lower_range[offset_ipv6], &vec_res_upper_range[offset_ipv6], cidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
columns[result].column = ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
|
columns[result].column = ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
|
||||||
@ -1763,7 +1773,7 @@ public:
|
|||||||
if (!isUInt8(second_argument))
|
if (!isUInt8(second_argument))
|
||||||
throw Exception{"Illegal type " + second_argument->getName()
|
throw Exception{"Illegal type " + second_argument->getName()
|
||||||
+ " of second argument of function " + getName()
|
+ " of second argument of function " + getName()
|
||||||
+ ", expected numeric type.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
+ ", expected UInt8", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
||||||
|
|
||||||
DataTypePtr element = DataTypeFactory::instance().get("IPv4");
|
DataTypePtr element = DataTypeFactory::instance().get("IPv4");
|
||||||
return std::make_shared<DataTypeTuple>(DataTypes{element, element});
|
return std::make_shared<DataTypeTuple>(DataTypes{element, element});
|
||||||
@ -1777,8 +1787,9 @@ public:
|
|||||||
const auto & col_type_name_ip = columns[arguments[0]];
|
const auto & col_type_name_ip = columns[arguments[0]];
|
||||||
const ColumnPtr & column_ip = col_type_name_ip.column;
|
const ColumnPtr & column_ip = col_type_name_ip.column;
|
||||||
|
|
||||||
|
const auto col_const_ip_in = checkAndGetColumnConst<ColumnUInt32>(column_ip.get());
|
||||||
const auto col_ip_in = checkAndGetColumn<ColumnUInt32>(column_ip.get());
|
const auto col_ip_in = checkAndGetColumn<ColumnUInt32>(column_ip.get());
|
||||||
if (!col_ip_in)
|
if (!col_const_ip_in && !col_ip_in)
|
||||||
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
|
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
|
||||||
+ " of argument of function " + getName(),
|
+ " of argument of function " + getName(),
|
||||||
ErrorCodes::ILLEGAL_COLUMN);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
@ -1794,8 +1805,6 @@ public:
|
|||||||
+ " of argument of function " + getName(),
|
+ " of argument of function " + getName(),
|
||||||
ErrorCodes::ILLEGAL_COLUMN);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
|
|
||||||
const auto & vec_in = col_ip_in->getData();
|
|
||||||
|
|
||||||
auto col_res_lower_range = ColumnUInt32::create();
|
auto col_res_lower_range = ColumnUInt32::create();
|
||||||
auto col_res_upper_range = ColumnUInt32::create();
|
auto col_res_upper_range = ColumnUInt32::create();
|
||||||
|
|
||||||
@ -1807,11 +1816,15 @@ public:
|
|||||||
|
|
||||||
for (size_t i = 0; i < input_rows_count; ++i)
|
for (size_t i = 0; i < input_rows_count; ++i)
|
||||||
{
|
{
|
||||||
|
UInt32 ip = col_const_ip_in
|
||||||
|
? col_const_ip_in->getValue<UInt32>()
|
||||||
|
: col_ip_in->getData()[i];
|
||||||
|
|
||||||
UInt8 cidr = col_const_cidr_in
|
UInt8 cidr = col_const_cidr_in
|
||||||
? col_const_cidr_in->getValue<UInt8>()
|
? col_const_cidr_in->getValue<UInt8>()
|
||||||
: col_cidr_in->getData()[i];
|
: col_cidr_in->getData()[i];
|
||||||
|
|
||||||
std::tie(vec_res_lower_range[i], vec_res_upper_range[i]) = applyCIDRMask(vec_in[i], cidr);
|
std::tie(vec_res_lower_range[i], vec_res_upper_range[i]) = applyCIDRMask(ip, cidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
columns[result].column = ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
|
columns[result].column = ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
check invalid params
|
||||||
|
tests
|
||||||
4
|
4
|
||||||
3
|
3
|
||||||
2
|
2
|
||||||
@ -14,3 +16,5 @@
|
|||||||
('192.168.5.2','192.168.5.2')
|
('192.168.5.2','192.168.5.2')
|
||||||
('0.0.0.0','0.255.255.255')
|
('0.0.0.0','0.255.255.255')
|
||||||
('240.0.0.0','255.255.255.255')
|
('240.0.0.0','255.255.255.255')
|
||||||
|
('240.0.0.0','255.255.255.255')
|
||||||
|
('248.0.0.0','255.255.255.255')
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
SELECT 'check invalid params';
|
||||||
|
SELECT IPv4CIDRToRange(1, 1); -- { serverError 43 }
|
||||||
|
SELECT IPv4CIDRToRange(toUInt32(1), 512); -- { serverError 43 }
|
||||||
|
|
||||||
|
SELECT 'tests';
|
||||||
|
|
||||||
DROP TABLE IF EXISTS ipv4_range;
|
DROP TABLE IF EXISTS ipv4_range;
|
||||||
CREATE TABLE ipv4_range(ip IPv4, cidr UInt8) ENGINE = Memory;
|
CREATE TABLE ipv4_range(ip IPv4, cidr UInt8) ENGINE = Memory;
|
||||||
|
|
||||||
@ -16,7 +22,9 @@ WITH IPv4CIDRToRange(ip, cidr) as ip_range SELECT ip, cidr, IPv4NumToString(tupl
|
|||||||
DROP TABLE ipv4_range;
|
DROP TABLE ipv4_range;
|
||||||
|
|
||||||
SELECT IPv4CIDRToRange(toIPv4('192.168.5.2'), 0);
|
SELECT IPv4CIDRToRange(toIPv4('192.168.5.2'), 0);
|
||||||
SELEcT IPv4CIDRToRange(toIPv4('255.255.255.255'), 8);
|
SELECT IPv4CIDRToRange(toIPv4('255.255.255.255'), 8);
|
||||||
SELECT IPv4CIDRToRange(toIPv4('192.168.5.2'), 32);
|
SELECT IPv4CIDRToRange(toIPv4('192.168.5.2'), 32);
|
||||||
SELECT IPv4CIDRToRange(toIPv4('0.0.0.0'), 8);
|
SELECT IPv4CIDRToRange(toIPv4('0.0.0.0'), 8);
|
||||||
SELECT IPv4CIDRToRange(toIPv4('255.0.0.0'), 4);
|
SELECT IPv4CIDRToRange(toIPv4('255.0.0.0'), 4);
|
||||||
|
|
||||||
|
SELECT IPv4CIDRToRange(toIPv4('255.0.0.0'), toUInt8(4 + number)) FROM numbers(2);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
check invalid params
|
||||||
|
tests
|
||||||
3
|
3
|
||||||
4
|
4
|
||||||
3
|
3
|
||||||
@ -16,3 +18,5 @@ ffff:: 4 ('f000::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
|
|||||||
('::','ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
|
('::','ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
|
||||||
('f000::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
|
('f000::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
|
||||||
1
|
1
|
||||||
|
('2001:db8:0:85a3::ac1f:8001','2001:db8:0:85a3::ac1f:8001')
|
||||||
|
('2001:db8:0:85a3::ac1f:8000','2001:db8:0:85a3::ac1f:8001')
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
SELECT 'check invalid params';
|
||||||
|
SELECT IPv6CIDRToRange(1, 1); -- { serverError 43 }
|
||||||
|
SELECT IPv6CIDRToRange('1234', 1); -- { serverError 43 }
|
||||||
|
SELECT IPv6CIDRToRange(toFixedString('1234', 10), 1); -- { serverError 43 }
|
||||||
|
SELECT IPv6CIDRToRange(toFixedString('1234', 16), toUInt16(1)); -- { serverError 43 }
|
||||||
|
|
||||||
|
SELECT 'tests';
|
||||||
|
|
||||||
DROP TABLE IF EXISTS ipv6_range;
|
DROP TABLE IF EXISTS ipv6_range;
|
||||||
CREATE TABLE ipv6_range(ip IPv6, cidr UInt8) ENGINE = Memory;
|
CREATE TABLE ipv6_range(ip IPv6, cidr UInt8) ENGINE = Memory;
|
||||||
|
|
||||||
@ -23,3 +31,5 @@ SELECT IPv6CIDRToRange(IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
|
|||||||
SELECT IPv6CIDRToRange(IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8);
|
||||||
SELECT IPv6CIDRToRange(IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
|
||||||
SELECT IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128) = IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 200) ;
|
SELECT IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128) = IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 200) ;
|
||||||
|
|
||||||
|
SELECT IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), toUInt8(128 - number)) FROM numbers(2);
|
||||||
|
Loading…
Reference in New Issue
Block a user