Repository navigation
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
Description
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 expectingFROM (VALUES (NULL::int4range)) AS w("Value") WHERE FALSE(orNULL::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 theCapturedCollectionProbeTestssweepsRanges_AnswerAsInMemoryandValueSets_AnswerAsInMemory, whose empty rows throw42883for every range and set type, every collection form (array,List,HashSet,IEnumerable), alone and beside aContains: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 aruntimeconfig.template.jsonconfigPropertiesentry) all 289 and all 280 pass on EF Core 10.0.13 / Npgsql EF 10.0.3: EF Core refuses the emptyVALUESagain and the 10.0.0 rewriter handles it. The cost is losing EF Core's own fix for empty parameter collections of other types (aJoinover 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
CaffeinatedCoder commentedon Oct 19, 2026
Fixed on
release/10.xby PR #306, merged as 05e5364 on 2026-10-19 (after #305 opened 10.1.0). Closed by hand:Closesacts only onmain, where the fix arrived with PR #292 (#290).TEMPORARY, to be dropped: revert the #302 rewriter to show the newest…
test: run the EF suites on the newest EF Core / Npgsql EF 10 patch as…
TEMPORARY, to be dropped: revert the #302 rewriter to show the newest…