Bind SQL NULL for an invalid Date instead of the PostgreSQL epoch - #44
Open
sfc-gh-okalaci wants to merge 1 commit into
Open
Bind SQL NULL for an invalid Date instead of the PostgreSQL epoch#44sfc-gh-okalaci wants to merge 1 commit into
sfc-gh-okalaci wants to merge 1 commit into
Conversation
A JavaScript Date whose getTime() is NaN has no epoch to convert. The conversion
read it as a double and did the epoch arithmetic regardless, and NaN came out the
far side finite: 2000-01-01, the PostgreSQL epoch, an offset of zero. A caller
holding no date at all stored a specific one, and nothing said so.
pljs.execute('SELECT $1::timestamptz AS v', [new Date(NaN)])
-- Sat Jan 01 2000 02:00:00 GMT+0200
Reaching it does not require writing NaN by hand. An infinite timestamp read back
into JavaScript *is* an invalid Date, so an ordinary read-modify-write of a row
holding 'infinity'::timestamptz turns that infinity into a real timestamp:
read=invalid Date wrote=Sat Jan 01 2000 02:00:00 GMT+0200
Such a value now becomes SQL NULL, through the same helper the other null-returning
paths use, so it is correct whether or not fcinfo is present -- a composite column
is converted without one.
The three date cases are also merged: DATEOID, TIMESTAMPOID and TIMESTAMPTZOID had
separate but identical Is_Date blocks, and the NaN check would otherwise have been
written twice.
Adds sql/pg_invalid_date.sql, covering a bound parameter, a returned value, a
composite column (the no-fcinfo path), the infinity round trip, and that a valid
Date is unaffected.
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.
Stacked on #43.
A JavaScript
DatewhosegetTime()isNaNhas no epoch to convert. The conversionread it as a double and did the epoch arithmetic anyway — and
NaNcame out the far sidefinite:
2000-01-01, the PostgreSQL epoch, an offset of zero.A caller holding no date at all stored a specific one, with nothing reported.
And it doesn't take
new Date(NaN)to get there. An infinite timestamp read back intoJavaScript is an invalid Date, so an ordinary read-modify-write of a row holding
'infinity'::timestamptzconverts that infinity into a real timestamp:Such a value now becomes SQL NULL, via the same helper the other null-returning paths
use, so it behaves correctly whether or not
fcinfois present — a composite column isconverted without one.
The three date cases are merged while here:
DATEOID,TIMESTAMPOIDandTIMESTAMPTZOIDhad separate but identical
Is_Dateblocks, and the check would otherwise be writtentwice.
Test plan
sql/pg_invalid_date.sqlcovers a bound parameter (timestamptzanddate), a returnedvalue, a composite column — the no-
fcinfopath — the infinity round trip, and that avalid Date still round-trips.
It discriminates: reverted, every NULL assertion returns
Sat Jan 01 2000 02:00:00orfinstead. Full suite green on PostgreSQL 17 (56 tests); builds clean on 16, 18 and 19beta3.