Skip to content

test: translation-support inventory — every public query member classified and probed against EF Core (#384) - #386

Open
CaffeinatedCoder wants to merge 1 commit into
mainfrom
test/384-translation-inventory
Open

CaffeinatedCoder wants to merge 1 commit into
mainfrom
test/384-translation-inventory

Conversation

@CaffeinatedCoder

Copy link
Copy Markdown
Owner

Closes #384

Stacked on #383 (it reuses the composition helpers and touches the same registry files); review that one first.

Problem

postgres-surface.json inventories PostgreSQL's side. Nothing inventoried the C# side: which public members a query can call, and whether EF Core runs each one as SQL. docs/efcore.md#what-runs-where lists both halves by hand, and a member in neither table (a new overload, a generic family, a member the docs never mention) had no stated support. A member whose translation disappeared or appeared was noticed only if a hand-written test called it. The composition sweeps counted Clamp as "untranslated" without saying whether that was intended.

Change

  • QueryMembers (conventions project, linked into the integration project): discovered from the public API, not from the translators. Every public method and instance property of a public, non-nested type of the two libraries whose receiver, a parameter or the result is a range, a multirange or a value set. One key per overload, with generic families kept generic. Converters, static constants and overloads an expression tree cannot hold (ReadOnlySpan<char>, out) are left out by rule. That gives 813 keys.
  • test/oracles/translation-support.json: 36 entries, first match wins: server, client (with the reason) or planned (with the issue). Every classification comes from the docs, or says plainly that the docs don't mention the member.
  • TranslationSupportInventoryTests (conventions, no database): every key is classified, no entry is stale, and every entry carries what its support needs. A new public member fails CI until it is classified.
  • TranslationSupportProbeTests (integration): 2,254 member × type cells over 13 range and 34 value set types, about 12 s. Each call takes a column as an operand. It first runs where the server must evaluate it: a filter for a predicate, a null test for a value that can be NULL, an ordering for one that can't (EF Core folds (int?)x == null away untranslated), and HAVING for an aggregate. Then it runs in a final projection. Both are compared with memory over the rows as loaded.
  • Registered in oracles.json, named in E30/E31 heldBy, described in docs/oracles.md and AGENTS.md.

What it found

  • RangeLowerBoundComparer.Compare runs as SQL in the range order: EF Core rewrites any Compare(a, b) to the natural comparison #385 (new, silent, low): EF Core rewrites any Compare(a, b) to the natural comparison. So RangeLowerBoundComparer<TRange, T>.Instance.Compare(r.Period, p) runs as SQL in the full range order. Where(… == 0) drops ranges that share p's lower bound. It is registered as a candidate. The root cause is EF Core's: a comparer that reverses int order gets the same treatment. Reporting that upstream is separate.
  • Everything else agrees with the docs: 1,656 cells run as SQL with memory's answers, and 598 run in memory only and project memory's answers.

Members docs/efcore.md#what-runs-where doesn't mention (classified from what the probe shows; listed for a docs decision)

The docs call the calendar factories (Month, Quarter, Year, IsoWeek with a column argument) "not translated yet" but no issue tracks them, so they're classified client, not planned.

Tests

  • TranslationSupportInventoryTests 3/3; conventions project 412/412.
  • TranslationSupportProbeTests passes on PostgreSQL 16 and 18 with the RangeLowerBoundComparer.Compare runs as SQL in the range order: EF Core rewrites any Compare(a, b) to the natural comparison #385 candidate; integration project 301/301 on both.
  • Seed merge-translation-dropped.patch (the range translator stops translating Merge): CAUGHT by TranslationSupportProbeTests as "classified server, but refused" on every range type.
  • While building it, three probe artifacts were fixed in the harness, not reported: an explicit Convert to the interface parameter (C# passes the column without one), CultureInfo as a constant in a client projection, and sub-microsecond probe elements (the store's truncation is TemporalStoreParityTests' to judge).

🤖 Generated with Claude Code

…ified and probed against EF Core (#384)

The public API's query members are discovered (QueryMembers: every public
method and instance property whose receiver, a parameter or the result is a
range, a multirange or a value set; one key per overload, generic families kept
generic; converters, constants and span/out overloads out by rule) and each is
classified in test/oracles/translation-support.json as server, client (with the
reason) or planned (with the issue).

- TranslationSupportInventoryTests (conventions): every key classified, no stale
  entry, every entry with what its support needs.
- TranslationSupportProbeTests (integration): 811 keys over 2,254 member/type
  cells, each with a column operand, first where the server must evaluate it
  (filter, null test, ordering for a non-nullable value, HAVING for an
  aggregate), then in a final projection, against memory over the loaded rows.

The first run found #385: EF Core rewrites any Compare(a, b) to the natural
order, so RangeLowerBoundComparer.Compare runs as SQL in the range order.
Seeded by merge-translation-dropped.patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CaffeinatedCoder CaffeinatedCoder added tests Adds or changes tests only (oracles, harnesses); no library code area/ranges Range unions, variants and the shape engines area/range-set RangeSet and multirange algebra area/value-sets Value set families and wrapper arities package/efcore Affects CodoMetis.ValueRanges.EFCore.PostgreSQL package/efcore-nodatime Affects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime stacked Base is another open PR; merge in order, CI does not run until it targets main labels Oct 24, 2026
Base automatically changed from test/362-composition-sweeps to main October 24, 2026 20:30

This branch has not been deployed

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

Labels

area/range-set RangeSet and multirange algebra area/ranges Range unions, variants and the shape engines area/value-sets Value set families and wrapper arities package/efcore Affects CodoMetis.ValueRanges.EFCore.PostgreSQL package/efcore-nodatime Affects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime stacked Base is another open PR; merge in order, CI does not run until it targets main tests Adds or changes tests only (oracles, harnesses); no library code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant