MySQL server-side prepared statements ignore session timezone for timestamp parameters
#8.879 aberto em 13 de ago. de 2026
Métricas do repositório
- Stars
- (6.566 estrelas)
- Métricas de merge de PR
- (Mesclagem média 2d 18h) (225 fundiu PRs em 30d)
Description
What type of bug is this?
Incorrect result
What subsystems are affected?
Frontend, Write Protocols, Query Engine
Minimal reproduce step
Connect to GreptimeDB through MySQL Connector/J with server-side prepared statements enabled and a non-UTC connection/session timezone:
jdbc:mysql://127.0.0.1:4002/public?useServerPrepStmts=true&connectionTimeZone=Asia/Shanghai&forceConnectionTimeZoneToSession=true
Create a table and verify the session timezone:
CREATE TABLE timezone_prepared_test (
ts TIMESTAMP TIME INDEX,
value INT
);
SELECT @@session.time_zone;
-- Asia/Shanghai
Insert a timestamp using a server-side prepared statement:
try (PreparedStatement stmt = conn.prepareStatement(
"INSERT INTO timezone_prepared_test (ts, value) VALUES (?, ?)")) {
stmt.setTimestamp(1, Timestamp.valueOf("2026-08-13 08:00:00"));
stmt.setInt(2, 1);
stmt.executeUpdate();
}
The same problem affects timestamp parameters in prepared query predicates:
try (PreparedStatement stmt = conn.prepareStatement(
"SELECT * FROM timezone_prepared_test WHERE ts = ?")) {
stmt.setTimestamp(1, Timestamp.valueOf("2026-08-13 08:00:00"));
stmt.executeQuery();
}
For comparison, execute an equivalent text-protocol statement after setting the session timezone:
SET time_zone = 'Asia/Shanghai';
INSERT INTO timezone_prepared_test VALUES ('2026-08-13 08:00:00', 2);
The two paths interpret the timezone-less timestamp differently.
The server-side prepared parameter path converts a MySQL binary DATETIME to a naive datetime and then unconditionally calls .and_utc().timestamp_millis() in src/servers/src/mysql/helper.rs. This conversion does not receive the query/session timezone. Byte parameters targeting timestamp columns are also parsed with Timestamp::from_str_utc.
What did you expect to see?
Timestamp parameters in MySQL server-side prepared statements should have timezone semantics consistent with ordinary SQL timestamp literals and the MySQL session.
When @@session.time_zone is Asia/Shanghai, a timezone-less prepared DATETIME value should be interpreted according to that session timezone, for both inserts and query predicates. Connector/J properties such as connectionTimeZone and forceConnectionTimeZoneToSession=true should not result in the server silently treating prepared parameters as UTC.
What did you see instead?
GreptimeDB interprets server-side prepared DATETIME parameters as UTC regardless of @@session.time_zone.
As a result:
- Prepared inserts can differ from equivalent text-protocol inserts by the timezone offset.
- Prepared timestamp predicates can compare against a different instant than the equivalent SQL literal.
- Returned values are formatted using the session timezone, making parameter handling and result formatting asymmetric.
- With
Asia/Shanghai, this can produce an eight-hour discrepancy.
Using useServerPrepStmts=false avoids this specific binary-parameter path and acts as a workaround.
What operating system did you use?
macOS Darwin 23.3.0 arm64
What version of GreptimeDB did you use?
Current main checkout: 1.3.0, commit 943eee852f (30 commits after the described v1.3.0 build tag).
Relevant log output and stack trace
No server error or stack trace is emitted. The query succeeds but uses incorrect timezone semantics for the prepared timestamp parameter.