cherry pick from #51546
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -2016,7 +2016,7 @@ PhysicalResultSink
|
||||
----------PhysicalProject
|
||||
------------PhysicalOlapScan[test_pull_up_predicate_literal]
|
||||
------PhysicalProject
|
||||
--------filter((t2.d_ipv4 = 2130706433))
|
||||
--------filter((t2.d_ipv4 = 127.0.0.1))
|
||||
----------PhysicalOlapScan[test_types]
|
||||
|
||||
-- !const_value_and_join_column_type239 --
|
||||
|
||||
@ -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)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user