Skip to content

10.x: Any/Count over an empty captured list of ranges or value sets fails with 42883: operator does not exist: text && int4range on EF Core 10.0.2 and later (dotnet/efcore#37216) #302

Closed

Description

@CaffeinatedCoder

Problem

EmptyCollectionRewriter (#137, 10.0.0) handles the shape EF Core 10.0.0 gives an empty captured collection that is sent one parameter per element: a VALUES with no rows, which EF Core's SQL generator refused, and which the rewriter replaces with one row of typed NULLs under WHERE FALSE. dotnet/efcore#37248 (milestone 10.0.2; backport of dotnet/efcore#37216; off switch Microsoft.EntityFrameworkCore.Issue37216, first present in the 10.0.2 assemblies) makes EF Core replace the empty VALUES itself, in SqlNullabilityProcessor, with (SELECT NULL AS "Value" WHERE FALSE) AS w. That runs before the plugin's pass, so the rewriter sees no empty VALUES and is a no-op. The NULL is bare: Npgsql writes a null constant without its type, PostgreSQL types it as text, and the query fails on the server.

Same defect as #290 on the 11 line, but on 10.x it is live, not pending: Npgsql EF 10.0.1, 10.0.2 and 10.0.3 require Microsoft.EntityFrameworkCore [10.0.4, 11.0.0), so every consumer on a current provider resolves an EF Core that has the change. Only an application pinned to Npgsql EF 10.0.0 with EF Core 10.0.0 or 10.0.1 — this repository's CI — does not see it (#297).

Measured 2026-10-19 on release/10.x (d47d9a3, the 10.0.0 code) with the test hosts resolving EF Core 10.0.13 and Npgsql EF 10.0.3 while the src/ projects stay compiled against the 10.0.0 floor, as a consumer's application is (a scratch test/Directory.Build.targets adding the newer packages to the EF test projects, -p:EfFloat=10.0.13 -p:NpgsqlEfFloat=10.0.3):

  • CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests: 4 of 289 fail — Any_OverAnEmptyCapturedList_ReadsNoRows, Count_OverAnEmptyCapturedList_ReadsNoRows, AnyAlone_OverAnEmptyCapturedList_ReadsNoRows, AnyBesideContains_OverAnEmptyCapturedList_ReadsNoRows — each expecting FROM (VALUES (NULL::int4range)) AS w("Value") WHERE FALSE (or NULL::text[]) and getting EF Core's shape.
  • CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests (PostgreSQL 16): 5 of 280 fail — AnEmptyCollection_AnyAndCountAnswerAsInMemory, AnEmptyCollectionAlone_AnyAndCountAnswerAsInMemory, AnEmptyCollectionBesideContains_AnyAndCountAnswerAsInMemory, and the CapturedCollectionProbeTests sweeps Ranges_AnswerAsInMemory and ValueSets_AnswerAsInMemory, whose empty rows throw 42883 for every range and set type, every collection form (array, List, HashSet, IEnumerable), alone and beside a Contains: operator does not exist: text && int4range, text && daterange, text -|- daterange, text && date[], text <@ date[], function isempty(text) does not exist, function cardinality(text) does not exist.
  • The NodaTime translation tests (83) and the InfinityDisabled integration tests (4) pass on the same versions.
  • Stopgap, measured: with AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue37216", true) (as a runtimeconfig.template.json configProperties entry) all 289 and all 280 pass on EF Core 10.0.13 / Npgsql EF 10.0.3: EF Core refuses the empty VALUES again and the 10.0.0 rewriter handles it. The cost is losing EF Core's own fix for empty parameter collections of other types (a Join over an empty list fails again with "Empty collections are not supported as inline query roots").

In memory the same Any is false and Count is 0, and docs/efcore.md promises "an empty list matches nothing". Loud, not silent.

Change

Port the #290 fix from PR #292 to release/10.x — the rewriter matches EF Core's table-less SELECT of null constants under WHERE FALSE and casts each constant whose type is a registered range or set type to its store type (NULL::int4range), the mapping EF Core attached from the parameter's element mapping — and keeps the 10.0.0 path: on the 10.x floor (EF Core 10.0.0 and 10.0.1, and any patch with the switch set) the empty VALUES still arrives and must still be rewritten. The 11 branch dropped that path because EF Core 11 never produces it. Other types keep EF Core's SQL (EmptyCollectionGuardTests).

Tests: the four translation tests pin one SQL per shape, chosen by the EF Core version the test host resolved, so the floor leg and the newest-patch leg of #297 each assert theirs; the integration tests of the answers are unchanged and stay the authority. The changelog line names the stopgap switch and its cost.

PR #292 is a single commit, so this is a hand-extracted commit naming the PR, not a cherry-pick -x.

Done when

On release/10.x, the EF translation and integration suites pass on EF Core 10.0.0 / Npgsql EF 10.0.0 and on EF Core 10.0.13 / Npgsql EF 10.0.3 with the switch unset, and reverting the port fails the four translation tests and the five integration tests on the newest patch while the floor stays green.

Activity

  1. added this to the 10.0.1 milestone on Oct 19, 2026
  2. added
    bugSomething isn't working
    area/range-setRangeSet and multirange algebra
    area/value-setsValue set families and wrapper arities
    package/efcoreAffects CodoMetis.ValueRanges.EFCore.PostgreSQL
    package/efcore-nodatimeAffects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime
    severity/highWrong results, crash or failed writes in a realistic scenario
    on Oct 19, 2026
  3. CaffeinatedCoder commented on Oct 19, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Fixed on release/10.x by PR #306, merged as 05e5364 on 2026-10-19 (after #305 opened 10.1.0). Closed by hand: Closes acts only on main, where the fix arrived with PR #292 (#290).

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/value-setsValue set families and wrapper aritiesbugSomething isn't workingpackage/efcoreAffects CodoMetis.ValueRanges.EFCore.PostgreSQLpackage/efcore-nodatimeAffects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTimeseverity/highWrong results, crash or failed writes in a realistic scenario

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions