Repository navigation
fix: read an exclusive infinite date bound as memory loads it (port of #489, #502) - #504
Merged
CaffeinatedCoder merged 3 commits intoOct 26, 2026
Conversation
PostgreSQL canonicalizes a finite discrete bound but leaves an infinite one as it is, so [2026-01-01,infinity) and (-infinity,2026-01-01) exist: another tool writes them, and the server's algebra computes them ((,) - (,-infinity] is (-infinity,), (,) - [infinity,) is (,infinity)). Memory loads them one day inside, [2026-01-01,9999-12-30] and [0001-01-02,2025-12-31]. In a query, upper(x) - 1 is still infinity and lower(x) is -infinity, so UpperBound(), LowerBound() and Clamp at the extremes answered 9999-12-31 and 0001-01-01, and LowerBoundInclusive() read lower_inc, which is false for (-infinity, where memory's closed form starts inclusive. RangeSet's bound readers go through the same helpers. A definition now names the extremes Npgsql writes as infinities and the bound memory loads for an exclusive one (ExclusiveInfinity), and the bound readers test for the exclusive sentinel in a CASE. LowerBoundInclusive() on a discrete type mirrors UpperBoundInclusive(): a finite lower bound exists and the range isn't empty. On LocalDateRange only the upper side applies: memory starts (-infinity on -9998-01-02, below PostgreSQL's dates. With Npgsql.DisableDateTimeInfinityConversions set no extreme is an infinity, the SQL stays as it was, and such a row fails to read in a query as it fails to load. YearMonthRange can't load these rows (partial months). ExclusiveInfinityBoundParityTests writes every infinite form by raw SQL and runs each reader as a predicate against memory's answer for the loaded row, on DateRange, LocalDateRange and both multiranges, plus the server-computed Except; with the translator change reverted all five parity tests fail for these rows. Measured on PostgreSQL 16.15 and 18.1. Found-By: CA Defect-Class: SQL Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 54d34ea)
…or seeds (#489) ExclusiveInfinityBoundParityTests is registered as a differential oracle with two seeds: the CASE answering the extreme instead of the day inside it (5 of 7 tests fail), and LowerBoundInclusive() reading lower_inc again (2 of 7). clamp-reads-the-stored-exclusive-upper-bound and range-isfinite-drops-isempty had context lines the fix moved; regenerated, both still caught (ClampParityTests, ClampDomainParityTests; ExecutedQueryTests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit a1645b2)
…he migration and changelog (#502) Rows written by other tools gains the bound readers and the two exceptions (LocalDateRange's lower side, the infinity conversions disabled); the discrete-bounds note names LowerBoundInclusive(); the domain-boundary section says how the readers do it. Claim E87 (and E06 following its reworded sentence), and the clone waiver for the definitions' new argument. 10.x specifics: the rows go under ### Changed answers in [10.4.0] in the root and both EF changelogs, linking #502 and the migration section (the NodaTime EF changelog gains the section and its intro line), and docs/migration.md lists the section under ## Changed answers in 10.4.0, beside #496's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit e465aa1)
Closed
CaffeinatedCoder
deleted the
fix/502-exclusive-infinite-date-bounds-10.x
branch
October 26, 2026 15:28
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.
Closes #502
Problem
On
release/10.x,LowerBound(),UpperBound(),LowerBoundInclusive()andClampread a date range's exclusive infinite bound as the extreme the database holds, one day wider than memory loads it (#489). On[2026-01-01,infinity),UpperBound()returned 9999-12-31 in a query and 9999-12-30 in memory. On(-infinity,2026-01-01),LowerBound()returned 0001-01-01 instead of 0001-01-02, andLowerBoundInclusive()returnedfalseinstead oftrue. #494 madeClamponDateRangeandLocalDateRangerun as SQL in this release, and the 10.4.0 changelog says it "answers as memory does, at the extremes too". Without this port, 10.4.0 would ship a new disagreement next to that sentence.Change
git cherry-pick -xof PR #503's three commits frommain:ExclusiveInfinityon the date definitions, and theCASEin the bound readers (InsideExclusiveInfinity).LowerBoundInclusive()on a discrete type becomesNOT lower_inf(x) AND NOT isempty(x).LocalDateRangereads the upper side only. WithNpgsql.DisableDateTimeInfinityConversionsset, the SQL is unchanged.ExclusiveInfinityBoundParityTests(registered as an oracle with two seeds), theInfinityConversionsDisabledTestscase, the translation tests, and two regenerated seeds.### Changed answersin[10.4.0]in the root and both EF changelogs, linking 10.x: read an exclusive infinite date bound as memory loads it (port of #489) #502 and the migration section. The NodaTime EF changelog gains that section and its intro line.docs/migration.mdadds Check date bounds at an exclusive infinity in queries under## Changed answers in 10.4.0, next to 10.x: reject a collation on a string set column unless it compares bytes (port of #483) #496's section.Tests
release/10.xwith the .NET 10 SDK: unit, conventions, ASP.NET Core and the EF no-database projects pass. Both integration projects pass on PostgreSQL 16 and 18 at the EF Core 10.0.0 floor, and on CI's newest-patch leg (EF Core 10.0.13, Npgsql EF 10.0.3).ExclusiveInfinityBoundParityTestsfails for the exclusive-infinity rows, as it does onmain.🤖 Generated with Claude Code