This is an automated email from the ASF dual-hosted git repository. lihaopeng pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new acc064565e7 [feature](function) support ip functions named to_ipv4[or_default, or_null](string) and to_ipv6[or_default, or_null](string) (#29838) acc064565e7 is described below commit acc064565e771133d5279f91de927d27d7f01921 Author: yangshijie <sjyang2...@zju.edu.cn> AuthorDate: Mon Jan 22 16:19:47 2024 +0800 [feature](function) support ip functions named to_ipv4[or_default, or_null](string) and to_ipv6[or_default, or_null](string) (#29838) --- be/src/vec/functions/function_ip.cpp | 26 +-- be/src/vec/functions/function_ip.h | 223 +++++++++++++++++---- .../doris/catalog/BuiltinScalarFunctions.java | 12 ++ .../trees/expressions/functions/scalar/ToIpv4.java | 67 +++++++ .../functions/scalar/ToIpv4OrDefault.java | 67 +++++++ .../expressions/functions/scalar/ToIpv4OrNull.java | 67 +++++++ .../trees/expressions/functions/scalar/ToIpv6.java | 67 +++++++ .../functions/scalar/ToIpv6OrDefault.java | 67 +++++++ .../expressions/functions/scalar/ToIpv6OrNull.java | 67 +++++++ .../expressions/visitor/ScalarFunctionVisitor.java | 30 +++ gensrc/script/doris_builtins_functions.py | 12 ++ .../ip_functions/test_to_ip_functions.out | 21 ++ .../ip_functions/test_to_ip_functions.groovy | 49 +++++ 13 files changed, 720 insertions(+), 55 deletions(-) diff --git a/be/src/vec/functions/function_ip.cpp b/be/src/vec/functions/function_ip.cpp index 349e095b4a2..7eed9c13364 100644 --- a/be/src/vec/functions/function_ip.cpp +++ b/be/src/vec/functions/function_ip.cpp @@ -22,25 +22,27 @@ namespace doris::vectorized { void register_function_ip(SimpleFunctionFactory& factory) { factory.register_function<FunctionIPv4NumToString>(); factory.register_alias(FunctionIPv4NumToString::name, "inet_ntoa"); - factory.register_function<FunctionIPv4StringToNum<IPStringToNumExceptionMode::Throw>>(); - factory.register_function<FunctionIPv4StringToNum<IPStringToNumExceptionMode::Default>>(); - factory.register_function<FunctionIPv4StringToNum<IPStringToNumExceptionMode::Null>>(); - factory.register_alias(FunctionIPv4StringToNum<IPStringToNumExceptionMode::Null>::name, - "inet_aton"); - + factory.register_function<FunctionIPv4StringToNum<IPExceptionMode::Throw>>(); + factory.register_function<FunctionIPv4StringToNum<IPExceptionMode::Default>>(); + factory.register_function<FunctionIPv4StringToNum<IPExceptionMode::Null>>(); + factory.register_alias(FunctionIPv4StringToNum<IPExceptionMode::Null>::name, "inet_aton"); factory.register_function<FunctionIPv6NumToString>(); factory.register_alias(FunctionIPv6NumToString::name, "inet6_ntoa"); - factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Throw>>(); - factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Default>>(); - factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Null>>(); - factory.register_alias(FunctionIPv6StringToNum<IPStringToNumExceptionMode::Null>::name, - "inet6_aton"); - + factory.register_function<FunctionIPv6StringToNum<IPExceptionMode::Throw>>(); + factory.register_function<FunctionIPv6StringToNum<IPExceptionMode::Default>>(); + factory.register_function<FunctionIPv6StringToNum<IPExceptionMode::Null>>(); + factory.register_alias(FunctionIPv6StringToNum<IPExceptionMode::Null>::name, "inet6_aton"); factory.register_function<FunctionIsIPv4Compat>(); factory.register_function<FunctionIsIPv4Mapped>(); factory.register_function<FunctionIsIPString<IPv4>>(); factory.register_function<FunctionIsIPString<IPv6>>(); factory.register_function<FunctionIsIPAddressInRange>(); factory.register_function<FunctionIPv6CIDRToRange>(); + factory.register_function<FunctionToIP<IPExceptionMode::Throw, IPv4>>(); + factory.register_function<FunctionToIP<IPExceptionMode::Default, IPv4>>(); + factory.register_function<FunctionToIP<IPExceptionMode::Null, IPv4>>(); + factory.register_function<FunctionToIP<IPExceptionMode::Throw, IPv6>>(); + factory.register_function<FunctionToIP<IPExceptionMode::Default, IPv6>>(); + factory.register_function<FunctionToIP<IPExceptionMode::Null, IPv6>>(); } } // 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 8a260b8fd82..359cafe7e34 100644 --- a/be/src/vec/functions/function_ip.h +++ b/be/src/vec/functions/function_ip.h @@ -117,13 +117,13 @@ public: } }; -enum class IPStringToNumExceptionMode : uint8_t { Throw, Default, Null }; +enum class IPExceptionMode : uint8_t { Throw, Default, Null }; static inline bool tryParseIPv4(const char* pos, Int64& result_value) { return parseIPv4whole(pos, reinterpret_cast<unsigned char*>(&result_value)); } -template <IPStringToNumExceptionMode exception_mode, typename ToColumn> +template <IPExceptionMode exception_mode, typename ToColumn> ColumnPtr convertToIPv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) { const ColumnString* column_string = check_and_get_column<ColumnString>(column.get()); @@ -138,7 +138,7 @@ ColumnPtr convertToIPv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map ColumnUInt8::MutablePtr col_null_map_to; ColumnUInt8::Container* vec_null_map_to = nullptr; - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { col_null_map_to = ColumnUInt8::create(column_size, false); vec_null_map_to = &col_null_map_to->get_data(); } @@ -156,7 +156,7 @@ ColumnPtr convertToIPv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map if (null_map && (*null_map)[i]) { vec_res[i] = 0; prev_offset = offsets_src[i]; - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { (*vec_null_map_to)[i] = true; } continue; @@ -169,11 +169,11 @@ ColumnPtr convertToIPv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map bool parse_result = tryParseIPv4(src.c_str(), vec_res[i]); if (!parse_result) { - if constexpr (exception_mode == IPStringToNumExceptionMode::Throw) { + if constexpr (exception_mode == IPExceptionMode::Throw) { throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value"); - } else if constexpr (exception_mode == IPStringToNumExceptionMode::Default) { + } else if constexpr (exception_mode == IPExceptionMode::Default) { vec_res[i] = 0; - } else if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + } else if constexpr (exception_mode == IPExceptionMode::Null) { (*vec_null_map_to)[i] = true; vec_res[i] = 0; } @@ -182,20 +182,20 @@ ColumnPtr convertToIPv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map prev_offset = offsets_src[i]; } - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) + if constexpr (exception_mode == IPExceptionMode::Null) return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to)); return col_res; } -template <IPStringToNumExceptionMode exception_mode> +template <IPExceptionMode exception_mode> class FunctionIPv4StringToNum : public IFunction { public: - static constexpr auto name = exception_mode == IPStringToNumExceptionMode::Throw - ? "ipv4_string_to_num" - : (exception_mode == IPStringToNumExceptionMode::Default - ? "ipv4_string_to_num_or_default" - : "ipv4_string_to_num_or_null"); + static constexpr auto name = + exception_mode == IPExceptionMode::Throw + ? "ipv4_string_to_num" + : (exception_mode == IPExceptionMode::Default ? "ipv4_string_to_num_or_default" + : "ipv4_string_to_num_or_null"); static FunctionPtr create() { return std::make_shared<FunctionIPv4StringToNum<exception_mode>>(); @@ -213,7 +213,7 @@ public: } auto result_type = std::make_shared<DataTypeInt64>(); - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { return make_nullable(result_type); } @@ -343,8 +343,7 @@ public: }; namespace detail { -template <IPStringToNumExceptionMode exception_mode, typename ToColumn = ColumnIPv6, - typename StringColumnType> +template <IPExceptionMode exception_mode, typename ToColumn = ColumnIPv6, typename StringColumnType> ColumnPtr convertToIPv6(const StringColumnType& string_column, const PaddedPODArray<UInt8>* null_map = nullptr) { if constexpr (!std::is_same_v<ToColumn, ColumnString> && @@ -359,7 +358,7 @@ ColumnPtr convertToIPv6(const StringColumnType& string_column, ColumnUInt8::MutablePtr col_null_map_to; ColumnUInt8::Container* vec_null_map_to = nullptr; - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { col_null_map_to = ColumnUInt8::create(column_size, false); vec_null_map_to = &col_null_map_to->get_data(); } @@ -420,9 +419,9 @@ ColumnPtr convertToIPv6(const StringColumnType& string_column, } if (null_map && (*null_map)[i]) { - if (exception_mode == IPStringToNumExceptionMode::Throw) { + if (exception_mode == IPExceptionMode::Throw) { throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value"); - } else if (exception_mode == IPStringToNumExceptionMode::Default) { + } else if (exception_mode == IPExceptionMode::Default) { std::fill_n(&vec_res[out_offset], offset_inc, 0); } else { std::fill_n(&vec_res[out_offset], offset_inc, 0); @@ -463,7 +462,7 @@ ColumnPtr convertToIPv6(const StringColumnType& string_column, col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH); } } else { - if (exception_mode == IPStringToNumExceptionMode::Throw) { + if (exception_mode == IPExceptionMode::Throw) { throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value"); } std::fill_n(&vec_res[out_offset], offset_inc, 0); @@ -471,21 +470,21 @@ ColumnPtr convertToIPv6(const StringColumnType& string_column, auto* column_string = assert_cast<ColumnString*>(col_res.get()); column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH); } - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { (*vec_null_map_to)[i] = true; } } src_offset = src_next_offset; } - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to)); } return col_res; } } // namespace detail -template <IPStringToNumExceptionMode exception_mode, typename ToColumn = ColumnIPv6> +template <IPExceptionMode exception_mode, typename ToColumn = ColumnIPv6> ColumnPtr convertToIPv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) { if (const auto* column_input_string = check_and_get_column<ColumnString>(column.get())) { auto result = @@ -497,14 +496,14 @@ ColumnPtr convertToIPv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map } } -template <IPStringToNumExceptionMode exception_mode> +template <IPExceptionMode exception_mode> 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 constexpr auto name = + exception_mode == IPExceptionMode::Throw + ? "ipv6_string_to_num" + : (exception_mode == IPExceptionMode::Default ? "ipv6_string_to_num_or_default" + : "ipv6_string_to_num_or_null"); static FunctionPtr create() { return std::make_shared<FunctionIPv6StringToNum<exception_mode>>(); @@ -525,7 +524,7 @@ public: auto result_type = std::make_shared<DataTypeString>(); - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { return make_nullable(result_type); } @@ -541,7 +540,7 @@ public: if (column->is_nullable()) { const auto* column_nullable = assert_cast<const ColumnNullable*>(column.get()); column = column_nullable->get_nested_column_ptr(); - if constexpr (exception_mode == IPStringToNumExceptionMode::Null) { + if constexpr (exception_mode == IPExceptionMode::Null) { null_map_column = column_nullable->get_null_map_column_ptr(); null_map = &column_nullable->get_null_map_data(); } @@ -640,29 +639,33 @@ public: Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) const override { - ColumnPtr& addr_column = block.get_by_position(arguments[0]).column; - ColumnPtr& cidr_column = block.get_by_position(arguments[1]).column; + const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]); + const auto& cidr_column_with_type_and_name = block.get_by_position(arguments[1]); + WhichDataType addr_type(addr_column_with_type_and_name.type); + WhichDataType cidr_type(cidr_column_with_type_and_name.type); + const ColumnPtr& addr_column = addr_column_with_type_and_name.column; + const ColumnPtr& cidr_column = cidr_column_with_type_and_name.column; const ColumnString* str_addr_column = nullptr; const ColumnString* str_cidr_column = nullptr; - const NullMap* nullmap_addr = nullptr; - const NullMap* nullmap_cidr = nullptr; + const NullMap* null_map_addr = nullptr; + const NullMap* null_map_cidr = nullptr; - if (addr_column->is_nullable()) { + if (addr_type.is_nullable()) { const auto* addr_column_nullable = assert_cast<const ColumnNullable*>(addr_column.get()); str_addr_column = check_and_get_column<ColumnString>(addr_column_nullable->get_nested_column()); - nullmap_addr = &addr_column_nullable->get_null_map_data(); + null_map_addr = &addr_column_nullable->get_null_map_data(); } else { str_addr_column = check_and_get_column<ColumnString>(addr_column.get()); } - if (cidr_column->is_nullable()) { + if (cidr_type.is_nullable()) { const auto* cidr_column_nullable = assert_cast<const ColumnNullable*>(cidr_column.get()); str_cidr_column = check_and_get_column<ColumnString>(cidr_column_nullable->get_nested_column()); - nullmap_cidr = &cidr_column_nullable->get_null_map_data(); + null_map_cidr = &cidr_column_nullable->get_null_map_data(); } else { str_cidr_column = check_and_get_column<ColumnString>(cidr_column.get()); } @@ -683,12 +686,12 @@ public: auto& col_res_data = col_res->get_data(); for (size_t i = 0; i < input_rows_count; ++i) { - if (nullmap_addr && (*nullmap_addr)[i]) { + if (null_map_addr && (*null_map_addr)[i]) { throw Exception(ErrorCode::INVALID_ARGUMENT, "The arguments of function {} must be String, not NULL", get_name()); } - if (nullmap_cidr && (*nullmap_cidr)[i]) { + if (null_map_cidr && (*null_map_cidr)[i]) { throw Exception(ErrorCode::INVALID_ARGUMENT, "The arguments of function {} must be String, not NULL", get_name()); @@ -885,4 +888,138 @@ private: } }; -} // namespace doris::vectorized +template <IPExceptionMode exception_mode, typename Type> +inline constexpr auto to_ip_func_name() { + if constexpr (std::is_same_v<Type, IPv4>) { + return exception_mode == IPExceptionMode::Throw + ? "to_ipv4" + : (exception_mode == IPExceptionMode::Default ? "to_ipv4_or_default" + : "to_ipv4_or_null"); + } else { + return exception_mode == IPExceptionMode::Throw + ? "to_ipv6" + : (exception_mode == IPExceptionMode::Default ? "to_ipv6_or_default" + : "to_ipv6_or_null"); + } +} + +template <IPExceptionMode exception_mode, typename Type> +class FunctionToIP : public IFunction { + static_assert(std::is_same_v<Type, IPv4> || std::is_same_v<Type, IPv6>); + +public: + static constexpr auto name = to_ip_func_name<exception_mode, Type>(); + + static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, Type>>(); } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 1; } + + 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 {}, expected String", + arguments[0]->get_name(), get_name()); + } + + DataTypePtr result_type; + + if constexpr (std::is_same_v<Type, IPv4>) { + result_type = std::make_shared<DataTypeIPv4>(); + } else { + result_type = std::make_shared<DataTypeIPv6>(); + } + + if constexpr (exception_mode == IPExceptionMode::Null) { + return make_nullable(result_type); + } else { + return result_type; + } + } + + bool use_default_implementation_for_nulls() const override { return false; } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) const override { + const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]); + WhichDataType addr_type(addr_column_with_type_and_name.type); + const ColumnPtr& addr_column = addr_column_with_type_and_name.column; + const ColumnString* str_addr_column = nullptr; + const NullMap* addr_null_map = nullptr; + + if (addr_type.is_nullable()) { + const auto* addr_column_nullable = + assert_cast<const ColumnNullable*>(addr_column.get()); + str_addr_column = + check_and_get_column<ColumnString>(addr_column_nullable->get_nested_column()); + addr_null_map = &addr_column_nullable->get_null_map_data(); + } else { + str_addr_column = check_and_get_column<ColumnString>(addr_column.get()); + } + + auto col_res = ColumnVector<Type>::create(input_rows_count, 0); + auto res_null_map = ColumnUInt8::create(input_rows_count, 0); + auto& col_res_data = col_res->get_data(); + auto& res_null_map_data = res_null_map->get_data(); + + for (size_t i = 0; i < input_rows_count; ++i) { + if (addr_null_map && (*addr_null_map)[i]) { + if constexpr (exception_mode == IPExceptionMode::Throw) { + throw Exception(ErrorCode::INVALID_ARGUMENT, + "The arguments of function {} must be String, not NULL", + get_name()); + } else if constexpr (exception_mode == IPExceptionMode::Default) { + col_res_data[i] = 0; // '0.0.0.0' or '::' + continue; + } else { + res_null_map_data[i] = 1; + continue; + } + } + + if constexpr (std::is_same_v<Type, IPv4>) { + StringRef ipv4_str = str_addr_column->get_data_at(i); + IPv4 ipv4_val = 0; + if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) { + col_res_data[i] = ipv4_val; + } else { + if constexpr (exception_mode == IPExceptionMode::Throw) { + throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'", + ipv4_str.to_string_view()); + } else if constexpr (exception_mode == IPExceptionMode::Default) { + col_res_data[i] = 0; // '0.0.0.0' + } else { + res_null_map_data[i] = 1; + } + } + } else { + StringRef ipv6_str = str_addr_column->get_data_at(i); + IPv6 ipv6_val = 0; + if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) { + col_res_data[i] = ipv6_val; + } else { + if constexpr (exception_mode == IPExceptionMode::Throw) { + throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'", + ipv6_str.to_string_view()); + } else if constexpr (exception_mode == IPExceptionMode::Default) { + col_res_data[i] = 0; // '::' + } else if constexpr (exception_mode == IPExceptionMode::Null) { + res_null_map_data[i] = 1; + } + } + } + } + + if constexpr (exception_mode == IPExceptionMode::Null) { + block.replace_by_position( + result, ColumnNullable::create(std::move(col_res), std::move(res_null_map))); + } else { + block.replace_by_position(result, std::move(col_res)); + } + + return Status::OK(); + } +}; + +} // namespace doris::vectorized \ 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 492c561f0a1..1a40365b523 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 @@ -393,6 +393,12 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmapWithC import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDate; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDateV2; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDays; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv4; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv4OrDefault; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv4OrNull; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv6; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv6OrDefault; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv6OrNull; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToMonday; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToQuantileState; import org.apache.doris.nereids.trees.expressions.functions.scalar.Tokenize; @@ -623,6 +629,12 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(IsIpv6String.class, "is_ipv6_string"), scalar(IsIpAddressInRange.class, "is_ip_address_in_range"), scalar(Ipv6CIDRToRange.class, "ipv6_cidr_to_range"), + scalar(ToIpv4.class, "to_ipv4"), + scalar(ToIpv4OrDefault.class, "to_ipv4_or_default"), + scalar(ToIpv4OrNull.class, "to_ipv4_or_null"), + scalar(ToIpv6.class, "to_ipv6"), + scalar(ToIpv6OrDefault.class, "to_ipv6_or_default"), + scalar(ToIpv6OrNull.class, "to_ipv6_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/ToIpv4.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4.java new file mode 100644 index 00000000000..590c16a6000 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4.java @@ -0,0 +1,67 @@ +// 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.IPv4Type; +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 to_ipv4 + */ +public class ToIpv4 extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(IPv4Type.INSTANCE).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(IPv4Type.INSTANCE).args(StringType.INSTANCE)); + + public ToIpv4(Expression arg0) { + super("to_ipv4", arg0); + } + + @Override + public ToIpv4 withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1, + "to_ipv4 accept 1 args, but got %s (%s)", + children.size(), + children); + return new ToIpv4(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitToIpv4(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4OrDefault.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4OrDefault.java new file mode 100644 index 00000000000..e77e8120d71 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4OrDefault.java @@ -0,0 +1,67 @@ +// 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.IPv4Type; +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 to_ipv4_or_default + */ +public class ToIpv4OrDefault extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(IPv4Type.INSTANCE).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(IPv4Type.INSTANCE).args(StringType.INSTANCE)); + + public ToIpv4OrDefault(Expression arg0) { + super("to_ipv4_or_default", arg0); + } + + @Override + public ToIpv4OrDefault withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1, + "to_ipv4_or_default accept 1 args, but got %s (%s)", + children.size(), + children); + return new ToIpv4OrDefault(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitToIpv4OrDefault(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4OrNull.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4OrNull.java new file mode 100644 index 00000000000..940ae4c3971 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv4OrNull.java @@ -0,0 +1,67 @@ +// 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.IPv4Type; +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 to_ipv4_or_null + */ +public class ToIpv4OrNull extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(IPv4Type.INSTANCE).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(IPv4Type.INSTANCE).args(StringType.INSTANCE)); + + public ToIpv4OrNull(Expression arg0) { + super("to_ipv4_or_null", arg0); + } + + @Override + public ToIpv4OrNull withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1, + "to_ipv4_or_null accept 1 args, but got %s (%s)", + children.size(), + children); + return new ToIpv4OrNull(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitToIpv4OrNull(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6.java new file mode 100644 index 00000000000..4261862147b --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6.java @@ -0,0 +1,67 @@ +// 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.IPv6Type; +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 to_ipv6 + */ +public class ToIpv6 extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(IPv6Type.INSTANCE).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(IPv6Type.INSTANCE).args(StringType.INSTANCE)); + + public ToIpv6(Expression arg0) { + super("to_ipv6", arg0); + } + + @Override + public ToIpv6 withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1, + "to_ipv6 accept 1 args, but got %s (%s)", + children.size(), + children); + return new ToIpv6(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitToIpv6(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6OrDefault.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6OrDefault.java new file mode 100644 index 00000000000..da9ec1083b0 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6OrDefault.java @@ -0,0 +1,67 @@ +// 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.IPv6Type; +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 to_ipv6_or_default + */ +public class ToIpv6OrDefault extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(IPv6Type.INSTANCE).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(IPv6Type.INSTANCE).args(StringType.INSTANCE)); + + public ToIpv6OrDefault(Expression arg0) { + super("to_ipv6_or_default", arg0); + } + + @Override + public ToIpv6OrDefault withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1, + "to_ipv6_or_default accept 1 args, but got %s (%s)", + children.size(), + children); + return new ToIpv6OrDefault(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitToIpv6OrDefault(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6OrNull.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6OrNull.java new file mode 100644 index 00000000000..6a3a3e0973c --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToIpv6OrNull.java @@ -0,0 +1,67 @@ +// 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.IPv6Type; +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 to_ipv6_or_null + */ +public class ToIpv6OrNull extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(IPv6Type.INSTANCE).args(VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(IPv6Type.INSTANCE).args(StringType.INSTANCE)); + + public ToIpv6OrNull(Expression arg0) { + super("to_ipv6_or_null", arg0); + } + + @Override + public ToIpv6OrNull withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1, + "to_ipv6_or_null accept 1 args, but got %s (%s)", + children.size(), + children); + return new ToIpv6OrNull(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitToIpv6OrNull(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 8629d15b2bc..d10c384c55e 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 @@ -383,6 +383,12 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmapWithC import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDate; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDateV2; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDays; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv4; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv4OrDefault; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv4OrNull; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv6; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv6OrDefault; +import org.apache.doris.nereids.trees.expressions.functions.scalar.ToIpv6OrNull; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToMonday; import org.apache.doris.nereids.trees.expressions.functions.scalar.ToQuantileState; import org.apache.doris.nereids.trees.expressions.functions.scalar.Tokenize; @@ -1196,6 +1202,30 @@ public interface ScalarFunctionVisitor<R, C> { return visitScalarFunction(ipv6CIDRToRange, context); } + default R visitToIpv4(ToIpv4 toIpv4, C context) { + return visitScalarFunction(toIpv4, context); + } + + default R visitToIpv4OrDefault(ToIpv4OrDefault toIpv4OrDefault, C context) { + return visitScalarFunction(toIpv4OrDefault, context); + } + + default R visitToIpv4OrNull(ToIpv4OrNull toIpv4OrNull, C context) { + return visitScalarFunction(toIpv4OrNull, context); + } + + default R visitToIpv6(ToIpv6 toIpv6, C context) { + return visitScalarFunction(toIpv6, context); + } + + default R visitToIpv6OrDefault(ToIpv6OrDefault toIpv6OrDefault, C context) { + return visitScalarFunction(toIpv6OrDefault, context); + } + + default R visitToIpv6OrNull(ToIpv6OrNull toIpv6OrNull, C context) { + return visitScalarFunction(toIpv6OrNull, 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 a9d2fe26dc2..9faf1e092ec 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -2035,6 +2035,18 @@ visible_functions = { [['is_ip_address_in_range'], 'BOOLEAN', ['STRING', 'STRING'], 'ALWAYS_NOT_NULLABLE'], [['ipv6_cidr_to_range'], 'STRUCT<IPV6, IPV6>', ['VARCHAR', 'SMALLINT'], ''], [['ipv6_cidr_to_range'], 'STRUCT<IPV6, IPV6>', ['STRING', 'SMALLINT'], ''], + [['to_ipv4'], 'IPV4', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv4'], 'IPV4', ['STRING'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv4_or_default'], 'IPV4', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv4_or_default'], 'IPV4', ['STRING'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv4_or_null'], 'IPV4', ['VARCHAR'], 'ALWAYS_NULLABLE'], + [['to_ipv4_or_null'], 'IPV4', ['STRING'], 'ALWAYS_NULLABLE'], + [['to_ipv6'], 'IPV6', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv6'], 'IPV6', ['STRING'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv6_or_default'], 'IPV6', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv6_or_default'], 'IPV6', ['STRING'], 'ALWAYS_NOT_NULLABLE'], + [['to_ipv6_or_null'], 'IPV6', ['VARCHAR'], 'ALWAYS_NULLABLE'], + [['to_ipv6_or_null'], 'IPV6', ['STRING'], 'ALWAYS_NULLABLE'], ], "NonNullalbe": [ diff --git a/regression-test/data/query_p0/sql_functions/ip_functions/test_to_ip_functions.out b/regression-test/data/query_p0/sql_functions/ip_functions/test_to_ip_functions.out new file mode 100644 index 00000000000..8015d0eef30 --- /dev/null +++ b/regression-test/data/query_p0/sql_functions/ip_functions/test_to_ip_functions.out @@ -0,0 +1,21 @@ +-- !sql -- +0.0.0.0 :: +192.168.0.1 ::1 +127.0.0.1 2001:1b70:a1:610::b102:2 +255.255.255.255 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + +-- !sql -- +0.0.0.0 :: +0.0.0.0 :: +192.168.0.1 ::1 +127.0.0.1 2001:1b70:a1:610::b102:2 +255.255.255.255 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +0.0.0.0 :: + +-- !sql -- +\N \N +0.0.0.0 :: +192.168.0.1 ::1 +127.0.0.1 2001:1b70:a1:610::b102:2 +255.255.255.255 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +\N \N diff --git a/regression-test/suites/query_p0/sql_functions/ip_functions/test_to_ip_functions.groovy b/regression-test/suites/query_p0/sql_functions/ip_functions/test_to_ip_functions.groovy new file mode 100644 index 00000000000..aefe338b959 --- /dev/null +++ b/regression-test/suites/query_p0/sql_functions/ip_functions/test_to_ip_functions.groovy @@ -0,0 +1,49 @@ +// 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. +suite("test_to_ip_functions") { + sql """ DROP TABLE IF EXISTS test_to_ip_functions """ + + sql """ SET enable_nereids_planner=true """ + sql """ SET enable_fallback_to_original_planner=false """ + + sql """ + CREATE TABLE `test_to_ip_functions` ( + `id` int, + `ip_v4` string, + `ip_v6` string + ) ENGINE=OLAP + DISTRIBUTED BY HASH(`id`) BUCKETS 4 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + """ + sql """ + insert into test_to_ip_functions values + (0, NULL, NULL), + (1, '0.0.0.0', '::'), + (2, '192.168.0.1', '::1'), + (3, '127.0.0.1', '2001:1b70:a1:610::b102:2'), + (4, '255.255.255.255', 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (5, '255.255.255.256', 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffg') + """ + + qt_sql "select to_ipv4(ip_v4), to_ipv6(ip_v6) from test_to_ip_functions where id in (1, 2, 3, 4) order by id" + qt_sql "select to_ipv4_or_default(ip_v4), to_ipv6_or_default(ip_v6) from test_to_ip_functions order by id" + qt_sql "select to_ipv4_or_null(ip_v4), to_ipv6_or_null(ip_v6) from test_to_ip_functions order by id" + + sql "DROP TABLE test_to_ip_functions" +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org