Repository navigation
Description
Problem
Length on Int32Range and Int64Range runs in memory only (docs/efcore.md#what-runs-where), so a query can't filter or order by it. The obstacle the docs gave until #402 (that int4range overflows before a cast can widen it) doesn't hold: casting first works.
Change
Translate Length on both types to a scalar the server evaluates, matching memory exactly:
Int32Range(long?):CASE WHEN isempty(x) THEN 0 ELSE upper(x)::bigint - lower(x)::bigint END. An unbounded side gives NULL becauseupper/lowerdo, which is memory'snull. Measured on PostgreSQL 16: 4294967295 for[-2147483648,2147483647), 0 forempty, NULL for[1,). PostgreSQL's canonical[)form makesupper - lowerthe count memory returns ([1,10]measures 10).Int64Range(long?): memory computes indecimaland returnsnullwhen the count exceedslong.MaxValue. The SQL has to do the same:numericarithmetic, and NULL above9223372036854775807, never anint8overflow error or a wrapped value.- Declared nullability: NULL for a NULL range too (rule (c), a value-producing member over NULL).
Done when
Every condition on the 10.3.0 epic's parity list holds for both types: empty and unbounded shapes, the domain extremes, a nullable column and an outer-join operand, Where, OrderBy, a final Select (which ran in memory before) and a composed predicate (Length > n with &&/!), each against memory over the loaded rows on a live server. translation-support.json (#384) classifies both server, and the docs move the row to "Runs as SQL". main first, then the cherry-pick to release/10.x.
Activity
CaffeinatedCoder commentedon Oct 25, 2026
PR #437 on
main. Measured on PostgreSQL 16 before writing it, over columns, parameters and inlined constants:int4range:[-2147483648,2147483646]gives 4294967295. The empty range gives 0, an unbounded side NULL, and a NULL range NULL.int8range:[0, long.MaxValue - 1]and[long.MinValue, -2]givelong.MaxValue. One more, as in[-1, long.MaxValue - 1], gives NULL, and constants too large to count raise no planning error.The composition sweeps run over the
DateRangefamily only, so they don't reach these members.IntegerLengthParityTestscovers #408's parity list for them instead. The 10.x cherry-pick follows the merge.Merge pull request #437 from CaffeinatedCoder/feat/405-translate-inte…
CaffeinatedCoder commentedon Oct 25, 2026
Runs as SQL on
mainsince PR #437 (67628e2). Therelease/10.xcherry-pick is tracked separately (port issue under #408).Merge pull request #439 from CaffeinatedCoder/feat/438-translate-inte…