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

lijibing pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 1fb21bafdc1 [fix](nereids) fix cast ipv4 to string (#51546)
1fb21bafdc1 is described below

commit 1fb21bafdc15b60b84a01b8a09c8521ee94e162e
Author: yujun <[email protected]>
AuthorDate: Mon Jun 16 10:08:16 2025 +0800

    [fix](nereids) fix cast ipv4 to string (#51546)
    
    ### What problem does this PR solve?
    
    when cast a literal L to string, it will call `new
    StringLiteral(L.getValue().toString())`, for a ipv4, its getValue return
    a long value.
    
    Then we will have:
    
    before this PR:
    ```
    MySQL [email protected]:db1> select cast(cast("192.168.1.10" as ipv4) as 
string)
    +----------------------------------------------+
    | cast(cast("192.168.1.10" as ipv4) as string) |
    +----------------------------------------------+
    | 3232235786                                   |
    +----------------------------------------------+
    ```
    
    this PR fix this, it will change ipv4 getValue return a ipv4 class.
    
    after this PR:
    ```
    MySQL [email protected]:db1> SELECT cast(cast('192.168.1.10' as ipv4) as 
string);
    +----------------------------------------------+
    | cast(cast('192.168.1.10' as ipv4) as string) |
    +----------------------------------------------+
    | 192.168.1.10                                 |
    +----------------------------------------------+
    ```
---
 .../org/apache/doris/common/util/NetUtils.java     |  28 ++++++++
 .../trees/expressions/literal/IPv4Literal.java     |  72 ++++++++++++++++++---
 .../org/apache/doris/common/util/NetUtilsTest.java |  39 +++++++++++
 .../infer_predicate/pull_up_predicate_literal.out  | Bin 102268 -> 102267 bytes
 .../fold_constant/fold_constant_ip.groovy          |  32 +++++++++
 5 files changed, 163 insertions(+), 8 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 6843bdd9007..448a1fd748f 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,26 +35,73 @@ public class IPv4Literal extends Literal implements 
ComparableLiteral {
     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;
     }
 
     @Override
     public double getDouble() {
-        return (double) value;
+        return (double) value.toLong();
     }
 
     @Override
@@ -61,13 +111,13 @@ public class IPv4Literal extends Literal implements 
ComparableLiteral {
 
     @Override
     public LiteralExpr toLegacyLiteral() {
-        return new org.apache.doris.analysis.IPv4Literal(value);
+        return new org.apache.doris.analysis.IPv4Literal(value.toLong());
     }
 
     @Override
     public int compareTo(ComparableLiteral other) {
         if (other instanceof IPv4Literal) {
-            return Long.compare(value, ((IPv4Literal) other).value);
+            return Long.compare(value.toLong(), ((IPv4Literal) 
other).value.toLong());
         }
         if (other instanceof NullLiteral) {
             return 1;
@@ -100,7 +150,13 @@ public class IPv4Literal extends Literal implements 
ComparableLiteral {
             }
             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..4b23a13832b
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/common/util/NetUtilsTest.java
@@ -0,0 +1,39 @@
+// 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 com.google.common.net.InetAddresses;
+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);
+        System.out.println(InetAddresses.forString("192.168.1.10").toString());
+    }
+}
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 6db062bdd8e..cc7e99a0603 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..cd4ce8f9920
--- /dev/null
+++ 
b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_ip.groovy
@@ -0,0 +1,32 @@
+// 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)")
+        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)")
+        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