Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 22 additions & 43 deletions be/src/vec/functions/function_ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,11 @@ class FunctionIPv4CIDRToRange : public IFunction {
}
};

/**
* this function accepts two arguments: an IPv6 address and a CIDR mask
* IPv6 address can be either ipv6 type or string type as ipv6 string address
* FE: PropagateNullable is used to handle nullable columns
*/
class FunctionIPv6CIDRToRange : public IFunction {
public:
static constexpr auto name = "ipv6_cidr_to_range";
Expand Down Expand Up @@ -847,12 +852,14 @@ class FunctionIPv6CIDRToRange : public IFunction {

if (addr_type.is_ipv6()) {
const auto* ipv6_addr_column = assert_cast<const ColumnIPv6*>(addr_column.get());
col_res = execute_impl<ColumnIPv6>(*ipv6_addr_column, *cidr_col, input_rows_count,
add_col_const, col_const);
col_res = execute_impl(*ipv6_addr_column, *cidr_col, input_rows_count, add_col_const,
col_const);
} else if (addr_type.is_string()) {
const auto* str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
col_res = execute_impl<ColumnString>(*str_addr_column, *cidr_col, input_rows_count,
add_col_const, col_const);
ColumnPtr col_ipv6 =
convert_to_ipv6<IPConvertExceptionMode::Throw>(addr_column, nullptr);
const auto* ipv6_addr_column = assert_cast<const ColumnIPv6*>(col_ipv6.get());
col_res = execute_impl(*ipv6_addr_column, *cidr_col, input_rows_count, add_col_const,
col_const);
} else {
return Status::RuntimeError(
"Illegal column {} of argument of function {}, Expected IPv6 or String",
Expand All @@ -863,8 +870,7 @@ class FunctionIPv6CIDRToRange : public IFunction {
return Status::OK();
}

template <typename FromColumn>
static ColumnPtr execute_impl(const FromColumn& from_column, const ColumnInt16& cidr_column,
static ColumnPtr execute_impl(const ColumnIPv6& from_column, const ColumnInt16& cidr_column,
size_t input_rows_count, bool is_addr_const = false,
bool is_cidr_const = false) {
auto col_res_lower_range = ColumnIPv6::create(input_rows_count, 0);
Expand All @@ -881,18 +887,9 @@ class FunctionIPv6CIDRToRange : public IFunction {
throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
std::to_string(cidr));
}
if constexpr (std::is_same_v<FromColumn, ColumnString>) {
// 16 bytes ipv6 string is stored in big-endian byte order
// so transfer to little-endian firstly
auto* src_data = const_cast<char*>(from_column.get_data_at(0).data);
std::reverse(src_data, src_data + IPV6_BINARY_LENGTH);
apply_cidr_mask(src_data, reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
} else {
apply_cidr_mask(from_column.get_data_at(0).data,
reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
}
apply_cidr_mask(from_column.get_data_at(0).data,
reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
}
} else if (is_cidr_const) {
auto cidr = cidr_column.get_int(0);
Expand All @@ -901,18 +898,9 @@ class FunctionIPv6CIDRToRange : public IFunction {
std::to_string(cidr));
}
for (size_t i = 0; i < input_rows_count; ++i) {
if constexpr (std::is_same_v<FromColumn, ColumnString>) {
// 16 bytes ipv6 string is stored in big-endian byte order
// so transfer to little-endian firstly
auto* src_data = const_cast<char*>(from_column.get_data_at(i).data);
std::reverse(src_data, src_data + IPV6_BINARY_LENGTH);
apply_cidr_mask(src_data, reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
} else {
apply_cidr_mask(from_column.get_data_at(i).data,
reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
}
apply_cidr_mask(from_column.get_data_at(i).data,
reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
}
} else {
for (size_t i = 0; i < input_rows_count; ++i) {
Expand All @@ -921,18 +909,9 @@ class FunctionIPv6CIDRToRange : public IFunction {
throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
std::to_string(cidr));
}
if constexpr (std::is_same_v<FromColumn, ColumnString>) {
// 16 bytes ipv6 string is stored in big-endian byte order
// so transfer to little-endian firstly
auto* src_data = const_cast<char*>(from_column.get_data_at(i).data);
std::reverse(src_data, src_data + IPV6_BINARY_LENGTH);
apply_cidr_mask(src_data, reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
} else {
apply_cidr_mask(from_column.get_data_at(i).data,
reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
}
apply_cidr_mask(from_column.get_data_at(i).data,
reinterpret_cast<char*>(&vec_res_lower_range[i]),
reinterpret_cast<char*>(&vec_res_upper_range[i]), cidr);
}
}
return ColumnStruct::create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ suite("test_ipv6_cidr_to_range_function") {
(9, 'ffff:0000:0000:0000:0000:0000:0000:0000', NULL)
"""

qt_sql "select id, struct_element(ipv6_cidr_to_range(ipv6_string_to_num_or_null(addr), cidr), 'min') as min_range, struct_element(ipv6_cidr_to_range(ipv6_string_to_num_or_null(addr), cidr), 'max') as max_range from test_str_cidr_to_range_function order by id"
qt_sql "select id, struct_element(ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num_or_null(addr)), cidr), 'min') as min_range, struct_element(ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num_or_null(addr)), cidr), 'max') as max_range from test_str_cidr_to_range_function order by id"

sql """ DROP TABLE IF EXISTS test_str_cidr_to_range_function """

qt_sql "select ipv6_cidr_to_range(ipv6_string_to_num('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0)"
qt_sql "select ipv6_cidr_to_range(ipv6_string_to_num('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128)"
qt_sql "select ipv6_cidr_to_range(ipv6_string_to_num('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 64)"
qt_sql "select ipv6_cidr_to_range(ipv6_string_to_num('0000:0000:0000:0000:0000:0000:0000:0000'), 8)"
qt_sql "select ipv6_cidr_to_range(ipv6_string_to_num('ffff:0000:0000:0000:0000:0000:0000:0000'), 4)"
qt_sql "select ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num('2001:0db8:0000:85a3:0000:0000:ac1f:8001')), 0)"
qt_sql "select ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num('2001:0db8:0000:85a3:0000:0000:ac1f:8001')), 128)"
qt_sql "select ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')), 64)"
qt_sql "select ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num('0000:0000:0000:0000:0000:0000:0000:0000')), 8)"
qt_sql "select ipv6_cidr_to_range(ipv6_num_to_string(ipv6_string_to_num('ffff:0000:0000:0000:0000:0000:0000:0000')), 4)"
}
Loading