Skip to content

10.x: Contains(element) on a range or RangeSet is NULL in SQL for a NULL element (port of #381) #387

Closed

Description

@CaffeinatedCoder

Problem

The same defect as #381, on release/10.x. Contains(T) on a range or a RangeSet is NULL in SQL when its element is NULL: a negated filter drops the row EF Core keeps, a projection into bool throws, and list.All(x => x.Contains(r.Day!.Value)) selects the NULL rows. Rule (c) reached 10.x in #357, but FalseOverNull in ValueRangesMethodCallTranslator wraps only range and multirange operands, not the element. The code is the same on both lines.

An element is NULL when it comes from the optional side of an outer join, or from a nullable column read with .Value. A value set's Contains(element) already answers false/true, so only the range and RangeSet forms are affected.

Change

Cherry-pick the #381 fix with -x, with its regression test: the element operand is wrapped like a range operand (e IS NOT NULL AND x @> e). It's SQL only. EF Core drops the check for a required element, so that SQL doesn't change.

The probes that found it (OuterJoinProbeTests, NullableOperandPairProbeTests, QuantifierProbeTests, PR #383) are on main only, so the port's own test has to cover the negation, the projection and All.

Release

silent: one row under ### Changed answers in ## [10.2.0], linking this issue and its entry under docs/migration.md#changed-answers-in-1020. Fixed only on release/10.x, so close it by hand (#365).

Activity

  1. added this to the 10.2.0 milestone on Oct 24, 2026
  2. added
    bugSomething isn't working
    silentAnswers wrongly without throwing — fixes go in the next major, never deferred
    area/rangesRange unions, variants and the shape engines
    area/range-setRangeSet and multirange algebra
    package/efcoreAffects CodoMetis.ValueRanges.EFCore.PostgreSQL
    on Oct 24, 2026
  3. CaffeinatedCoder commented on Oct 24, 2026

    @CaffeinatedCoder
    OwnerAuthor

    PR #393 cherry-picks the #381 fix (PR #391) with -x. It adds NullElementTests on this line, because the composition probes are on main only. That covers the negation, the projection and All; with the fix stripped, all of them fail.

  4. added 2 commits that reference this issue on Oct 24, 2026
  5. CaffeinatedCoder commented on Oct 24, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Fixed on release/10.x by #393, merged as 03c04e4: Contains(T) over a NULL element is false in a query and its negation true, for a range and a RangeSet, in a filter, a bool projection and All. [10.2.0] has the ### Changed answers row and docs/migration.md its subsection under ## Changed answers in 10.2.0. The RangeSet projection case was added in #394 after the release review. Ships in 10.2.0 (#358). Closed by hand, since Closes acts only on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/range-setRangeSet and multirange algebraarea/rangesRange unions, variants and the shape enginesbugSomething isn't workingpackage/efcoreAffects CodoMetis.ValueRanges.EFCore.PostgreSQLseverity/lowCosmetic, message or documentation-level differencesilentAnswers wrongly without throwing — fixes go in the next major, never deferred

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions