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 range bound with a leading space is refused; PostgreSQL accepts it #45
PostgreSQL trims the element before passing it to the element type's input function. The strict ISO grammar here doesn't. It fails loudly, and accepting it only loosens, so it can wait for 9.1.0.
Check which element types PostgreSQL trims for (the numeric ones and the temporal ones may differ) before matching it.
Measured on PostgreSQL 17.10 (postgres:17-alpine, the integration tests' image)
Every range type here treats whitespace inside a bound the same way. It doesn't matter whether the whitespace is quoted, unquoted or backslash-escaped, or whether it's leading, trailing or both: range_in keeps it all in the bound text, and every element input function strips it from both ends.
Types: int4range, int8range, numrange, daterange (including -infinity), tsrange, tstzrange, and a custom timerange (subtype = time).
So no type differs from another, and the numeric and temporal types behave alike. Arrays behave the same way: '{" 1"}'::int4[] is {1} and '{" 2026-01-01"}'::date[] is {2026-01-01}. But '{" ab"}'::text[] keeps the space, because textin doesn't trim.
Fix: trim the same six ASCII characters (LiteralWhiteSpace) from both ends of a bound's text after unquoting and unescaping, instead of only from its unquoted part. The element grammar is still strict ISO 8601. A bound of only whitespace still throws, and so does a non-ASCII space.
Oracle check (main at 3ecfa10):Would be caught today (retroactive; no oracle found it at the time) by RangeLiteralGrammarContractTests and LiteralGrammarParityTests, seed quoted-bound-whitespace-kept. The failing rows: RangeLiteralGrammarContractTests (EveryRangeType_ReadsBoundsWithPostgresRangeGrammar, e.g. DateRange [" 2026-01-01","2026-06-30 "): refused, expected [2026-01-01,2026-06-29]) and LiteralGrammarParityTests (BoundWhitespace_ReadsAsPostgresReadsIt and RangeLiterals_ReadAsPostgresReadsThem, daterange [" 2026-01-01",2026-02-01): library refused, PostgreSQL [2026-01-01,2026-01-31]). Verified by a run: I reverse-applied #73's src/ diff on 3ecfa10 and ran every class in oracles.json, including the live PostgreSQL ones. These three methods failed, and nothing else did.
Would be caught today by LiteralCorpusProbeTests (#135). This is retroactive: LiteralGrammarParityTests found it, and #73 fixed it. Row: DateRange whitespace [" 2026-01-01",2026-01-02), library refused (FormatException), PostgreSQL reads [2026-01-01,2026-01-02). The same happens on every temporal range and multirange type, for a trailing space and for [\ …. Verified by applying test/oracles/seeds/quoted-bound-whitespace-kept.patch (the revert of #73's fix) to main + #135 and running the class against postgres:17: 14 of 49 rows fail with 28 lines. That seed now names LiteralCorpusProbeTests too.
Activity
CaffeinatedCoder commentedon Oct 17, 2026
Measured on PostgreSQL 17.10 (
postgres:17-alpine, the integration tests' image)Every range type here treats whitespace inside a bound the same way. It doesn't matter whether the whitespace is quoted, unquoted or backslash-escaped, or whether it's leading, trailing or both:
range_inkeeps it all in the bound text, and every element input function strips it from both ends.Types:
int4range,int8range,numrange,daterange(including-infinity),tsrange,tstzrange, and a customtimerange(subtype = time)." 1", unquoted1, escaped\ 1[" ",5))invalid input syntax)So no type differs from another, and the numeric and temporal types behave alike. Arrays behave the same way:
'{" 1"}'::int4[]is{1}and'{" 2026-01-01"}'::date[]is{2026-01-01}. But'{" ab"}'::text[]keeps the space, becausetextindoesn't trim.Fix: trim the same six ASCII characters (
LiteralWhiteSpace) from both ends of a bound's text after unquoting and unescaping, instead of only from its unquoted part. The element grammar is still strict ISO 8601. A bound of only whitespace still throws, and so does a non-ASCII space.CaffeinatedCoder commentedon Oct 17, 2026
Oracle check (main at 3ecfa10): Would be caught today (retroactive; no oracle found it at the time) by
RangeLiteralGrammarContractTestsandLiteralGrammarParityTests, seedquoted-bound-whitespace-kept. The failing rows:RangeLiteralGrammarContractTests(EveryRangeType_ReadsBoundsWithPostgresRangeGrammar, e.g.DateRange [" 2026-01-01","2026-06-30 "): refused, expected [2026-01-01,2026-06-29]) andLiteralGrammarParityTests(BoundWhitespace_ReadsAsPostgresReadsItandRangeLiterals_ReadAsPostgresReadsThem,daterange [" 2026-01-01",2026-02-01): library refused, PostgreSQL [2026-01-01,2026-01-31]).Verified by a run: I reverse-applied #73's
src/diff on 3ecfa10 and ran every class inoracles.json, including the live PostgreSQL ones. These three methods failed, and nothing else did.CaffeinatedCoder commentedon Oct 17, 2026
Would be caught today by
LiteralCorpusProbeTests(#135). This is retroactive:LiteralGrammarParityTestsfound it, and #73 fixed it. Row:DateRange whitespace [" 2026-01-01",2026-01-02), library refused (FormatException), PostgreSQL reads[2026-01-01,2026-01-02). The same happens on every temporal range and multirange type, for a trailing space and for[\ …. Verified by applyingtest/oracles/seeds/quoted-bound-whitespace-kept.patch(the revert of #73's fix) to main + #135 and running the class against postgres:17: 14 of 49 rows fail with 28 lines. That seed now namesLiteralCorpusProbeTeststoo.test: infinity-bound and quoted-whitespace rows in the literal corpus…