[Pg-kit]: Add Temporal support for PostgreSQL (rebase of #4475)#5656
Open
SamPearlma wants to merge 5 commits intodrizzle-team:mainfrom
Open
[Pg-kit]: Add Temporal support for PostgreSQL (rebase of #4475)#5656SamPearlma wants to merge 5 commits intodrizzle-team:mainfrom
SamPearlma wants to merge 5 commits intodrizzle-team:mainfrom
Conversation
The postgres-interval package silently returned wrong values for two
PostgreSQL interval styles rather than throwing:
- postgres_verbose ("@ 2 days 3 hours 45 mins 30 secs") tokenized
"mins" as a month prefix and produced months: 45, losing the
minutes and fabricating a year-month component.
- sql_standard ("2 3:45:30") dropped the leading day count and
returned { hours: 3, minutes: 45, seconds: 30 }, off by two days.
Because the result was populated but wrong, the bad parse could not be
detected at runtime, risking silent data corruption for any caller on a
session configured with one of those styles.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR is a continuation of #4475, originally opened by @XiNiHa. It adds Temporal mapping support for PostgreSQL
date,time,timestamp, andintervalcolumns via a new{ mode: 'temporal' }option.The original PR fell behind
mainand developed merge conflicts. Since I don't have permission to push to the contributor's fork, I rebased the branch onto the latestmain, resolved the conflicts (primarily inpnpm-lock.yaml), and added the test coverage and scope adjustments described below so the work is ready to review and merge.What changed relative to #4475
Rebased onto the latest
mainand resolved merge conflicts.Added integration test coverage for the Temporal-mode variants of
date,time,timestamp, andinterval:Added a
temporal-polyfillsetup file wired into Vitest viasetupFilesso the test suite runs on Node versions without native Temporal support.Scope change for
interval:postgres-intervalpeer dependencyPgTemporalInterval.mapFromDriverValueSee Known limitations below.
No other functional changes were introduced beyond conflict resolution.
Testing
Integration tests exercise the Temporal mode for every supported column type against a live Postgres:
date,time(with precision)timestamp(with/without TZ, configurable precision)intervalAll column types co-exist in a single all-columns table to verify schema generation and mixed inserts.
Additional assertions:
Timestamps remain stable across DST transitions (spring-forward and fall-back) under session time zones:
UTCAmerica/New_YorkAsia/TokyoInterval tests cover:
relativeToDrizzleErroron unparseable driver valuesKnown limitations
intervalTemporal mode requires:on the session. The default PostgreSQL output styles (
postgres,postgres_verbose,sql_standard) are not supported and will throw aDrizzleErrorwith a clear remediation message.Why the fallback was removed
The
postgres-intervalfallback was removed because it can silently produce incorrect durations for two real server outputs:postgres_verboseExample:
The tokenizer matches
"mins"as a month prefix and produces:months: 45sql_standardExample:
This drops the leading day count and returns:
{ hours: 3, minutes: 45, seconds: 30 }Because the result is still populated (not empty), the incorrect parse cannot be safely detected at runtime, risking silent data corruption. Failing loudly on unsupported formats is the safer contract.
This rationale is documented in
PgTemporalInterval.mapFromDriverValuefor future reference.Temporal.Duration support notes
Supported inputs include ISO 8601-2 extensions supported by
Temporal.Duration.from, such as:Examples like:
P3W1D-P1Mwill round-trip correctly, even though strict ISO 8601-1 would reject them.
Note: other systems reading the same column may not accept these extended forms.
Original work
All implementation and design decisions are from the original author, @XiNiHa. Please refer to the original PR for full context and discussion: #4475.
Notes
Related