This is an automated email from the ASF dual-hosted git repository.
dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.0 by this push:
new 32eb7bbca8d branch-30: [Bug](ipv6) fix fe can't parse ipv4-mapped type
to ipv6 (#54391) (#54686)
32eb7bbca8d is described below
commit 32eb7bbca8d35fcd57d655162833e9a4ed80b105
Author: zhangstar333 <[email protected]>
AuthorDate: Wed Aug 13 22:29:19 2025 +0800
branch-30: [Bug](ipv6) fix fe can't parse ipv4-mapped type to ipv6 (#54391)
(#54686)
### What problem does this PR solve?
Problem Summary:
cherry-pick from master (#54391)
---
.../org/apache/doris/analysis/IPv6Literal.java | 6 ++-
.../trees/expressions/literal/IPv6Literal.java | 23 +++++++++--
.../trees/expressions/literal/IPV6LiteralTest.java | 43 +++++++++++++++++++++
.../data/datatype_p0/ip/test_ip_crud.out | Bin 1367 -> 1763 bytes
.../suites/datatype_p0/ip/test_ip_crud.groovy | 34 ++++++++++++++++
5 files changed, 102 insertions(+), 4 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv6Literal.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv6Literal.java
index 7d719720442..8648b2be867 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv6Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv6Literal.java
@@ -41,6 +41,9 @@ public class IPv6Literal extends LiteralExpr {
Pattern.compile("^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
private static final Pattern IPV6_COMPRESS_REGEX =
Pattern.compile("^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::((([0-9A-Fa-f]{1,4}:)*[0-9A-Fa-f]{1,4})?)$");
+ private static final String IPV4_PART =
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
+ private static final Pattern IPV6_MAPPED_REGEX =
+ Pattern.compile("^::[fF]{4}:(" + IPV4_PART + "\\.){3}" + IPV4_PART
+ "$");
@SerializedName("v")
private String value;
@@ -75,7 +78,8 @@ public class IPv6Literal extends LiteralExpr {
private void checkValueValid(String ipv6) throws AnalysisException {
if (ipv6.length() > 39) {
throw new AnalysisException("The length of IPv6 must not exceed
39. type: " + Type.IPV6);
- } else if (!IPV6_STD_REGEX.matcher(ipv6).matches() &&
!IPV6_COMPRESS_REGEX.matcher(ipv6).matches()) {
+ } else if (!IPV6_STD_REGEX.matcher(ipv6).matches() &&
!IPV6_COMPRESS_REGEX.matcher(ipv6).matches()
+ && !IPV6_MAPPED_REGEX.matcher(ipv6).matches()) {
throw new AnalysisException("Invalid IPv6 format: " + ipv6 + ".
type: " + Type.IPV6);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
index 0ac12ae85e4..a869541a417 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
@@ -22,6 +22,8 @@ import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.IPv6Type;
+import com.google.common.annotations.VisibleForTesting;
+
import java.util.regex.Pattern;
/**
@@ -33,6 +35,9 @@ public class IPv6Literal extends Literal {
Pattern.compile("^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
private static final Pattern IPV6_COMPRESS_REGEX =
Pattern.compile("^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::((([0-9A-Fa-f]{1,4}:)*[0-9A-Fa-f]{1,4})?)$");
+ private static final String IPV4_PART =
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
+ private static final Pattern IPV6_MAPPED_REGEX =
+ Pattern.compile("^::[fF]{4}:(" + IPV4_PART + "\\.){3}" + IPV4_PART
+ "$");
private final String value;
@@ -61,11 +66,23 @@ public class IPv6Literal extends Literal {
}
}
+ /**
+ * check IPv6 is valid
+ */
public void checkValueValid(String ipv6) throws AnalysisException {
if (ipv6.length() > 39) {
- throw new AnalysisException("The length of IPv6 must not exceed
39.");
- } else if (!IPV6_STD_REGEX.matcher(ipv6).matches() &&
!IPV6_COMPRESS_REGEX.matcher(ipv6).matches()) {
- throw new AnalysisException("Invalid IPv6 format.");
+ throw new AnalysisException("The length of IPv6 must not exceed
39: " + ipv6);
+ } else if (!isValidIPv6(ipv6)) {
+ throw new AnalysisException("Invalid IPv6 format: " + ipv6);
+ }
+ }
+
+ @VisibleForTesting
+ public static boolean isValidIPv6(String ipv6) {
+ if (IPV6_STD_REGEX.matcher(ipv6).matches() ||
IPV6_COMPRESS_REGEX.matcher(ipv6).matches()
+ || IPV6_MAPPED_REGEX.matcher(ipv6).matches()) {
+ return true;
}
+ return false;
}
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IPV6LiteralTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IPV6LiteralTest.java
new file mode 100644
index 00000000000..038608608c6
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IPV6LiteralTest.java
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.literal;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class IPV6LiteralTest {
+
+ @Test
+ public void testValidIPv6() {
+
Assertions.assertTrue(IPv6Literal.isValidIPv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
+ Assertions.assertTrue(IPv6Literal.isValidIPv6("fe80::1"));
+
Assertions.assertTrue(IPv6Literal.isValidIPv6("2001:db8::8a2e:370:7334"));
+ Assertions.assertTrue(IPv6Literal.isValidIPv6("::1"));
+ Assertions.assertTrue(IPv6Literal.isValidIPv6("::ffff:192.168.1.1"));
+ Assertions.assertTrue(IPv6Literal.isValidIPv6("::FFFF:10.0.0.255"));
+ }
+
+ @Test
+ public void testInvalidIPv6() {
+ Assertions.assertFalse(IPv6Literal.isValidIPv6("2001:db8::8a2e::370"));
+ Assertions.assertFalse(IPv6Literal.isValidIPv6("2001:db8:xyz::1"));
+ Assertions.assertFalse(IPv6Literal.isValidIPv6("192.168.1.1"));
+ Assertions.assertFalse(IPv6Literal.isValidIPv6("::aaaa:192.168.1.1"));
+ Assertions.assertFalse(IPv6Literal.isValidIPv6("::FFFF:10.0.0.256"));
+ }
+}
diff --git a/regression-test/data/datatype_p0/ip/test_ip_crud.out
b/regression-test/data/datatype_p0/ip/test_ip_crud.out
index 07323da29e5..60297af9226 100644
Binary files a/regression-test/data/datatype_p0/ip/test_ip_crud.out and
b/regression-test/data/datatype_p0/ip/test_ip_crud.out differ
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 255457fd2cf..4cb5f1df9a0 100644
--- a/regression-test/suites/datatype_p0/ip/test_ip_crud.groovy
+++ b/regression-test/suites/datatype_p0/ip/test_ip_crud.groovy
@@ -98,4 +98,38 @@ suite("test_ip_crud") {
qt_sql14 "select * from test_dup_ip_crud order by id"
sql "delete from test_dup_ip_crud where ip_v6='2001:4888:1f:e891:161:26::'"
qt_sql15 "select * from test_dup_ip_crud order by id"
+
+ sql "DROP TABLE IF EXISTS log"
+ sql """
+ CREATE TABLE IF NOT EXISTS log
+ (
+ type INT,
+ day DATE NOT NULL,
+ timestamp BIGINT NOT NULL,
+ sip IPV6,
+ dip IPV6
+ )
+ DUPLICATE KEY (`type`, `day`, `timestamp`)
+ DISTRIBUTED BY HASH(`type`) BUCKETS 8
+ PROPERTIES (
+ "replication_num" = "1"
+ );
+ """
+ sql "INSERT INTO log VALUES (1, '2025-08-05', 1754386200,
'::ffff:10.20.136.244', '::ffff:192.168.1.1');"
+ sql "INSERT INTO log VALUES (2, '2025-08-05', 1754386200,
'::ffff:11.20.136.244', '::ffff:192.168.1.2');"
+ sql "INSERT INTO log VALUES (3, '2025-08-05', 1754386200,
'::ffff:12.20.136.244', '::1');"
+ qt_sql16 "select * from log order by type;"
+ sql "delete from log where sip='::ffff:10.20.136.244';"
+ qt_sql17 "select * from log order by type;"
+
+ sql "delete from log where sip='0000:0000:0000:0000:0000:FFFF:0B14:88F4';"
+ qt_sql17 "select * from log order by type;"
+
+ sql "delete from log where dip='0000:0000:0000:0000:0000:0000:0000:0001';"
+ qt_sql17 "select * from log order by type;"
+
+ sql "DROP TABLE test_unique_ip_crud"
+ sql "DROP TABLE test_agg_ip_crud"
+ sql "DROP TABLE test_dup_ip_crud"
+ sql "DROP TABLE log"
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]