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]

Reply via email to