-
Notifications
You must be signed in to change notification settings - Fork 5.5k
fix(plugin-postgres): Fix Timestamp values in JDBC connectors #26449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideThis PR enforces UTC-based timestamp handling in JDBC connectors by introducing an explicit UTC calendar for read/write operations, preserves legacy behavior via new mappings toggled by the legacy_timestamp session property, propagates this flag through connector APIs, and adds rigorous tests validating timestamp/datetime storage and retrieval in both modes for PostgreSQL and MySQL. Sequence diagram for timestamp read/write with legacy flag propagationsequenceDiagram
participant "User Query (Presto)"
participant "ConnectorSession"
participant "JdbcClient"
participant "StandardColumnMappings"
participant "Database (JDBC)"
"User Query (Presto)"->>"ConnectorSession": Execute query with session
"ConnectorSession"->>"JdbcClient": Request toReadMapping / toWriteMapping with session
"JdbcClient"->>"StandardColumnMappings": Pass legacyTimestamp flag from session
alt legacyTimestamp = true
"StandardColumnMappings"->>"Database (JDBC)": Use legacy mapping (no UTC calendar)
else legacyTimestamp = false
"StandardColumnMappings"->>"Database (JDBC)": Use UTC calendar for timestamp
end
ER diagram for timestamp mapping modes in sessionerDiagram
CONNECTOR_SESSION {
bool legacyTimestamp
}
STANDARD_COLUMN_MAPPINGS {
method timestampReadMapping()
method timestampReadMappingLegacy()
method timestampWriteMapping(TimestampType)
method timestampWriteMappingLegacy(TimestampType)
}
CONNECTOR_SESSION ||--o| STANDARD_COLUMN_MAPPINGS : "uses legacyTimestamp to select mapping"
Class diagram for updated timestamp mapping in JDBC connectorsclassDiagram
class StandardColumnMappings {
+booleanReadMapping()
+timeWriteMapping()
+timestampReadMapping()
+timestampReadMappingLegacy() <<deprecated>>
+timestampWriteMapping(TimestampType)
+timestampWriteMappingLegacy(TimestampType) <<deprecated>>
+uuidWriteMapping()
+jdbcTypeToReadMapping(JdbcTypeHandle)
+prestoTypeToWriteMapping(ConnectorSession, Type)
}
class BaseJdbcClient {
+getColumns(ConnectorSession, JdbcTableHandle)
+toPrestoType(ConnectorSession, JdbcTypeHandle)
+toWriteMapping(ConnectorSession, Type)
}
class JdbcClient {
+toPrestoType(ConnectorSession, JdbcTypeHandle)
+toWriteMapping(ConnectorSession, Type)
}
class JdbcPageSink {
+JdbcPageSink(ConnectorSession, JdbcOutputTableHandle, JdbcClient)
}
StandardColumnMappings <|-- BaseJdbcClient
JdbcClient <|-- BaseJdbcClient
JdbcClient <|-- JdbcPageSink
BaseJdbcClient o-- StandardColumnMappings
JdbcPageSink o-- JdbcClient
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
7636f52 to
968bb6f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/mapping/StandardColumnMappings.java:97` </location>
<code_context>
private StandardColumnMappings() {}
private static final ISOChronology UTC_CHRONOLOGY = ISOChronology.getInstanceUTC();
+ private static final Calendar UTC_CALENDAR = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
public static ReadMapping booleanReadMapping()
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider using a thread-safe alternative to Calendar for UTC handling.
Since Calendar is mutable, sharing a static instance can cause concurrency issues. Use java.time APIs, instantiate Calendar per use, or clearly document thread-safety assumptions.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| assertEquals(dbValue1, "1970-01-01 00:00:00.000000", "JDBC insert should store wall clock time 1970-01-01 00:00:00 in DB"); | ||
| } | ||
|
|
||
| // In legacy mode, DB value 1970-01-01 00:00:00 is interpreted as if it's in JVM timezone (America/Bahia_Banderas UTC-7) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the user session and server are in different zone . what happens if we set session timezone key as "Asia/kolkata" for same scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good . Thank you !
|
@sourcery-ai summary |
BryanCutler
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, very thorough tests. Thanks @tdcmeehan !
…prestodb#26449)" This reverts commit 5efa463.
Description
Fix timestamp handling in MySQL and PostgreSQL JDBC connectors when
legacy_timestamp=false. Timestamps are now correctly stored and read as wall-clock values without timezone conversion.Motivation and Context
When
legacy_timestamp=false(the default), the JDBC connectors were incorrectly applying JVM timezone conversion on both reads and writes. This caused:The fix adds UTC calendar parameter for non-legacy timestamp mappings so they use wall-clock semantics.
Impact
Fixes data corruption for users with non-UTC JVM timezone.
Test Plan
Included unit tests.
Contributor checklist
Release Notes