This is an automated email from the ASF dual-hosted git repository.

yiguolei 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 d6ed4149f5b [feature](function) support ip function is_ipv4_compat, 
is_ipv4_mapped (#29954)
d6ed4149f5b is described below

commit d6ed4149f5b2b15e97a5a8861387141749c0339e
Author: Chester <42577861+superdiaod...@users.noreply.github.com>
AuthorDate: Sun Jan 21 10:51:58 2024 +0800

    [feature](function) support ip function is_ipv4_compat, is_ipv4_mapped 
(#29954)
---
 be/src/vec/common/unaligned.h                      |  33 +++++-
 be/src/vec/functions/function_ip.cpp               |   4 +
 be/src/vec/functions/function_ip.h                 | 130 ++++++++++++++-------
 .../sql-functions/ip-functions/is-ipv4-compat.md   |  65 +++++++++++
 .../sql-functions/ip-functions/is-ipv4-mapped.md   |  69 +++++++++++
 docs/sidebars.json                                 |   7 +-
 .../sql-functions/ip-functions/is-ipv4-compat.md   |  65 +++++++++++
 .../sql-functions/ip-functions/is-ipv4-mapped.md   |  68 +++++++++++
 .../doris/catalog/BuiltinScalarFunctions.java      |   4 +
 .../expressions/functions/scalar/IsIpv4Compat.java |  67 +++++++++++
 .../expressions/functions/scalar/IsIpv4Mapped.java |  67 +++++++++++
 .../expressions/visitor/ScalarFunctionVisitor.java |  10 ++
 gensrc/script/doris_builtins_functions.py          |   4 +
 .../data/nereids_function_p0/ip_functions.out      |  32 ++++-
 .../ip_functions/test_ip_functions.out             |  32 ++++-
 .../suites/nereids_function_p0/ip_functions.groovy |  12 ++
 .../ip_functions/test_ip_functions.groovy          |  12 ++
 17 files changed, 635 insertions(+), 46 deletions(-)

diff --git a/be/src/vec/common/unaligned.h b/be/src/vec/common/unaligned.h
index d56eca59b23..ee807c606e5 100644
--- a/be/src/vec/common/unaligned.h
+++ b/be/src/vec/common/unaligned.h
@@ -20,8 +20,9 @@
 
 #pragma once
 
-#include <string.h>
-
+#include <bit>
+#include <cstdint>
+#include <cstring>
 #include <type_traits>
 
 template <typename T>
@@ -40,3 +41,31 @@ void unaligned_store(void* address, const typename 
std::enable_if<true, T>::type
     static_assert(std::is_trivially_copyable_v<T>);
     memcpy(address, &src, sizeof(src));
 }
+
+inline void reverse_memcpy(void* dst, const void* src, size_t size) {
+    uint8_t* uint_dst = reinterpret_cast<uint8_t*>(dst) + size; // Perform 
addition here
+    const uint8_t* uint_src = reinterpret_cast<const uint8_t*>(src);
+
+    while (size) {
+        --uint_dst;
+        *uint_dst = *uint_src;
+        ++uint_src;
+        --size;
+    }
+}
+
+template <std::endian endian, typename T>
+inline T unaligned_load_endian(const void* address) {
+    T res {};
+    if constexpr (std::endian::native == endian) {
+        memcpy(&res, address, sizeof(res));
+    } else {
+        reverse_memcpy(&res, address, sizeof(res));
+    }
+    return res;
+}
+
+template <typename T>
+inline T unaligned_load_little_endian(const void* address) {
+    return unaligned_load_endian<std::endian::little, T>(address);
+}
\ No newline at end of file
diff --git a/be/src/vec/functions/function_ip.cpp 
b/be/src/vec/functions/function_ip.cpp
index 3faa6a42d8c..140100d22b3 100644
--- a/be/src/vec/functions/function_ip.cpp
+++ b/be/src/vec/functions/function_ip.cpp
@@ -27,6 +27,7 @@ void register_function_ip(SimpleFunctionFactory& factory) {
     
factory.register_function<FunctionIPv4StringToNum<IPStringToNumExceptionMode::Null>>();
     
factory.register_alias(FunctionIPv4StringToNum<IPStringToNumExceptionMode::Throw>::name,
                            "inet_aton");
+
     factory.register_function<FunctionIPv6NumToString>();
     factory.register_alias(FunctionIPv6NumToString::name, "inet6_ntoa");
     
factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Throw>>();
@@ -34,6 +35,9 @@ void register_function_ip(SimpleFunctionFactory& factory) {
     
factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Null>>();
     
factory.register_alias(FunctionIPv6StringToNum<IPStringToNumExceptionMode::Throw>::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>();
diff --git a/be/src/vec/functions/function_ip.h 
b/be/src/vec/functions/function_ip.h
index 313ad0fdd65..8a260b8fd82 100644
--- a/be/src/vec/functions/function_ip.h
+++ b/be/src/vec/functions/function_ip.h
@@ -364,44 +364,6 @@ ColumnPtr convertToIPv6(const StringColumnType& 
string_column,
         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<StringColumnType, ColumnString>) {
-        if (string_column.get_offsets()[0] - 1 == IPV6_BINARY_LENGTH) {
-            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
-                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<ToColumn, ColumnString>) {
             auto column_string = ColumnString::create();
@@ -833,4 +795,94 @@ private:
     }
 };
 
-} // namespace doris::vectorized
\ No newline at end of file
+class FunctionIsIPv4Compat : public IFunction {
+public:
+    static constexpr auto name = "is_ipv4_compat";
+    static FunctionPtr create() { return 
std::make_shared<FunctionIsIPv4Compat>(); }
+
+    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 {
+        return std::make_shared<DataTypeUInt8>();
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) const override 
{
+        const ColumnPtr& column = block.get_by_position(arguments[0]).column;
+        const auto* col_in = check_and_get_column<ColumnString>(column.get());
+
+        if (!col_in)
+            throw Exception(ErrorCode::INVALID_ARGUMENT,
+                            "Illegal column {} of argument of function {}, 
expected String",
+                            column->get_name(), get_name());
+        size_t col_size = col_in->size();
+        auto col_res = ColumnUInt8::create(col_size, 0);
+        auto& col_res_data = col_res->get_data();
+
+        for (size_t i = 0; i < col_size; ++i) {
+            auto ipv4_in = col_in->get_data_at(i);
+            if (is_ipv4_compat(reinterpret_cast<const UInt8*>(ipv4_in.data))) {
+                col_res_data[i] = 1;
+            }
+        }
+
+        block.replace_by_position(result, std::move(col_res));
+        return Status::OK();
+    }
+
+private:
+    static bool is_ipv4_compat(const UInt8* address) {
+        return (unaligned_load_little_endian<UInt64>(address) == 0) &&
+               (unaligned_load_little_endian<UInt32>(address + 8) == 0) &&
+               (unaligned_load_little_endian<UInt32>(address + 12) != 0);
+    }
+};
+
+class FunctionIsIPv4Mapped : public IFunction {
+public:
+    static constexpr auto name = "is_ipv4_mapped";
+    static FunctionPtr create() { return 
std::make_shared<FunctionIsIPv4Mapped>(); }
+
+    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 {
+        return std::make_shared<DataTypeUInt8>();
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) const override 
{
+        const ColumnPtr& column = block.get_by_position(arguments[0]).column;
+        const auto* col_in = check_and_get_column<ColumnString>(column.get());
+
+        if (!col_in)
+            throw Exception(ErrorCode::INVALID_ARGUMENT,
+                            "Illegal column {} of argument of function {}, 
expected String",
+                            column->get_name(), get_name());
+        size_t col_size = col_in->size();
+        auto col_res = ColumnUInt8::create(col_size, 0);
+        auto& col_res_data = col_res->get_data();
+
+        for (size_t i = 0; i < col_size; ++i) {
+            auto ipv4_in = col_in->get_data_at(i);
+            if (is_ipv4_mapped(reinterpret_cast<const UInt8*>(ipv4_in.data))) {
+                col_res_data[i] = 1;
+            }
+        }
+
+        block.replace_by_position(result, std::move(col_res));
+        return Status::OK();
+    }
+
+private:
+    static bool is_ipv4_mapped(const UInt8* address) {
+        return (unaligned_load_little_endian<UInt64>(address) == 0) &&
+               ((unaligned_load_little_endian<UInt64>(address + 8) & 
0x00000000FFFFFFFFULL) ==
+                0x00000000FFFF0000ULL);
+    }
+};
+
+} // namespace doris::vectorized
diff --git 
a/docs/en/docs/sql-manual/sql-functions/ip-functions/is-ipv4-compat.md 
b/docs/en/docs/sql-manual/sql-functions/ip-functions/is-ipv4-compat.md
new file mode 100644
index 00000000000..84c5aff9b63
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/ip-functions/is-ipv4-compat.md
@@ -0,0 +1,65 @@
+---
+{
+"title": "IS_IPV4_COMPAT",
+"language": "en"
+}
+---
+
+<!-- 
+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.
+-->
+
+## IS_IPV4_COMPAT
+
+<version since="dev">
+
+IS_IPV4_COMPAT
+
+</version>
+
+### description
+
+#### Syntax
+
+`VARCHAR IS_IPV4_COMPAT(INET6_ATON(VARCHAR ipv4_addr))`
+
+This function takes an IPv6 address represented in numeric form as a binary 
string, as returned by INET6_ATON(). 
+It returns 1 if the argument is a valid IPv4-compatible IPv6 address, 0 
otherwise (unless expr is NULL, in which case the function returns NULL). 
+IPv4-compatible addresses have the form ::ipv4_address.
+
+### example
+
+```
+mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::ffff:10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         0 |
++-----------+
+1 row in set (0.02 sec)
+
+mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         1 |
++-----------+
+1 row in set (0.03 sec)
+```
+
+### keywords
+
+IS_IPV4_COMPAT, IP
\ No newline at end of file
diff --git 
a/docs/en/docs/sql-manual/sql-functions/ip-functions/is-ipv4-mapped.md 
b/docs/en/docs/sql-manual/sql-functions/ip-functions/is-ipv4-mapped.md
new file mode 100644
index 00000000000..9e338eb1353
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/ip-functions/is-ipv4-mapped.md
@@ -0,0 +1,69 @@
+---
+{
+"title": "IS_IPV4_MAPPED",
+"language": "en"
+}
+---
+
+<!-- 
+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.
+-->
+
+## IS_IPV4_MAPPED
+
+<version since="dev">
+
+IS_IPV4_MAPPED
+
+</version>
+
+### description
+
+#### Syntax
+
+`VARCHAR IS_IPV4_MAPPED(INET6_ATON(VARCHAR ipv4_addr))`
+
+This function takes an IPv6 address represented in numeric form as a binary 
string, as returned by INET6_ATON(). 
+It returns 1 if the argument is a valid IPv4-mapped IPv6 address, 0 otherwise, 
unless expr is NULL, in which case the function returns NULL. 
+IPv4-mapped addresses have the form ::ffff:ipv4_address. 
+
+### notice
+
+`When the source input doesn't have a prefix of '::ffff:', but if it's still a 
valid ipv4 address, this result will also be 1 for the reason that the 
INET6_ATON() automatically adds the prefix for it.`
+
+### example
+
+```
+mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         1 |
++-----------+
+1 row in set (0.02 sec)
+
+mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         0 |
++-----------+
+1 row in set (0.03 sec)
+```
+
+### keywords
+
+IS_IPV4_MAPPED, IP
\ No newline at end of file
diff --git a/docs/sidebars.json b/docs/sidebars.json
index 6b94989d180..bda6b8da310 100644
--- a/docs/sidebars.json
+++ b/docs/sidebars.json
@@ -811,11 +811,12 @@
                                 
"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/ipv6-num-to-string",
+                                
"sql-manual/sql-functions/ip-functions/ipv6-string-to-num",
                                 
"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"
-
+                                
"sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null",
+                                
"sql-manual/sql-functions/ip-functions/is-ipv4-compat",
+                                
"sql-manual/sql-functions/ip-functions/is-ipv4-mapped"
                             ]
                         },
                         {
diff --git 
a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/is-ipv4-compat.md 
b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/is-ipv4-compat.md
new file mode 100644
index 00000000000..fba93b83430
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/is-ipv4-compat.md
@@ -0,0 +1,65 @@
+---
+{
+"title": "IS_IPV4_COMPAT",
+"language": "zh-CN"
+}
+---
+
+<!-- 
+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.
+-->
+
+## IS_IPV4_COMPAT
+
+<version since="dev">
+
+IS_IPV4_COMPAT
+
+</version>
+
+### description
+
+#### Syntax
+
+`VARCHAR IS_IPV4_COMPAT(INET6_ATON(VARCHAR ipv4_addr))`
+
+该函数采用以数字形式表示的二进制字符串形式的 IPv6 地址,由 INET6_ATON() 返回。
+如果参数是有效的 IPv4 兼容 IPv6 地址,则返回 1,否则返回 0(除非 expr 为 NULL,在这种情况下该函数返回 NULL)。
+IPv4 兼容地址的格式为::ipv4_address。
+
+### example
+
+```
+mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::ffff:10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         0 |
++-----------+
+1 row in set (0.02 sec)
+
+mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         1 |
++-----------+
+1 row in set (0.03 sec)
+```
+
+### keywords
+
+IS_IPV4_COMPAT, IP
\ No newline at end of file
diff --git 
a/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/is-ipv4-mapped.md 
b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/is-ipv4-mapped.md
new file mode 100644
index 00000000000..66de4022209
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/ip-functions/is-ipv4-mapped.md
@@ -0,0 +1,68 @@
+---
+{
+"title": "IS_IPV4_MAPPED",
+"language": "zh-CN"
+}
+---
+
+<!-- 
+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.
+-->
+
+## IS_IPV4_MAPPED
+
+<version since="dev">
+
+IS_IPV4_MAPPED
+
+</version>
+
+### description
+
+#### Syntax
+
+`VARCHAR IS_IPV4_MAPPED(INET6_ATON(VARCHAR ipv4_addr))`
+
+该函数采用以数字形式表示的二进制字符串形式的lPv6地址,由INET6_ATON返回。
+如果参数是有效的IPv4映射IPv6地址,则返回1,否则返回0,除非expr为 NULL,在这种情况下该函数返回NULL。
+IPv4映射地址的格式为::ffff:ipv4_address
+
+### notice
+`当源输入没有'::ffff:'前缀时,但如果它仍然是有效的ipv4地址,则该结果也将为1,因为INET6_ATON()会自动为有效的ipv4地址添加前缀。`
+
+### example
+
+```
+mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         1 |
++-----------+
+1 row in set (0.02 sec)
+
+mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9')) AS is_result;
++-----------+
+| is_result |
++-----------+
+|         0 |
++-----------+
+1 row in set (0.03 sec)
+```
+
+### keywords
+
+IS_IPV4_MAPPED, 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 f4f7af5cf38..68da4df08ab 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
@@ -203,6 +203,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToN
 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.IsIpAddressInRange;
+import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv4Compat;
+import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv4Mapped;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv4String;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv6String;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonArray;
@@ -609,6 +611,8 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             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(IsIpv4Compat.class, "is_ipv4_compat"),
+            scalar(IsIpv4Mapped.class, "is_ipv4_mapped"),
             scalar(IsIpv4String.class, "is_ipv4_string"),
             scalar(IsIpv6String.class, "is_ipv6_string"),
             scalar(IsIpAddressInRange.class, "is_ip_address_in_range"),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/IsIpv4Compat.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/IsIpv4Compat.java
new file mode 100644
index 00000000000..684eee0e9c9
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/IsIpv4Compat.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.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.BooleanType;
+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 is_ipv4_compat
+ */
+public class IsIpv4Compat extends ScalarFunction
+        implements BinaryExpression, ExplicitlyCastableSignature, 
PropagateNullable {
+
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(BooleanType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
+            
FunctionSignature.ret(BooleanType.INSTANCE).args(StringType.INSTANCE));
+
+    public IsIpv4Compat(Expression arg0) {
+        super("is_ipv4_compat", arg0);
+    }
+
+    @Override
+    public IsIpv4Compat withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1,
+                "is_ipv4_compat accept 1 args, but got %s (%s)",
+                children.size(),
+                children);
+        return new IsIpv4Compat(children.get(0));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitIsIpv4Compat(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/IsIpv4Mapped.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/IsIpv4Mapped.java
new file mode 100644
index 00000000000..c3640af5437
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/IsIpv4Mapped.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.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.BooleanType;
+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 is_ipv4_mapped
+ */
+public class IsIpv4Mapped extends ScalarFunction
+        implements BinaryExpression, ExplicitlyCastableSignature, 
PropagateNullable {
+
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(BooleanType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
+            
FunctionSignature.ret(BooleanType.INSTANCE).args(StringType.INSTANCE));
+
+    public IsIpv4Mapped(Expression arg0) {
+        super("is_ipv4_mapped", arg0);
+    }
+
+    @Override
+    public IsIpv4Mapped withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1,
+                "is_ipv4_mapped accept 1 args, but got %s (%s)",
+                children.size(),
+                children);
+        return new IsIpv4Mapped(children.get(0));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitIsIpv4Mapped(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 899a31abbd7..01823f78199 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
@@ -199,6 +199,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToN
 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.IsIpAddressInRange;
+import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv4Compat;
+import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv4Mapped;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv4String;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.IsIpv6String;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonArray;
@@ -1155,6 +1157,14 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(ipv6StringToNumOrNull, context);
     }
 
+    default R visitIsIpv4Compat(IsIpv4Compat isIpv4Compat, C context) {
+        return visitScalarFunction(isIpv4Compat, context);
+    }
+
+    default R visitIsIpv4Mapped(IsIpv4Mapped isIpv4Mapped, C context) {
+        return visitScalarFunction(isIpv4Mapped, context);
+    }
+
     default R visitIsIpv4String(IsIpv4String isIpv4String, C context) {
         return visitScalarFunction(isIpv4String, context);
     }
diff --git a/gensrc/script/doris_builtins_functions.py 
b/gensrc/script/doris_builtins_functions.py
index 973a4675621..6a6ff96e83d 100644
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -2014,6 +2014,10 @@ visible_functions = {
         [['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'],  
+        [['is_ipv4_compat'], 'BOOLEAN', ['VARCHAR'], ''],
+        [['is_ipv4_compat'], 'BOOLEAN', ['STRING'], ''],
+        [['is_ipv4_mapped'], 'BOOLEAN', ['VARCHAR'], ''],
+        [['is_ipv4_mapped'], 'BOOLEAN', ['STRING'], ''],
         [['is_ipv4_string'], 'BOOLEAN', ['VARCHAR'], ''],
         [['is_ipv4_string'], 'BOOLEAN', ['STRING'], ''],
         [['is_ipv6_string'], 'BOOLEAN', ['VARCHAR'], ''],
diff --git a/regression-test/data/nereids_function_p0/ip_functions.out 
b/regression-test/data/nereids_function_p0/ip_functions.out
index 2e3b749a152..914b5ccd683 100644
--- a/regression-test/data/nereids_function_p0/ip_functions.out
+++ b/regression-test/data/nereids_function_p0/ip_functions.out
@@ -162,4 +162,34 @@ false
 true
 
 -- !ip55 --
-false
\ No newline at end of file
+false
+
+-- !ip56 --
+true
+
+-- !ip57 --
+false
+
+-- !ip58 --
+false
+
+-- !ip59 --
+true
+
+-- !ip60 --
+false
+
+-- !ip61 --
+true
+
+-- !ip62 --
+false
+
+-- !ip63 --
+true
+
+-- !ip64 --
+false
+
+-- !ip65 --
+true
\ 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 71f02449d3b..1837acc4bab 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
@@ -137,4 +137,34 @@ AAAAAAAAFFFFFFFFFFFFFFFFAAAAAAAA
 00000000000000000000FFFFC0A80001
 
 -- !sql --
-2A0206B8000000000000000000000011
\ No newline at end of file
+2A0206B8000000000000000000000011
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
\ 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 1ac00102094..b5d4d177e89 100644
--- a/regression-test/suites/nereids_function_p0/ip_functions.groovy
+++ b/regression-test/suites/nereids_function_p0/ip_functions.groovy
@@ -77,4 +77,16 @@ suite("ip_functions") {
     qt_ip53 "SELECT is_ipv4_string('255.255.255.256');"
     qt_ip54 "SELECT is_ipv6_string('2001:5b0:23ff:fffa::113');"
     qt_ip55 "SELECT is_ipv6_string('2001:da8:e000:1691:2eaa:7eff:ffe7:7924e');"
+
+    qt_ip56 "SELECT is_ipv4_compat(inet6_aton('::10.0.5.9'));"
+    qt_ip57 "SELECT is_ipv4_compat(inet6_aton('::ffff:10.0.5.9'));"
+    qt_ip58 "SELECT is_ipv4_compat(inet6_aton('::'));"
+    qt_ip59 "SELECT is_ipv4_compat(inet6_aton('::c0a8:0001'));"
+    qt_ip60 "SELECT is_ipv4_compat(inet6_aton('::0.0.0.0'));"
+    qt_ip61 "SELECT is_ipv4_compat(inet6_aton('::255.255.255.255'));"
+
+    qt_ip62 "SELECT is_ipv4_mapped(inet6_aton('::10.0.5.9'));"
+    qt_ip63 "SELECT is_ipv4_mapped(inet6_aton('::ffff:10.0.5.9'));"
+    qt_ip64 "SELECT is_ipv4_mapped(inet6_aton('::'));"
+    qt_ip65 "SELECT is_ipv4_mapped(inet6_aton('::ffff:c0a8:0001'));"
 }
\ 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 828de6cbe41..c5ff6d36a13 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
@@ -67,4 +67,16 @@ suite("test_ip_functions", "arrow_flight_sql") {
     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'));"
+
+    qt_sql "SELECT is_ipv4_compat(inet6_aton('::10.0.5.9'));"
+    qt_sql "SELECT is_ipv4_compat(inet6_aton('::ffff:10.0.5.9'));"
+    qt_sql "SELECT is_ipv4_compat(inet6_aton('::'));"
+    qt_sql "SELECT is_ipv4_compat(inet6_aton('::c0a8:0001'));"
+    qt_sql "SELECT is_ipv4_compat(inet6_aton('::0.0.0.0'));"
+    qt_sql "SELECT is_ipv4_compat(inet6_aton('::255.255.255.255'));"
+
+    qt_sql "SELECT is_ipv4_mapped(inet6_aton('::10.0.5.9'));"
+    qt_sql "SELECT is_ipv4_mapped(inet6_aton('::ffff:10.0.5.9'));"
+    qt_sql "SELECT is_ipv4_mapped(inet6_aton('::'));"
+    qt_sql "SELECT is_ipv4_mapped(inet6_aton('::ffff:c0a8:0001'));"
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org


Reply via email to