GreptimeTeam/greptimedb

MySQL server-side prepared statements ignore session timezone for timestamp parameters

Aperta

#8879 aperta il 13 ago 2026

 (1 commento) (0 reazioni) (0 assegnatari)Rust (528 fork)github user discovery
C-buggood first issuehelp wanted

Metriche repository

Star
 (6566 stelle)
Metriche merge PR
 (Merge medio 2g 18h) (225 PR mergiate in 30 g)

Descrizione

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.

Guida contributor