You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Quoted value set element with surrounding whitespace is refused for temporal sets; PostgreSQL accepts it #70
array_in hands a quoted element to the element input function with its whitespace intact. date_in, time_in, timestamp_in, timestamptz_in, int4in and numeric_in strip ASCII whitespace from both ends (measured on PostgreSQL 17, see #45). textin keeps it. So trimming can't happen in SetFormat for every family: StringSet and the string wrapper arities have to keep the space. It belongs to the families whose PostgreSQL input function trims.
Before matching it, measure uuid_in and the NodaTime families' store types (date, timestamp, timestamptz, time, and YearMonthSet's date). It fails loudly and only accepts more, so it fits a minor release.
For each element type, I tried six ASCII whitespace characters (space, tab, LF, CR, VT, FF) plus U+00A0 and U+2003. The forms were:
quoted, at the start, the end, or both: {" x"}
backslash-escaped, at the start or the end: {\ x}
bare: { x}
quoted, whitespace only: {" "}
array_in itself drops whitespace around a bare element. It passes quoted and escaped whitespace to the element input function.
Element type (library family)
Quoted or escaped ASCII whitespace
U+00A0 / U+2003
Whitespace only
int2, int4, int8, numeric
stripped
rejected
rejected
date (also infinity), timestamp, timestamptz, time
stripped
rejected
rejected
uuid
rejected (bare is fine, array_in drops it)
rejected
rejected
text
kept ({" ab"})
kept
kept ({" "})
What the library does today
Already the same as PostgreSQL:Int16Set, Int32Set, Int64Set and DecimalSet (the BCL number parsers trim exactly these six characters), and StringSet, which keeps everything.
This issue:DateSet, DateTimeSet, DateTimeOffsetSet, TimeSet, LocalDateSet, LocalDateTimeSet, InstantSet, LocalTimeSet and YearMonthSet (stored as date[]) throw on quoted or escaped ASCII whitespace. PostgreSQL strips it.
The opposite problem, filed separately for 10.0.0:GuidSet accepts quoted and escaped whitespace, and a no-break space even bare. Guid.Parse trims all Unicode whitespace, but uuid_in rejects it. Fixing that rejects input that parses today.
Fix for this issue: each temporal family's element parser (ParseValue, which Parse, TryParse, JSON, the TypeConverter and the wrapper arities all use) trims these six characters, and only them. Nothing changes for StringSet or the string wrapper arities.
Oracle check (main at 3ecfa10):Would be caught today (retroactive; no oracle found it at the time) by SetElementWhiteSpaceContractTests and LiteralGrammarParityTests, seed temporal-set-element-whitespace-kept. The failing rows: SetElementWhiteSpaceContractTests (EverySetType_ReadsElementWhitespaceAsItsInputFunctionDoes, 1,080 lines, e.g. DateSet: Parse rejected {" 2024-06-15 "}, expected {2024-06-15}, through Parse, TryParse, TypeConverter and JSON) and LiteralGrammarParityTests (ElementWhitespace_ReadsAsPostgresReadsIt, 324 lines, date[] DateSet {" 2026-01-01"}: library refused, PostgreSQL {2026-01-01}). Verified by a run: I reverse-applied #81's src/ diff on 3ecfa10 and ran every registered oracle. These two methods failed, and nothing else did.
Would be caught today by LiteralCorpusProbeTests (#135). This is retroactive: LiteralGrammarParityTests found it, and #81 fixed it. Row: DateSet whitespace {" 2026-01-01"}, library refused (FormatException), PostgreSQL reads {2026-01-01}. The same happens on every temporal set family and its wrapper arity (BCL and NodaTime), for a trailing space and for {\ …}. Verified by applying test/oracles/seeds/temporal-set-element-whitespace-kept.patch (the revert of #81's fix) to main + #135 and running the class against postgres:17: 16 of 49 rows fail with 48 lines. That seed now names LiteralCorpusProbeTests too.
Activity
CaffeinatedCoder commentedon Oct 17, 2026
Measured on PostgreSQL 17.10 (
postgres:17-alpine)For each element type, I tried six ASCII whitespace characters (space, tab, LF, CR, VT, FF) plus U+00A0 and U+2003. The forms were:
{" x"}{\ x}{ x}{" "}array_initself drops whitespace around a bare element. It passes quoted and escaped whitespace to the element input function.int2,int4,int8,numericdate(alsoinfinity),timestamp,timestamptz,timeuuidarray_indrops it)text{" ab"}){" "})What the library does today
Int16Set,Int32Set,Int64SetandDecimalSet(the BCL number parsers trim exactly these six characters), andStringSet, which keeps everything.DateSet,DateTimeSet,DateTimeOffsetSet,TimeSet,LocalDateSet,LocalDateTimeSet,InstantSet,LocalTimeSetandYearMonthSet(stored asdate[]) throw on quoted or escaped ASCII whitespace. PostgreSQL strips it.GuidSetaccepts quoted and escaped whitespace, and a no-break space even bare.Guid.Parsetrims all Unicode whitespace, butuuid_inrejects it. Fixing that rejects input that parses today.Fix for this issue: each temporal family's element parser (
ParseValue, whichParse,TryParse, JSON, theTypeConverterand the wrapper arities all use) trims these six characters, and only them. Nothing changes forStringSetor the string wrapper arities.CaffeinatedCoder commentedon Oct 17, 2026
Oracle check (main at 3ecfa10): Would be caught today (retroactive; no oracle found it at the time) by
SetElementWhiteSpaceContractTestsandLiteralGrammarParityTests, seedtemporal-set-element-whitespace-kept. The failing rows:SetElementWhiteSpaceContractTests(EverySetType_ReadsElementWhitespaceAsItsInputFunctionDoes, 1,080 lines, e.g.DateSet: Parse rejected {" 2024-06-15 "}, expected {2024-06-15}, through Parse, TryParse, TypeConverter and JSON) andLiteralGrammarParityTests(ElementWhitespace_ReadsAsPostgresReadsIt, 324 lines,date[] DateSet {" 2026-01-01"}: library refused, PostgreSQL {2026-01-01}).Verified by a run: I reverse-applied #81's
src/diff on 3ecfa10 and ran every registered oracle. These two methods failed, and nothing else did.CaffeinatedCoder commentedon Oct 17, 2026
Would be caught today by
LiteralCorpusProbeTests(#135). This is retroactive:LiteralGrammarParityTestsfound it, and #81 fixed it. Row:DateSet whitespace {" 2026-01-01"}, library refused (FormatException), PostgreSQL reads{2026-01-01}. The same happens on every temporal set family and its wrapper arity (BCL and NodaTime), for a trailing space and for{\ …}. Verified by applyingtest/oracles/seeds/temporal-set-element-whitespace-kept.patch(the revert of #81's fix) to main + #135 and running the class against postgres:17: 16 of 49 rows fail with 48 lines. That seed now namesLiteralCorpusProbeTeststoo.test: infinity-bound and quoted-whitespace rows in the literal corpus…