From 7402fee1fcfe597f157b93115cf29f7f9cf360e7 Mon Sep 17 00:00:00 2001 From: Chester <42577861+superdiaodiao@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:24:45 +0800 Subject: [PATCH] [feature](function) support ip function ipv6_string_to_num(_or_default, _or_null), inet6_aton (#28361) --- be/src/vec/common/format_ip.cpp | 3 - be/src/vec/common/format_ip.h | 1 + be/src/vec/functions/function_ip.cpp | 5 + be/src/vec/functions/function_ip.h | 257 ++++++++++++++++++ .../sql-functions/ip-functions/inet6-aton.md | 70 +++++ .../ipv6-string-to-num-or-default.md | 75 +++++ .../ipv6-string-to-num-or-null.md | 75 +++++ .../ip-functions/ipv6-string-to-num.md | 70 +++++ docs/sidebars.json | 7 +- .../sql-functions/ip-functions/inet6-aton.md | 70 +++++ .../sql-functions/ip-functions/inet6-ntoa.md | 2 +- .../ip-functions/ipv6-num-to-string.md | 2 +- .../ipv6-string-to-num-or-default.md | 75 +++++ .../ipv6-string-to-num-or-null.md | 75 +++++ .../ip-functions/ipv6-string-to-num.md | 70 +++++ .../doris/catalog/BuiltinScalarFunctions.java | 6 + .../functions/scalar/Ipv6StringToNum.java | 66 +++++ .../scalar/Ipv6StringToNumOrDefault.java | 66 +++++ .../scalar/Ipv6StringToNumOrNull.java | 66 +++++ .../visitor/ScalarFunctionVisitor.java | 15 + gensrc/script/doris_builtins_functions.py | 6 + .../data/nereids_function_p0/ip_functions.out | 65 ++++- .../ip_functions/test_ip_functions.out | 65 ++++- .../nereids_function_p0/ip_functions.groovy | 22 ++ .../ip_functions/test_ip_functions.groovy | 22 ++ 25 files changed, 1248 insertions(+), 8 deletions(-) create mode 100644 docs/en/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md create mode 100644 docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md create mode 100644 docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md create mode 100644 docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md create mode 100644 docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md create mode 100644 docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md create mode 100644 docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md create mode 100644 docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNum.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrDefault.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrNull.java diff --git a/be/src/vec/common/format_ip.cpp b/be/src/vec/common/format_ip.cpp index b673d5575d..3e4379872a 100644 --- a/be/src/vec/common/format_ip.cpp +++ b/be/src/vec/common/format_ip.cpp @@ -23,9 +23,6 @@ #include #include -#include "vec/common/hex.h" -#include "vec/core/types.h" - namespace doris::vectorized { /** Further we want to generate constexpr array of strings with sizes from sequence of unsigned ints [0..N) diff --git a/be/src/vec/common/format_ip.h b/be/src/vec/common/format_ip.h index 58322ecd9f..71c7c73b50 100644 --- a/be/src/vec/common/format_ip.h +++ b/be/src/vec/common/format_ip.h @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/be/src/vec/functions/function_ip.cpp b/be/src/vec/functions/function_ip.cpp index 643c69939d..6e59503dba 100644 --- a/be/src/vec/functions/function_ip.cpp +++ b/be/src/vec/functions/function_ip.cpp @@ -32,5 +32,10 @@ void register_function_ip(SimpleFunctionFactory& factory) { "inet_aton"); factory.register_function(); factory.register_alias(FunctionIPv6NumToString::name, "inet6_ntoa"); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_alias(FunctionIPv6StringToNum::name, + "inet6_aton"); } } // namespace doris::vectorized \ No newline at end of file diff --git a/be/src/vec/functions/function_ip.h b/be/src/vec/functions/function_ip.h index 4a39242e85..042f102360 100644 --- a/be/src/vec/functions/function_ip.h +++ b/be/src/vec/functions/function_ip.h @@ -348,4 +348,261 @@ public: } }; +namespace detail { +template +ColumnPtr convertToIPv6(const StringColumnType& string_column, + const PaddedPODArray* null_map = nullptr) { + if constexpr (!std::is_same_v && + !std::is_same_v) { + throw Exception(ErrorCode::INVALID_ARGUMENT, + "Illegal return column type {}. Expected IPv6 or String", + TypeName::get()); + } + + const size_t column_size = string_column.size(); + + ColumnUInt8::MutablePtr col_null_map_to; + ColumnUInt8::Container* vec_null_map_to = nullptr; + + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + col_null_map_to = ColumnUInt8::create(column_size, false); + vec_null_map_to = &col_null_map_to->get_data(); + } + + /// This is a special treatment for source column of type String + /// to preserve previous behavior when IPv6 was a domain type of String + if constexpr (std::is_same_v) { + if (string_column.get_offsets()[0] - 1 == IPV6_BINARY_LENGTH) { + if constexpr (std::is_same_v) { + auto col_res = ColumnString::create(); + + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + col_null_map_to = ColumnUInt8::create(column_size, false); + if (null_map) { + memcpy(col_null_map_to->get_data().data(), null_map->data(), column_size); + } + + return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to)); + } + + return col_res; + } else { + auto col_res = ColumnIPv6::create(); + auto& vec_res = col_res->get_data(); + + vec_res.resize(column_size); + memcpy(vec_res.data(), string_column.get_chars().data(), + column_size * IPV6_BINARY_LENGTH); + + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + col_null_map_to = ColumnUInt8::create(column_size, false); + if (null_map) { + memcpy(col_null_map_to->get_data().data(), null_map->data(), column_size); + } + return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to)); + } + + return col_res; + } + } + } + + auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr { + if constexpr (std::is_same_v) { + auto column_string = ColumnString::create(); + column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH); + column_string->get_offsets().reserve(column_size); + return column_string; + } else { + return ColumnIPv6::create(); + } + }; + + auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) { + if constexpr (std::is_same_v) { + auto& vec_res = col_res->get_chars(); + vec_res.resize(col_size * IPV6_BINARY_LENGTH); + return (vec_res); + } else { + auto& vec_res = col_res->get_data(); + vec_res.resize(col_size); + return (vec_res); + } + }; + + auto col_res = column_create(column_size); + auto& vec_res = get_vector(col_res, column_size); + + using Chars = typename StringColumnType::Chars; + const Chars& vec_src = string_column.get_chars(); + + size_t src_offset = 0; + char src_ipv4_buf[sizeof("::ffff:") + IPV4_MAX_TEXT_LENGTH + 1] = "::ffff:"; + + /// ColumnString contains not null terminated strings. But functions parseIPv6, parseIPv4 expect null terminated string. + /// TODO fix this - now parseIPv6/parseIPv4 accept end iterator, so can be parsed in-place + std::string string_buffer; + + int offset_inc = 1; + if constexpr (std::is_same_v) { + offset_inc = IPV6_BINARY_LENGTH; + } + + for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) { + size_t src_next_offset = src_offset; + + const char* src_value = nullptr; + auto* res_value = reinterpret_cast(&vec_res[out_offset]); + + if constexpr (std::is_same_v) { + src_value = reinterpret_cast(&vec_src[src_offset]); + src_next_offset = string_column.get_offsets()[i]; + + string_buffer.assign(src_value, src_next_offset - src_offset); + src_value = string_buffer.c_str(); + } + + if (null_map && (*null_map)[i]) { + if (exception_mode == IPStringToNumExceptionMode::Throw) { + throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value"); + } else if (exception_mode == IPStringToNumExceptionMode::Default) { + std::fill_n(&vec_res[out_offset], offset_inc, 0); + } else { + std::fill_n(&vec_res[out_offset], offset_inc, 0); + (*vec_null_map_to)[i] = true; + if constexpr (std::is_same_v) { + auto* column_string = assert_cast(col_res.get()); + column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH); + } + } + src_offset = src_next_offset; + continue; + } + + bool parse_result = false; + Int64 dummy_result = 0; + + /// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes. + + /// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address. + /// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address. + size_t string_length = src_next_offset - src_offset; + if (string_length != 0) { + if (tryParseIPv4(src_value, dummy_result)) { + strcat(src_ipv4_buf, src_value); + parse_result = parseIPv6whole(src_ipv4_buf, res_value); + } else { + parse_result = parseIPv6whole(src_value, res_value); + } + } + + if (parse_result && string_length != 0) { + if constexpr (std::is_same_v) { + auto* column_string = assert_cast(col_res.get()); + std::copy(res_value, res_value + IPV6_BINARY_LENGTH, + column_string->get_chars().begin() + i * IPV6_BINARY_LENGTH); + column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH); + } else { + col_res->insert_data(reinterpret_cast(res_value), IPV6_BINARY_LENGTH); + } + } else { + if (exception_mode == IPStringToNumExceptionMode::Throw) { + throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value"); + } + std::fill_n(&vec_res[out_offset], offset_inc, 0); + if constexpr (std::is_same_v) { + auto* column_string = assert_cast(col_res.get()); + column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH); + } + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + (*vec_null_map_to)[i] = true; + } + } + src_offset = src_next_offset; + } + + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to)); + } + return col_res; +} +} // namespace detail + +template +ColumnPtr convertToIPv6(ColumnPtr column, const PaddedPODArray* null_map = nullptr) { + if (const auto* column_input_string = check_and_get_column(column.get())) { + auto result = + detail::convertToIPv6(*column_input_string, null_map); + return result; + } else { + throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal column type {}. Expected String", + column->get_name()); + } +} + +template +class FunctionIPv6StringToNum : public IFunction { +public: + static constexpr auto name = exception_mode == IPStringToNumExceptionMode::Throw + ? "ipv6_string_to_num" + : (exception_mode == IPStringToNumExceptionMode::Default + ? "ipv6_string_to_num_or_default" + : "ipv6_string_to_num_or_null"); + + static FunctionPtr create() { + return std::make_shared>(); + } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 1; } + + bool use_default_implementation_for_nulls() const override { return false; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + if (!is_string(remove_nullable(arguments[0]))) { + throw Exception(ErrorCode::INVALID_ARGUMENT, + "Illegal type {} of argument of function {}", arguments[0]->get_name(), + get_name()); + } + + auto result_type = std::make_shared(); + + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + return make_nullable(result_type); + } + + return result_type; + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) const override { + ColumnPtr column = block.get_by_position(arguments[0]).column; + ColumnPtr null_map_column; + const NullMap* null_map = nullptr; + + if (column->is_nullable()) { + const auto* column_nullable = assert_cast(column.get()); + column = column_nullable->get_nested_column_ptr(); + if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + null_map_column = column_nullable->get_null_map_column_ptr(); + null_map = &column_nullable->get_null_map_data(); + } + } + + auto col_res = convertToIPv6(column, null_map); + + if (null_map && !col_res->is_nullable()) { + block.replace_by_position(result, + ColumnNullable::create(IColumn::mutate(col_res), + IColumn::mutate(null_map_column))); + return Status::OK(); + } + + block.replace_by_position(result, col_res); + return Status::OK(); + } +}; + } // namespace doris::vectorized \ No newline at end of file diff --git a/docs/en/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md b/docs/en/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md new file mode 100644 index 0000000000..69bf4a4486 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md @@ -0,0 +1,70 @@ +--- +{ +"title": "INET6_ATON", +"language": "en" +} +--- + + + +## INET6_ATON + + + +inet6_aton + + + +### description + +#### Syntax + +`VARCHAR INET6_ATON(VARCHAR ipv6_string)` + +The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format. +If the input string contains a valid IPv4 address, returns its IPv6 equivalent. + +### notice + +`will return an error if the input string is not a valid IP address` + +### example +``` +mysql> select hex(inet6_aton('1111::ffff')); ++----------------------------------+ +| hex(inet6_aton('1111::ffff')) | ++----------------------------------+ +| 1111000000000000000000000000FFFF | ++----------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(inet6_aton('192.168.0.1')); ++----------------------------------+ +| hex(inet6_aton('192.168.0.1')) | ++----------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++----------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(inet6_aton('notaaddress')); +ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value +``` + +### keywords + +INET6_ATON, IP \ No newline at end of file diff --git a/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md b/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md new file mode 100644 index 0000000000..30c3455adf --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md @@ -0,0 +1,75 @@ +--- +{ +"title": "IPV6_STRING_TO_NUM_OR_DEFAULT", +"language": "en" +} +--- + + + +## IPV6_STRING_TO_NUM_OR_DEFAULT + + + +IPV6_STRING_TO_NUM_OR_DEFAULT + + + +### description + +#### Syntax + +`VARCHAR IPV6_STRING_TO_NUM_OR_DEFAULT(VARCHAR ipv6_string)` + +The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format. +If the input string contains a valid IPv4 address, returns its IPv6 equivalent. + +### notice + +`will return zero if the input string is not a valid IP address` + +### example +``` +mysql> select hex(ipv6_string_to_num_or_default('1111::ffff')); ++--------------------------------------------------+ +| hex(ipv6_string_to_num_or_default('1111::ffff')) | ++--------------------------------------------------+ +| 1111000000000000000000000000FFFF | ++--------------------------------------------------+ +1 row in set (0.01 sec) + +mysql> select hex(ipv6_string_to_num_or_default('192.168.0.1')); ++---------------------------------------------------+ +| hex(ipv6_string_to_num_or_default('192.168.0.1')) | ++---------------------------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++---------------------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num_or_default('notaaddress')); ++---------------------------------------------------+ +| hex(ipv6_string_to_num_or_default('notaaddress')) | ++---------------------------------------------------+ +| 00000000000000000000000000000000 | ++---------------------------------------------------+ +1 row in set (0.02 sec) +``` + +### keywords + +IPV6_STRING_TO_NUM_OR_DEFAULT, IP \ No newline at end of file diff --git a/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md b/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md new file mode 100644 index 0000000000..9df5f11414 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md @@ -0,0 +1,75 @@ +--- +{ +"title": "IPV6_STRING_TO_NUM_OR_NULL", +"language": "en" +} +--- + + + +## IPV6_STRING_TO_NUM_OR_NULL + + + +IPV6_STRING_TO_NUM_OR_NULL + + + +### description + +#### Syntax + +`VARCHAR IPV6_STRING_TO_NUM_OR_NULL(VARCHAR ipv6_string)` + +The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format. +If the input string contains a valid IPv4 address, returns its IPv6 equivalent. + +### notice + +`will return NULL if the input string is not a valid IP address` + +### example +``` +mysql> select hex(ipv6_string_to_num_or_null('1111::ffff')); ++-----------------------------------------------+ +| hex(ipv6_string_to_num_or_null('1111::ffff')) | ++-----------------------------------------------+ +| 1111000000000000000000000000FFFF | ++-----------------------------------------------+ +1 row in set (0.01 sec) + +mysql> select hex(ipv6_string_to_num_or_null('192.168.0.1')); ++------------------------------------------------+ +| hex(ipv6_string_to_num_or_null('192.168.0.1')) | ++------------------------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++------------------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num_or_null('notaaddress')); ++------------------------------------------------+ +| hex(ipv6_string_to_num_or_null('notaaddress')) | ++------------------------------------------------+ +| NULL | ++------------------------------------------------+ +1 row in set (0.02 sec) +``` + +### keywords + +IPV6_STRING_TO_NUM_OR_NULL, IP \ No newline at end of file diff --git a/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md b/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md new file mode 100644 index 0000000000..c9d1530549 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md @@ -0,0 +1,70 @@ +--- +{ +"title": "IPV6_STRING_TO_NUM", +"language": "en" +} +--- + + + +## IPV6_STRING_TO_NUM + + + +IPV6_STRING_TO_NUM + + + +### description + +#### Syntax + +`VARCHAR IPV6_STRING_TO_NUM(VARCHAR ipv6_string)` + +The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format. +If the input string contains a valid IPv4 address, returns its IPv6 equivalent. + +### notice + +`will return an error if the input string is not a valid IP address` + +### example +``` +mysql> select hex(ipv6_string_to_num('1111::ffff')); ++---------------------------------------+ +| hex(ipv6_string_to_num('1111::ffff')) | ++---------------------------------------+ +| 1111000000000000000000000000FFFF | ++---------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num('192.168.0.1')); ++----------------------------------------+ +| hex(ipv6_string_to_num('192.168.0.1')) | ++----------------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++----------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num('notaaddress')); +ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value +``` + +### keywords + +IPV6_STRING_TO_NUM, IP \ No newline at end of file diff --git a/docs/sidebars.json b/docs/sidebars.json index f8aa83eb3a..d0bcae3aa5 100644 --- a/docs/sidebars.json +++ b/docs/sidebars.json @@ -800,7 +800,12 @@ "sql-manual/sql-functions/ip-functions/ipv4-string-to-num-or-default", "sql-manual/sql-functions/ip-functions/ipv4-string-to-num-or-null", "sql-manual/sql-functions/ip-functions/ipv6-num-to-string", - "sql-manual/sql-functions/ip-functions/inet6-ntoa" + "sql-manual/sql-functions/ip-functions/inet6-ntoa", + "sql-manual/sql-functions/ip-functions/ipv6-num-to-string", + "sql-manual/sql-functions/ip-functions/inet6-aton", + "sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default", + "sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null" + ] }, { diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md new file mode 100644 index 0000000000..cc2bd6f04d --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-aton.md @@ -0,0 +1,70 @@ +--- +{ +"title": "INET6_ATON", +"language": "zh-CN" +} +--- + + + +## INET6_ATON + + + +inet6_aton + + + +### description + +#### Syntax + +`VARCHAR INET6_ATON(VARCHAR ipv6_string)` + +IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。 +如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。 + +### notice + +`如果输入非法的IP地址,会抛出异常` + +### example +``` +mysql> select hex(inet6_aton('1111::ffff')); ++----------------------------------+ +| hex(inet6_aton('1111::ffff')) | ++----------------------------------+ +| 1111000000000000000000000000FFFF | ++----------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(inet6_aton('192.168.0.1')); ++----------------------------------+ +| hex(inet6_aton('192.168.0.1')) | ++----------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++----------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(inet6_aton('notaaddress')); +ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value +``` + +### keywords + +INET6_ATON, IP \ No newline at end of file diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-ntoa.md b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-ntoa.md index aaeb3cc0c3..d92dcee522 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-ntoa.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/inet6-ntoa.md @@ -1,7 +1,7 @@ --- { "title": "INET6_NTOA", -"language": "en" +"language": "zh-CN" } --- diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-num-to-string.md b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-num-to-string.md index c58ecf42f4..44bb3a9da6 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-num-to-string.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-num-to-string.md @@ -1,7 +1,7 @@ --- { "title": "IPV6_NUM_TO_STRING", -"language": "en" +"language": "zh-CN" } --- diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md new file mode 100644 index 0000000000..4215256a84 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default.md @@ -0,0 +1,75 @@ +--- +{ +"title": "IPV6_STRING_TO_NUM_OR_DEFAULT", +"language": "zh-CN" +} +--- + + + +## IPV6_STRING_TO_NUM_OR_DEFAULT + + + +IPV6_STRING_TO_NUM_OR_DEFAULT + + + +### description + +#### Syntax + +`VARCHAR IPV6_STRING_TO_NUM_OR_DEFAULT(VARCHAR ipv6_string)` + +IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。 +如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。 + +### notice + +`如果输入非法的IP地址,会返回0` + +### example +``` +mysql> select hex(ipv6_string_to_num_or_default('1111::ffff')); ++--------------------------------------------------+ +| hex(ipv6_string_to_num_or_default('1111::ffff')) | ++--------------------------------------------------+ +| 1111000000000000000000000000FFFF | ++--------------------------------------------------+ +1 row in set (0.01 sec) + +mysql> select hex(ipv6_string_to_num_or_default('192.168.0.1')); ++---------------------------------------------------+ +| hex(ipv6_string_to_num_or_default('192.168.0.1')) | ++---------------------------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++---------------------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num_or_default('notaaddress')); ++---------------------------------------------------+ +| hex(ipv6_string_to_num_or_default('notaaddress')) | ++---------------------------------------------------+ +| 00000000000000000000000000000000 | ++---------------------------------------------------+ +1 row in set (0.02 sec) +``` + +### keywords + +IPV6_STRING_TO_NUM_OR_DEFAULT, IP \ No newline at end of file diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md new file mode 100644 index 0000000000..9549d2b100 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null.md @@ -0,0 +1,75 @@ +--- +{ +"title": "IPV6_STRING_TO_NUM_OR_NULL", +"language": "zh-CN" +} +--- + + + +## IPV6_STRING_TO_NUM_OR_NULL + + + +IPV6_STRING_TO_NUM_OR_NULL + + + +### description + +#### Syntax + +`VARCHAR IPV6_STRING_TO_NUM_OR_NULL(VARCHAR ipv6_string)` + +IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。 +如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。 + +### notice + +`如果输入非法的IP地址,会返回NULL` + +### example +``` +mysql> select hex(ipv6_string_to_num_or_null('1111::ffff')); ++-----------------------------------------------+ +| hex(ipv6_string_to_num_or_null('1111::ffff')) | ++-----------------------------------------------+ +| 1111000000000000000000000000FFFF | ++-----------------------------------------------+ +1 row in set (0.01 sec) + +mysql> select hex(ipv6_string_to_num_or_null('192.168.0.1')); ++------------------------------------------------+ +| hex(ipv6_string_to_num_or_null('192.168.0.1')) | ++------------------------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++------------------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num_or_null('notaaddress')); ++------------------------------------------------+ +| hex(ipv6_string_to_num_or_null('notaaddress')) | ++------------------------------------------------+ +| NULL | ++------------------------------------------------+ +1 row in set (0.02 sec) +``` + +### keywords + +IPV6_STRING_TO_NUM_OR_NULL, IP \ No newline at end of file diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md new file mode 100644 index 0000000000..a02ae6374d --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/ipv6-string-to-num.md @@ -0,0 +1,70 @@ +--- +{ +"title": "IPV6_STRING_TO_NUM", +"language": "zh-CN" +} +--- + + + +## IPV6_STRING_TO_NUM + + + +IPV6_STRING_TO_NUM + + + +### description + +#### Syntax + +`VARCHAR IPV6_STRING_TO_NUM(VARCHAR ipv6_string)` + +IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。 +如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。 + +### notice + +`如果输入非法的IP地址,会抛出异常` + +### example +``` +mysql> select hex(ipv6_string_to_num('1111::ffff')); ++---------------------------------------+ +| hex(ipv6_string_to_num('1111::ffff')) | ++---------------------------------------+ +| 1111000000000000000000000000FFFF | ++---------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num('192.168.0.1')); ++----------------------------------------+ +| hex(ipv6_string_to_num('192.168.0.1')) | ++----------------------------------------+ +| 00000000000000000000FFFFC0A80001 | ++----------------------------------------+ +1 row in set (0.02 sec) + +mysql> select hex(ipv6_string_to_num('notaaddress')); +ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value +``` + +### keywords + +IPV6_STRING_TO_NUM, IP \ No newline at end of file diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java index 726cef054e..2a2627d29a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java @@ -195,6 +195,9 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToN import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrDefault; import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrNull; import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6NumToString; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNum; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrDefault; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrNull; import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonArray; import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonContains; import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonExtract; @@ -593,6 +596,9 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(Ipv4StringToNumOrDefault.class, "ipv4stringtonumordefault"), scalar(Ipv4StringToNumOrNull.class, "ipv4stringtonumornull"), scalar(Ipv6NumToString.class, "ipv6numtostring", "inet6_ntoa"), + scalar(Ipv6StringToNum.class, "ipv6_string_to_num", "inet6_aton"), + scalar(Ipv6StringToNumOrDefault.class, "ipv6_string_to_num_or_default"), + scalar(Ipv6StringToNumOrNull.class, "ipv6_string_to_num_or_null"), scalar(JsonArray.class, "json_array"), scalar(JsonObject.class, "json_object"), scalar(JsonQuote.class, "json_quote"), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNum.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNum.java new file mode 100644 index 0000000000..646d005e49 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNum.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.StringType; +import org.apache.doris.nereids.types.VarcharType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * scalar function ipv6_string_to_num + */ +public class Ipv6StringToNum extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE)); + + public Ipv6StringToNum(Expression arg0) { + super("ipv6_string_to_num", arg0); + } + + @Override + public Ipv6StringToNum withChildren(List children) { + Preconditions.checkArgument(children.size() == 1, + "ipv6_string_to_num accept 1 args, but got %s (%s)", + children.size(), + children); + return new Ipv6StringToNum(children.get(0)); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitIpv6StringToNum(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrDefault.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrDefault.java new file mode 100644 index 0000000000..e34e6ea2fe --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrDefault.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.StringType; +import org.apache.doris.nereids.types.VarcharType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * scalar function ipv6_string_to_num_or_default + */ +public class Ipv6StringToNumOrDefault extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE)); + + public Ipv6StringToNumOrDefault(Expression arg0) { + super("ipv6_string_to_num_or_default", arg0); + } + + @Override + public Ipv6StringToNumOrDefault withChildren(List children) { + Preconditions.checkArgument(children.size() == 1, + "ipv6_string_to_num_or_default accept 1 args, but got %s (%s)", + children.size(), + children); + return new Ipv6StringToNumOrDefault(children.get(0)); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitIpv6StringToNumOrDefault(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrNull.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrNull.java new file mode 100644 index 0000000000..9a099c8df3 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Ipv6StringToNumOrNull.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.StringType; +import org.apache.doris.nereids.types.VarcharType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * scalar function ipv6_string_to_num_or_null + */ +public class Ipv6StringToNumOrNull extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE)); + + public Ipv6StringToNumOrNull(Expression arg0) { + super("ipv6_string_to_num_or_null", arg0); + } + + @Override + public Ipv6StringToNumOrNull withChildren(List children) { + Preconditions.checkArgument(children.size() == 1, + "ipv6_string_to_num_or_null accept 1 args, but got %s (%s)", + children.size(), + children); + return new Ipv6StringToNumOrNull(children.get(0)); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitIpv6StringToNumOrNull(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java index ae147b633b..944bb4fdb8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java @@ -191,6 +191,9 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToN import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrDefault; import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrNull; import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6NumToString; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNum; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrDefault; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrNull; import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonArray; import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonContains; import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonExtract; @@ -1121,6 +1124,18 @@ public interface ScalarFunctionVisitor { return visitScalarFunction(ipv6NumToString, context); } + default R visitIpv6StringToNum(Ipv6StringToNum ipv6StringToNum, C context) { + return visitScalarFunction(ipv6StringToNum, context); + } + + default R visitIpv6StringToNumOrDefault(Ipv6StringToNumOrDefault ipv6StringToNumOrDefault, C context) { + return visitScalarFunction(ipv6StringToNumOrDefault, context); + } + + default R visitIpv6StringToNumOrNull(Ipv6StringToNumOrNull ipv6StringToNumOrNull, C context) { + return visitScalarFunction(ipv6StringToNumOrNull, context); + } + default R visitJsonArray(JsonArray jsonArray, C context) { return visitScalarFunction(jsonArray, context); } diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 5e45a1a78a..77992a539b 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -2006,6 +2006,12 @@ visible_functions = { [['ipv4stringtonumornull'], 'BIGINT', ['STRING'], 'ALWAYS_NULLABLE'], [['ipv6numtostring','inet6_ntoa'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NULLABLE'], [['ipv6numtostring','inet6_ntoa'], 'STRING', ['STRING'], 'ALWAYS_NULLABLE'], + [['ipv6_string_to_num','inet6_aton'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'], + [['ipv6_string_to_num','inet6_aton'], 'STRING', ['STRING'], 'ALWAYS_NOT_NULLABLE'], + [['ipv6_string_to_num_or_default'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'], + [['ipv6_string_to_num_or_default'], 'STRING', ['STRING'], 'ALWAYS_NOT_NULLABLE'], + [['ipv6_string_to_num_or_null'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NULLABLE'], + [['ipv6_string_to_num_or_null'], 'STRING', ['STRING'], 'ALWAYS_NULLABLE'], ], "NonNullalbe": [ diff --git a/regression-test/data/nereids_function_p0/ip_functions.out b/regression-test/data/nereids_function_p0/ip_functions.out index f906ee221f..56ae095999 100644 --- a/regression-test/data/nereids_function_p0/ip_functions.out +++ b/regression-test/data/nereids_function_p0/ip_functions.out @@ -87,4 +87,67 @@ aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa \N -- !ip30 -- -::ffff:127.0.0.1 \ No newline at end of file +::ffff:127.0.0.1 + +-- !ip31 -- +00000000000000000000FFFFC0A80001 + +-- !ip32 -- +2A0206B8000000000000000000000011 + +-- !ip33 -- +00000000000000000000000000000000 + +-- !ip34 -- +00A00050910000000000000000000000 + +-- !ip35 -- +00000000000000000000FFFFC0A80001 + +-- !ip36 -- +2A0206B8000000000000000000000011 + +-- !ip37 -- +00000000000000000000000000000000 + +-- !ip38 -- +00000000000000000000000000000000 + +-- !ip39 -- +00000000000000000000000000000000 + +-- !ip40 -- +00000000000000000000FFFFC0A80001 + +-- !ip41 -- +2A0206B8000000000000000000000011 + +-- !ip42 -- +00000000000000000000000000000000 + +-- !ip43 -- +\N + +-- !ip44 -- +\N + +-- !ip45 -- +\N + +-- !ip46 -- +\N + +-- !ip47 -- +\N + +-- !ip48 -- +\N + +-- !ip49 -- +AAAAAAAAFFFFFFFFFFFFFFFFAAAAAAAA + +-- !ip50 -- +00000000000000000000FFFFC0A80001 + +-- !ip51 -- +2A0206B8000000000000000000000011 \ No newline at end of file diff --git a/regression-test/data/query_p0/sql_functions/ip_functions/test_ip_functions.out b/regression-test/data/query_p0/sql_functions/ip_functions/test_ip_functions.out index 54e2fac889..71f02449d3 100644 --- a/regression-test/data/query_p0/sql_functions/ip_functions/test_ip_functions.out +++ b/regression-test/data/query_p0/sql_functions/ip_functions/test_ip_functions.out @@ -74,4 +74,67 @@ aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa \N -- !sql -- -::ffff:127.0.0.1 \ No newline at end of file +::ffff:127.0.0.1 + +-- !sql -- +00000000000000000000FFFFC0A80001 + +-- !sql -- +2A0206B8000000000000000000000011 + +-- !sql -- +00000000000000000000000000000000 + +-- !sql -- +00A00050910000000000000000000000 + +-- !sql -- +00000000000000000000FFFFC0A80001 + +-- !sql -- +2A0206B8000000000000000000000011 + +-- !sql -- +00000000000000000000000000000000 + +-- !sql -- +00000000000000000000000000000000 + +-- !sql -- +00000000000000000000000000000000 + +-- !sql -- +00000000000000000000FFFFC0A80001 + +-- !sql -- +2A0206B8000000000000000000000011 + +-- !sql -- +00000000000000000000000000000000 + +-- !sql -- +\N + +-- !sql -- +\N + +-- !sql -- +\N + +-- !sql -- +\N + +-- !sql -- +\N + +-- !sql -- +\N + +-- !sql -- +AAAAAAAAFFFFFFFFFFFFFFFFAAAAAAAA + +-- !sql -- +00000000000000000000FFFFC0A80001 + +-- !sql -- +2A0206B8000000000000000000000011 \ No newline at end of file diff --git a/regression-test/suites/nereids_function_p0/ip_functions.groovy b/regression-test/suites/nereids_function_p0/ip_functions.groovy index 2a6f8caad6..76accd986d 100644 --- a/regression-test/suites/nereids_function_p0/ip_functions.groovy +++ b/regression-test/suites/nereids_function_p0/ip_functions.groovy @@ -50,4 +50,26 @@ suite("ip_functions") { qt_ip28 "SELECT inet6_ntoa(unhex('aaaa@#'));" qt_ip29 "SELECT inet6_ntoa(unhex('\0'));" qt_ip30 "SELECT inet6_ntoa(unhex('00000000000000000000FFFF7F000001'));" + + qt_ip31 "SELECT hex(ipv6_string_to_num('192.168.0.1'));" + qt_ip32 "SELECT hex(ipv6_string_to_num('2a02:6b8::11'));" + qt_ip33 "SELECT hex(ipv6_string_to_num('::'));" + qt_ip34 "SELECT hex(ipv6_string_to_num('a0:50:9100::'));" + qt_ip35 "SELECT hex(ipv6_string_to_num_or_default('192.168.0.1'));" + qt_ip36 "SELECT hex(ipv6_string_to_num_or_default('2a02:6b8::11'));" + qt_ip37 "SELECT hex(ipv6_string_to_num_or_default('::'));" + qt_ip38 "SELECT hex(ipv6_string_to_num_or_default('KK'));" + qt_ip39 "SELECT hex(ipv6_string_to_num_or_default('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));" + qt_ip40 "SELECT hex(ipv6_string_to_num_or_null('192.168.0.1'));" + qt_ip41 "SELECT hex(ipv6_string_to_num_or_null('2a02:6b8::11'));" + qt_ip42 "SELECT hex(ipv6_string_to_num_or_null('::'));" + qt_ip43 "SELECT hex(ipv6_string_to_num_or_null('KK'));" + qt_ip44 "SELECT hex(ipv6_string_to_num_or_null('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));" + qt_ip45 "SELECT hex(ipv6_string_to_num_or_null(''));" + qt_ip46 "SELECT hex(ipv6_string_to_num_or_null(NULL));" + qt_ip47 "SELECT hex(ipv6_string_to_num_or_null('\0'));" + qt_ip48 "SELECT hex(ipv6_string_to_num_or_null('00'));" + qt_ip49 "SELECT hex(ipv6_string_to_num_or_null('aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa'));" + qt_ip50 "SELECT hex(inet6_aton('192.168.0.1'));" + qt_ip51 "SELECT hex(inet6_aton('2a02:6b8::11'));" } \ No newline at end of file diff --git a/regression-test/suites/query_p0/sql_functions/ip_functions/test_ip_functions.groovy b/regression-test/suites/query_p0/sql_functions/ip_functions/test_ip_functions.groovy index 60ba7d3c07..633ff9ddf4 100644 --- a/regression-test/suites/query_p0/sql_functions/ip_functions/test_ip_functions.groovy +++ b/regression-test/suites/query_p0/sql_functions/ip_functions/test_ip_functions.groovy @@ -45,4 +45,26 @@ suite("test_ip_functions", "arrow_flight_sql") { qt_sql "SELECT inet6_ntoa(unhex('aaaa@#'));" qt_sql "SELECT inet6_ntoa(unhex('\0'));" qt_sql "SELECT inet6_ntoa(unhex('00000000000000000000FFFF7F000001'));" + + qt_sql "SELECT hex(ipv6_string_to_num('192.168.0.1'));" + qt_sql "SELECT hex(ipv6_string_to_num('2a02:6b8::11'));" + qt_sql "SELECT hex(ipv6_string_to_num('::'));" + qt_sql "SELECT hex(ipv6_string_to_num('a0:50:9100::'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_default('192.168.0.1'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_default('2a02:6b8::11'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_default('::'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_default('KK'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_default('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('192.168.0.1'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('2a02:6b8::11'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('::'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('KK'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null(''));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null(NULL));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('\0'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('00'));" + qt_sql "SELECT hex(ipv6_string_to_num_or_null('aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa'));" + qt_sql "SELECT hex(inet6_aton('192.168.0.1'));" + qt_sql "SELECT hex(inet6_aton('2a02:6b8::11'));" }