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

morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 553f742143b branch-3.1: [feature](udf) Support for IP types in Java 
UDF #44871 (#56346)
553f742143b is described below

commit 553f742143ba92144a5691d4f4b0c026815931c7
Author: Mryange <[email protected]>
AuthorDate: Thu Sep 25 17:38:17 2025 +0800

    branch-3.1: [feature](udf) Support for IP types in Java UDF #44871 (#56346)
    
    picked from #44871
---
 be/src/vec/exec/jni_connector.cpp                  |  12 +-
 .../doris/common/jni/utils/JavaUdfDataType.java    |   8 ++
 .../doris/common/jni/utils/TypeNativeBytes.java    |  16 +++
 .../apache/doris/common/jni/utils/UdfUtils.java    |   6 +
 .../apache/doris/common/jni/vec/ColumnType.java    |  20 +++
 .../apache/doris/common/jni/vec/VectorColumn.java  |  79 +++++++++++
 .../main/java/org/apache/doris/catalog/Type.java   |   4 +-
 .../data/nereids_p0/javaudf/test_javaudf_ip.out    |  42 ++++++
 .../java/org/apache/doris/udf/IPV4TypeTest.java    |  74 +++++++++++
 .../java/org/apache/doris/udf/IPV6TypeTest.java    |  73 +++++++++++
 .../main/java/org/apache/doris/udf/MySumIP.java    |  76 +++++++++++
 .../nereids_p0/javaudf/test_javaudf_ip.groovy      | 146 +++++++++++++++++++++
 12 files changed, 554 insertions(+), 2 deletions(-)

diff --git a/be/src/vec/exec/jni_connector.cpp 
b/be/src/vec/exec/jni_connector.cpp
index 3030c2bde57..d8039b5537a 100644
--- a/be/src/vec/exec/jni_connector.cpp
+++ b/be/src/vec/exec/jni_connector.cpp
@@ -63,7 +63,9 @@ namespace doris::vectorized {
     M(TypeIndex::Date, ColumnVector<Int64>, Int64)                  \
     M(TypeIndex::DateV2, ColumnVector<UInt32>, UInt32)              \
     M(TypeIndex::DateTime, ColumnVector<Int64>, Int64)              \
-    M(TypeIndex::DateTimeV2, ColumnVector<UInt64>, UInt64)
+    M(TypeIndex::DateTimeV2, ColumnVector<UInt64>, UInt64)          \
+    M(TypeIndex::IPv4, ColumnVector<IPv4>, IPv4)                    \
+    M(TypeIndex::IPv6, ColumnVector<IPv6>, IPv6)
 
 Status JniConnector::open(RuntimeState* state, RuntimeProfile* profile) {
     _state = state;
@@ -500,6 +502,10 @@ std::string JniConnector::get_jni_type(const DataTypePtr& 
data_type) {
         return "float";
     case TYPE_DOUBLE:
         return "double";
+    case TYPE_IPV4:
+        return "ipv4";
+    case TYPE_IPV6:
+        return "ipv6";
     case TYPE_VARCHAR:
         [[fallthrough]];
     case TYPE_CHAR:
@@ -584,6 +590,10 @@ std::string JniConnector::get_jni_type(const 
TypeDescriptor& desc) {
         return "float";
     case TYPE_DOUBLE:
         return "double";
+    case TYPE_IPV4:
+        return "ipv4";
+    case TYPE_IPV6:
+        return "ipv6";
     case TYPE_VARCHAR: {
         buffer << "varchar(" << desc.len << ")";
         return buffer.str();
diff --git 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/JavaUdfDataType.java
 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/JavaUdfDataType.java
index 546b917a2b3..4d6b6006316 100644
--- 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/JavaUdfDataType.java
+++ 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/JavaUdfDataType.java
@@ -27,6 +27,7 @@ import org.apache.log4j.Logger;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
@@ -57,6 +58,9 @@ public class JavaUdfDataType {
     public static final JavaUdfDataType DECIMAL64 = new 
JavaUdfDataType("DECIMAL64", TPrimitiveType.DECIMAL64, 8);
     public static final JavaUdfDataType DECIMAL128 = new 
JavaUdfDataType("DECIMAL128", TPrimitiveType.DECIMAL128I,
             16);
+
+    public static final JavaUdfDataType IPV4 = new JavaUdfDataType("IPV4", 
TPrimitiveType.IPV4, 4);
+    public static final JavaUdfDataType IPV6 = new JavaUdfDataType("IPV6", 
TPrimitiveType.IPV6, 16);
     public static final JavaUdfDataType ARRAY_TYPE = new 
JavaUdfDataType("ARRAY_TYPE", TPrimitiveType.ARRAY, 0);
     public static final JavaUdfDataType MAP_TYPE = new 
JavaUdfDataType("MAP_TYPE", TPrimitiveType.MAP, 0);
     public static final JavaUdfDataType STRUCT_TYPE = new 
JavaUdfDataType("STRUCT_TYPE", TPrimitiveType.STRUCT, 0);
@@ -87,6 +91,8 @@ public class JavaUdfDataType {
         JavaUdfDataTypeSet.add(ARRAY_TYPE);
         JavaUdfDataTypeSet.add(MAP_TYPE);
         JavaUdfDataTypeSet.add(STRUCT_TYPE);
+        JavaUdfDataTypeSet.add(IPV4);
+        JavaUdfDataTypeSet.add(IPV6);
     }
 
     private final String description;
@@ -158,6 +164,8 @@ public class JavaUdfDataType {
             return Sets.newHashSet(JavaUdfDataType.ARRAY_TYPE, 
JavaUdfDataType.STRUCT_TYPE);
         } else if (Type.MAP_SUPPORTED_JAVA_TYPE.contains(c)) {
             return Sets.newHashSet(JavaUdfDataType.MAP_TYPE);
+        } else if (c == InetAddress.class) {
+            return Sets.newHashSet(JavaUdfDataType.IPV4, JavaUdfDataType.IPV6);
         }
         return Sets.newHashSet(JavaUdfDataType.INVALID_TYPE);
     }
diff --git 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/TypeNativeBytes.java
 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/TypeNativeBytes.java
index c6c3c28d228..7474ce4467d 100644
--- 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/TypeNativeBytes.java
+++ 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/TypeNativeBytes.java
@@ -20,6 +20,8 @@ package org.apache.doris.common.jni.utils;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -58,6 +60,20 @@ public class TypeNativeBytes {
         return new BigInteger(originalBytes);
     }
 
+    public static InetAddress getInetAddress(byte[] bytes) {
+        // Convert the byte order back if necessary
+        byte[] originalBytes = convertByteOrder(bytes);
+        try {
+            return InetAddress.getByAddress(originalBytes);
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    public static byte[] getInetAddressBytes(InetAddress v) {
+        return convertByteOrder(v.getAddress());
+    }
+
     public static byte[] getDecimalBytes(BigDecimal v, int scale, int size) {
         BigDecimal retValue = v.setScale(scale, RoundingMode.HALF_EVEN);
         BigInteger data = retValue.unscaledValue();
diff --git 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/UdfUtils.java
 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/UdfUtils.java
index 8cc9ceb014f..c5580c98090 100644
--- 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/UdfUtils.java
+++ 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/utils/UdfUtils.java
@@ -190,6 +190,12 @@ public class UdfUtils {
                 StructType structType = (StructType) parameterTypes[finalI];
                 ArrayList<StructField> fields = structType.getFields();
                 inputArgTypes[i].setFields(fields);
+            } else if (parameterTypes[finalI].isIP()) {
+                if (parameterTypes[finalI].isIPv4()) {
+                    inputArgTypes[i] = new 
JavaUdfDataType(JavaUdfDataType.IPV4);
+                } else {
+                    inputArgTypes[i] = new 
JavaUdfDataType(JavaUdfDataType.IPV6);
+                }
             }
             if (res.length == 0) {
                 return Pair.of(false, inputArgTypes);
diff --git 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/ColumnType.java
 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/ColumnType.java
index 1a919d84631..e159f608c9c 100644
--- 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/ColumnType.java
+++ 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/ColumnType.java
@@ -56,6 +56,8 @@ public class ColumnType {
         DECIMAL32(4),
         DECIMAL64(8),
         DECIMAL128(16),
+        IPV4(4),
+        IPV6(16),
         STRING(-1),
         ARRAY(-1),
         MAP(-1),
@@ -155,6 +157,18 @@ public class ColumnType {
         return type == Type.ARRAY;
     }
 
+    public boolean isIpv4() {
+        return type == Type.IPV4;
+    }
+
+    public boolean isIpv6() {
+        return type == Type.IPV6;
+    }
+
+    public boolean isIp() {
+        return isIpv4() || isIpv6();
+    }
+
     public boolean isMap() {
         return type == Type.MAP;
     }
@@ -287,6 +301,12 @@ public class ColumnType {
             case "double":
                 type = Type.DOUBLE;
                 break;
+            case "ipv4":
+                type = Type.IPV4;
+                break;
+            case "ipv6":
+                type = Type.IPV6;
+                break;
             case "datev1":
                 type = Type.DATE;
                 break;
diff --git 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/VectorColumn.java
 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/VectorColumn.java
index 04609ab1b1f..d044ec5edff 100644
--- 
a/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/VectorColumn.java
+++ 
b/fe/be-java-extensions/java-common/src/main/java/org/apache/doris/common/jni/vec/VectorColumn.java
@@ -27,6 +27,8 @@ import com.google.common.collect.Lists;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.nio.charset.StandardCharsets;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -73,6 +75,19 @@ public class VectorColumn {
     // todo: support pruned struct fields
     private List<Integer> structFieldIndex;
 
+
+    public static final InetAddress DEFAULT_IPV4;
+    public static final InetAddress DEFAULT_IPV6;
+
+    static {
+        try {
+            DEFAULT_IPV4 = InetAddress.getByName("127.0.0.1");
+            DEFAULT_IPV6 = InetAddress.getByName("::1");
+        } catch (UnknownHostException e) {
+            throw new RuntimeException("Failed to initialize default 
InetAddress values", e);
+        }
+    }
+
     // Create writable column
     private VectorColumn(ColumnType columnType, int capacity) {
         this.columnType = columnType;
@@ -361,6 +376,10 @@ public class VectorColumn {
                 return appendLong(0);
             case LARGEINT:
                 return appendBigInteger(BigInteger.ZERO);
+            case IPV4:
+                return appendInetAddress(DEFAULT_IPV4);
+            case IPV6:
+                return appendInetAddress(DEFAULT_IPV6);
             case FLOAT:
                 return appendFloat(0);
             case DOUBLE:
@@ -852,6 +871,56 @@ public class VectorColumn {
         return result;
     }
 
+    public byte[] getInetAddressBytes(int rowId) {
+        int typeSize = columnType.getTypeSize();
+        byte[] bytes = new byte[typeSize];
+        OffHeap.copyMemory(null, data + (long) rowId * typeSize, bytes, 
OffHeap.BYTE_ARRAY_OFFSET, typeSize);
+        return bytes;
+    }
+
+    public InetAddress getInetAddress(int rowId) {
+        return TypeNativeBytes.getInetAddress(getInetAddressBytes(rowId));
+    }
+
+    public InetAddress[] getInetAddressColumn(int start, int end) {
+        InetAddress[] result = new InetAddress[end - start];
+        for (int i = start; i < end; ++i) {
+            if (!isNullAt(i)) {
+                result[i - start] = getInetAddress(i);
+            }
+        }
+        return result;
+    }
+
+    public int appendInetAddress(InetAddress v) {
+        reserve(appendIndex + 1);
+        putInetAddress(appendIndex, v);
+        return appendIndex++;
+    }
+
+    public void appendInetAddress(InetAddress[] batch, boolean isNullable) {
+        reserve(appendIndex + batch.length);
+        for (InetAddress v : batch) {
+            if (v == null) {
+                putNull(appendIndex);
+                if (columnType.isIpv4()) {
+                    putInetAddress(appendIndex, DEFAULT_IPV4);
+                } else {
+                    putInetAddress(appendIndex, DEFAULT_IPV6);
+                }
+            } else {
+                putInetAddress(appendIndex, v);
+            }
+            appendIndex++;
+        }
+    }
+
+    private void putInetAddress(int rowId, InetAddress v) {
+        int typeSize = columnType.getTypeSize();
+        byte[] bytes = TypeNativeBytes.getInetAddressBytes(v);
+        OffHeap.copyMemory(bytes, OffHeap.BYTE_ARRAY_OFFSET, null, data + 
(long) rowId * typeSize, typeSize);
+    }
+
     public int appendDecimal(BigDecimal v) {
         reserve(appendIndex + 1);
         putDecimal(appendIndex, v);
@@ -1401,6 +1470,9 @@ public class VectorColumn {
                 return new Long[size];
             case LARGEINT:
                 return new BigInteger[size];
+            case IPV4:
+            case IPV6:
+                return new InetAddress[size];
             case FLOAT:
                 return new Float[size];
             case DOUBLE:
@@ -1450,6 +1522,10 @@ public class VectorColumn {
             case LARGEINT:
                 appendBigInteger((BigInteger[]) batch, isNullable);
                 break;
+            case IPV4:
+            case IPV6:
+                appendInetAddress((InetAddress[]) batch, isNullable);
+                break;
             case FLOAT:
                 appendFloat((Float[]) batch, isNullable);
                 break;
@@ -1507,6 +1583,9 @@ public class VectorColumn {
                 return getLongColumn(start, end);
             case LARGEINT:
                 return getBigIntegerColumn(start, end);
+            case IPV4:
+            case IPV6:
+                return getInetAddressColumn(start, end);
             case FLOAT:
                 return getFloatColumn(start, end);
             case DOUBLE:
diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java 
b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
index 6c0af7951e5..1f413f304d6 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
@@ -36,6 +36,7 @@ import org.apache.logging.log4j.Logger;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.net.InetAddress;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
@@ -304,9 +305,10 @@ public abstract class Type {
                     .put(PrimitiveType.FLOAT, Sets.newHashSet(Float.class, 
float.class))
                     .put(PrimitiveType.DOUBLE, Sets.newHashSet(Double.class, 
double.class))
                     .put(PrimitiveType.BIGINT, Sets.newHashSet(Long.class, 
long.class))
-                    .put(PrimitiveType.IPV4, Sets.newHashSet(Integer.class, 
int.class))
                     .put(PrimitiveType.CHAR, Sets.newHashSet(String.class))
                     .put(PrimitiveType.VARCHAR, Sets.newHashSet(String.class))
+                    .put(PrimitiveType.IPV4, 
Sets.newHashSet(InetAddress.class))
+                    .put(PrimitiveType.IPV6, 
Sets.newHashSet(InetAddress.class))
                     .put(PrimitiveType.STRING, Sets.newHashSet(String.class))
                     .put(PrimitiveType.DATE, DATE_SUPPORTED_JAVA_TYPE)
                     .put(PrimitiveType.DATEV2, DATE_SUPPORTED_JAVA_TYPE)
diff --git a/regression-test/data/nereids_p0/javaudf/test_javaudf_ip.out 
b/regression-test/data/nereids_p0/javaudf/test_javaudf_ip.out
new file mode 100644
index 00000000000..b7eb66cab9c
--- /dev/null
+++ b/regression-test/data/nereids_p0/javaudf/test_javaudf_ip.out
@@ -0,0 +1,42 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select_ipv4_1 --
+1      0.0.0.123       /0.0.0.123
+2      0.0.12.42       /0.0.12.42
+3      0.119.130.67    /0.119.130.67
+4      \N      null
+
+-- !select_ipv4_2 --
+1      0.0.0.123       0.0.0.123
+2      0.0.0.123       0.0.0.123
+
+-- !select_ipv4_3 --
+nulludf/0.0.0.123udf/0.0.12.42udf/0.119.130.67udf
+
+-- !select_ipv4_4 --
+1      ["127.0.0.1", "127.0.0.1", "127.0.0.1", null, null, "127.0.0.1"]
+2      ["127.0.0.1", "127.0.0.1", "127.0.0.1", null, null, "127.0.0.1"]
+3      ["127.0.0.1", "127.0.0.1", "127.0.0.1", null, null, "127.0.0.1"]
+4      ["127.0.0.1", "127.0.0.1", "127.0.0.1", null, null, "127.0.0.1"]
+
+-- !select_ipv6_1 --
+1      ::855d  /0:0:0:0:0:0:0:855d
+2      ::0.4.221.183   /0:0:0:0:0:0:4:ddb7
+3      ::a:7429:d0d6:6e08:9f5f /0:0:0:a:7429:d0d6:6e08:9f5f
+4      \N      null
+
+-- !select_ipv6_2 --
+3      2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D 
2001:db8:ac10:fe01:feed:babe:cafe:f00d
+4      2001:0DB8:AC10:FE01:FEED:BABE:CAFE:F00D 
2001:db8:ac10:fe01:feed:babe:cafe:f00d
+
+-- !select_ipv6_3 --
+nulludf/0:0:0:0:0:0:0:855dudf/0:0:0:0:0:0:4:ddb7udf/0:0:0:a:7429:d0d6:6e08:9f5fudf
+
+-- !select_ipv6_4 --
+1      ["::1", "::1", "::1", null, null, "::1"]
+2      ["::1", "::1", "::1", null, null, "::1"]
+3      ["::1", "::1", "::1", null, null, "::1"]
+4      ["::1", "::1", "::1", null, null, "::1"]
+
+-- !select_ipv6_5 --
+/0:0:0:0:0:0:0:855d, /0:0:0:0:0:0:4:ddb7, /0:0:0:a:7429:d0d6:6e08:9f5f
+
diff --git 
a/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/IPV4TypeTest.java
 
b/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/IPV4TypeTest.java
new file mode 100644
index 00000000000..65d6ea2ab1a
--- /dev/null
+++ 
b/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/IPV4TypeTest.java
@@ -0,0 +1,74 @@
+// 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.udf;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+public class IPV4TypeTest {
+    // input ipv4
+    public String evaluate(InetAddress x) {
+        if (x == null) {
+            return "null";
+        }
+        return x.toString();
+    }
+
+    // output ipv4
+    public InetAddress evaluate(String s) {
+        try {
+            InetAddress ipv4Address = InetAddress.getByName(s);
+            if (ipv4Address.getAddress().length == 4) {
+                return ipv4Address;
+            } else {
+                return null;
+            }
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    // input array<ipv4>
+    public String evaluate(ArrayList<InetAddress> s) {
+        String ret = "";
+        for (InetAddress ip : s) {
+            ret += evaluate(ip) + "udf";
+        }
+        return ret;
+    }
+
+    // output array<ipv4>
+    public ArrayList<InetAddress> evaluate() {
+        ArrayList<InetAddress> ret = new ArrayList<InetAddress>();
+        InetAddress DEFAULT_IPV = null;
+        try {
+            DEFAULT_IPV = InetAddress.getByName("127.0.0.1");
+        } catch (UnknownHostException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        ret.add(DEFAULT_IPV);
+        ret.add(DEFAULT_IPV);
+        ret.add(DEFAULT_IPV);
+        ret.add(null);
+        ret.add(null);
+        ret.add(DEFAULT_IPV);
+        return ret;
+    }
+}
diff --git 
a/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/IPV6TypeTest.java
 
b/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/IPV6TypeTest.java
new file mode 100644
index 00000000000..f4345cbab5d
--- /dev/null
+++ 
b/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/IPV6TypeTest.java
@@ -0,0 +1,73 @@
+// 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.udf;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+public class IPV6TypeTest {
+    // input ipv6
+    public String evaluate(InetAddress x) {
+        if (x == null) {
+            return "null";
+        }
+        return x.toString();
+    }
+
+    // output ipv6
+    public InetAddress evaluate(String s) {
+        try {
+            InetAddress ipv6Address = InetAddress.getByName(s);
+            if (ipv6Address.getAddress().length == 16) {
+                return ipv6Address;
+            } else {
+                return null;
+            }
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    // input array<ipv6>
+    public String evaluate(ArrayList<InetAddress> s) {
+        String ret = "";
+        for (InetAddress ip : s) {
+            ret += evaluate(ip) + "udf";
+        }
+        return ret;
+    }
+
+    // output array<ipv6>
+    public ArrayList<InetAddress> evaluate() {
+        ArrayList<InetAddress> ret = new ArrayList<InetAddress>();
+        InetAddress DEFAULT_IPV = null;
+        try {
+            DEFAULT_IPV = InetAddress.getByName("::1");
+        } catch (UnknownHostException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        ret.add(DEFAULT_IPV);
+        ret.add(DEFAULT_IPV);
+        ret.add(DEFAULT_IPV);
+        ret.add(null);
+        ret.add(null);
+        ret.add(DEFAULT_IPV);
+        return ret;
+    }
+}
diff --git 
a/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/MySumIP.java 
b/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/MySumIP.java
new file mode 100644
index 00000000000..b57418ec04c
--- /dev/null
+++ 
b/regression-test/java-udf-src/src/main/java/org/apache/doris/udf/MySumIP.java
@@ -0,0 +1,76 @@
+// 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.udf;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.stream.Collectors;
+
+public class MySumIP {
+    public static class State {
+        public ArrayList<String> list = new ArrayList<>();
+    }
+
+    public State create() {
+        return new State();
+    }
+
+    public void destroy(State state) {
+    }
+
+    public void add(State state, InetAddress val1) {
+        if (val1 == null)
+            return;
+        state.list.add(val1.toString());
+    }
+
+    public void serialize(State state, DataOutputStream out) throws 
IOException {
+        out.writeInt(state.list.size());
+
+        for (String str : state.list) {
+            out.writeUTF(str);
+        }
+    }
+
+    public void deserialize(State state, DataInputStream in) throws 
IOException {
+        int size = in.readInt();
+
+        state.list = new ArrayList<>(size);
+
+        for (int i = 0; i < size; i++) {
+            state.list.add(in.readUTF());
+        }
+    }
+
+    public void merge(State state, State rhs) {
+        for (String s : rhs.list) {
+            state.list.add(s);
+        }
+    }
+
+    public String getValue(State state) {
+        state.list.sort(Comparator.nullsLast(String::compareTo));
+        String result = state.list.stream()
+                .filter(s -> s != null)
+                .collect(Collectors.joining(", "));
+        return result;
+    }
+}
\ 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
new file mode 100644
index 00000000000..aa079af16d0
--- /dev/null
+++ b/regression-test/suites/nereids_p0/javaudf/test_javaudf_ip.groovy
@@ -0,0 +1,146 @@
+// 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.
+
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+import java.nio.file.Paths
+
+suite("nereids_test_javaudf_ip") {
+    sql 'set enable_nereids_planner=true'
+    sql 'set enable_fallback_to_original_planner=false'
+
+    def jarPath = 
"""${context.file.parent}/../../javaudf_p0/jars/java-udf-case-jar-with-dependencies.jar"""
+    scp_udf_file_to_all_be(jarPath)
+
+    try {
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv4_test1(ipv4);"""
+        sql """ CREATE FUNCTION java_udf_ipv4_test1(ipv4) RETURNS string 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV4TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv4_test2(string);"""
+        sql """ CREATE FUNCTION java_udf_ipv4_test2(string) RETURNS ipv4 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV4TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv4_test3(array<ipv4>);"""
+        sql """ CREATE FUNCTION java_udf_ipv4_test3(array<ipv4>) RETURNS 
string PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV4TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv4_test4();"""
+        sql """ CREATE FUNCTION java_udf_ipv4_test4() RETURNS array<ipv4> 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV4TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+
+        sql """DROP TABLE IF EXISTS test_udf_ip;"""
+        sql """
+                CREATE TABLE test_udf_ip
+                (
+                    k1 BIGINT ,
+                    k4 ipv4 ,
+                    k6 ipv6 ,
+                    s string 
+                )
+                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");
 """
+        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   """
+        qt_select_ipv4_4 """ select k1, java_udf_ipv4_test4() from test_udf_ip 
order by k1   """
+        
+    } finally {
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv4_test1(ipv4);")
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv4_test2(string);")
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv4_test3(array<ipv4>);")
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv4_test4();")
+    }
+
+    try {
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv6_test1(ipv6);"""
+        sql """ CREATE FUNCTION java_udf_ipv6_test1(ipv6) RETURNS string 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV6TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv6_test2(string);"""
+        sql """ CREATE FUNCTION java_udf_ipv6_test2(string) RETURNS ipv6 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV6TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv6_test3(array<ipv6>);"""
+        sql """ CREATE FUNCTION java_udf_ipv6_test3(array<ipv6>) RETURNS 
string PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV6TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+        sql """ DROP FUNCTION IF EXISTS java_udf_ipv6_test4();"""
+        sql """ CREATE FUNCTION java_udf_ipv6_test4() RETURNS array<ipv6> 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.IPV6TypeTest",
+            "type"="JAVA_UDF"
+        ); """
+
+        sql """DROP TABLE IF EXISTS test_udf_ip;"""
+        sql """
+                CREATE TABLE test_udf_ip
+                (
+                    k1 BIGINT ,
+                    k4 ipv4 ,
+                    k6 ipv6 ,
+                    s string 
+                )
+                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");
 """
+        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   """
+        qt_select_ipv6_4 """ select k1, java_udf_ipv6_test4() from test_udf_ip 
order by k1   """
+
+
+
+
+        sql """ CREATE AGGREGATE FUNCTION udaf_my_sum_ip(ipv6) RETURNS string 
PROPERTIES (
+            "file"="file://${jarPath}",
+            "symbol"="org.apache.doris.udf.MySumIP",
+            "always_nullable"="false",
+            "type"="JAVA_UDF"
+        ); """
+
+
+        qt_select_ipv6_5  """ select udaf_my_sum_ip(k6) from test_udf_ip; """
+        
+    } finally {
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv6_test1(ipv4);")
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv6_test2(string);")
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv6_test3(array<ipv4>);")
+        try_sql("DROP FUNCTION IF EXISTS java_udf_ipv6_test4();")
+        try_sql("DROP FUNCTION IF EXISTS udaf_my_sum_ip(ipv6);")
+    }
+}


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

Reply via email to