Skip to content

fix: Contains(T) over a NULL element is false in a query (10.x, #387) - #393

Merged
CaffeinatedCoder merged 1 commit into
release/10.xfrom
fix/387-null-element-contains-10.x
Oct 24, 2026
Merged

CaffeinatedCoder merged 1 commit into
release/10.xfrom
fix/387-null-element-contains-10.x

Conversation

@CaffeinatedCoder

Copy link
Copy Markdown
Owner

Closes #387

This is the 10.x port of #381 for 10.2.0 (#358). It is git cherry-pick -x of c976194 from PR #391.

Problem

Rule (c) reached 10.x in #357, but its predicate wrapper guarded only the range and multirange operands. When the element of Contains(T) was NULL (the optional side of an outer join, or a nullable column read with .Value):

  • a negated filter dropped the row;
  • a projection into bool threw;
  • list.All(x => x.Contains(e)) selected the NULL rows.

Change

Tests

  • NullOperandTranslationTests.ANullableElement_IsCheckedForNull (SQL pins).
  • The three NullElementTests.

Both pass, and with the fix stripped all four fail.

  • Every suite outside the integration projects passes on the floor: unit, NodaTime, EF translation, AspNetCore and conventions.
  • Both integration projects pass on PostgreSQL 16, on EF Core 10.0.0 and on -p:EfFloat=10.0.13 -p:NpgsqlEfFloat=10.0.3.

Closes doesn't act on release/10.x, so close #387 by hand after the merge. #388 is stacked on this PR.

🤖 Generated with Claude Code

Rule (c) guarded a NULL range, multirange or value set operand, but not
the element. Over the optional side of an outer join, or a nullable
column read with .Value, r."Period" @> e was NULL: the negation dropped
the row EF Core keeps for its own comparisons, a projection into bool
threw, and All over a captured list selected the NULL rows. The
predicate wrapper now checks the element too (e IS NOT NULL AND ...);
EF Core drops the check for a required element.

Found-By: OT
Defect-Class: SQL

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c976194)
@CaffeinatedCoder CaffeinatedCoder added this to the 10.2.0 milestone Oct 24, 2026
@CaffeinatedCoder CaffeinatedCoder added bug Something isn't working silent Answers wrongly without throwing — fixes go in the next major, never deferred area/ranges Range unions, variants and the shape engines area/range-set RangeSet and multirange algebra package/efcore Affects CodoMetis.ValueRanges.EFCore.PostgreSQL package/efcore-nodatime Affects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime severity/low Cosmetic, message or documentation-level difference labels Oct 24, 2026
@CaffeinatedCoder
CaffeinatedCoder merged commit 03c04e4 into release/10.x Oct 24, 2026
10 of 12 checks passed
@CaffeinatedCoder
CaffeinatedCoder deleted the fix/387-null-element-contains-10.x branch October 24, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/range-set RangeSet and multirange algebra area/ranges Range unions, variants and the shape engines bug Something isn't working package/efcore Affects CodoMetis.ValueRanges.EFCore.PostgreSQL package/efcore-nodatime Affects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime severity/low Cosmetic, message or documentation-level difference silent Answers wrongly without throwing — fixes go in the next major, never deferred

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant