Skip to content

Commit 2309e9c

Browse files
committed
Same behavior between V1 and V2
1 parent d8ef304 commit 2309e9c

File tree

7 files changed

+52
-60
lines changed

7 files changed

+52
-60
lines changed

clickhouse-jdbc/src/test/java/com/clickhouse/jdbc/comparison/DateTimeComparisonTest.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.sql.ResultSet;
1616
import java.sql.SQLException;
1717
import java.sql.Statement;
18+
import java.sql.Timestamp;
1819
import java.util.GregorianCalendar;
1920
import java.util.Properties;
2021
import java.util.TimeZone;
@@ -133,13 +134,16 @@ public void setTimeTest() throws SQLException {
133134
@Test (groups = "integration", enabled = true)
134135
public void setTimestampTest() throws SQLException {
135136
run("DROP TABLE IF EXISTS test_timestamp");
136-
run("CREATE TABLE IF NOT EXISTS test_timestamp (id Int8, t1 Datetime64(3), t2 Datetime64(6), t3 Datetime64(9)) ENGINE = MergeTree ORDER BY id");
137+
run("CREATE TABLE IF NOT EXISTS test_timestamp (id Int8, t1 Datetime64(3), t2 Datetime64(6), t3 Datetime64(9), t4 DateTime64(9)) ENGINE = MergeTree ORDER BY id");
138+
139+
Timestamp ts = new Timestamp(System.currentTimeMillis());
137140

138141
try (Connection connV1 = getJdbcConnectionV1(null)) {
139-
try (PreparedStatement stmtV1 = connV1.prepareStatement("INSERT INTO test_timestamp VALUES (1, ?, ?, ?)")) {//INSERT with V1
142+
try (PreparedStatement stmtV1 = connV1.prepareStatement("INSERT INTO test_timestamp VALUES (1, ?, ?, ?, ?)")) {//INSERT with V1
140143
stmtV1.setTimestamp(1, java.sql.Timestamp.valueOf("2021-01-01 01:23:45"));
141144
stmtV1.setTimestamp(2, java.sql.Timestamp.valueOf("2021-01-01 01:23:45"), new GregorianCalendar());
142145
stmtV1.setTimestamp(3, java.sql.Timestamp.valueOf("2021-01-01 01:23:45"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
146+
stmtV1.setTimestamp(4, ts);
143147
stmtV1.execute();
144148
}
145149
}
@@ -157,6 +161,7 @@ public void setTimestampTest() throws SQLException {
157161
assertEquals(rsV2.getTimestamp(3, new GregorianCalendar()), rsV1.getTimestamp(3, new GregorianCalendar()));
158162
assertEquals(rsV2.getTimestamp(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))),
159163
rsV1.getTimestamp(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))));
164+
assertEquals(rsV2.getTimestamp(5), rsV1.getTimestamp(5));
160165
}
161166
}
162167
}

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

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.sql.ShardingKey;
3131
import java.sql.Statement;
3232
import java.sql.Struct;
33+
import java.util.Calendar;
3334
import java.util.HashSet;
3435
import java.util.List;
3536
import java.util.Map;
@@ -52,6 +53,7 @@ public class ConnectionImpl implements Connection, JdbcV2Wrapper {
5253
private QuerySettings defaultQuerySettings;
5354

5455
private final com.clickhouse.jdbc.metadata.DatabaseMetaData metadata;
56+
protected final Calendar defaultCalendar;
5557

5658
public ConnectionImpl(String url, Properties info) throws SQLException {
5759
try {
@@ -80,6 +82,7 @@ public ConnectionImpl(String url, Properties info) throws SQLException {
8082
.serverSetting(ServerSettings.WAIT_END_OF_QUERY, "0");
8183

8284
this.metadata = new com.clickhouse.jdbc.metadata.DatabaseMetaData(this, false, url);
85+
this.defaultCalendar = Calendar.getInstance();
8386
} catch (SQLException e) {
8487
throw e;
8588
} catch (Exception e) {

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

+7-14
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import java.util.Collection;
4242
import java.util.GregorianCalendar;
4343
import java.util.Map;
44-
import java.util.TimeZone;
4544

4645
public class PreparedStatementImpl extends StatementImpl implements PreparedStatement, JdbcV2Wrapper {
4746
private static final Logger LOG = LoggerFactory.getLogger(PreparedStatementImpl.class);
@@ -52,6 +51,8 @@ public class PreparedStatementImpl extends StatementImpl implements PreparedStat
5251
public static final DateTimeFormatter DATETIME_FORMATTER = new DateTimeFormatterBuilder()
5352
.appendPattern("yyyy-MM-dd HH:mm:ss").appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true).toFormatter();
5453

54+
private final Calendar defaultCalendar;
55+
5556
String originalSql;
5657
String [] sqlSegments;
5758
Object [] parameters;
@@ -68,6 +69,8 @@ public PreparedStatementImpl(ConnectionImpl connection, String sql) throws SQLEx
6869
} else {
6970
this.parameters = new Object[0];
7071
}
72+
73+
this.defaultCalendar = connection.defaultCalendar;
7174
}
7275

7376
private String compileSql() {
@@ -268,12 +271,8 @@ public ResultSetMetaData getMetaData() throws SQLException {
268271
@Override
269272
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
270273
checkClosed();
271-
if (cal == null) {
272-
cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));//This says whatever date is in UTC
273-
}
274-
275274
LocalDate d = x.toLocalDate();
276-
Calendar c = (Calendar) cal.clone();
275+
Calendar c = (Calendar) (cal != null ? cal : defaultCalendar).clone();
277276
c.clear();
278277
c.set(d.getYear(), d.getMonthValue() - 1, d.getDayOfMonth(), 0, 0, 0);
279278
parameters[parameterIndex - 1] = encodeObject(c.toInstant());
@@ -282,12 +281,9 @@ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLExceptio
282281
@Override
283282
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
284283
checkClosed();
285-
if (cal == null) {
286-
cal = new GregorianCalendar();
287-
}
288284

289285
LocalTime t = x.toLocalTime();
290-
Calendar c = (Calendar) cal.clone();
286+
Calendar c = (Calendar) (cal != null ? cal : defaultCalendar).clone();
291287
c.clear();
292288
c.set(1970, Calendar.JANUARY, 1, t.getHour(), t.getMinute(), t.getSecond());
293289
parameters[parameterIndex - 1] = encodeObject(c.toInstant());
@@ -296,12 +292,9 @@ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLExceptio
296292
@Override
297293
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
298294
checkClosed();
299-
if (cal == null) {
300-
cal = new GregorianCalendar();
301-
}
302295

303296
LocalDateTime ldt = x.toLocalDateTime();
304-
Calendar c = (Calendar) cal.clone();
297+
Calendar c = (Calendar) (cal != null ? cal : defaultCalendar).clone();
305298
c.clear();
306299
c.set(ldt.getYear(), ldt.getMonthValue() - 1, ldt.getDayOfMonth(), ldt.getHour(), ldt.getMinute(), ldt.getSecond());
307300
parameters[parameterIndex - 1] = encodeObject(c.toInstant().atZone(ZoneId.of("UTC")).withNano(x.getNanos()));

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

+2-9
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
package com.clickhouse.jdbc;
22

33
import java.io.ByteArrayInputStream;
4-
import java.io.CharArrayReader;
54
import java.io.InputStream;
65
import java.io.Reader;
76
import java.io.StringReader;
87
import java.math.BigDecimal;
9-
import java.net.MalformedURLException;
108
import java.net.URL;
119
import java.nio.charset.StandardCharsets;
1210
import java.sql.*;
13-
import java.time.LocalDate;
14-
import java.time.LocalDateTime;
15-
import java.time.LocalTime;
16-
import java.time.ZoneId;
1711
import java.time.ZonedDateTime;
1812
import java.util.Calendar;
1913
import java.util.GregorianCalendar;
2014
import java.util.Map;
21-
import java.util.TimeZone;
2215

2316
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
2417
import com.clickhouse.client.api.metadata.TableSchema;
@@ -47,7 +40,7 @@ public ResultSetImpl(StatementImpl parentStatement, QueryResponse response, Clic
4740
this.metaData = new com.clickhouse.jdbc.metadata.ResultSetMetaData(this);
4841
this.closed = false;
4942
this.wasNull = false;
50-
this.defaultCalendar = new GregorianCalendar();
43+
this.defaultCalendar = parentStatement.connection.defaultCalendar;
5144
}
5245

5346
protected ResultSetImpl(ResultSetImpl resultSet) {
@@ -57,7 +50,7 @@ protected ResultSetImpl(ResultSetImpl resultSet) {
5750
this.metaData = resultSet.metaData;
5851
this.closed = false;
5952
this.wasNull = false;
60-
this.defaultCalendar = new GregorianCalendar();
53+
this.defaultCalendar = parentStatement.connection.defaultCalendar;
6154
}
6255

6356
private void checkClosed() throws SQLException {

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

+20-20
Original file line numberDiff line numberDiff line change
@@ -283,29 +283,29 @@ public void testDateTypes() throws SQLException {
283283
assertTrue(rs.next());
284284
assertEquals(rs.getDate("date"), Date.valueOf("1970-01-01"));
285285
assertEquals(rs.getDate("date32"), Date.valueOf("1970-01-01"));
286-
assertEquals(rs.getTimestamp("dateTime").toInstant().toString(), "1970-01-01T00:00:00Z");
287-
assertEquals(rs.getTimestamp("dateTime32").toInstant().toString(), "1970-01-01T00:00:00Z");
288-
assertEquals(rs.getTimestamp("dateTime643").toInstant().toString(), "1970-01-01T00:00:00Z");
289-
assertEquals(rs.getTimestamp("dateTime646").toInstant().toString(), "1970-01-01T00:00:00Z");
290-
assertEquals(rs.getTimestamp("dateTime649").toInstant().toString(), "1970-01-01T00:00:00Z");
286+
assertEquals(rs.getTimestamp("dateTime").toString(), "1970-01-01 00:00:00.0");
287+
assertEquals(rs.getTimestamp("dateTime32").toString(), "1970-01-01 00:00:00.0");
288+
assertEquals(rs.getTimestamp("dateTime643").toString(), "1970-01-01 00:00:00.0");
289+
assertEquals(rs.getTimestamp("dateTime646").toString(), "1970-01-01 00:00:00.0");
290+
assertEquals(rs.getTimestamp("dateTime649").toString(), "1970-01-01 00:00:00.0");
291291

292292
assertTrue(rs.next());
293293
assertEquals(rs.getDate("date"), Date.valueOf("2149-06-06"));
294294
assertEquals(rs.getDate("date32"), Date.valueOf("2299-12-31"));
295-
assertEquals(rs.getTimestamp("dateTime").toInstant().toString(), "2106-02-07T06:28:15Z");
296-
assertEquals(rs.getTimestamp("dateTime32").toInstant().toString(), "2106-02-07T06:28:15Z");
297-
assertEquals(rs.getTimestamp("dateTime643").toInstant().toString(), "2261-12-31T23:59:59.999Z");
298-
assertEquals(rs.getTimestamp("dateTime646").toInstant().toString(), "2261-12-31T23:59:59.999999Z");
299-
assertEquals(rs.getTimestamp("dateTime649").toInstant().toString(), "2261-12-31T23:59:59.999999999Z");
295+
assertEquals(rs.getTimestamp("dateTime").toString(), "2106-02-07 06:28:15.0");
296+
assertEquals(rs.getTimestamp("dateTime32").toString(), "2106-02-07 06:28:15.0");
297+
assertEquals(rs.getTimestamp("dateTime643").toString(), "2261-12-31 23:59:59.999");
298+
assertEquals(rs.getTimestamp("dateTime646").toString(), "2261-12-31 23:59:59.999999");
299+
assertEquals(rs.getTimestamp("dateTime649").toString(), "2261-12-31 23:59:59.999999999");
300300

301301
assertTrue(rs.next());
302302
assertEquals(rs.getDate("date").toString(), date.toString());
303303
assertEquals(rs.getDate("date32").toString(), date32.toString());
304-
assertEquals(rs.getTimestamp("dateTime").toString(), dateTime.toString());
305-
assertEquals(rs.getTimestamp("dateTime32").toString(), dateTime32.toString());
306-
assertEquals(rs.getTimestamp("dateTime643").toString(), dateTime643.toString());
307-
assertEquals(rs.getTimestamp("dateTime646").toString(), dateTime646.toString());
308-
assertEquals(rs.getTimestamp("dateTime649").toString(), dateTime649.toString());
304+
assertEquals(rs.getTimestamp("dateTime", new GregorianCalendar(TimeZone.getTimeZone("UTC"))).toString(), dateTime.toString());
305+
assertEquals(rs.getTimestamp("dateTime32", new GregorianCalendar(TimeZone.getTimeZone("UTC"))).toString(), dateTime32.toString());
306+
assertEquals(rs.getTimestamp("dateTime643", new GregorianCalendar(TimeZone.getTimeZone("UTC"))).toString(), dateTime643.toString());
307+
assertEquals(rs.getTimestamp("dateTime646", new GregorianCalendar(TimeZone.getTimeZone("UTC"))).toString(), dateTime646.toString());
308+
assertEquals(rs.getTimestamp("dateTime649", new GregorianCalendar(TimeZone.getTimeZone("UTC"))).toString(), dateTime649.toString());
309309

310310
assertFalse(rs.next());
311311
}
@@ -887,37 +887,37 @@ public void testTypeConversions() throws Exception {
887887
assertEquals(rs.getObject(3, Double.class), 1.0);
888888
assertEquals(String.valueOf(rs.getObject(3, new HashMap<String, Class<?>>(){{put(JDBCType.FLOAT.getName(), Float.class);}})), "1.0");
889889

890-
assertEquals(rs.getDate(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))), Date.valueOf("2024-12-01"));
890+
assertEquals(rs.getDate(4), Date.valueOf("2024-12-01"));
891891
assertTrue(rs.getObject(4) instanceof Date);
892892
assertEquals(rs.getObject(4), Date.valueOf("2024-12-01"));
893893
assertEquals(rs.getString(4), "2024-12-01");//Underlying object is ZonedDateTime
894894
assertEquals(rs.getObject(4, LocalDate.class), LocalDate.of(2024, 12, 1));
895895
assertEquals(rs.getObject(4, ZonedDateTime.class), ZonedDateTime.of(2024, 12, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
896896
assertEquals(String.valueOf(rs.getObject(4, new HashMap<String, Class<?>>(){{put(JDBCType.DATE.getName(), LocalDate.class);}})), "2024-12-01");
897897

898-
assertEquals(rs.getTimestamp(5).toInstant().toString(), "2024-12-01T12:34:56Z");
898+
assertEquals(rs.getTimestamp(5).toString(), "2024-12-01 12:34:56.0");
899899
assertTrue(rs.getObject(5) instanceof Timestamp);
900900
assertEquals(rs.getObject(5), Timestamp.valueOf("2024-12-01 12:34:56"));
901901
assertEquals(rs.getString(5), "2024-12-01T12:34:56Z[UTC]");
902902
assertEquals(rs.getObject(5, LocalDateTime.class), LocalDateTime.of(2024, 12, 1, 12, 34, 56));
903903
assertEquals(rs.getObject(5, ZonedDateTime.class), ZonedDateTime.of(2024, 12, 1, 12, 34, 56, 0, ZoneId.of("UTC")));
904904
assertEquals(String.valueOf(rs.getObject(5, new HashMap<String, Class<?>>(){{put(JDBCType.TIMESTAMP.getName(), LocalDateTime.class);}})), "2024-12-01T12:34:56");
905905

906-
assertEquals(rs.getTimestamp(6).toInstant().toString(), "2024-12-01T12:34:56.789Z");
906+
assertEquals(rs.getTimestamp(6).toString(), "2024-12-01 12:34:56.789");
907907
assertTrue(rs.getObject(6) instanceof Timestamp);
908908
assertEquals(rs.getObject(6), Timestamp.valueOf("2024-12-01 12:34:56.789"));
909909
assertEquals(rs.getString(6), "2024-12-01T12:34:56.789Z[UTC]");
910910
assertEquals(rs.getObject(6, LocalDateTime.class), LocalDateTime.of(2024, 12, 1, 12, 34, 56, 789000000));
911911
assertEquals(String.valueOf(rs.getObject(6, new HashMap<String, Class<?>>(){{put(JDBCType.TIMESTAMP.getName(), LocalDateTime.class);}})), "2024-12-01T12:34:56.789");
912912

913-
assertEquals(rs.getTimestamp(7).toInstant().toString(), "2024-12-01T12:34:56.789789Z");
913+
assertEquals(rs.getTimestamp(7).toString(), "2024-12-01 12:34:56.789789");
914914
assertTrue(rs.getObject(7) instanceof Timestamp);
915915
assertEquals(rs.getObject(7), Timestamp.valueOf("2024-12-01 12:34:56.789789"));
916916
assertEquals(rs.getString(7), "2024-12-01T12:34:56.789789Z[UTC]");
917917
assertEquals(rs.getObject(7, LocalDateTime.class), LocalDateTime.of(2024, 12, 1, 12, 34, 56, 789789000));
918918
assertEquals(String.valueOf(rs.getObject(7, new HashMap<String, Class<?>>(){{put(JDBCType.TIMESTAMP.getName(), OffsetDateTime.class);}})), "2024-12-01T12:34:56.789789Z");
919919

920-
assertEquals(rs.getTimestamp(8).toInstant().toString(), "2024-12-01T12:34:56.789789789Z");
920+
assertEquals(rs.getTimestamp(8).toString(), "2024-12-01 12:34:56.789789789");
921921
assertTrue(rs.getObject(8) instanceof Timestamp);
922922
assertEquals(rs.getObject(8), Timestamp.valueOf("2024-12-01 12:34:56.789789789"));
923923
assertEquals(rs.getString(8), "2024-12-01T12:34:56.789789789Z[UTC]");

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

+5-7
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,10 @@ public void testSetBytes() throws Exception {
170170
public void testSetDate() throws Exception {
171171
try (Connection conn = getJdbcConnection()) {
172172
try (PreparedStatement stmt = conn.prepareStatement("SELECT toDate(?)")) {
173-
stmt.setDate(1, java.sql.Date.valueOf("2021-01-01"));
173+
stmt.setDate(1, java.sql.Date.valueOf("2021-01-01"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
174174
try (ResultSet rs = stmt.executeQuery()) {
175175
assertTrue(rs.next());
176-
assertEquals(rs.getDate(1, new GregorianCalendar(TimeZone.getTimeZone("UTC"))), java.sql.Date.valueOf("2021-01-01"));
176+
assertEquals(rs.getDate(1), java.sql.Date.valueOf("2021-01-01"));
177177
assertFalse(rs.next());
178178
}
179179
}
@@ -184,7 +184,7 @@ public void testSetDate() throws Exception {
184184
public void testSetTime() throws Exception {
185185
try (Connection conn = getJdbcConnection()) {
186186
try (PreparedStatement stmt = conn.prepareStatement("SELECT toDateTime(?)")) {
187-
stmt.setTime(1, java.sql.Time.valueOf("12:34:56"));
187+
stmt.setTime(1, java.sql.Time.valueOf("12:34:56"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
188188
try (ResultSet rs = stmt.executeQuery()) {
189189
assertTrue(rs.next());
190190
assertEquals(rs.getTime(1).toString(), "12:34:56");
@@ -197,13 +197,11 @@ public void testSetTime() throws Exception {
197197
@Test(groups = { "integration" })
198198
public void testSetTimestamp() throws Exception {
199199
try (Connection conn = getJdbcConnection()) {
200-
try (PreparedStatement stmt = conn.prepareStatement("SELECT toDateTime64(?, 3), toDateTime64(?, 3)")) {
201-
stmt.setTimestamp(1, java.sql.Timestamp.valueOf("2021-01-01 01:34:56.456"));
202-
stmt.setTimestamp(2, java.sql.Timestamp.valueOf("2021-01-01 01:34:56.456"), java.util.Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC")));
200+
try (PreparedStatement stmt = conn.prepareStatement("SELECT toDateTime64(?, 3)")) {
201+
stmt.setTimestamp(1, java.sql.Timestamp.valueOf("2021-01-01 01:34:56.456"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
203202
try (ResultSet rs = stmt.executeQuery()) {
204203
assertTrue(rs.next());
205204
assertEquals(rs.getTimestamp(1).toString(), "2021-01-01 01:34:56.456");
206-
assertEquals(rs.getTimestamp(2, java.util.Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC"))).toString(), "2021-01-01 01:34:56.456");
207205
assertFalse(rs.next());
208206
}
209207
}

0 commit comments

Comments
 (0)