IPv4CIDRtoIPv4Range and IPv6CIDRtoIPv6Range return now an IP

This commit is contained in:
Guillaume Tassery 2019-04-26 13:30:07 +07:00
parent 68b0144178
commit f21004ed7e
7 changed files with 62 additions and 84 deletions

Binary file not shown.

View File

@ -1473,13 +1473,12 @@ public:
/** Check how many bits we need to set the masks, if we got more bits who can be contain in one byte
* with our current offset, we just clean the whole byte,
*/
const size_t shifts_bits =
byte_offset - bits_to_keep > bits_in_uint8
const size_t shifts_bits = byte_offset - bits_to_keep > bits_in_uint8
? bits_in_uint8
: byte_offset - bits_to_keep;
constexpr UInt8 byte_reference = lower_range ? 0 : std::numeric_limits<UInt8>::max();
/// Clean the bits we don't want on byte
const UInt16 src_byte_shift = (static_cast<UInt16>(src[offset]) >> shifts_bits) << shifts_bits;
/// Set the CIDR mask.
@ -1515,8 +1514,8 @@ public:
+ ", expected numeric type.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
decltype(arguments) return_type = {
std::make_shared<DataTypeFixedString>(IPV6_BINARY_LENGTH),
std::make_shared<DataTypeFixedString>(IPV6_BINARY_LENGTH)
DataTypeFactory::instance().get("IPv6"),
DataTypeFactory::instance().get("IPv6")
};
return std::make_shared<DataTypeTuple>(return_type);
}
@ -1533,7 +1532,7 @@ public:
const auto & col_type_name_cidr = block.getByPosition(arguments[1]);
const ColumnPtr & column_cidr = col_type_name_cidr.column;
const auto col_const_cidr_in = checkAndGetColumnConst<ColumnUInt8>(column_cidr.get());
const auto col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
@ -1597,7 +1596,7 @@ public:
static UInt32 setCIDRMask(UInt32 src, UInt8 bits_to_keep)
{
UInt32 byte_reference = lower_range ? 0 : std::numeric_limits<UInt32>::max();
if (bits_to_keep >= bits_in_uint32)
return src;
@ -1636,7 +1635,7 @@ public:
+ " of second argument of function " + getName()
+ ", expected numeric type.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
decltype(arguments) return_type = { std::make_shared<DataTypeUInt32>(), std::make_shared<DataTypeUInt32>() };
decltype(arguments) return_type = { DataTypeFactory::instance().get("IPv4"), DataTypeFactory::instance().get("IPv4") };
return std::make_shared<DataTypeTuple>(return_type);
}
@ -1652,7 +1651,7 @@ public:
const auto & col_type_name_cidr = block.getByPosition(arguments[1]);
const ColumnPtr & column_cidr = col_type_name_cidr.column;
const auto col_const_cidr_in = checkAndGetColumnConst<ColumnUInt8>(column_cidr.get());
const auto col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
@ -1660,7 +1659,7 @@ public:
{
const auto size = col_ip_in->size();
const auto & vec_in = col_ip_in->getData();
Columns tuple_columns(ip_range_tuple_size);
auto col_res_lower_range = ColumnUInt32::create();

View File

@ -2,15 +2,15 @@
3
2
7
192.168.5.2 0 0.0.0.0 255.255.255.255
192.168.5.20 32 192.168.5.20 192.168.5.20
255.255.255.255 16 255.255.0.0 255.255.255.255
192.142.32.2 32 192.142.32.2 192.142.32.2
192.172.5.2 16 192.172.0.0 192.172.255.255
0.0.0.0 8 0.0.0.0 0.255.255.255
255.0.0.0 4 240.0.0.0 255.255.255.255
0.0.0.0 255.255.255.255
192.168.5.2 192.168.5.2
255.0.0.0 255.255.255.255
0.0.0.0 0.255.255.255
240.0.0.0 255.255.255.255
192.168.5.2 0 0.0.0.0 ('0.0.0.0','255.255.255.255')
192.168.5.20 32 192.168.5.20 ('192.168.5.20','192.168.5.20')
255.255.255.255 16 255.255.0.0 ('255.255.0.0','255.255.255.255')
192.142.32.2 32 192.142.32.2 ('192.142.32.2','192.142.32.2')
192.172.5.2 16 192.172.0.0 ('192.172.0.0','192.172.255.255')
0.0.0.0 8 0.0.0.0 ('0.0.0.0','0.255.255.255')
255.0.0.0 4 240.0.0.0 ('240.0.0.0','255.255.255.255')
('0.0.0.0','255.255.255.255')
('255.0.0.0','255.255.255.255')
('192.168.5.2','192.168.5.2')
('0.0.0.0','0.255.255.255')
('240.0.0.0','255.255.255.255')

View File

@ -1,29 +1,25 @@
USE test;
DROP TABLE IF EXISTS ipv4_range;
CREATE TABLE ipv4_range(ip UInt32, cidr UInt8) ENGINE = Memory;
CREATE TABLE ipv4_range(ip IPv4, cidr UInt8) ENGINE = Memory;
INSERT INTO ipv4_range (ip, cidr) VALUES (IPv4StringToNum('192.168.5.2'), 0), (IPv4StringToNum('192.168.5.20'), 32), (IPv4StringToNum('255.255.255.255'), 16), (IPv4StringToNum('192.142.32.2'), 32), (IPv4StringToNum('192.172.5.2'), 16), (IPv4StringToNum('0.0.0.0'), 8), (IPv4StringToNum('255.0.0.0'), 4);
INSERT INTO ipv4_range (ip, cidr) VALUES (toIPv4('192.168.5.2'), 0), (toIPv4('192.168.5.20'), 32), (toIPv4('255.255.255.255'), 16), (toIPv4('192.142.32.2'), 32), (toIPv4('192.172.5.2'), 16), (toIPv4('0.0.0.0'), 8), (toIPv4('255.0.0.0'), 4);
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('192.168.0.0'), 8) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 8) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('192.168.0.0'), 13) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 13) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('192.168.0.0'), 16) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 16) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('192.168.0.0'), 0) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 0) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv4CIDRtoIPv4Range(ip, cidr) as ip_range SELECT IPv4NumToString(ip), cidr, IPv4NumToString(tupleElement(ip_range, 1)), IPv4NumToString(tupleElement(ip_range, 2)) FROM ipv4_range;
WITH IPv4CIDRtoIPv4Range(ip, cidr) as ip_range SELECT ip, cidr, IPv4NumToString(tupleElement(ip_range, 1)), ip_range FROM ipv4_range;
DROP TABLE ipv4_range;
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('192.168.5.2'), 0) as ip_range SELECT IPv4NumToString(tupleElement(ip_range, 1)) as lower_range, IPv4NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('192.168.5.2'), 32) as ip_range SELECT IPv4NumToString(tupleElement(ip_range, 1)) as lower_range, IPv4NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('255.255.255.255'), 8) as ip_range SELECT IPv4NumToString(tupleElement(ip_range, 1)) as lower_range, IPv4NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('0.0.0.0'), 8) as ip_range SELECT IPv4NumToString(tupleElement(ip_range, 1)) as lower_range, IPv4NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv4CIDRtoIPv4Range(IPv4StringToNum('255.0.0.0'), 4) as ip_range SELECT IPv4NumToString(tupleElement(ip_range, 1)) as lower_range, IPv4NumToString(tupleElement(ip_range, 2)) as higher_range;
SELECT IPv4CIDRtoIPv4Range(toIPv4('192.168.5.2'), 0);
SELEcT IPv4CIDRtoIPv4Range(toIPv4('255.255.255.255'), 8);
SELECT IPv4CIDRtoIPv4Range(toIPv4('192.168.5.2'), 32);
SELECT IPv4CIDRtoIPv4Range(toIPv4('0.0.0.0'), 8);
SELECT IPv4CIDRtoIPv4Range(toIPv4('255.0.0.0'), 4);

View File

@ -3,15 +3,15 @@
3
2
7
2001:db8:0:85a3::ac1f:8001 0 :: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
2001:db8:0:85a3:ffff:ffff:ffff:ffff 32 2001:db8:: 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 16 ffff:: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
2001:df8:0:85a3::ac1f:8001 32 2001:df8:: 2001:df8:ffff:ffff:ffff:ffff:ffff:ffff
2001:db8:85a3:85a3::ac1f:8001 16 2001:: 2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff
:: 8 :: ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
ffff:: 4 f000:: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
:: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
2001:db8:0:85a3::ac1f:8001 2001:db8:0:85a3::ac1f:8001
ffff:ffff:ffff:ffff:: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
:: ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
f000:: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
2001:db8:0:85a3::ac1f:8001 0 ('::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
2001:db8:0:85a3:ffff:ffff:ffff:ffff 32 ('2001:db8::','2001:db8:ffff:ffff:ffff:ffff:ffff:ffff')
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 16 ('ffff::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
2001:df8:0:85a3::ac1f:8001 32 ('2001:df8::','2001:df8:ffff:ffff:ffff:ffff:ffff:ffff')
2001:db8:85a3:85a3::ac1f:8001 16 ('2001::','2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
:: 8 ('::','ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
ffff:: 4 ('f000::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
('::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
('2001:db8:0:85a3::ac1f:8001','2001:db8:0:85a3::ac1f:8001')
('ffff:ffff:ffff:ffff::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
('::','ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
('f000::','ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')

View File

@ -1,7 +1,7 @@
USE test;
DROP TABLE IF EXISTS ipv6_range;
CREATE TABLE ipv6_range(ip FixedString(16), cidr UInt8) ENGINE = Memory;
CREATE TABLE ipv6_range(ip IPv6, cidr UInt8) ENGINE = Memory;
INSERT INTO ipv6_range (ip, cidr) VALUES (IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0), (IPv6StringToNum('2001:0db8:0000:85a3:ffff:ffff:ffff:ffff'), 32), (IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 16), (IPv6StringToNum('2001:df8:0:85a3::ac1f:8001'), 32), (IPv6StringToNum('2001:0db8:85a3:85a3:0000:0000:ac1f:8001'), 16), (IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8), (IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
@ -15,17 +15,13 @@ WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:800
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
WITH IPv6CIDRtoIPv6Range(ip, cidr) as ip_range SELECT IPv6NumToString(ip), cidr, IPv6NumToString(tupleElement(ip_range, 1)), IPv6NumToString(tupleElement(ip_range, 2)) FROM ipv6_range;
SELECT IPv6NumToString(ip), cidr, IPv6CIDRtoIPv6Range(ip, cidr) FROM ipv6_range;
DROP TABLE ipv6_range;
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0) as ip_range SELECT IPv6NumToString(tupleElement(ip_range, 1)) as lower_range, IPv6NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128) as ip_range SELECT IPv6NumToString(tupleElement(ip_range, 1)) as lower_range, IPv6NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 64) as ip_range SELECT IPv6NumToString(tupleElement(ip_range, 1)) as lower_range, IPv6NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8) as ip_range SELECT IPv6NumToString(tupleElement(ip_range, 1)) as lower_range, IPv6NumToString(tupleElement(ip_range, 2)) as higher_range;
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4) as ip_range SELECT IPv6NumToString(tupleElement(ip_range, 1)) as lower_range, IPv6NumToString(tupleElement(ip_range, 2)) as higher_range;
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0);
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128);
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 64);
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8);
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);

View File

@ -149,46 +149,33 @@ SELECT
## IPv4CIDRtoIPv4Range(ipv4, cidr),
Accepts a UInt32 value interpreted as an IPv4 address in big endian and an UInt8 value containing the CIDR. Return a tuple with two UInt32 interpreted as an IPv4 address in big endian containing the lower range and the higher range of the subnet.
Accepts an IPv4 and an UInt8 value containing the CIDR. Return a tuple with two IPv4 containing the lower range and the higher range of the subnet.
```sql
WITH
IPv4StringToNum('192.168.5.2') AS ipv4,
IPv4CIDRtoIPv4Range(ipv4, 16) AS ip_range
SELECT
IPv4CIDRtoIPv4Range(ipv4, 16),
IPv4NumToString(ip_range.1) AS lower_range,
IPv4NumToString(ip_range.2) AS higher_range
SELECT IPv4CIDRtoIPv4Range(toIPv4('192.168.5.2'), 16)
```
```
┌─IPv4CIDRtoIPv4Range(ipv4, 16)─┬─lower_range─┬─higher_range────┐
│ (3232235520,3232301055) │ 192.168.0.0 │ 192.168.255.255
└───────────────────────────────┴─────────────┴─────────────────┘
┌─IPv4CIDRtoIPv4Range(toIPv4('192.168.5.2'), 16)─┐
│ ('192.168.0.0','192.168.255.255') │
└────────────────────────────────────────────────┘
```
## IPv6CIDRtoIPv6Range(ipv6, cidr),
Accepts a FixedString(16) value containing the IPv6 address in binary format and an UInt8 value containing the CIDR. Return a tuple with two FixedString(16) containing the lower range and the higher range of the subnet.
Accepts an IPv6 and an UInt8 value containing the CIDR. Return a tuple with two IPv6 containing the lower range and the higher range of the subnet.
```sql
WITH
IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001') AS ipv6,
IPv6CIDRtoIPv6Range(ipv6, 32) AS ip_range
SELECT
IPv6NumToString(ip_range.1) AS lower_range,
IPv6NumToString(ip_range.2) AS higher_range
SELECT IPv6CIDRtoIPv6Range(toIPv6('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 32);
```
```
┌─lower_range─┬─higher_range───────────────────────────┐
2001:db8:: │ 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff
└─────────────────────────────────────────────────────┘
┌─IPv6CIDRtoIPv6Range(toIPv6('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 32)─┐
│ ('2001:db8::','2001:db8:ffff:ffff:ffff:ffff:ffff:ffff') │
└────────────────────────────────────────────────────────────────────────────┘
```