Skip to content

fix(bigquery-jdbc): preserve Timestamp instant in PreparedStatement and CallableStatement Calendar overloads - #14640

Open
keshavdandeva wants to merge 3 commits into
mainfrom
jdbc/timestamp-bug-1
Open

keshavdandeva wants to merge 3 commits into
mainfrom
jdbc/timestamp-bug-1

Conversation

@keshavdandeva

Copy link
Copy Markdown
Contributor

b/565785264

Summary

Fixes an issue where passing a Calendar to PreparedStatement.setTimestamp or CallableStatement.setTimestamp/getTimestamp corrupted the underlying UTC instant by shifting it by JVM_offset - Calendar_offset (or 2 * (JVM_offset - Calendar_offset) on a CallableStatement setter-to-getter round trip).

Root Cause

A java.sql.Timestamp already represents an absolute UTC epoch instant (milliseconds + nanos), and BigQuery's TIMESTAMP type is a timezone-aware absolute instant. Previously, the Calendar overloads called BigQueryTemporalUtility.convertTimestampWithCalendar(ts, cal), which extracted the JVM-local wall-clock fields (ts.toLocalDateTime()) and re-anchored them in cal.getTimeZone(), shifting the epoch instant whenever the Calendar timezone differed from the JVM default timezone.

Changes

  • BigQueryPreparedStatement: Delegate setTimestamp(int, Timestamp, Calendar) directly to setTimestamp(int, Timestamp).
  • BigQueryCallableStatement: Delegate getTimestamp(int, Calendar), getTimestamp(String, Calendar), and setTimestamp(String, Timestamp, Calendar) directly to their non-Calendar counterparts.
  • BigQueryTemporalUtility: Remove unused convertTimestampWithCalendar(Timestamp, Calendar) helper.
  • Tests: Update unit and integration tests (BigQueryPreparedStatementSettersTest, BigQueryCallableStatementTest, BigQueryTemporalUtilityTest, ITCallableStatementTest) to verify Timestamp preservation across distinct JVM (America/New_York) and Calendar (Asia/Tokyo) timezones.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies timestamp handling in BigQueryCallableStatement and BigQueryPreparedStatement by removing the BigQueryTemporalUtility.convertTimestampWithCalendar utility and delegating Calendar-based timestamp getters and setters to their non-Calendar overloads. However, feedback highlights that ignoring the Calendar parameter entirely may cause issues with timezone-naive DATETIME values, which should be interpreted using the provided Calendar's timezone. Additionally, several test updates modify the JVM-wide default timezone (TimeZone.setDefault), which can introduce flakiness and race conditions during parallel test execution; it is recommended to dynamically select a test timezone instead.

@keshavdandeva
keshavdandeva marked this pull request as ready for review October 12, 2026 17:09
@keshavdandeva
keshavdandeva requested review from a team as code owners October 12, 2026 17:09

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant