Skip to content

Commit f35261e

Browse files
authored
Merge pull request #2288 from ClickHouse/add-ipaddress-support
Add IP conversion and encoding
2 parents 7a13970 + 79db670 commit f35261e

File tree

4 files changed

+57
-15
lines changed

4 files changed

+57
-15
lines changed

jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.io.InputStream;
99
import java.io.Reader;
1010
import java.math.BigDecimal;
11+
import java.net.InetAddress;
1112
import java.net.URL;
1213
import java.sql.Array;
1314
import java.sql.Blob;
@@ -517,6 +518,8 @@ private static String encodeObject(Object x) throws SQLException {
517518
return encodeObject(((ZonedDateTime) x).toInstant());
518519
} else if (x instanceof Instant) {
519520
return "fromUnixTimestamp64Nano(" + (((Instant) x).getEpochSecond() * 1_000_000_000L + ((Instant) x).getNano())+ ")";
521+
} else if (x instanceof InetAddress) {
522+
return "'" + ((InetAddress) x).getHostAddress() + "'";
520523
} else if (x instanceof Array) {
521524
StringBuilder listString = new StringBuilder();
522525
listString.append("[");

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.clickhouse.data.ClickHouseDataType;
55
import com.clickhouse.jdbc.types.Array;
66

7+
import java.net.Inet4Address;
8+
import java.net.Inet6Address;
79
import java.sql.Date;
810
import java.sql.JDBCType;
911
import java.sql.SQLException;
@@ -233,6 +235,12 @@ public static Object convert(Object value, Class<?> type) throws SQLException {
233235
return java.sql.Time.valueOf(LocalTime.from((TemporalAccessor) value));
234236
} else if (type == java.sql.Array.class && value instanceof BinaryStreamReader.ArrayValue) {//It's cleaner to use getList but this handles the more generic getObject
235237
return new Array(((BinaryStreamReader.ArrayValue) value).asList(), "Object", JDBCType.JAVA_OBJECT.getVendorTypeNumber());
238+
} else if (type == Inet4Address.class && value instanceof Inet6Address) {
239+
// Convert Inet6Address to Inet4Address
240+
return Inet4Address.getByName(value.toString());
241+
} else if (type == Inet6Address.class && value instanceof Inet4Address) {
242+
// Convert Inet4Address to Inet6Address
243+
return Inet6Address.getByName(value.toString());
236244
}
237245
} catch (Exception e) {
238246
throw new SQLException("Failed to convert " + value + " to " + type.getName(), ExceptionUtils.SQL_STATE_DATA_EXCEPTION);

jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java

+46-11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
import java.math.BigDecimal;
1111
import java.math.BigInteger;
12+
import java.net.Inet4Address;
13+
import java.net.Inet6Address;
14+
import java.net.InetAddress;
15+
import java.net.UnknownHostException;
1216
import java.sql.Connection;
1317
import java.sql.Date;
1418
import java.sql.JDBCType;
@@ -317,35 +321,29 @@ public void testStringTypes() throws SQLException {
317321
runQuery("CREATE TABLE test_strings (order Int8, "
318322
+ "str String, fixed FixedString(6), "
319323
+ "enum Enum8('a' = 6, 'b' = 7, 'c' = 8), enum8 Enum8('a' = 1, 'b' = 2, 'c' = 3), enum16 Enum16('a' = 1, 'b' = 2, 'c' = 3), "
320-
+ "uuid UUID, ipv4 IPv4, ipv6 IPv6, "
321-
+ "escaped String "
324+
+ "uuid UUID, escaped String "
322325
+ ") ENGINE = MergeTree ORDER BY ()");
323326

324327
// Insert random (valid) values
325328
long seed = System.currentTimeMillis();
326329
Random rand = new Random(seed);
327-
log.info("Random seed was: {}", seed);
328330

329331
String str = "string" + rand.nextInt(1000);
330332
String fixed = "fixed" + rand.nextInt(10);
331333
String enum8 = "a";
332334
String enum16 = "b";
333335
String uuid = UUID.randomUUID().toString();
334-
String ipv4 = rand.nextInt(256) + "." + rand.nextInt(256) + "." + rand.nextInt(256) + "." + rand.nextInt(256);
335-
String ipv6 = "2001:adb8:85a3:1:2:8a2e:370:7334";
336336
String escaped = "\\xA3\\xA3\\x12\\xA0\\xDF\\x13\\x4E\\x8C\\x87\\x74\\xD4\\x53\\xDB\\xFC\\x34\\x95";
337337

338338
try (Connection conn = getConnection()) {
339-
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_strings VALUES ( 1, ?, ?, ?, ?, ?, ?, ?, ?, ? )")) {
339+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_strings VALUES ( 1, ?, ?, ?, ?, ?, ?, ? )")) {
340340
stmt.setString(1, str);
341341
stmt.setString(2, fixed);
342342
stmt.setString(3, enum8);
343343
stmt.setString(4, enum8);
344344
stmt.setString(5, enum16);
345345
stmt.setString(6, uuid);
346-
stmt.setString(7, ipv4);
347-
stmt.setString(8, ipv6);
348-
stmt.setString(9, escaped);
346+
stmt.setString(7, escaped);
349347
stmt.executeUpdate();
350348
}
351349
}
@@ -364,15 +362,52 @@ public void testStringTypes() throws SQLException {
364362
assertEquals(rs.getString("enum16"), "b");
365363
assertEquals(rs.getInt("enum16"), 2);
366364
assertEquals(rs.getString("uuid"), uuid);
367-
assertEquals(rs.getString("ipv4"), "/" + ipv4);
368-
assertEquals(rs.getString("ipv6"), "/" + ipv6);
369365
assertEquals(rs.getString("escaped"), escaped);
370366
assertFalse(rs.next());
371367
}
372368
}
373369
}
374370
}
375371

372+
@Test(groups = { "integration" })
373+
public void testIpAddressTypes() throws SQLException, UnknownHostException {
374+
runQuery("CREATE TABLE test_ips (order Int8, "
375+
+ "ipv4_ip IPv4, ipv4_name IPv4, ipv6 IPv6"
376+
+ ") ENGINE = MergeTree ORDER BY ()");
377+
378+
// Insert random (valid) values
379+
long seed = System.currentTimeMillis();
380+
Random rand = new Random(seed);
381+
382+
InetAddress ipv4AddressByIp = Inet4Address.getByName(rand.nextInt(256) + "." + rand.nextInt(256) + "." + rand.nextInt(256) + "." + rand.nextInt(256));
383+
InetAddress ipv4AddressByName = Inet4Address.getByName("www.example.com");
384+
InetAddress ipv6Address = Inet6Address.getByName("2001:adb8:85a3:1:2:8a2e:370:7334");
385+
386+
try (Connection conn = getConnection()) {
387+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_ips VALUES ( 1, ?, ?, ? )")) {
388+
stmt.setObject(1, ipv4AddressByIp);
389+
stmt.setObject(2, ipv4AddressByName);
390+
stmt.setObject(3, ipv6Address);
391+
stmt.executeUpdate();
392+
}
393+
}
394+
395+
// Check the results
396+
try (Connection conn = getConnection()) {
397+
try (Statement stmt = conn.createStatement()) {
398+
try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_ips ORDER BY order")) {
399+
assertTrue(rs.next());
400+
assertEquals(rs.getObject("ipv4_ip"), ipv4AddressByIp);
401+
assertEquals(rs.getString("ipv4_ip"), ipv4AddressByIp.toString());
402+
assertEquals(rs.getObject("ipv4_name"), ipv4AddressByName);
403+
assertEquals(rs.getObject("ipv6"), ipv6Address);
404+
assertEquals(rs.getString("ipv6"), ipv6Address.toString());
405+
assertFalse(rs.next());
406+
}
407+
}
408+
}
409+
}
410+
376411
@Test(groups = { "integration" })
377412
public void testFloatTypes() throws SQLException {
378413
runQuery("CREATE TABLE test_floats (order Int8, "

jdbc-v2/src/test/java/com/clickhouse/jdbc/PreparedStatementTest.java

-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.clickhouse.jdbc;
22

3-
import com.clickhouse.client.api.data_formats.internal.BinaryStreamReader;
43
import org.apache.commons.lang3.RandomStringUtils;
54
import org.testng.annotations.Ignore;
65
import org.testng.annotations.Test;
@@ -10,11 +9,8 @@
109
import java.sql.PreparedStatement;
1110
import java.sql.ResultSet;
1211
import java.sql.Statement;
13-
import java.sql.Timestamp;
1412
import java.sql.Types;
15-
import java.time.ZoneId;
1613
import java.util.Arrays;
17-
import java.util.Calendar;
1814
import java.util.GregorianCalendar;
1915
import java.util.TimeZone;
2016

0 commit comments

Comments
 (0)