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 2404371f3c8 branch-3.0: [fix](nereids) fix cast ipv4 to string #51546
(#51739)
2404371f3c8 is described below
commit 2404371f3c8e050a3d0ce5da44183daba2724aed
Author: yujun <[email protected]>
AuthorDate: Wed Jun 18 12:23:11 2025 +0800
branch-3.0: [fix](nereids) fix cast ipv4 to string #51546 (#51739)
cherry pick from #51546
---
.../org/apache/doris/common/util/NetUtils.java | 28 +++++++++
.../trees/expressions/literal/IPv4Literal.java | 68 +++++++++++++++++++--
.../org/apache/doris/common/util/NetUtilsTest.java | 37 +++++++++++
.../infer_predicate/pull_up_predicate_literal.out | Bin 110312 -> 110311 bytes
.../fold_constant/fold_constant_ip.groovy | 30 +++++++++
5 files changed, 157 insertions(+), 6 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java
b/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java
index 9b787f52bf4..13fa4fbaf9c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.net.DatagramSocket;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
@@ -161,4 +162,31 @@ public class NetUtils {
return new SystemInfoService.HostInfo(pair[0],
Integer.valueOf(pair[1]));
}
+ /**
+ * Convert IPv4 address to long
+ * @param inet4Address IPv4 address
+ * @return The corresponding long value
+ */
+ public static long inet4AddressToLong(Inet4Address inet4Address) {
+ byte[] bytes = inet4Address.getAddress();
+ long result = 0;
+ for (byte b : bytes) {
+ result = result << 8 | (b & 0xFF);
+ }
+ return result;
+ }
+
+ /**
+ * Convert long value back to IPv4 address
+ * @param value IP address as a long value
+ * @return The corresponding IPv4 address
+ */
+ public static Inet4Address longToInet4Address(long value) throws Exception
{
+ byte[] bytes = new byte[4];
+ bytes[0] = (byte) ((value >> 24) & 0xFF);
+ bytes[1] = (byte) ((value >> 16) & 0xFF);
+ bytes[2] = (byte) ((value >> 8) & 0xFF);
+ bytes[3] = (byte) (value & 0xFF);
+ return (Inet4Address) Inet4Address.getByAddress(bytes);
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
index e4e931738b0..fd012561260 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
@@ -18,10 +18,13 @@
package org.apache.doris.nereids.trees.expressions.literal;
import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.common.util.NetUtils;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.IPv4Type;
+import java.net.Inet4Address;
+import java.util.Objects;
import java.util.regex.Pattern;
/**
@@ -32,20 +35,67 @@ public class IPv4Literal extends Literal {
private static final Pattern IPV4_STD_REGEX =
Pattern.compile("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
- private long value;
+ /**
+ * Add a class Inet4Addr wrap in Inet4Address,
+ * When cast ipv4 literal to string, it will call `new
StringLiteral(ipv4Literal.getValue().toString())`,
+ * but Inet4Address.toString() contains a prefix "/", like "/192.168.1.10".
+ * Use Inet4Addr can solve this problem.
+ */
+ public static class Inet4Addr {
+ final Inet4Address address;
+
+ public Inet4Addr(Inet4Address addr) {
+ this.address = addr;
+ }
+
+ public Inet4Address getAddress() {
+ return this.address;
+ }
+
+ public long toLong() {
+ return NetUtils.inet4AddressToLong(address);
+ }
+
+ @Override
+ public String toString() {
+ return address.getHostAddress();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(address);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Inet4Addr)) {
+ return false;
+ }
+ Inet4Addr otherAddr = (Inet4Addr) other;
+ return address.equals(otherAddr.address);
+ }
+ }
+
+ private Inet4Addr value;
public IPv4Literal(String ipv4) throws AnalysisException {
super(IPv4Type.INSTANCE);
init(ipv4);
}
- protected IPv4Literal(long value) {
+ protected IPv4Literal(long value) throws AnalysisException {
super(IPv4Type.INSTANCE);
- this.value = value;
+ Inet4Address address;
+ try {
+ address = NetUtils.longToInet4Address(value);
+ } catch (Exception e) {
+ throw new AnalysisException(e.getMessage());
+ }
+ this.value = new Inet4Addr(address);
}
@Override
- public Long getValue() {
+ public Inet4Addr getValue() {
return value;
}
@@ -56,7 +106,7 @@ public class IPv4Literal extends Literal {
@Override
public LiteralExpr toLegacyLiteral() {
- return new org.apache.doris.analysis.IPv4Literal(value);
+ return new org.apache.doris.analysis.IPv4Literal(value.toLong());
}
void init(String ipv4) throws AnalysisException {
@@ -80,7 +130,13 @@ public class IPv4Literal extends Literal {
}
value = (value << 8) | octet;
}
- this.value = value;
+ Inet4Address address;
+ try {
+ address = NetUtils.longToInet4Address(value);
+ } catch (Exception e) {
+ throw new AnalysisException(e.getMessage());
+ }
+ this.value = new Inet4Addr(address);
}
private void checkValueValid(String ipv4) throws AnalysisException {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/common/util/NetUtilsTest.java
b/fe/fe-core/src/test/java/org/apache/doris/common/util/NetUtilsTest.java
new file mode 100644
index 00000000000..bbebfdfd33f
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/common/util/NetUtilsTest.java
@@ -0,0 +1,37 @@
+// 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.common.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
+public class NetUtilsTest {
+
+ @Test
+ public void testConvertIp() throws Exception {
+ long ipValue = 3232235786L;
+ InetAddress ip = InetAddress.getByName("192.168.1.10");
+ Assert.assertTrue(ip instanceof Inet4Address);
+ Assert.assertEquals(ipValue,
NetUtils.inet4AddressToLong((Inet4Address) ip));
+ Inet4Address convertIp = NetUtils.longToInet4Address(ipValue);
+ Assert.assertEquals(ip, convertIp);
+ }
+}
diff --git
a/regression-test/data/nereids_rules_p0/infer_predicate/pull_up_predicate_literal.out
b/regression-test/data/nereids_rules_p0/infer_predicate/pull_up_predicate_literal.out
index 88d7fa790d9..1b4c185e280 100644
Binary files
a/regression-test/data/nereids_rules_p0/infer_predicate/pull_up_predicate_literal.out
and
b/regression-test/data/nereids_rules_p0/infer_predicate/pull_up_predicate_literal.out
differ
diff --git
a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_ip.groovy
b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_ip.groovy
new file mode 100644
index 00000000000..375057a01a8
--- /dev/null
+++
b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_ip.groovy
@@ -0,0 +1,30 @@
+// 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("fold_constant_ip") {
+ // cast function
+ for (def ipv4 : ["1", "256.256.256.256", "192.168.1.10"]) {
+ testFoldConst("SELECT cast('${ipv4}' as ipv4)")
+ testFoldConst("SELECT cast(cast('${ipv4}' as ipv4) as string)")
+ testFoldConst("SELECT cast(cast(cast('${ipv4}' as ipv4) as string) as
ipv4)")
+ }
+ for (def ipv6 : ["1", "ef8d:3d6a:869b:2582:7200:aa46:4dcd:2bd4"]) {
+ testFoldConst("SELECT cast('${ipv6}' as ipv6)")
+ testFoldConst("SELECT cast(cast('${ipv6}' as ipv6) as string)")
+ testFoldConst("SELECT cast(cast(cast('${ipv6}' as ipv6) as string) as
ipv6)")
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]