Repository navigation
fix: a range factory over a NULL element is NULL in a query (10.x, #388) - #394
Merged
Merged
Conversation
CreateFinite fell into its inverted-bounds guard and gave empty, and CreateUnboundedStart/End passed the NULL to PostgreSQL's range constructor, which reads a NULL bound as unbounded and gave (,). So Contains(v) was true for a row without the element: the optional side of an outer join, or a nullable column read with .Value. The factories are now CASE WHEN e IS NULL THEN NULL ELSE <translation> END, which EF Core folds away for required elements, non-null parameters and constants. Found-By: OT Defect-Class: SQL Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 5cf3845)
This was referenced Oct 24, 2026
Base automatically changed from
fix/387-null-element-contains-10.x
to
release/10.x
October 24, 2026 20:46
#387, #388) On main the composition sweeps hold #381 and #382 over every shape; this line has none of them. Adds the cases the release review named: a bool projection of RangeSet.Contains, and a range factory over a NULL element consumed by Contains in a projection, by Overlaps in a filter, its negation and a projection, and by All over a captured list. Each new assertion fails with the translator from before #382's fix (and the RangeSet projection with the one from before #381's). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 #388
This is the 10.x port of #382 for 10.2.0 (#358). It is
git cherry-pick -xof 5cf3845 from PR #392. It was stacked on PR #393 (#387), which has merged.Problem
Over a NULL element, the translated
CreateFinitegaveemptyandCreateUnboundedStart/CreateUnboundedEndgave(,), instead of NULL. SoDateRange.CreateUnboundedEnd(b.Visit!.From).Contains(v)selected a booking without a visit: a positive filter answering wrongly.Change
The three factories are wrapped by
NullOverNullElement:CASE WHEN e IS NULL THEN NULL ELSE <translation> END. This is the same code as onmain. EF Core folds it away for required elements, non-null parameters and constants.Conflicts, resolved:
candidates.json: kept 10.x's version. The six The range factories over a NULL element build a range: CreateFinite gives empty and CreateUnboundedStart/End give (,), where EF Core answers NULL #382 candidates exist only onmain.### Changed answersrow under[10.2.0]in the three changelogs, linking this issue anddocs/migration.md#changed-answers-in-1020.mainlistsOuterJoinProbeTests, which doesn't exist here, so on 10.x E04 listsNullElementTestsinstead.Added on this line only:
NullElementTests.RangeFactories_OverANullElement_AreNull. It coversContains, its negation,== null,IsEmpty()beside an inverted-bounds row (stillempty, as in memory), and a projected range.Added after the release review:
RangeFactories_OverANullElement_AreNull_WhereAPredicateConsumesThemholds a factory over a NULL element where a predicate consumes it:Containsin aboolprojection,Overlapsin a filter, its negation and a projection, andAllover a captured list.Contains_OverANullElement_ProjectsFalsealso projectsRangeSet.Contains(10.x: Contains(element) on a range or RangeSet is NULL in SQL for a NULL element (port of #381) #387). Each new assertion was checked on its own: with the translator from before this fix, all six factory assertions fail; with the one from before Contains(element) on a range or RangeSet is NULL in SQL for a NULL element: the negation drops the row EF Core keeps, and a projection into bool throws #381's fix, theRangeSetprojection throws.Tests
NullOperandTranslationTests.ARangeFactoryOverANullableElement_IsNull(SQL pins) and the new live test. With the fix, both pass.NullElementTests(5 tests) passes on both legs again.Closesdoesn't act onrelease/10.x, so close #388 by hand after the merge.🤖 Generated with Claude Code