Skip to content

Commit

Permalink
[CONJ-964] adding 'auto' timezone possibility
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed May 17, 2022
1 parent 2ba083c commit 0609c6d
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,11 @@ public String createSessionVariableQuery(String serverTz) {
// force client timezone to connection to ensure result of now(), ...
if (conf.timezone() != null && !"disable".equalsIgnoreCase(conf.timezone())) {
boolean mustSetTimezone = true;
ZoneId clientZoneId = ZoneId.of(conf.timezone()).normalized();
TimeZone connectionTz =
"auto".equalsIgnoreCase(conf.timezone())
? TimeZone.getDefault()
: TimeZone.getTimeZone(ZoneId.of(conf.timezone()).normalized());
ZoneId clientZoneId = connectionTz.toZoneId();

// try to avoid timezone consideration if server use the same one
try {
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/driver.properties
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ serverRsaPublicKeyFile=Indicate path to RSA server public key file for sha256_pa
allowPublicKeyRetrieval=Authorize client to retrieve RSA server public key when serverRsaPublicKeyFile is not set (for sha256_password and caching_sha2_password authentication password). Default: false.
useReadAheadInput=use a buffered inputSteam that read socket available data. This cost a bit more in CPU, but permit returning result-set faster. Default true
cachePrepStmts=enable/disable prepare Statement cache. When enable, PreparedStatement.close won't close prepare immediately, keeping a pool of most used prepared results. Default true.
timezone=Driver set connection timezone to client timezone. Value default to client default time-zone ID, but can be set using this option. If you are sure that server use the same timezone, setting connection timezone can be disabled using value 'disable'.
timezone=permits to force session timezone in case of client having a different timezone compare to server. The option `timezone` can have 3 types of value: 'disabled' (default) : connector doesn't change time_zone. '<a timezone>': connector will set connection variable to value. see timezone consideration tp know more
transactionReplay=When having a failover, can current transaction being re-executed, having a completely transparent failover. All commands must be idempotent. Default false.
transactionReplaySize=replay cache buffer maximum size. If a transaction has more command that this size and a failover occurs, transaction will then not be replayed, just throwing an exception error. (Integer) default 64.
allowLocalInfile=Indicate if LOAD DATA LOCAL INFILE commands are permitted. This will disable all pipelining implementation. Default false.
Expand All @@ -62,4 +62,4 @@ tcpKeepCount=permit setting socket TCP_KEEPCOUNT value. Only valid for java 11+(
tcpKeepInterval=permit setting socket TCP_KEEPINTERVAL value. Only valid for java 11+(for previous version, this option will have no use). (Integer) Default null
useMysqlMetadata=force DatabaseMetadata.getDatabaseProductName() to return "MySQL" (for compatibility reason)
maxAllowedPacket=permit to driver to avoid sending command with size > to server max_allowed_packet, throwing an error in place of server dropping the connection.
createDatabaseIfNotExist=the specified database in the url will be created if nonexistent. Default: false
createDatabaseIfNotExist=the specified database in the url will be created if nonexistent. Default: false
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static void drop() throws SQLException {
Statement stmt = sharedConn.createStatement();
stmt.execute("DROP TABLE IF EXISTS DateTimeCodec");
stmt.execute("DROP TABLE IF EXISTS DateTimeCodec2");
stmt.execute("DROP TABLE IF EXISTS DateTimeCodec3");
}

@BeforeAll
Expand All @@ -43,6 +44,9 @@ public static void beforeAll2() throws SQLException {
: ""));
stmt.execute(
"CREATE TABLE DateTimeCodec2 (id int not null primary key auto_increment, t1 DATETIME(6))");
stmt.execute(
"CREATE TABLE DateTimeCodec3 (id int not null primary key auto_increment, t1 DATETIME(6))");

stmt.execute("FLUSH TABLES");
}

Expand Down Expand Up @@ -393,6 +397,167 @@ public void getDate(ResultSet rs) throws SQLException {
}
}

@Test
public void getDateTimezoneTest() throws SQLException {
TimeZone initialTz = Calendar.getInstance().getTimeZone();

TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
try (Connection conGmt8 = createCon("timezone=auto")) {
getDateTimezoneTestGmt8(conGmt8, getPrepare(conGmt8), TimeZone.getTimeZone("GMT+8"));
TimeZone.setDefault(TimeZone.getTimeZone("GMT-8"));
try (Connection conGmtm8 = createCon("timezone=auto")) {
getDateTimezoneTestGmtm8(conGmtm8, getPrepare(conGmtm8), TimeZone.getTimeZone("GMT-8"));
}
} finally{
TimeZone.setDefault(initialTz);
}
}

public void getDateTimezoneTestGmt8(Connection conGmt8, ResultSet rs, TimeZone tz) throws SQLException {

assertEquals(
"2010-01-12T01:55:12+08:00",
rs.getObject(1, OffsetDateTime.class).toString());

conGmt8.createStatement().execute("TRUNCATE TABLE DateTimeCodec3");
try (PreparedStatement prep = conGmt8.prepareStatement("INSERT INTO DateTimeCodec3 values (?,?)")) {
prep.setInt(1,-2);
prep.setString(2, "2010-01-12 01:55:12");
prep.execute();

prep.setInt(1,1);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12+08:00"));
prep.execute();

prep.setInt(1,2);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12+01:00"));
prep.execute();

prep.setInt(1,3);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12Z"));
prep.execute();

prep.setInt(1,4);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T17:55:12-04:00"));
prep.execute();
}
conGmt8.commit();

java.sql.Statement stmt = conGmt8.createStatement();
stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
try (PreparedStatement prepStmt = conGmt8.prepareStatement("select * from DateTimeCodec3")) {
rs = prepStmt.executeQuery();
rs.next();
assertEquals("2010-01-12T01:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));

rs.next();
assertEquals("2010-01-12T01:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 01:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263232512000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-12 09:55:12.0", rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
assertEquals("2010-01-12", rs.getDate(2).toString());
assertEquals("2010-01-12", rs.getDate(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
assertEquals("2010-01-12T01:55:12", rs.getObject(2, LocalDateTime.class).toString());

rs.next();
assertEquals("2010-01-12T08:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 08:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263257712000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-12 08:55:12.000000", rs.getString(2));
assertEquals("2010-01-12", rs.getDate(2).toString());

rs.next();
assertEquals("2010-01-12T09:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 09:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263261312000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-12 09:55:12.000000", rs.getString(2));
assertEquals("2010-01-12", rs.getDate(2).toString());

rs.next();
assertEquals("2010-01-13T05:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-13 05:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263333312000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-13 05:55:12.000000", rs.getString(2));
assertEquals("2010-01-13", rs.getDate(2).toString());
}
conGmt8.rollback();

}

public void getDateTimezoneTestGmtm8(Connection conGmt8, ResultSet rs, TimeZone tz) throws SQLException {

assertEquals(
"2010-01-12T01:55:12-08:00",
rs.getObject(1, OffsetDateTime.class).toString());

conGmt8.createStatement().execute("TRUNCATE TABLE DateTimeCodec3");
try (PreparedStatement prep = conGmt8.prepareStatement("INSERT INTO DateTimeCodec3 values (?,?)")) {
prep.setInt(1,-2);
prep.setString(2, "2010-01-12 01:55:12");
prep.execute();

prep.setInt(1,1);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12-08:00"));
prep.execute();

prep.setInt(1,2);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12-01:00"));
prep.execute();

prep.setInt(1,3);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12Z"));
prep.execute();

prep.setInt(1,4);
prep.setObject(2, OffsetDateTime.parse("2010-01-12T17:55:12+04:00"));
prep.execute();
}
conGmt8.commit();

java.sql.Statement stmt = conGmt8.createStatement();
stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
try (PreparedStatement prepStmt = conGmt8.prepareStatement("select * from DateTimeCodec3")) {
rs = prepStmt.executeQuery();
rs.next();
assertEquals("2010-01-12T01:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));

rs.next();
assertEquals("2010-01-12T01:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 01:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263290112000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-11 17:55:12.0", rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
assertEquals("2010-01-12", rs.getDate(2).toString());
assertEquals("2010-01-11", rs.getDate(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
assertEquals("2010-01-12T01:55:12", rs.getObject(2, LocalDateTime.class).toString());

rs.next();
assertEquals("2010-01-11T18:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-11 18:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263264912000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-11 18:55:12.000000", rs.getString(2));
assertEquals("2010-01-11", rs.getDate(2).toString());

rs.next();
assertEquals("2010-01-11T17:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-11 17:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263261312000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-11 17:55:12.000000", rs.getString(2));
assertEquals("2010-01-11", rs.getDate(2).toString());

rs.next();
assertEquals("2010-01-12T05:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
assertEquals("2010-01-12 05:55:12.0", rs.getTimestamp(2).toString());
assertEquals(1263304512000L, rs.getTimestamp(2).getTime());
assertEquals("2010-01-12 05:55:12.000000", rs.getString(2));
assertEquals("2010-01-12", rs.getDate(2).toString());
}
conGmt8.rollback();

}
@Test
public void getTime() throws SQLException {
getTime(get());
Expand Down

0 comments on commit 0609c6d

Please sign in to comment.