Skip to content

Commit d8ef304

Browse files
author
Paultagoras
committed
Changing the default calendar back and adding a comparison test
1 parent 01a06c3 commit d8ef304

File tree

2 files changed

+180
-17
lines changed

2 files changed

+180
-17
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package com.clickhouse.jdbc.comparison;
2+
3+
import com.clickhouse.client.ClickHouseProtocol;
4+
import com.clickhouse.client.ClickHouseServerForTest;
5+
import com.clickhouse.client.api.ClientConfigProperties;
6+
import com.clickhouse.jdbc.ConnectionImpl;
7+
import com.clickhouse.jdbc.JdbcIntegrationTest;
8+
import com.clickhouse.jdbc.internal.ClickHouseConnectionImpl;
9+
import org.testng.Assert;
10+
import org.testng.annotations.Test;
11+
12+
import java.sql.Connection;
13+
import java.sql.Date;
14+
import java.sql.PreparedStatement;
15+
import java.sql.ResultSet;
16+
import java.sql.SQLException;
17+
import java.sql.Statement;
18+
import java.util.GregorianCalendar;
19+
import java.util.Properties;
20+
import java.util.TimeZone;
21+
22+
import static org.testng.Assert.assertEquals;
23+
import static org.testng.Assert.assertFalse;
24+
import static org.testng.Assert.assertThrows;
25+
import static org.testng.Assert.assertTrue;
26+
27+
public class DateTimeComparisonTest extends JdbcIntegrationTest {
28+
public Connection getJdbcConnectionV1(Properties properties) throws SQLException {
29+
Properties info = new Properties();
30+
info.setProperty("user", "default");
31+
info.setProperty("password", ClickHouseServerForTest.getPassword());
32+
info.setProperty("database", ClickHouseServerForTest.getDatabase());
33+
34+
if (properties != null) {
35+
info.putAll(properties);
36+
}
37+
38+
return new ClickHouseConnectionImpl(getJDBCEndpointString(), info);
39+
}
40+
41+
public Connection getJdbcConnectionV2(Properties properties) throws SQLException {
42+
Properties info = new Properties();
43+
info.setProperty("user", "default");
44+
info.setProperty("password", ClickHouseServerForTest.getPassword());
45+
info.setProperty("database", ClickHouseServerForTest.getDatabase());
46+
47+
if (properties != null) {
48+
info.putAll(properties);
49+
}
50+
51+
info.setProperty(ClientConfigProperties.DATABASE.getKey(), ClickHouseServerForTest.getDatabase());
52+
53+
return new ConnectionImpl(getJDBCEndpointString(), info);
54+
}
55+
56+
public String getJDBCEndpointString() {
57+
return "jdbc:ch:" + (isCloud() ? "" : "http://") +
58+
ClickHouseServerForTest.getClickHouseAddress(ClickHouseProtocol.HTTP, false) + "/" + (isCloud() ? ClickHouseServerForTest.getDatabase() : "");
59+
}
60+
61+
private void run(String query) throws SQLException {
62+
try (Connection connection = getJdbcConnectionV2(null)) {
63+
try (Statement stmt = connection.createStatement()) {
64+
stmt.execute("CREATE DATABASE IF NOT EXISTS " + ClickHouseServerForTest.getDatabase());
65+
stmt.execute(query);
66+
}
67+
}
68+
}
69+
70+
@Test (groups = "integration", enabled = true)
71+
public void setDateTest() throws SQLException {
72+
run("DROP TABLE IF EXISTS test_date");
73+
run("CREATE TABLE IF NOT EXISTS test_date (id Int8, d1 Date, d2 Date, d3 Date) ENGINE = MergeTree ORDER BY id");
74+
75+
try (Connection connV1 = getJdbcConnectionV1(null)) {
76+
try (PreparedStatement stmtV1 = connV1.prepareStatement("INSERT INTO test_date VALUES (1, ?, ?, ?)")) {//INSERT with V1
77+
stmtV1.setDate(1, java.sql.Date.valueOf("2021-01-01"));
78+
stmtV1.setDate(2, java.sql.Date.valueOf("2021-01-01"), new GregorianCalendar());
79+
stmtV1.setDate(3, java.sql.Date.valueOf("2021-01-01"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
80+
stmtV1.execute();
81+
}
82+
}
83+
84+
try (Connection connV1 = getJdbcConnectionV1(null);
85+
Connection connV2 = getJdbcConnectionV2(null)) {
86+
try (Statement stmtV1 = connV1.createStatement();
87+
Statement stmtV2 = connV2.createStatement()) {
88+
ResultSet rsV1 = stmtV1.executeQuery("SELECT * FROM test_date");
89+
ResultSet rsV2 = stmtV2.executeQuery("SELECT * FROM test_date");
90+
assertTrue(rsV1.next());
91+
assertTrue(rsV2.next());
92+
93+
assertEquals(rsV2.getDate(2), rsV1.getDate(2));
94+
assertEquals(rsV2.getDate(3, new GregorianCalendar()), rsV1.getDate(3, new GregorianCalendar()));
95+
assertEquals(rsV2.getDate(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))),
96+
rsV1.getDate(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))));
97+
}
98+
}
99+
}
100+
101+
102+
@Test (groups = "integration", enabled = true)
103+
public void setTimeTest() throws SQLException {
104+
run("DROP TABLE IF EXISTS test_time");
105+
run("CREATE TABLE IF NOT EXISTS test_time (id Int8, t1 Datetime, t2 Datetime, t3 Datetime) ENGINE = MergeTree ORDER BY id");
106+
107+
try (Connection connV1 = getJdbcConnectionV1(null)) {
108+
try (PreparedStatement stmtV1 = connV1.prepareStatement("INSERT INTO test_time VALUES (1, ?, ?, ?)")) {//INSERT with V1
109+
stmtV1.setTime(1, java.sql.Time.valueOf("12:34:56"));
110+
stmtV1.setTime(2, java.sql.Time.valueOf("12:34:56"), new GregorianCalendar());
111+
stmtV1.setTime(3, java.sql.Time.valueOf("12:34:56"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
112+
stmtV1.execute();
113+
}
114+
}
115+
116+
try (Connection connV1 = getJdbcConnectionV1(null);
117+
Connection connV2 = getJdbcConnectionV2(null)) {
118+
try (Statement stmtV1 = connV1.createStatement();
119+
Statement stmtV2 = connV2.createStatement()) {
120+
ResultSet rsV1 = stmtV1.executeQuery("SELECT * FROM test_time");
121+
ResultSet rsV2 = stmtV2.executeQuery("SELECT * FROM test_time");
122+
assertTrue(rsV1.next());
123+
assertTrue(rsV2.next());
124+
125+
assertEquals(rsV2.getTime(2), rsV1.getTime(2));
126+
assertEquals(rsV2.getTime(3, new GregorianCalendar()), rsV1.getTime(3, new GregorianCalendar()));
127+
assertEquals(rsV2.getTime(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))),
128+
rsV1.getTime(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))));
129+
}
130+
}
131+
}
132+
133+
@Test (groups = "integration", enabled = true)
134+
public void setTimestampTest() throws SQLException {
135+
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+
138+
try (Connection connV1 = getJdbcConnectionV1(null)) {
139+
try (PreparedStatement stmtV1 = connV1.prepareStatement("INSERT INTO test_timestamp VALUES (1, ?, ?, ?)")) {//INSERT with V1
140+
stmtV1.setTimestamp(1, java.sql.Timestamp.valueOf("2021-01-01 01:23:45"));
141+
stmtV1.setTimestamp(2, java.sql.Timestamp.valueOf("2021-01-01 01:23:45"), new GregorianCalendar());
142+
stmtV1.setTimestamp(3, java.sql.Timestamp.valueOf("2021-01-01 01:23:45"), new GregorianCalendar(TimeZone.getTimeZone("UTC")));
143+
stmtV1.execute();
144+
}
145+
}
146+
147+
try (Connection connV1 = getJdbcConnectionV1(null);
148+
Connection connV2 = getJdbcConnectionV2(null)) {
149+
try (Statement stmtV1 = connV1.createStatement();
150+
Statement stmtV2 = connV2.createStatement()) {
151+
ResultSet rsV1 = stmtV1.executeQuery("SELECT * FROM test_timestamp");
152+
ResultSet rsV2 = stmtV2.executeQuery("SELECT * FROM test_timestamp");
153+
assertTrue(rsV1.next());
154+
assertTrue(rsV2.next());
155+
156+
assertEquals(rsV2.getTimestamp(2), rsV1.getTimestamp(2));
157+
assertEquals(rsV2.getTimestamp(3, new GregorianCalendar()), rsV1.getTimestamp(3, new GregorianCalendar()));
158+
assertEquals(rsV2.getTimestamp(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))),
159+
rsV1.getTimestamp(4, new GregorianCalendar(TimeZone.getTimeZone("UTC"))));
160+
}
161+
}
162+
}
163+
}

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class ResultSetImpl implements ResultSet, JdbcV2Wrapper {
3838
private boolean closed;
3939
private final StatementImpl parentStatement;
4040
private boolean wasNull;
41+
private final Calendar defaultCalendar;
4142

4243
public ResultSetImpl(StatementImpl parentStatement, QueryResponse response, ClickHouseBinaryFormatReader reader) {
4344
this.parentStatement = parentStatement;
@@ -46,6 +47,7 @@ public ResultSetImpl(StatementImpl parentStatement, QueryResponse response, Clic
4647
this.metaData = new com.clickhouse.jdbc.metadata.ResultSetMetaData(this);
4748
this.closed = false;
4849
this.wasNull = false;
50+
this.defaultCalendar = new GregorianCalendar();
4951
}
5052

5153
protected ResultSetImpl(ResultSetImpl resultSet) {
@@ -55,6 +57,7 @@ protected ResultSetImpl(ResultSetImpl resultSet) {
5557
this.metaData = resultSet.metaData;
5658
this.closed = false;
5759
this.wasNull = false;
60+
this.defaultCalendar = new GregorianCalendar();
5861
}
5962

6063
private void checkClosed() throws SQLException {
@@ -1052,11 +1055,10 @@ public Date getDate(String columnLabel, Calendar cal) throws SQLException {
10521055
}
10531056
wasNull = false;
10541057

1055-
if (cal == null) {
1056-
cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));//Default to UTC
1057-
}
1058-
1059-
return Date.valueOf(zdt.withZoneSameInstant(cal.getTimeZone().toZoneId()).toLocalDate());
1058+
Calendar c = (Calendar) (cal != null ? cal : defaultCalendar).clone();
1059+
c.clear();
1060+
c.set(zdt.getYear(), zdt.getMonthValue() - 1, zdt.getDayOfMonth(), 0, 0, 0);
1061+
return new Date(c.getTimeInMillis());
10601062
} catch (Exception e) {
10611063
throw ExceptionUtils.toSqlState(String.format("Method: getDate(\"%s\") encountered an exception.", columnLabel), String.format("SQL: [%s]", parentStatement.getLastSql()), e);
10621064
}
@@ -1078,11 +1080,10 @@ public Time getTime(String columnLabel, Calendar cal) throws SQLException {
10781080
}
10791081
wasNull = false;
10801082

1081-
if (cal == null) {
1082-
cal = new GregorianCalendar();
1083-
}
1084-
1085-
return Time.valueOf(zdt.withZoneSameInstant(cal.getTimeZone().toZoneId()).toLocalTime());
1083+
Calendar c = (Calendar) (cal != null ? cal : defaultCalendar).clone();
1084+
c.clear();
1085+
c.set(1970, Calendar.JANUARY, 1, zdt.getHour(), zdt.getMinute(), zdt.getSecond());
1086+
return new Time(c.getTimeInMillis());
10861087
} catch (Exception e) {
10871088
throw ExceptionUtils.toSqlState(String.format("Method: getTime(\"%s\") encountered an exception.", columnLabel), String.format("SQL: [%s]", parentStatement.getLastSql()), e);
10881089
}
@@ -1104,13 +1105,12 @@ public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLExcept
11041105
}
11051106
wasNull = false;
11061107

1107-
if (cal == null) {
1108-
cal = new GregorianCalendar();
1109-
}
1110-
1111-
Timestamp ts = Timestamp.valueOf(zdt.withZoneSameInstant(cal.getTimeZone().toZoneId()).toLocalDateTime());
1112-
ts.setNanos(zdt.getNano());
1113-
return ts;//This assumes the response is in cal.getTimeZone()
1108+
Calendar c = (Calendar) (cal != null ? cal : defaultCalendar).clone();
1109+
c.set(zdt.getYear(), zdt.getMonthValue() - 1, zdt.getDayOfMonth(), zdt.getHour(), zdt.getMinute(),
1110+
zdt.getSecond());
1111+
Timestamp timestamp = new Timestamp(c.getTimeInMillis());
1112+
timestamp.setNanos(zdt.getNano());
1113+
return timestamp;
11141114
} catch (Exception e) {
11151115
throw ExceptionUtils.toSqlState(String.format("Method: getTimestamp(\"%s\") encountered an exception.", columnLabel), String.format("SQL: [%s]", parentStatement.getLastSql()), e);
11161116
}

0 commit comments

Comments
 (0)