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]