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

panxiaolei 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 ce0e987adbe [refine](cast) Use the new cast to implement cast to ip 
(#53722)
ce0e987adbe is described below

commit ce0e987adbeb536575d3c6a4b5589a4744057c58
Author: Mryange <[email protected]>
AuthorDate: Mon Jul 28 15:39:29 2025 +0800

    [refine](cast) Use the new cast to implement cast to ip (#53722)
    
    https://github.com/apache/doris-website/pull/2653
---
 be/src/vec/common/format_ip.h                      |   9 +
 .../vec/data_types/serde/data_type_ipv4_serde.cpp  |  40 +++
 be/src/vec/data_types/serde/data_type_ipv4_serde.h |   7 +
 .../vec/data_types/serde/data_type_ipv6_serde.cpp  |  40 +++
 be/src/vec/data_types/serde/data_type_ipv6_serde.h |   7 +
 be/src/vec/functions/cast/cast_to_ip.h             | 127 ++++------
 be/test/vec/function/cast/cast_to_ip_test.cpp      | 277 +++++++++++++++++++++
 be/test/vec/function/function_test_util.h          |   2 +
 .../doris/nereids/trees/expressions/Cast.java      |   3 +-
 .../data/function_p0/cast/test_cast_to_ip.out      | Bin 0 -> 1169 bytes
 .../nereids_function_p0/fn_test_ip_invalid.csv     |   8 +-
 .../suites/datatype_p0/ip/test_ip_crud.groovy      |   2 +-
 .../datatype_p0/ip/test_ip_implicit_cast.groovy    |   8 +-
 .../suites/function_p0/cast/test_cast_to_ip.groovy | 198 +++++++++++++++
 .../nereids_p0/javaudf/test_javaudf_ip.groovy      |   4 +-
 .../suites/query_p0/aggregate/array_agg.groovy     |   4 +-
 .../suites/statistics/test_analyze_ip_type.groovy  |   8 +-
 17 files changed, 644 insertions(+), 100 deletions(-)

diff --git a/be/src/vec/common/format_ip.h b/be/src/vec/common/format_ip.h
index 365b182161a..3b6a5483998 100644
--- a/be/src/vec/common/format_ip.h
+++ b/be/src/vec/common/format_ip.h
@@ -379,6 +379,10 @@ inline bool parse_ipv6(T*& src, EOFfunction eof, unsigned 
char* dst, int32_t fir
                     return clear_dst();
                 zptr = iter;
                 ++src;
+                if (!eof() && *src == ':') {
+                    /// more than one all-zeroes block is not allowed
+                    return clear_dst();
+                }
                 continue;
             }
             if (groups == 0) /// leading colon is not allowed
@@ -446,6 +450,11 @@ inline bool parse_ipv6(T*& src, EOFfunction eof, unsigned 
char* dst, int32_t fir
 
     /// process all-zeroes block
     if (zptr != nullptr) {
+        if (groups == 8) {
+            /// all-zeroes block at least should be one
+            /// 2001:0db8:86a3::08d3:1319:8a2e:0370:7344 not valid
+            return clear_dst();
+        }
         size_t msize = iter - zptr;
         std::memmove(dst + IPV6_BINARY_LENGTH - msize, zptr, msize);
         std::memset(zptr, '\0', IPV6_BINARY_LENGTH - (iter - dst));
diff --git a/be/src/vec/data_types/serde/data_type_ipv4_serde.cpp 
b/be/src/vec/data_types/serde/data_type_ipv4_serde.cpp
index 463c91f6dcd..db318afc3fe 100644
--- a/be/src/vec/data_types/serde/data_type_ipv4_serde.cpp
+++ b/be/src/vec/data_types/serde/data_type_ipv4_serde.cpp
@@ -21,6 +21,7 @@
 
 #include "vec/columns/column_const.h"
 #include "vec/core/types.h"
+#include "vec/functions/cast/cast_to_ip.h"
 #include "vec/io/io_helper.h"
 
 namespace doris::vectorized {
@@ -148,4 +149,43 @@ Status DataTypeIPv4SerDe::read_column_from_arrow(IColumn& 
column, const arrow::A
     col_data.insert(raw_data, raw_data + row_count);
     return Status::OK();
 }
+
+Status DataTypeIPv4SerDe::from_string_batch(const ColumnString& str, 
ColumnNullable& column,
+                                            const FormatOptions& options) 
const {
+    const auto size = str.size();
+    column.resize(size);
+
+    auto& column_to = assert_cast<ColumnType&>(column.get_nested_column());
+    auto& vec_to = column_to.get_data();
+    auto& null_map = column.get_null_map_data();
+
+    CastParameters params;
+    params.is_strict = false;
+    for (size_t i = 0; i < size; ++i) {
+        null_map[i] = !CastToIPv4::from_string(str.get_data_at(i), vec_to[i], 
params);
+    }
+    return Status::OK();
+}
+
+Status DataTypeIPv4SerDe::from_string_strict_mode_batch(const ColumnString& 
str, IColumn& column,
+                                                        const FormatOptions& 
options,
+                                                        const 
NullMap::value_type* null_map) const {
+    const auto size = str.size();
+    column.resize(size);
+
+    auto& column_to = assert_cast<ColumnType&>(column);
+    auto& vec_to = column_to.get_data();
+    CastParameters params;
+    params.is_strict = true;
+    for (size_t i = 0; i < size; ++i) {
+        if (null_map && null_map[i]) {
+            continue;
+        }
+        if (!CastToIPv4::from_string(str.get_data_at(i), vec_to[i], params)) {
+            return Status::InvalidArgument("parse ipv4 fail, string: '{}'",
+                                           str.get_data_at(i).to_string());
+        }
+    }
+    return Status::OK();
+}
 } // namespace doris::vectorized
diff --git a/be/src/vec/data_types/serde/data_type_ipv4_serde.h 
b/be/src/vec/data_types/serde/data_type_ipv4_serde.h
index 24cc66f4646..eb7505feea2 100644
--- a/be/src/vec/data_types/serde/data_type_ipv4_serde.h
+++ b/be/src/vec/data_types/serde/data_type_ipv4_serde.h
@@ -59,6 +59,13 @@ public:
     Status read_column_from_arrow(IColumn& column, const arrow::Array* 
arrow_array, int64_t start,
                                   int64_t end, const cctz::time_zone& ctz) 
const override;
 
+    Status from_string_batch(const ColumnString& str, ColumnNullable& column,
+                             const FormatOptions& options) const override;
+
+    Status from_string_strict_mode_batch(
+            const ColumnString& str, IColumn& column, const FormatOptions& 
options,
+            const NullMap::value_type* null_map = nullptr) const override;
+
 private:
     template <bool is_binary_format>
     Status _write_column_to_mysql(const IColumn& column, 
MysqlRowBuffer<is_binary_format>& result,
diff --git a/be/src/vec/data_types/serde/data_type_ipv6_serde.cpp 
b/be/src/vec/data_types/serde/data_type_ipv6_serde.cpp
index 656897f3095..537006464cf 100644
--- a/be/src/vec/data_types/serde/data_type_ipv6_serde.cpp
+++ b/be/src/vec/data_types/serde/data_type_ipv6_serde.cpp
@@ -25,6 +25,7 @@
 #include "util/jsonb_writer.h"
 #include "vec/columns/column_const.h"
 #include "vec/core/types.h"
+#include "vec/functions/cast/cast_to_ip.h"
 #include "vec/io/io_helper.h"
 
 namespace doris::vectorized {
@@ -250,4 +251,43 @@ Status DataTypeIPv6SerDe::write_column_to_orc(const 
std::string& timezone, const
     return Status::OK();
 }
 
+Status DataTypeIPv6SerDe::from_string_batch(const ColumnString& str, 
ColumnNullable& column,
+                                            const FormatOptions& options) 
const {
+    const auto size = str.size();
+    column.resize(size);
+
+    auto& column_to = assert_cast<ColumnType&>(column.get_nested_column());
+    auto& vec_to = column_to.get_data();
+    auto& null_map = column.get_null_map_data();
+
+    CastParameters params;
+    params.is_strict = false;
+    for (size_t i = 0; i < size; ++i) {
+        null_map[i] = !CastToIPv6::from_string(str.get_data_at(i), vec_to[i], 
params);
+    }
+    return Status::OK();
+}
+
+Status DataTypeIPv6SerDe::from_string_strict_mode_batch(const ColumnString& 
str, IColumn& column,
+                                                        const FormatOptions& 
options,
+                                                        const 
NullMap::value_type* null_map) const {
+    const auto size = str.size();
+    column.resize(size);
+
+    auto& column_to = assert_cast<ColumnType&>(column);
+    auto& vec_to = column_to.get_data();
+    CastParameters params;
+    params.is_strict = true;
+    for (size_t i = 0; i < size; ++i) {
+        if (null_map && null_map[i]) {
+            continue;
+        }
+        if (!CastToIPv6::from_string(str.get_data_at(i), vec_to[i], params)) {
+            return Status::InvalidArgument("parse ipv6 fail, string: '{}'",
+                                           str.get_data_at(i).to_string());
+        }
+    }
+    return Status::OK();
+}
+
 } // namespace doris::vectorized
diff --git a/be/src/vec/data_types/serde/data_type_ipv6_serde.h 
b/be/src/vec/data_types/serde/data_type_ipv6_serde.h
index 85e2f8167fb..1c586025a22 100644
--- a/be/src/vec/data_types/serde/data_type_ipv6_serde.h
+++ b/be/src/vec/data_types/serde/data_type_ipv6_serde.h
@@ -69,6 +69,13 @@ public:
     void write_one_cell_to_jsonb(const IColumn& column, 
JsonbWriterT<JsonbOutStream>& result,
                                  Arena& mem_pool, int unique_id, int64_t 
row_num) const override;
 
+    Status from_string_batch(const ColumnString& str, ColumnNullable& column,
+                             const FormatOptions& options) const override;
+
+    Status from_string_strict_mode_batch(
+            const ColumnString& str, IColumn& column, const FormatOptions& 
options,
+            const NullMap::value_type* null_map = nullptr) const override;
+
 private:
     template <bool is_binary_format>
     Status _write_column_to_mysql(const IColumn& column, 
MysqlRowBuffer<is_binary_format>& result,
diff --git a/be/src/vec/functions/cast/cast_to_ip.h 
b/be/src/vec/functions/cast/cast_to_ip.h
index fd447bd1032..c953830b54d 100644
--- a/be/src/vec/functions/cast/cast_to_ip.h
+++ b/be/src/vec/functions/cast/cast_to_ip.h
@@ -25,36 +25,31 @@
 namespace doris::vectorized {
 #include "common/compile_check_begin.h"
 
-template <CastModeType AllMode>
-class CastToImpl<AllMode, DataTypeString, DataTypeIPv4> : public CastToBase {
-public:
-    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                        uint32_t result, size_t input_rows_count,
-                        const NullMap::value_type* null_map = nullptr) const 
override {
-        const auto* col_from = 
check_and_get_column<DataTypeString::ColumnType>(
-                block.get_by_position(arguments[0]).column.get());
-
-        const auto size = col_from->size();
+struct CastToIPv4 {
+    static bool from_string(const StringRef& from, IPv4& to, CastParameters&);
+};
 
-        auto column_to = DataTypeIPv4::ColumnType::create(size);
-        auto column_null_map = ColumnUInt8::create(size, 0);
+inline bool CastToIPv4::from_string(const StringRef& from, IPv4& to, 
CastParameters&) {
+    return IPv4Value::from_string(to, from.data, from.size);
+}
 
-        auto& to_data = column_to->get_data();
-        auto& null_map_data = column_null_map->get_data();
+struct CastToIPv6 {
+    static bool from_string(const StringRef& from, IPv6& to, CastParameters&);
+    static bool from_ipv4(const IPv4& from, IPv6& to, CastParameters&);
+};
 
-        for (size_t i = 0; i < size; ++i) {
-            auto str = col_from->get_data_at(i);
-            null_map_data[i] = !IPv4Value::from_string(to_data[i], str.data, 
str.size);
-        }
+inline bool CastToIPv6::from_string(const StringRef& from, IPv6& to, 
CastParameters&) {
+    return IPv6Value::from_string(to, from.data, from.size);
+}
 
-        block.get_by_position(result).column =
-                ColumnNullable::create(std::move(column_to), 
std::move(column_null_map));
-        return Status::OK();
-    }
-};
+inline bool CastToIPv6::from_ipv4(const IPv4& from, IPv6& to, CastParameters&) 
{
+    map_ipv4_to_ipv6(from, reinterpret_cast<UInt8*>(&to));
+    return true;
+}
 
-template <CastModeType AllMode>
-class CastToImpl<AllMode, DataTypeString, DataTypeIPv6> : public CastToBase {
+template <CastModeType Mode, typename IpDataType>
+    requires(IsIPType<IpDataType>)
+class CastToImpl<Mode, DataTypeString, IpDataType> : public CastToBase {
 public:
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         uint32_t result, size_t input_rows_count,
@@ -62,21 +57,29 @@ public:
         const auto* col_from = 
check_and_get_column<DataTypeString::ColumnType>(
                 block.get_by_position(arguments[0]).column.get());
 
-        const auto size = col_from->size();
-
-        auto column_to = DataTypeIPv6::ColumnType::create(size);
-        auto column_null_map = ColumnUInt8::create(size, 0);
-
-        auto& to_data = column_to->get_data();
-        auto& null_map_data = column_null_map->get_data();
-
-        for (size_t i = 0; i < size; ++i) {
-            auto str = col_from->get_data_at(i);
-            null_map_data[i] = !IPv6Value::from_string(to_data[i], str.data, 
str.size);
+        auto to_type = block.get_by_position(result).type;
+        auto serde = remove_nullable(to_type)->get_serde();
+        MutableColumnPtr column_to;
+
+        if constexpr (Mode == CastModeType::NonStrictMode) {
+            auto to_nullable_type = make_nullable(to_type);
+            column_to = to_nullable_type->create_column();
+            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
+            RETURN_IF_ERROR(serde->from_string_batch(*col_from, 
nullable_col_to, {}));
+        } else if constexpr (Mode == CastModeType::StrictMode) {
+            if (to_type->is_nullable()) {
+                return Status::InternalError(
+                        "result type should be not nullable when casting 
string to ip in "
+                        "strict cast mode");
+            }
+            column_to = to_type->create_column();
+            RETURN_IF_ERROR(
+                    serde->from_string_strict_mode_batch(*col_from, 
*column_to, {}, null_map));
+        } else {
+            return Status::InternalError("Unsupported cast mode");
         }
 
-        block.get_by_position(result).column =
-                ColumnNullable::create(std::move(column_to), 
std::move(column_null_map));
+        block.get_by_position(result).column = std::move(column_to);
         return Status::OK();
     }
 };
@@ -93,31 +96,11 @@ public:
         auto col_to = DataTypeIPv6::ColumnType::create(size);
         auto& to_data = col_to->get_data();
         const auto& from_data = col_from->get_data();
+        CastParameters params;
+        params.is_strict = (AllMode == CastModeType::StrictMode);
 
         for (size_t i = 0; i < size; ++i) {
-            map_ipv4_to_ipv6(from_data[i], 
reinterpret_cast<UInt8*>(&to_data[i]));
-        }
-
-        block.get_by_position(result).column = std::move(col_to);
-        return Status::OK();
-    }
-};
-
-template <CastModeType AllMode, typename OtherType>
-class CastToImpl<AllMode, OtherType, DataTypeIPv4> : public CastToBase {
-public:
-    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                        uint32_t result, size_t input_rows_count,
-                        const NullMap::value_type* null_map = nullptr) const 
override {
-        const auto* col_from = check_and_get_column<typename 
OtherType::ColumnType>(
-                block.get_by_position(arguments[0]).column.get());
-        const auto size = col_from->size();
-        auto col_to = DataTypeIPv4::ColumnType::create(size);
-        auto& to_data = col_to->get_data();
-        const auto& from_data = col_from->get_data();
-
-        for (size_t i = 0; i < size; ++i) {
-            to_data[i] = static_cast<IPv4>(from_data[i]);
+            CastToIPv6::from_ipv4(from_data[i], to_data[i], params);
         }
 
         block.get_by_position(result).column = std::move(col_to);
@@ -125,26 +108,6 @@ public:
     }
 };
 
-template <CastModeType AllMode, typename OtherType>
-class CastToImpl<AllMode, OtherType, DataTypeIPv6> : public CastToBase {
-public:
-    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                        uint32_t result, size_t input_rows_count,
-                        const NullMap::value_type* null_map = nullptr) const 
override {
-        const auto* col_from = check_and_get_column<typename 
OtherType::ColumnType>(
-                block.get_by_position(arguments[0]).column.get());
-        const auto size = col_from->size();
-        auto col_to = DataTypeIPv6::ColumnType::create(size);
-        auto& to_data = col_to->get_data();
-        const auto& from_data = col_from->get_data();
-        for (size_t i = 0; i < size; ++i) {
-            to_data[i] = static_cast<IPv6>(from_data[i]);
-        }
-        block.get_by_position(result).column = std::move(col_to);
-        return Status::OK();
-    }
-};
-
 namespace CastWrapper {
 
 template <typename IpType>
@@ -172,7 +135,7 @@ WrapperType create_ip_wrapper(FunctionContext* context, 
const DataTypePtr& from_
 
     if (!call_on_index_and_data_type<void>(from_type->get_primitive_type(), 
make_ip_wrapper)) {
         return create_unsupport_wrapper(
-                fmt::format("CAST AS bool not supported {}", 
from_type->get_name()));
+                fmt::format("CAST AS ip not supported {}", 
from_type->get_name()));
     }
 
     return [cast_to_ip](FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
diff --git a/be/test/vec/function/cast/cast_to_ip_test.cpp 
b/be/test/vec/function/cast/cast_to_ip_test.cpp
new file mode 100644
index 00000000000..fe4d205fb5b
--- /dev/null
+++ b/be/test/vec/function/cast/cast_to_ip_test.cpp
@@ -0,0 +1,277 @@
+// 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.
+
+#include "cast_test.h"
+#include "vec/data_types/data_type_ipv4.h"
+#include "vec/data_types/data_type_ipv6.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/function/function_test_util.h"
+
+namespace doris::vectorized {
+using namespace ut_type;
+
+IPV4 ipv4_from_string(const std::string& str) {
+    IPV4 ipv4;
+    IPv4Value::from_string(ipv4, str.data(), str.size());
+    return ipv4;
+}
+
+IPV6 ipv6_from_string(const std::string& str) {
+    IPV6 ipv6;
+    IPv6Value::from_string(ipv6, str.data(), str.size());
+    return ipv6;
+}
+
+TEST_F(FunctionCastTest, test_from_string_to_ipv4) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+    DataSet data_set = {
+            // Edge cases
+            {{std::string("null")}, Null()},
+            {{std::string("")}, Null()},
+            {{std::string(" ")}, Null()},
+
+            // Invalid formats
+            {{std::string("x")}, Null()},
+            {{std::string("192.168")}, Null()},
+            {{std::string("192.168.0")}, Null()},
+            {{std::string("192.168.0.256")}, Null()},
+            {{std::string("192.168.0.1.5")}, Null()},
+            {{std::string("192.168.0.a")}, Null()},
+            {{std::string("2001:db8::1")}, Null()}, // IPv6 format
+
+            // Valid formats
+            {{std::string("0.0.0.0")}, ipv4_from_string("0.0.0.0")},
+            {{std::string("127.0.0.1")}, ipv4_from_string("127.0.0.1")},
+            {{std::string("192.168.0.1")}, ipv4_from_string("192.168.0.1")},
+            {{std::string("255.255.255.255")}, 
ipv4_from_string("255.255.255.255")},
+
+            // With spaces
+            {{std::string(" 10.0.0.1 ")}, ipv4_from_string("10.0.0.1")},
+            {{std::string("  172.16.0.1  ")}, ipv4_from_string("172.16.0.1")},
+
+            // With leading zeros
+            {{std::string("010.000.000.001")}, ipv4_from_string("10.0.0.1")},
+            {{std::string("001.002.003.004")}, ipv4_from_string("1.2.3.4")},
+    };
+    check_function_for_cast<DataTypeIPv4>(input_types, data_set);
+}
+
+TEST_F(FunctionCastTest, test_from_string_to_ipv6) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+    DataSet data_set = {
+            // Edge cases
+            {{std::string("null")}, Null()},
+            {{std::string("")}, Null()},
+            {{std::string(" ")}, Null()},
+
+            // Invalid formats
+            {{std::string("x")}, Null()},
+            {{std::string("2001:db8::gggg")}, Null()},
+            {{std::string("2001:db8:::1")}, Null()},           // Double ::
+            {{std::string("2001:db8::1::2")}, Null()},         // Multiple ::
+            {{std::string("1:1:::1")}, Null()},                // Double ::
+            {{std::string("1:1:1::1:1:1:1:1")}, Null()},       //  :: not use
+            {{std::string("2001:db8:0:0:0:0:0:0:1")}, Null()}, // Too many 
segments
+
+            // Valid formats - standard
+            {{std::string("::1")}, ipv6_from_string("::1")}, // Localhost
+            {{std::string("::")}, ipv6_from_string("::")},   // All zeros
+            {{std::string("2001:db8::1")}, ipv6_from_string("2001:db8::1")},
+            {{std::string("2001:db8:0:0:0:0:0:1")},
+             ipv6_from_string("2001:db8:0:0:0:0:0:1")}, // Full form
+            {{std::string("2001:db8::0:1")},
+             ipv6_from_string("2001:db8::0:1")}, // Compressed with non-zero 
after ::
+
+            // Mixed IPv6/IPv4
+            {{std::string("::ffff:192.168.0.1")},
+             ipv6_from_string("::ffff:192.168.0.1")}, // IPv4-mapped IPv6
+            {{std::string("::ffff:c0a8:1")},
+             ipv6_from_string("::ffff:c0a8:1")}, // IPv4-mapped IPv6 in hex
+            {{std::string("::192.168.0.1")},
+             ipv6_from_string("::192.168.0.1")}, // IPv4-compatible IPv6
+
+            // With spaces
+            {{std::string(" 2001:db8::1 ")}, ipv6_from_string("2001:db8::1")},
+            {{std::string("  fe80::1  ")}, ipv6_from_string("fe80::1")},
+
+            // Case sensitivity
+            {{std::string("2001:DB8::1")}, ipv6_from_string("2001:db8::1")},
+            {{std::string("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210")},
+             ipv6_from_string("fedc:ba98:7654:3210:fedc:ba98:7654:3210")},
+    };
+    check_function_for_cast<DataTypeIPv6>(input_types, data_set);
+}
+
+TEST_F(FunctionCastTest, test_from_string_to_ipv4_strict_mode) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+
+    // Valid formats in strict mode
+    {
+        DataSet data_set = {
+                {{std::string("0.0.0.0")}, ipv4_from_string("0.0.0.0")},
+                {{std::string("127.0.0.1")}, ipv4_from_string("127.0.0.1")},
+                {{std::string("192.168.0.1")}, 
ipv4_from_string("192.168.0.1")},
+                {{std::string("255.255.255.255")}, 
ipv4_from_string("255.255.255.255")},
+                {{std::string(" 10.0.0.1 ")}, ipv4_from_string("10.0.0.1")},
+                {{std::string("010.000.000.001")}, 
ipv4_from_string("10.0.0.1")},
+        };
+        check_function_for_cast_strict_mode<DataTypeIPv4>(input_types, 
data_set);
+    }
+
+    // Invalid formats in strict mode - each should raise error
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv4>(input_types,
+                                                          
{{{std::string("x")}, Null()}}, "fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv4>(
+                input_types, {{{std::string("192.168")}, Null()}}, "fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv4>(
+                input_types, {{{std::string("192.168.0.256")}, Null()}}, 
"fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv4>(input_types,
+                                                          {{{std::string("")}, 
Null()}}, "fail");
+    }
+}
+
+TEST_F(FunctionCastTest, test_from_string_to_ipv6_strict_mode) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+
+    // Valid formats in strict mode
+    {
+        DataSet data_set = {
+                {{std::string("::1")}, ipv6_from_string("::1")},
+                {{std::string("::")}, ipv6_from_string("::")},
+                {{std::string("2001:db8::1")}, 
ipv6_from_string("2001:db8::1")},
+                {{std::string("2001:db8:0:0:0:0:0:1")}, 
ipv6_from_string("2001:db8:0:0:0:0:0:1")},
+                {{std::string("::ffff:192.168.0.1")}, 
ipv6_from_string("::ffff:192.168.0.1")},
+                {{std::string(" 2001:db8::1 ")}, 
ipv6_from_string("2001:db8::1")},
+        };
+        check_function_for_cast_strict_mode<DataTypeIPv6>(input_types, 
data_set);
+    }
+
+    // Invalid formats in strict mode - each should raise error
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv6>(input_types,
+                                                          
{{{std::string("x")}, Null()}}, "fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv6>(
+                input_types, {{{std::string("2001:db8::gggg")}, Null()}}, 
"fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv6>(
+                input_types, {{{std::string("2001:db8:::1")}, Null()}}, 
"fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv6>(
+                input_types, {{{std::string("1:1:::1")}, Null()}}, "fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv6>(
+                input_types, {{{std::string(" 1:1:1::1:1:1:1:1")}, Null()}}, 
"fail");
+    }
+    {
+        check_function_for_cast_strict_mode<DataTypeIPv6>(input_types,
+                                                          {{{std::string("")}, 
Null()}}, "fail");
+    }
+}
+
+TEST_F(FunctionCastTest, test_ipv4_to_ipv6) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_IPV4};
+    DataSet data_set = {
+            {{ipv4_from_string("0.0.0.0")}, 
ipv6_from_string("::ffff:0.0.0.0")},
+            {{ipv4_from_string("127.0.0.1")}, 
ipv6_from_string("::ffff:127.0.0.1")},
+            {{ipv4_from_string("192.168.0.1")}, 
ipv6_from_string("::ffff:192.168.0.1")},
+            {{ipv4_from_string("255.255.255.255")}, 
ipv6_from_string("::ffff:255.255.255.255")},
+    };
+    check_function_for_cast<DataTypeIPv6>(input_types, data_set);
+}
+
+TEST_F(FunctionCastTest, test_ip_to_string) {
+    // IPv4 to string
+    {
+        InputTypeSet input_types = {PrimitiveType::TYPE_IPV4};
+        DataSet data_set = {
+                {{ipv4_from_string("0.0.0.0")}, std::string("0.0.0.0")},
+                {{ipv4_from_string("127.0.0.1")}, std::string("127.0.0.1")},
+                {{ipv4_from_string("192.168.0.1")}, 
std::string("192.168.0.1")},
+                {{ipv4_from_string("255.255.255.255")}, 
std::string("255.255.255.255")},
+        };
+        check_function_for_cast<DataTypeString>(input_types, data_set);
+    }
+
+    // IPv6 to string
+    {
+        InputTypeSet input_types = {PrimitiveType::TYPE_IPV6};
+        DataSet data_set = {
+                {{ipv6_from_string("::")}, std::string("::")},
+                {{ipv6_from_string("::1")}, std::string("::1")},
+                {{ipv6_from_string("2001:db8::1")}, 
std::string("2001:db8::1")},
+                {{ipv6_from_string("::ffff:192.168.0.1")}, 
std::string("::ffff:192.168.0.1")},
+        };
+        check_function_for_cast<DataTypeString>(input_types, data_set);
+    }
+}
+
+TEST_F(FunctionCastTest, test_non_strict_cast_string_to_ipv4) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+    DataSet data_set = {
+            {{std::string("192.168.1.1")}, ipv4_from_string("192.168.1.1")},
+            {{std::string("0.0.0.0")}, ipv4_from_string("0.0.0.0")},
+            {{std::string("255.255.255.255")}, 
ipv4_from_string("255.255.255.255")},
+            {{std::string("10.20.30.40")}, ipv4_from_string("10.20.30.40")},
+            {{std::string(" 192.168.1.1 ")}, ipv4_from_string("192.168.1.1")},
+            {{std::string("192.168.01.1")}, ipv4_from_string("192.168.1.1")},
+            {{std::string("1.2.3")}, Null()},
+            {{std::string("1.2.3.4.5")}, Null()},
+            {{std::string("256.0.0.1")}, Null()},
+            {{std::string("1.300.2.3")}, Null()},
+            {{std::string("1.2.3.")}, Null()},
+            {{std::string(".1.2.3")}, Null()},
+            {{std::string("1..2.3")}, Null()},
+            {{std::string("a.b.c.d")}, Null()},
+            {{std::string("1.2.+3.4")}, Null()},
+    };
+    check_function_for_cast<DataTypeIPv4>(input_types, data_set);
+}
+
+TEST_F(FunctionCastTest, test_non_strict_cast_string_to_ipv6) {
+    InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+    DataSet data_set = {
+            {{std::string("2001:db8:85a3:0000:0000:8a2e:0370:7334")},
+             ipv6_from_string("2001:db8:85a3:0000:0000:8a2e:0370:7334")},
+            {{std::string("::")}, ipv6_from_string("::")},
+            {{std::string("2001:db8::")}, ipv6_from_string("2001:db8::")},
+            {{std::string("::ffff:192.168.1.1")}, 
ipv6_from_string("::ffff:192.168.1.1")},
+            {{std::string(" 2001:db8::1 ")}, ipv6_from_string("2001:db8::1")},
+            {{std::string("2001:db8::1::2")}, Null()},
+            {{std::string("2001:db8:85a3:0000:0000:8a2e:0370:7334:1234")}, 
Null()},
+            {{std::string("2001:db8:85a3:0000:8a2e:0370")}, Null()},
+            {{std::string("2001:db8:85g3:0000:0000:8a2e:0370:7334")}, Null()},
+            {{std::string("2001:db8::ffff:192.168.1.260")}, Null()},
+            {{std::string("2001:db8::ffff:192.168..1")}, Null()},
+            {{std::string("2001:0db8:85a3:::8a2e:0370:7334")}, Null()},
+            {{std::string("20001:db8::1")}, Null()},
+    };
+    check_function_for_cast<DataTypeIPv6>(input_types, data_set);
+}
+
+} // namespace doris::vectorized
diff --git a/be/test/vec/function/function_test_util.h 
b/be/test/vec/function/function_test_util.h
index 4570f1a1db3..c002d4724c5 100644
--- a/be/test/vec/function/function_test_util.h
+++ b/be/test/vec/function/function_test_util.h
@@ -168,10 +168,12 @@ struct ut_input_type<DataTypeHLL> {
 template <>
 struct ut_input_type<DataTypeIPv4> {
     using type = IPV4;
+    inline static type default_value = 0;
 };
 template <>
 struct ut_input_type<DataTypeIPv6> {
     using type = IPV6;
+    inline static type default_value = 0;
 };
 template <>
 struct ut_input_type<DataTypeArray> {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
index 1284ece2ec1..061a620ab2d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
@@ -79,7 +79,8 @@ public class Cast extends Expression implements 
UnaryExpression, Monotonic {
     @Override
     public boolean nullable() {
         if (ConnectContext.get().getSessionVariable().enableStrictCast()) {
-            if (targetType.isNumericType() || targetType.isDateLikeType() || 
targetType.isBooleanType()) {
+            if (targetType.isNumericType() || targetType.isDateLikeType() || 
targetType.isBooleanType()
+                    || targetType.isIPType()) {
                 return child().nullable();
             }
             DataType childDataType = child().getDataType();
diff --git a/regression-test/data/function_p0/cast/test_cast_to_ip.out 
b/regression-test/data/function_p0/cast/test_cast_to_ip.out
new file mode 100644
index 00000000000..9cf8be14724
Binary files /dev/null and 
b/regression-test/data/function_p0/cast/test_cast_to_ip.out differ
diff --git a/regression-test/data/nereids_function_p0/fn_test_ip_invalid.csv 
b/regression-test/data/nereids_function_p0/fn_test_ip_invalid.csv
index 21344d61bcb..93861abda08 100644
--- a/regression-test/data/nereids_function_p0/fn_test_ip_invalid.csv
+++ b/regression-test/data/nereids_function_p0/fn_test_ip_invalid.csv
@@ -1,5 +1,5 @@
 1;256.0.0.1;2001:db8::12345;'256.0.0.1';'2001:db8::12345'
-2;192.168.1.999;2001:db8:::1;'192.168.1.999';'2001:db8:::1'
+2;192.168.1.999;2001:db8::1;'192.168.1.999';'2001:db8::1'
 3;300.300.300.300;::fffff:0:0;'300.300.300.300';'::fffff:0:0'
 4;192.168.1.1.1;2001:db8::g123;'192.168.1.1.1';'2001:db8::g123'
 5;1234.56.78.90;2001:db8::zzz;'1234.56.78.90';'2001:db8::zzz'
@@ -15,16 +15,16 @@
 15;192.168.1.;fe80:1234::85a3::7334;'192.168.1.';'fe80:1234::85a3::7334'
 16;192.168.1.1;::12345:abcd;'192.168.1.1';'::12345:abcd'
 17;10.0.0.1;2001:db8:85a3:0::123::;'10.0.0.1';'2001:db8:85a3:0::123::'
-18;172.16.0.1;2001:db8:::;'172.16.0.1';'2001:db8:::'
+18;172.16.0.1;2001:db8::;'172.16.0.1';'2001:db8::'
 
19;192.168.1.1;2001:db8:85a3:0000:0000:8a2e:0370:12345;'192.168.1.1';'2001:db8:85a3:0000:0000:8a2e:0370:12345'
 
20;172.16.0.0;2001:db8:85a3:0:0:0:0:0:0;'172.16.0.0';'2001:db8:85a3:0:0:0:0:0:0'
-21;10.0.0.1;fe80:85a3:::7334;'10.0.0.1';'fe80:85a3:::7334'
+21;10.0.0.1;fe80:85a3::7334;'10.0.0.1';'fe80:85a3::7334'
 22;192.168.1.1;2001:db8::85a3::7334;'192.168.1.1';'2001:db8::85a3::7334'
 23;172.16.0.1;g123:abcd::85a3::7334;'172.16.0.1';'g123:abcd::85a3::7334'
 
24;10.0.0.1;2001:db8:85a3:0000:0000:8a2e:0370:abcdg;'10.0.0.1';'2001:db8:85a3:0000:0000:8a2e:0370:abcdg'
 
25;192.168.0.1;fe80:0000:0000:0000:0000:0000:0000:0001;'192.168.0.1';'fe80:0000:0000:0000:0000:0000:0000:0001'
 26;192.168.1.1;12345::abcd;'192.168.1.1';'12345::abcd'
-27;10.0.0.1;::85a3:::7334;'10.0.0.1';'::85a3:::7334'
+27;10.0.0.1;::85a3::7334;'10.0.0.1';'::85a3::7334'
 
28;172.16.0.0;2001:db8:85a3:0000:0000:8a2e:0370:abcd::;'172.16.0.0';'2001:db8:85a3:0000:0000:8a2e:0370:abcd::'
 
29;192.168.1.1;2001:db8:85a3:0000::g123;'192.168.1.1';'2001:db8:85a3:0000::g123'
 
30;10.0.0.1;2001:db8:85a3:0000::0370:abcd:12345;'10.0.0.1';'2001:db8:85a3:0000::0370:abcd:12345'
diff --git a/regression-test/suites/datatype_p0/ip/test_ip_crud.groovy 
b/regression-test/suites/datatype_p0/ip/test_ip_crud.groovy
index 95fff863794..36b8ec754f7 100644
--- a/regression-test/suites/datatype_p0/ip/test_ip_crud.groovy
+++ b/regression-test/suites/datatype_p0/ip/test_ip_crud.groovy
@@ -46,7 +46,7 @@ suite("test_ip_crud") {
     qt_sql4 "select * from test_unique_ip_crud where ip_v4='119.36.22.147' and 
ip_v6='2001:4888:1f:e891:161:26::'"
 
     // Only unique table could be updated
-    sql "update test_unique_ip_crud set ip_v4=0, ip_v6='2804:64:0:25::1' where 
id=3"
+    sql "update test_unique_ip_crud set ip_v4='0.0.0.0', 
ip_v6='2804:64:0:25::1' where id=3"
     qt_sql5 "select * from test_unique_ip_crud order by id"
 
     // test ip datatype in aggregate table
diff --git a/regression-test/suites/datatype_p0/ip/test_ip_implicit_cast.groovy 
b/regression-test/suites/datatype_p0/ip/test_ip_implicit_cast.groovy
index 30291b3af3a..9e5cb4562ba 100644
--- a/regression-test/suites/datatype_p0/ip/test_ip_implicit_cast.groovy
+++ b/regression-test/suites/datatype_p0/ip/test_ip_implicit_cast.groovy
@@ -35,10 +35,10 @@ suite("test_ip_implicit_cast") {
     );
     """
     sql "insert into ${tableName} values(-1, NULL, NULL)"
-    sql "insert into ${tableName} values(0, 0, '::')"
-    sql "insert into ${tableName} values(1, 1, '::1')"
-    sql "insert into ${tableName} values(2130706433, 2130706433, 
'2001:1b70:a1:610::b102:2')"
-    sql "insert into ${tableName} values(4294967295, 4294967295, 
'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')"
+    sql "insert into ${tableName} values(0, TO_IPV4(IPV4_NUM_TO_STRING(0)), 
'::')"
+    sql "insert into ${tableName} values(1, TO_IPV4(IPV4_NUM_TO_STRING(1)), 
'::1')"
+    sql "insert into ${tableName} 
values(2130706433,TO_IPV4(IPV4_NUM_TO_STRING(2130706433)) , 
'2001:1b70:a1:610::b102:2')"
+    sql "insert into ${tableName} 
values(4294967295,TO_IPV4(IPV4_NUM_TO_STRING(4294967295)), 
'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')"
 
     qt_sql1 "select id, ip_v4, ip_v6 from ${tableName} order by id"
 
diff --git a/regression-test/suites/function_p0/cast/test_cast_to_ip.groovy 
b/regression-test/suites/function_p0/cast/test_cast_to_ip.groovy
new file mode 100644
index 00000000000..8ad3f78e2fb
--- /dev/null
+++ b/regression-test/suites/function_p0/cast/test_cast_to_ip.groovy
@@ -0,0 +1,198 @@
+// 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_cast_to_ip") {
+    sql "set debug_skip_fold_constant=true;"
+    
+    // Test casting to IPv4 from valid string formats
+    sql "set enable_strict_cast=false;"
+    qt_cast_str_to_ipv4_valid """
+    SELECT 
+        CAST('192.168.0.1' AS IPv4) AS ipv4_standard,
+        CAST('127.0.0.1' AS IPv4) AS ipv4_localhost,
+        CAST('0.0.0.0' AS IPv4) AS ipv4_zero,
+        CAST('255.255.255.255' AS IPv4) AS ipv4_broadcast,
+        CAST(' 10.0.0.1 ' AS IPv4) AS ipv4_with_spaces,
+        CAST('010.000.000.001' AS IPv4) AS ipv4_with_leading_zeros;
+    """
+    
+    // Test casting to IPv4 from invalid string formats (non-strict mode)
+    qt_cast_str_to_ipv4_invalid """
+    SELECT 
+        CAST('not_an_ip' AS IPv4) AS ipv4_invalid_str,
+        CAST('192.168.0' AS IPv4) AS ipv4_incomplete,
+        CAST('192.168.0.256' AS IPv4) AS ipv4_out_of_range,
+        CAST('192.168.0.1.5' AS IPv4) AS ipv4_too_many_parts,
+        CAST('2001:db8::1' AS IPv4) AS ipv4_from_ipv6,
+        CAST('192.168.0' AS IPv4) AS ipv4_too_few_parts,
+        CAST('192.168.0.a' AS IPv4) AS ipv4_non_numeric;
+    """
+
+    qt_cast_str_to_ipv4 """
+    SELECT 
+        CAST('192.168.1.1' AS IPv4) AS standard_valid_ipv4,           
+        CAST('0.0.0.0' AS IPv4) AS min_boundary_ipv4,                
+        CAST('255.255.255.255' AS IPv4) AS max_boundary_ipv4,        
+        CAST('10.20.30.40' AS IPv4) AS regular_ipv4,                 
+        CAST(' 192.168.1.1 ' AS IPv4) AS whitespace_ipv4,          
+        CAST('192.168.01.1' AS IPv4) AS leading_zero_ipv4,         
+        CAST('1.2.3' AS IPv4) AS missing_segment_ipv4,              
+        CAST('1.2.3.4.5' AS IPv4) AS extra_segment_ipv4,            
+        CAST('256.0.0.1' AS IPv4) AS first_out_of_range_ipv4,        
+        CAST('1.300.2.3' AS IPv4) AS second_out_of_range_ipv4,      
+        CAST('1.2.3.' AS IPv4) AS last_segment_missing_ipv4,         
+        CAST('.1.2.3' AS IPv4) AS first_segment_missing_ipv4,       
+        CAST('1..2.3' AS IPv4) AS empty_segment_ipv4,               
+        CAST('a.b.c.d' AS IPv4) AS non_numeric_ipv4,               
+        CAST('1.2.+3.4' AS IPv4) AS invalid_symbol_ipv4;           
+    """
+
+   qt_cast_str_to_ipv6 """
+    SELECT 
+    CAST('2001:db8:85a3:0000:0000:8a2e:0370:7334' AS IPv6) AS 
standard_valid_ipv6,  
+    CAST('::' AS IPv6) AS zero_ipv6,                                           
     
+    CAST('2001:db8::' AS IPv6) AS compressed_ipv6,                             
     
+    CAST('::ffff:192.168.1.1' AS IPv6) AS ipv4_mapped_ipv6,                    
    
+    CAST(' 2001:db8::1 ' AS IPv6) AS whitespace_ipv6,                          
     
+    CAST('2001:db8::1::2' AS IPv6) AS double_compression_ipv6,                 
   
+    CAST('2001:db8:85a3:0000:0000:8a2e:0370:7334:1234' AS IPv6) AS 
too_many_groups_ipv6, 
+    CAST('2001:db8:85a3:0000:8a2e:0370' AS IPv6) AS too_few_groups_ipv6,       
     
+    CAST('2001:db8:85g3:0000:0000:8a2e:0370:7334' AS IPv6) AS 
invalid_hex_char_ipv6,
+    CAST('2001:db8::ffff:192.168.1.260' AS IPv6) AS 
ipv4_part_out_of_range_ipv6,    
+    CAST('2001:db8::ffff:192.168..1' AS IPv6) AS ipv4_part_format_error_ipv6,  
     
+    CAST('2001:0db8:85a3:::8a2e:0370:7334' AS IPv6) AS triple_colon_ipv6,      
   
+    CAST('20001:db8::1' AS IPv6) AS first_group_too_long_ipv6;                 
 
+   """
+
+
+    // Test casting to IPv6 from valid string formats
+    qt_cast_str_to_ipv6_valid """
+    SELECT 
+        CAST('2001:db8::1' AS IPv6) AS ipv6_standard,
+        CAST('::1' AS IPv6) AS ipv6_localhost,
+        CAST('::' AS IPv6) AS ipv6_zero,
+        CAST('2001:db8:0:0:0:0:0:1' AS IPv6) AS ipv6_full,
+        CAST('2001:db8::0:1' AS IPv6) AS ipv6_compressed,
+        CAST(' 2001:db8::1 ' AS IPv6) AS ipv6_with_spaces,
+        CAST('2001:DB8::1' AS IPv6) AS ipv6_uppercase,
+        CAST('2001:db8:85a3:0000:0000:8a2e:0370:7334' AS IPv6) AS 
ipv6_full_standard,
+        CAST('2001:db8::' AS IPv6) AS ipv6_compressed_end;
+    """
+    
+    // Test IPv6 mapped IPv4 addresses
+    qt_cast_str_to_ipv6_mapped_ipv4 """
+    SELECT 
+        CAST('::ffff:192.168.0.1' AS IPv6) AS ipv6_mapped_ipv4,
+        CAST('::ffff:c0a8:1' AS IPv6) AS ipv6_mapped_ipv4_hex,
+        CAST('::192.168.0.1' AS IPv6) AS ipv6_compat_ipv4,
+        CAST('::ffff:192.168.1.1' AS IPv6) AS ipv6_mapped_ipv4_new;
+    """
+    
+    // Test casting to IPv6 from invalid string formats (non-strict mode)
+    qt_cast_str_to_ipv6_invalid """
+    SELECT 
+        CAST('not_an_ip' AS IPv6) AS ipv6_invalid_str,
+        CAST('2001:db8::gggg' AS IPv6) AS ipv6_invalid_hex,
+        CAST('2001:db8:::1' AS IPv6) AS ipv6_invalid_format,
+        CAST('2001:db8::1::2' AS IPv6) AS ipv6_too_many_compressions,
+        CAST(' 1:1:::1' AS IPv6) AS ipv6_with_double_compression,
+        CAST(' 1:1:1::1:1:1:1:1 ' AS IPv6) AS ipv6_with_not_use_compression,
+        CAST('2001:db8:0:0:0:0:0:0:1' AS IPv6) AS ipv6_too_many_parts;
+    """
+
+    // Test casting between IPv4 and IPv6
+    qt_cast_between_ip_types """
+    SELECT 
+        CAST(CAST('192.168.0.1' AS IPv4) AS VARCHAR) AS ipv4_to_string,
+        CAST(CAST('2001:db8::1' AS IPv6) AS VARCHAR) AS ipv6_to_string,
+        CAST(CAST('192.168.0.1' AS IPv4) AS IPv6) AS ipv4_to_ipv6;
+    """
+    
+    // Enable strict mode for the same tests
+    sql "set enable_strict_cast=true;"
+    
+    // Test casting to IPv4 from valid string formats (strict mode)
+    qt_cast_str_to_ipv4_valid_strict """
+    SELECT 
+        CAST('192.168.0.1' AS IPv4) AS ipv4_standard,
+        CAST('127.0.0.1' AS IPv4) AS ipv4_localhost,
+        CAST('0.0.0.0' AS IPv4) AS ipv4_zero,
+        CAST('255.255.255.255' AS IPv4) AS ipv4_broadcast,
+        CAST(' 10.0.0.1 ' AS IPv4) AS ipv4_with_spaces,
+        CAST('010.000.000.001' AS IPv4) AS ipv4_with_leading_zeros;
+    """
+    
+    // Test casting to IPv6 from valid string formats (strict mode)
+    qt_cast_str_to_ipv6_valid_strict """
+    SELECT 
+        CAST('2001:db8::1' AS IPv6) AS ipv6_standard,
+        CAST('::1' AS IPv6) AS ipv6_localhost,
+        CAST('::' AS IPv6) AS ipv6_zero,
+        CAST('2001:db8:0:0:0:0:0:1' AS IPv6) AS ipv6_full,
+        CAST('2001:db8::0:1' AS IPv6) AS ipv6_compressed,
+        CAST(' 2001:db8::1 ' AS IPv6) AS ipv6_with_spaces,
+        CAST('2001:DB8::1' AS IPv6) AS ipv6_uppercase;
+    """
+
+
+
+    // IPv4 map to IPv6 addresses in strict mode
+    qt_cast_str_to_ipv6_mapped_ipv4_strict """
+    SELECT 
+        CAST('192.168.0.0' as IPv4) AS ipv4_address,
+        CAST( CAST('192.168.0.0' as IPv4) as IPv6) AS ipv6_mapped_ipv4,
+        CAST('0.0.0.0' as IPv4) AS ipv4_address2,
+        CAST( CAST('0.0.0.0' as IPv4) as IPv6) AS ipv6_mapped_ipv4_zero;
+    """
+    // Test invalid IP formats in strict mode (should throw error)
+    test {
+        sql "SELECT CAST('not_an_ip' AS IPv4) AS invalid_ipv4;"
+        exception "parse ipv4 fail"
+    }
+    
+    test {
+        sql "SELECT CAST('192.168.0.256' AS IPv4) AS out_of_range_ipv4;"
+        exception "parse ipv4 fail"
+    }
+    
+    test {
+        sql "SELECT CAST('not_an_ip' AS IPv6) AS invalid_ipv6;"
+        exception "parse ipv6 fail"
+    }
+    
+    test {
+        sql "SELECT CAST('2001:db8::gggg' AS IPv6) AS invalid_hex_ipv6;"
+       exception "parse ipv6 fail"
+    }  
+
+    test {
+        sql "SELECT CAST('2001:db8:::1' AS IPv6) AS invalid_format_ipv6;"
+        exception "parse ipv6 fail"
+    }
+
+    test {
+        sql "SELECT CAST('1:1:::1' AS IPv6) AS too_many_compressions_ipv6;"
+        exception "parse ipv6 fail"
+    }
+
+    test {
+        sql "SELECT CAST(' 1:1:1::1:1:1:1:1' AS IPv6) AS 
too_many_compressions_ipv6;"
+        exception "parse ipv6 fail"
+    }
+
+}
\ No newline at end of file
diff --git a/regression-test/suites/nereids_p0/javaudf/test_javaudf_ip.groovy 
b/regression-test/suites/nereids_p0/javaudf/test_javaudf_ip.groovy
index aa079af16d0..b6d739a9e32 100644
--- a/regression-test/suites/nereids_p0/javaudf/test_javaudf_ip.groovy
+++ b/regression-test/suites/nereids_p0/javaudf/test_javaudf_ip.groovy
@@ -66,7 +66,7 @@ suite("nereids_test_javaudf_ip") {
                 DISTRIBUTED BY HASH(k1) BUCKETS 1
                 PROPERTIES("replication_num" = "1");
         """
-        sql """ insert into test_udf_ip values(1,123,34141,"0.0.0.123") , 
(2,3114,318903,"0.0.0.123") , 
(3,7832131,192837891738927931231,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D"),(4,null,null,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D");
 """
+        sql """ insert into test_udf_ip 
values(1,'0.0.0.123','::855d',"0.0.0.123") , 
(2,'0.0.12.42','::0.4.221.183',"0.0.0.123") , 
(3,'0.119.130.67','::a:7429:d0d6:6e08:9f5f',"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D"),(4,null,null,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D");
 """
         qt_select_ipv4_1 """ select k1,k4,java_udf_ipv4_test1(k4) from 
test_udf_ip order by k1   """
         qt_select_ipv4_2 """ select k1,s,java_udf_ipv4_test2(s) from 
test_udf_ip where IS_IPV4_STRING(s) order by k1  """
         qt_select_ipv4_3 """ select 
java_udf_ipv4_test3(array_sort(array_agg(k4))) from test_udf_ip   """
@@ -117,7 +117,7 @@ suite("nereids_test_javaudf_ip") {
                 DISTRIBUTED BY HASH(k1) BUCKETS 1
                 PROPERTIES("replication_num" = "1");
         """
-        sql """ insert into test_udf_ip values(1,123,34141,"0.0.0.123") , 
(2,3114,318903,"0.0.0.123") , 
(3,7832131,192837891738927931231,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D"),(4,null,null,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D");
 """
+        sql """ insert into test_udf_ip 
values(1,'0.0.0.123','::855d',"0.0.0.123") , 
(2,'0.0.12.42','::0.4.221.183',"0.0.0.123") , 
(3,'0.119.130.67','::a:7429:d0d6:6e08:9f5f',"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D"),(4,null,null,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D");
 """
         qt_select_ipv6_1 """ select k1,k6,java_udf_ipv6_test1(k6) from 
test_udf_ip order by k1   """
         qt_select_ipv6_2 """ select k1,s,java_udf_ipv6_test2(s) from 
test_udf_ip where IS_IPV6_STRING(s) order by k1  """
         qt_select_ipv6_3 """ select 
java_udf_ipv6_test3(array_sort(array_agg(k6))) from test_udf_ip   """
diff --git a/regression-test/suites/query_p0/aggregate/array_agg.groovy 
b/regression-test/suites/query_p0/aggregate/array_agg.groovy
index c78f84394fd..f58971a0fa9 100644
--- a/regression-test/suites/query_p0/aggregate/array_agg.groovy
+++ b/regression-test/suites/query_p0/aggregate/array_agg.groovy
@@ -317,8 +317,8 @@ suite("array_agg") {
             s string
         ) DISTRIBUTED BY HASH(k1) BUCKETS 1 PROPERTIES("replication_num" = 
"1");
     """
-    sql """ insert into test_array_agg_ip values(1,123,34141,"0.0.0.123") , 
(2,3114,318903,"0.0.0.123") , 
(3,7832131,192837891738927931231,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D"),(4,null,null,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D");
 """
-
+    sql """ insert into test_array_agg_ip 
values(1,'0.0.0.123','::855d',"0.0.0.123") , 
(2,'0.0.12.42','::0.4.221.183',"0.0.0.123") , 
(3,'0.119.130.67','::a:7429:d0d6:6e08:9f5f',"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D"),(4,null,null,"2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D");
 """
+        
 
      qt_select """select array_sort(array_agg(k4)),array_sort(array_agg(k6)) 
from test_array_agg_ip """
 
diff --git a/regression-test/suites/statistics/test_analyze_ip_type.groovy 
b/regression-test/suites/statistics/test_analyze_ip_type.groovy
index 33a71c438b4..584a05c7204 100644
--- a/regression-test/suites/statistics/test_analyze_ip_type.groovy
+++ b/regression-test/suites/statistics/test_analyze_ip_type.groovy
@@ -36,10 +36,10 @@ suite("test_analyze_ip_type") {
         );  
     """
     sql """insert into ${tableName} values(-1, NULL, NULL)"""
-    sql """insert into ${tableName} values(0, 0, '::')"""
-    sql """insert into ${tableName} values(1, 1, '::1')"""
-    sql """insert into ${tableName} values(2130706433, 2130706433, 
'2001:1b70:a1:610::b102:2')"""
-    sql """insert into ${tableName} values(4294967295, 4294967295, 
'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')"""
+    sql """insert into ${tableName} values(0, '0.0.0.0', '::')"""
+    sql """insert into ${tableName} values(1, '0.0.0.1', '::1')"""
+    sql """insert into ${tableName} values(2130706433, '127.0.0.1', 
'2001:1b70:a1:610::b102:2')"""
+    sql """insert into ${tableName} values(4294967295, '255.255.255.255', 
'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')"""
     sql """analyze table ${tableName} with sync"""
 
     def result = sql """show column stats ${tableName}"""


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to