Repository navigation
Translation-support inventory: every public query member classified as server, client-only or planned, and probed against EF Core #384
Description
Problem
test/oracles/postgres-surface.json inventories PostgreSQL's range, multirange and array surface and what the library does about each row. The other direction has no inventory: which public C# members a query can call, and what EF Core does with each. docs/efcore.md#what-runs-where lists both halves by hand, and ClientSideOnlyTranslationTests / ClientSideOnlyProjectionTests hold the in-memory rows by name. A member that is in neither table (a new overload, a generic family, a member the docs never mention) has no stated support, and a member whose translation disappears or appears is noticed only if a hand-written test happens to call it. The composition sweeps (#362, #375–#380) count such members as "untranslated" without saying whether that is intended; Clamp was the example.
Discovering from the registered translators would miss exactly the members without one, so the inventory starts from the public API.
Change
- Discovery (
QueryMembers, conventions project): every public method and instance property declared on a public, non-nested type of the core and NodaTime libraries whose receiver, a parameter or the result is a range, a multirange or a value set; one key per overload, generic families kept generic (RangeSet<TRange, T>.Union(TRange),StringSet<TElement>.Count). Converters, static constants and overloads an expression tree cannot hold (ReadOnlySpan<char>,out) are out by rule. 813 keys today. test/oracles/translation-support.json: each key classified by the first entry whose pattern matches it:server(translates and executes with memory's answer),client(refused where the server is required, correct in a final projection; with the reason), orplanned(asclient, with the issue that adds it). A conventions test fails on an unclassified key and on an entry that matches nothing.- Probe (integration project): each key over every closed type it applies to, with a column operand, in a filter or a null test (where the server is required) and in a final projection, against memory over the rows as loaded. A
servermember that is refused or answers differently, and aclientorplannedmember that now translates, end inCandidates.Verdict.
Defects it finds get their own issue under the release epic they ship in, with a candidate entry. Members the docs do not mention get a classification that says so, and a list in the PR for the user to decide on.
Done when
Registered in test/oracles/oracles.json, seeded (a removed translation is caught), every key classified, and the PR lists what the docs do not say.
Activity
CaffeinatedCoder commentedon Oct 25, 2026
Evaluation and 10.2.0 triage, 2026-10-25.
Runs. PR #386's head (a1263b7) on
main: EF Core 11 RC2, PostgreSQL 16. The same probe and classification ported unchanged to a scratchrelease/10.xcheckout (03c04e4, not committed): EF Core 10.0.0, and 10.0.13 with Npgsql 10.0.3. I added a temporary tally of outcome by classification. All three runs give the same 2,256 cells:server/ runs as SQL, agrees with memoryclient/ refused, projection agrees with memoryclient/ runs as SQL, answers differently (#385)client/ unprobed (no operand)On 10.x the 10.x public API is fully classified by the same
translation-support.json. The only failures are #385's 26 lines, which 10.x'scandidates.jsondoesn't register (main's does).Triage for 10.2.0.
what-runs-wheredoesn't mention are tracked in docs: what-runs-where omits Equals, RangeSet.Count, the indexers, Values, Parse/ToString and the NodaTime conversions (found by #384) #399, docs only, with no wrong answer. Whether it goes into 10.2.0 is open.serveris refused or answers differently, and nothing classifiedclienttranslates.Notes on the probe, for PR #386 (none of them hides a defect today):
unprobedcells fail only when the member is classifiedserver. The twoclientcells,ToInstantRange(Interval)andToLocalDateRange(DateInterval), are never run and nothing reports them. Npgsql's NodaTime plugin mapsIntervalandDateIntervalcolumns, so a column operand could reach them.observedis collected but never written or asserted. The table above needed a temporary tally.RangeSetholds one range. That's enough for translation support; shape and pair coverage stays withShapeMatrixParityTestsand the composition sweeps.CaffeinatedCoder commentedon Oct 25, 2026
10.3.0 (#408) depends on this: its additions (#405, #406, #191) are done only when
translation-support.jsonclassifies themserver, so each is now linked as blocked by this issue. The 10.x port is #430. Next on PR #386: bring it up to date withmain, and make thereasontexts follow #399 and #402 (the three notes on the PR).test: follow #399 and #402 in the translation-support reasons, and pl…
Merge pull request #386 from CaffeinatedCoder/test/384-translation-in…
Merge pull request #431 from CaffeinatedCoder/test/430-translation-in…