From f5ecac8f7cdbffcaa03159646510aecc8d291960 Mon Sep 17 00:00:00 2001 From: Feng Yu Date: Fri, 31 Jan 2025 21:47:38 +0800 Subject: [PATCH] add test for new java.time type support --- .../ClickHouseBinaryFormatReader.java | 10 +-- .../internal/AbstractBinaryFormatReader.java | 47 +++++++---- .../internal/BinaryReaderBackedRecord.java | 10 +++ .../internal/MapBackedRecord.java | 18 +++++ .../client/api/query/GenericRecord.java | 4 + .../clickhouse/client/insert/InsertTests.java | 7 ++ .../clickhouse/client/insert/SamplePOJO.java | 81 ++++++++++++++++++- 7 files changed, 156 insertions(+), 21 deletions(-) diff --git a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/ClickHouseBinaryFormatReader.java b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/ClickHouseBinaryFormatReader.java index b361f34d0..b0edfac56 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/ClickHouseBinaryFormatReader.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/ClickHouseBinaryFormatReader.java @@ -11,11 +11,7 @@ import java.math.BigInteger; import java.net.Inet4Address; import java.net.Inet6Address; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZonedDateTime; +import java.time.*; import java.util.List; import java.util.Map; import java.util.UUID; @@ -535,6 +531,10 @@ public interface ClickHouseBinaryFormatReader extends AutoCloseable { LocalDateTime getLocalDateTime(int index); + OffsetDateTime getOffsetDateTime(String colName); + + OffsetDateTime getOffsetDateTime(int index); + TableSchema getSchema(); ClickHouseBitmap getClickHouseBitmap(String colName); diff --git a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java index cab0afa6f..a3582575f 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java @@ -27,12 +27,7 @@ import java.math.BigInteger; import java.net.Inet4Address; import java.net.Inet6Address; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; +import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; @@ -221,7 +216,7 @@ protected void endReached() { protected void setSchema(TableSchema schema) { this.schema = schema; - this.columns = schema.getColumns().toArray(new ClickHouseColumn[0]); + this.columns = schema.getColumns().toArray(ClickHouseColumn.EMPTY_ARRAY); this.convertions = new Map[columns.length]; for (int i = 0; i < columns.length; i++) { @@ -279,7 +274,7 @@ public String getString(String colName) { ClickHouseDataType dataType = schema.getColumnByName(colName).getDataType(); ZonedDateTime zdt = (ZonedDateTime) value; if (dataType == ClickHouseDataType.Date) { - return zdt.format(com.clickhouse.client.api.DataTypeUtils.DATE_FORMATTER).toString(); + return zdt.format(com.clickhouse.client.api.DataTypeUtils.DATE_FORMATTER); } return value.toString(); } else { @@ -369,11 +364,17 @@ public Instant getInstant(String colName) { return data.atStartOfDay().toInstant(ZoneOffset.UTC); case DateTime: case DateTime64: - LocalDateTime dateTime = readValue(colName); - return dateTime.toInstant(column.getTimeZone().toZoneId().getRules().getOffset(dateTime)); - + Object colValue = readValue(colName); + if (colValue instanceof LocalDateTime) { + LocalDateTime dateTime = (LocalDateTime) colValue; + return dateTime.toInstant(column.getTimeZone().toZoneId().getRules().getOffset(dateTime)); + } else { + ZonedDateTime dateTime = (ZonedDateTime) colValue; + return dateTime.toInstant(); + } + default: + throw new ClientException("Column of type " + column.getDataType() + " cannot be converted to Instant"); } - throw new ClientException("Column of type " + column.getDataType() + " cannot be converted to Instant"); } @Override @@ -386,9 +387,9 @@ public ZonedDateTime getZonedDateTime(String colName) { case Date: case Date32: return readValue(colName); + default: + throw new ClientException("Column of type " + column.getDataType() + " cannot be converted to Instant"); } - - throw new ClientException("Column of type " + column.getDataType() + " cannot be converted to Instant"); } @Override @@ -725,6 +726,24 @@ public LocalDateTime getLocalDateTime(int index) { return (LocalDateTime) value; } + @Override + public OffsetDateTime getOffsetDateTime(String colName) { + Object value = readValue(colName); + if (value instanceof ZonedDateTime) { + return ((ZonedDateTime) value).toOffsetDateTime(); + } + return (OffsetDateTime) value; + } + + @Override + public OffsetDateTime getOffsetDateTime(int index) { + Object value = readValue(index); + if (value instanceof ZonedDateTime) { + return ((ZonedDateTime) value).toOffsetDateTime(); + } + return (OffsetDateTime) value; + } + @Override public ClickHouseBitmap getClickHouseBitmap(String colName) { return readValue(colName); diff --git a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryReaderBackedRecord.java b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryReaderBackedRecord.java index 6ed9cb52b..abf26015e 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryReaderBackedRecord.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryReaderBackedRecord.java @@ -354,6 +354,16 @@ public LocalDateTime getLocalDateTime(int index) { return reader.getLocalDateTime(index); } + @Override + public OffsetDateTime getOffsetDateTime(String colName) { + return reader.getOffsetDateTime(colName); + } + + @Override + public OffsetDateTime getOffsetDateTime(int index) { + return reader.getOffsetDateTime(index); + } + @Override public Object getObject(String colName) { return reader.readValue(colName); diff --git a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/MapBackedRecord.java b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/MapBackedRecord.java index 6c514c4a6..d68267e4e 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/MapBackedRecord.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/MapBackedRecord.java @@ -489,6 +489,24 @@ public LocalDateTime getLocalDateTime(int index) { return (LocalDateTime) value; } + @Override + public OffsetDateTime getOffsetDateTime(String colName) { + Object value = readValue(colName); + if (value instanceof ZonedDateTime) { + return ((ZonedDateTime) value).toOffsetDateTime(); + } + return (OffsetDateTime) value; + } + + @Override + public OffsetDateTime getOffsetDateTime(int index) { + Object value = readValue(index); + if (value instanceof ZonedDateTime) { + return ((ZonedDateTime) value).toOffsetDateTime(); + } + return (OffsetDateTime) value; + } + @Override public ClickHouseBitmap getClickHouseBitmap(String colName) { return readValue(colName); diff --git a/client-v2/src/main/java/com/clickhouse/client/api/query/GenericRecord.java b/client-v2/src/main/java/com/clickhouse/client/api/query/GenericRecord.java index 56f08b3c5..db27d43e1 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/query/GenericRecord.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/query/GenericRecord.java @@ -487,6 +487,10 @@ public interface GenericRecord { LocalDateTime getLocalDateTime(int index); + OffsetDateTime getOffsetDateTime(String colName); + + OffsetDateTime getOffsetDateTime(int index); + Object getObject(String colName); Object getObject(int index); diff --git a/client-v2/src/test/java/com/clickhouse/client/insert/InsertTests.java b/client-v2/src/test/java/com/clickhouse/client/insert/InsertTests.java index a7fb4e43e..c67272a7c 100644 --- a/client-v2/src/test/java/com/clickhouse/client/insert/InsertTests.java +++ b/client-v2/src/test/java/com/clickhouse/client/insert/InsertTests.java @@ -43,6 +43,7 @@ import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.temporal.ChronoField; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -207,6 +208,12 @@ public void insertPOJOAndReadBack() throws Exception { Assert.assertEquals(reader.getDouble("float64"), pojo.getFloat64()); Assert.assertEquals(reader.getString("string"), pojo.getString()); Assert.assertEquals(reader.getString("fixedString"), pojo.getFixedString()); + Assert.assertTrue(reader.getZonedDateTime("zonedDateTime").isEqual(pojo.getZonedDateTime().withNano(0))); + Assert.assertTrue(reader.getZonedDateTime("zonedDateTime64").isEqual(pojo.getZonedDateTime64())); + Assert.assertTrue(reader.getOffsetDateTime("offsetDateTime").isEqual(pojo.getOffsetDateTime().withNano(0))); + Assert.assertTrue(reader.getOffsetDateTime("offsetDateTime64").isEqual(pojo.getOffsetDateTime64())); + Assert.assertEquals(reader.getInstant("instant"), pojo.getInstant().with(ChronoField.MICRO_OF_SECOND, 0)); + Assert.assertEquals(reader.getInstant("instant64"), pojo.getInstant64()); } } diff --git a/client-v2/src/test/java/com/clickhouse/client/insert/SamplePOJO.java b/client-v2/src/test/java/com/clickhouse/client/insert/SamplePOJO.java index 9a55e823b..699a7bbcc 100644 --- a/client-v2/src/test/java/com/clickhouse/client/insert/SamplePOJO.java +++ b/client-v2/src/test/java/com/clickhouse/client/insert/SamplePOJO.java @@ -8,8 +8,7 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.UnknownHostException; -import java.time.LocalDate; -import java.time.LocalDateTime; +import java.time.*; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -67,6 +66,15 @@ public class SamplePOJO { private LocalDateTime dateTime; private LocalDateTime dateTime64; + private ZonedDateTime zonedDateTime; + private ZonedDateTime zonedDateTime64; + + private OffsetDateTime offsetDateTime; + private OffsetDateTime offsetDateTime64; + + private Instant instant; + private Instant instant64; + private UUID uuid; private byte enum8; @@ -140,6 +148,15 @@ public SamplePOJO() { dateTime = LocalDateTime.now(); dateTime64 = LocalDateTime.now(); + zonedDateTime = ZonedDateTime.now(); + zonedDateTime64 = ZonedDateTime.now(); + + offsetDateTime = OffsetDateTime.now(); + offsetDateTime64 = OffsetDateTime.now(); + + instant = Instant.now(); + instant64 = Instant.now(); + uuid = UUID.randomUUID(); enum8 = (byte) random.nextInt(27); @@ -474,6 +491,54 @@ public void setDateTime64(LocalDateTime dateTime64) { this.dateTime64 = dateTime64; } + public ZonedDateTime getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(ZonedDateTime zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } + + public ZonedDateTime getZonedDateTime64() { + return zonedDateTime64; + } + + public void setZonedDateTime64(ZonedDateTime zonedDateTime64) { + this.zonedDateTime64 = zonedDateTime64; + } + + public OffsetDateTime getOffsetDateTime() { + return offsetDateTime; + } + + public void setOffsetDateTime(OffsetDateTime offsetDateTime) { + this.offsetDateTime = offsetDateTime; + } + + public OffsetDateTime getOffsetDateTime64() { + return offsetDateTime64; + } + + public void setOffsetDateTime64(OffsetDateTime offsetDateTime64) { + this.offsetDateTime64 = offsetDateTime64; + } + + public Instant getInstant() { + return instant; + } + + public void setInstant(Instant instant) { + this.instant = instant; + } + + public Instant getInstant64() { + return instant64; + } + + public void setInstant64(Instant instant64) { + this.instant64 = instant64; + } + public UUID getUuid() { return uuid; } @@ -628,6 +693,12 @@ public String toString() { ", date32=" + date32 + ", dateTime=" + dateTime + ", dateTime64=" + dateTime64 + + ", zonedDateTime=" + zonedDateTime + + ", zonedDateTime64=" + zonedDateTime64 + + ", offsetDateTime=" + offsetDateTime + + ", offsetDateTime64=" + offsetDateTime64 + + ", instant=" + instant + + ", instant64=" + instant64 + ", uuid=" + uuid + ", enum8=" + enum8 + ", enum16=" + enum16 + @@ -684,6 +755,12 @@ public static String generateTableCreateSQL(String tableName) { "date32 Date, " + "dateTime DateTime, " + "dateTime64 DateTime64(3), " + + "zonedDateTime DateTime, " + + "zonedDateTime64 DateTime64(9), " + + "offsetDateTime DateTime, " + + "offsetDateTime64 DateTime64(9), " + + "instant DateTime, " + + "instant64 DateTime64(9), " + "uuid UUID, " + "enum8 Enum8('a' = 1, 'b' = 2, 'c' = 3, 'd' = 4, 'e' = 5, 'f' = 6, 'g' = 7, 'h' = 8, 'i' = 9, 'j' = 10, 'k' = 11, 'l' = 12, 'm' = 13, 'n' = 14, 'o' = 15, 'p' = 16, 'q' = 17, 'r' = 18, 's' = 19, 't' = 20, 'u' = 21, 'v' = 22, 'w' = 23, 'x' = 24, 'y' = 25, 'z' = 26), " + "enum16 Enum16('a' = 1, 'b' = 2, 'c' = 3, 'd' = 4, 'e' = 5, 'f' = 6, 'g' = 7, 'h' = 8, 'i' = 9, 'j' = 10, 'k' = 11, 'l' = 12, 'm' = 13, 'n' = 14, 'o' = 15, 'p' = 16, 'q' = 17, 'r' = 18, 's' = 19, 't' = 20, 'u' = 21, 'v' = 22, 'w' = 23, 'x' = 24, 'y' = 25, 'z' = 26), " +