Skip to content

test: composition sweeps — outer joins, nullable operand pairs, quantifiers, repeated execution, filtered aggregates, declared nullability (#375–#380) - #383

Merged
CaffeinatedCoder merged 2 commits into
mainfrom
test/362-composition-sweeps
Oct 24, 2026
Merged

CaffeinatedCoder merged 2 commits into
mainfrom
test/362-composition-sweeps

Conversation

@CaffeinatedCoder

Copy link
Copy Markdown
Owner

Closes #375
Closes #376
Closes #377
Closes #378
Closes #379
Closes #380

Problem

The differential sweeps vary shapes, types and operand kinds, mostly in a projection and over one nullable column at most. #349, #350, #355, #360 and #361 all came from how a translated call composes inside a query: where the NULL comes from, what EF Core's null semantics do around it, and what a later execution reuses. Nothing swept that axis (#362).

Change

Six sweeps in the integration project, each in a database of its own, over DateRange, its RangeSet and StringSet, with the members discovered (Composition/CompositionMembers.cs):

Class Issue What it composes
OuterJoinProbeTests #375 every member over the child of a parent without one (navigation, GroupJoin + DefaultIfEmpty, LeftJoin), the factories over the child's element columns, bounds through ??
NullableOperandPairProbeTests #376 every binary member over two nullable columns, a CASE and a COALESCE, on every (null, value) pair; equality and CompareTo under their documented rules
QuantifierProbeTests #377 Any/All/Count/Contains over captured lists holding NULL; P && Q, P || Q with De Morgan; predicates over value-producing members
RepeatedExecutionProbeTests #378 one query re-run with its parameter walked null → finite → empty → (,) → null and back, lists walked empty → one → duplicate → NULL; EF.CompileQuery/EF.CompileAsyncQuery
FilteredAggregateProbeTests #379 RangeAgg/RangeIntersectAgg over groups that are filtered empty, all NULL, hold empty, or are a LeftJoin key without rows, consumed by every member, HAVING, HAVING NOT and an ordering by a bound
DeclaredNullabilityTests #380 every function the translators emit against pg_proc.proisstrict and the server (typed NULLs, empty, (,), {}); every translated value's null test against its projection

The reference is Composition/NullRule.cs: the expression rewritten so a NULL never reaches the library (rule (c) for a predicate, no value for a value-producing member or a missing element, equality and CompareTo under their own documented rules, aggregates skipping NULL). Documented differences are mapped, not reported: E07 (aggregates over zero inputs), E72 (ordering by a bound), CompareTo (#261). CompositionRunner adds a reference-free check to every call: Where(P) and Where(!P) partition the rows and Select(P) says which side each row is on.

Registered in test/oracles/oracles.json, named in the heldBy of E07, E70, E71 and E72, with the axes in test/oracles/axes.md and a section in docs/oracles.md. No change to src/.

What they found

Every disagreement is a filed issue and a candidates.json entry:

Clean: predicates, bounds and range/multirange value operations over a missing child; two nullable operands including CASE/COALESCE; equality and CompareTo; quantifiers over lists holding NULL (apart from #381's All); 112 compound predicates with De Morgan; nested predicates; repeated and compiled execution (apart from #360); every aggregate consumption; every other emitted function's declaration.

Tests

  • All six classes pass on PostgreSQL 16 and 18 with their candidates (floors: judged calls per sweep).
  • Seeds, dotnet run tools/oracles.cs seeds, each CAUGHT by the sweeps it names:
    • range-predicate-over-a-null-column-is-null, value-set-predicate-over-a-null-column-is-null: sweeps 1–4;
    • bound-declared-null-only-for-a-null-argument (fix: declare lower() and upper() NULL for a non-null range #353 reverted): sweeps 1, 2, 5, 6;
    • aggregates-fold-a-null-input: sweep 5;
    • new sql-processor-reuses-its-first-output: sweep 4 (no other sweep re-executes a query shape with another parameter);
    • new range-agg-declared-never-null: sweep 5.
  • Conventions project green (seeds, candidates, claims, catalogue).

🤖 Generated with Claude Code

…antifiers, repeated execution, filtered aggregates and declared nullability (#375–#380)

Six integration sweeps vary how a translated range, RangeSet or value set call
composes inside a query, against a rule (c) reference that never lets a NULL
reach the library (Composition/NullRule.cs), plus a reference-free partition
check on every call: Where(P) and Where(!P) partition the rows and Select(P)
says which side each row is on.

- OuterJoinProbeTests (#375): every member over the child of a parent without
  one, through a navigation, GroupJoin with DefaultIfEmpty and LeftJoin.
- NullableOperandPairProbeTests (#376): every binary member over two nullable
  columns, a CASE and a COALESCE of them.
- QuantifierProbeTests (#377): Any/All/Count/Contains over captured lists
  holding NULL, compound predicates with De Morgan, nested predicates.
- RepeatedExecutionProbeTests (#378): one query re-run with its parameter
  walked through null, finite, empty and infinite; compiled queries.
- FilteredAggregateProbeTests (#379): RangeAgg/RangeIntersectAgg over groups a
  filter empties, all NULL, holding empty, or a LeftJoin key without rows,
  consumed by every member, HAVING and an ordering; E07 mapped.
- DeclaredNullabilityTests (#380): every emitted function's declaration against
  pg_proc.proisstrict and the server, and every value's null test against its
  projection.

Disagreements are registered as candidates: #381 and #382 (new), #360.
Two new seeds prove the re-execution and aggregate sweeps; the existing null
seeds now name the sweeps they were shown to catch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CaffeinatedCoder
CaffeinatedCoder merged commit f541bde into main Oct 24, 2026
11 checks passed
@CaffeinatedCoder
CaffeinatedCoder deleted the test/362-composition-sweeps branch October 24, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment