diff --git a/be/src/vec/functions/function_ip.h b/be/src/vec/functions/function_ip.h index 86b0c85745abb5..99b37c94a52d6e 100644 --- a/be/src/vec/functions/function_ip.h +++ b/be/src/vec/functions/function_ip.h @@ -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"; @@ -847,12 +852,14 @@ class FunctionIPv6CIDRToRange : public IFunction { if (addr_type.is_ipv6()) { const auto* ipv6_addr_column = assert_cast(addr_column.get()); - col_res = execute_impl(*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(addr_column.get()); - col_res = execute_impl(*str_addr_column, *cidr_col, input_rows_count, - add_col_const, col_const); + ColumnPtr col_ipv6 = + convert_to_ipv6(addr_column, nullptr); + const auto* ipv6_addr_column = assert_cast(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", @@ -863,8 +870,7 @@ class FunctionIPv6CIDRToRange : public IFunction { return Status::OK(); } - template - 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); @@ -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) { - // 16 bytes ipv6 string is stored in big-endian byte order - // so transfer to little-endian firstly - auto* src_data = const_cast(from_column.get_data_at(0).data); - std::reverse(src_data, src_data + IPV6_BINARY_LENGTH); - apply_cidr_mask(src_data, reinterpret_cast(&vec_res_lower_range[i]), - reinterpret_cast(&vec_res_upper_range[i]), cidr); - } else { - apply_cidr_mask(from_column.get_data_at(0).data, - reinterpret_cast(&vec_res_lower_range[i]), - reinterpret_cast(&vec_res_upper_range[i]), cidr); - } + apply_cidr_mask(from_column.get_data_at(0).data, + reinterpret_cast(&vec_res_lower_range[i]), + reinterpret_cast(&vec_res_upper_range[i]), cidr); } } else if (is_cidr_const) { auto cidr = cidr_column.get_int(0); @@ -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) { - // 16 bytes ipv6 string is stored in big-endian byte order - // so transfer to little-endian firstly - auto* src_data = const_cast(from_column.get_data_at(i).data); - std::reverse(src_data, src_data + IPV6_BINARY_LENGTH); - apply_cidr_mask(src_data, reinterpret_cast(&vec_res_lower_range[i]), - reinterpret_cast(&vec_res_upper_range[i]), cidr); - } else { - apply_cidr_mask(from_column.get_data_at(i).data, - reinterpret_cast(&vec_res_lower_range[i]), - reinterpret_cast(&vec_res_upper_range[i]), cidr); - } + apply_cidr_mask(from_column.get_data_at(i).data, + reinterpret_cast(&vec_res_lower_range[i]), + reinterpret_cast(&vec_res_upper_range[i]), cidr); } } else { for (size_t i = 0; i < input_rows_count; ++i) { @@ -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) { - // 16 bytes ipv6 string is stored in big-endian byte order - // so transfer to little-endian firstly - auto* src_data = const_cast(from_column.get_data_at(i).data); - std::reverse(src_data, src_data + IPV6_BINARY_LENGTH); - apply_cidr_mask(src_data, reinterpret_cast(&vec_res_lower_range[i]), - reinterpret_cast(&vec_res_upper_range[i]), cidr); - } else { - apply_cidr_mask(from_column.get_data_at(i).data, - reinterpret_cast(&vec_res_lower_range[i]), - reinterpret_cast(&vec_res_upper_range[i]), cidr); - } + apply_cidr_mask(from_column.get_data_at(i).data, + reinterpret_cast(&vec_res_lower_range[i]), + reinterpret_cast(&vec_res_upper_range[i]), cidr); } } return ColumnStruct::create( diff --git a/regression-test/suites/query_p0/sql_functions/ip_functions/test_ipv6_cidr_to_range_function.groovy b/regression-test/suites/query_p0/sql_functions/ip_functions/test_ipv6_cidr_to_range_function.groovy index 41432c986fec49..0a8ba107013b4e 100644 --- a/regression-test/suites/query_p0/sql_functions/ip_functions/test_ipv6_cidr_to_range_function.groovy +++ b/regression-test/suites/query_p0/sql_functions/ip_functions/test_ipv6_cidr_to_range_function.groovy @@ -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)" }