Skip to content

Epic: 10.2.0 #358

Closed
12 of 12 issues completed
Closed

Description

@CaffeinatedCoder

Goal

10.2.0 is the second release on the 10.x LTS line, shipped from release/10.x. It is a minor because it carries silent fixes, which ship only in a minor that opens with ### Changed answers (CONTRIBUTING.md, "A fix that changes an answer"). Both came from a consumer's differential probe against 10.1.0 (2026-10-23), which ran each EF Core query and the same LINQ over the loaded rows. The query and memory selected different rows in two cases: when a range bound is compared with null, and when a predicate runs over a NULL column.

In scope

Changed answers

Docs

Fixed (not silent)

Release

Sequence

  1. Open 10.2.0 on release/10.x #331 merges first, so pr-hygiene.sh sees a minor and each fix adds its row under ## [10.2.0].
  2. PR test: register #349 and #350 as ExecutedQueryTests candidates #352 and then PR fix: declare lower() and upper() NULL for a non-null range #353 merge into main. 10.x: LowerBound() and UpperBound() in a query: == null becomes WHERE FALSE and ?? loses its COALESCE (port of #349) #354 cherry-picks both onto release/10.x with -x.
  3. On main: RangeSet.From accepts a null element: the set holds null, IsEmpty() is false and Contains throws #356, A predicate over a NULL range, RangeSet or value set column is NULL in SQL, so its negation drops the row EF Core's own translations keep #355 and A null range answers some extensions in memory and throws on others, and the answers it gives disagree with PostgreSQL on a NULL column #350's predicate part. Then 10.x: a predicate over a null range, RangeSet or value set is false in memory and in SQL (port of the predicate half of #350, #355 and #356) #357 ports them.
  4. On main: RangeIntersectAgg returns empty over a sequence holding a null range, where range_intersect_agg skips the NULL; RangeAgg throws #361 and Docs: ordering by LowerBound() or UpperBound() puts open-ended and empty rows where PostgreSQL puts NULLs, also on a required column #359. Then 10.x: RangeIntersectAgg returns empty over a sequence holding a null range, where range_intersect_agg skips the NULL; RangeAgg throws (port of #361) #363 and 10.x: docs: ordering by LowerBound() or UpperBound() puts open-ended and empty rows where PostgreSQL puts NULLs (port of #359) #364 port them. Neither depends on steps 2 and 3.
  5. On main: Contains(element) on a range or RangeSet is NULL in SQL for a NULL element: the negation drops the row EF Core keeps, and a projection into bool throws #381 and The range factories over a NULL element build a range: CreateFinite gives empty and CreateUnboundedStart/End give (,), where EF Core answers NULL #382, after PR test: composition sweeps — outer joins, nullable operand pairs, quantifiers, repeated execution, filtered aggregates, declared nullability (#375–#380) #383, which registers their candidates. Then 10.x: Contains(element) on a range or RangeSet is NULL in SQL for a NULL element (port of #381) #387 and 10.x: the range factories over a NULL element build a range instead of answering NULL (port of #382) #388 port them.
  6. On main: main: the empty-root rewrite casts EF Core's _ord column to the range type (NULL::int4range AS _ord) #319. Then 10.x: the empty-root rewrite casts EF Core's _ord column to the range type on EF Core 10.0.2 and later (port of #319) #325 ports it. It doesn't depend on steps 2–5.
  7. PR chore: write each package's changelog section into its NuGet release notes (10.x) #348 and PR docs: name the two known differences 10.2.0 ships with (10.x, #397) #398 (10.x: docs: name the two known differences 10.2.0 ships with — value set Union/Remove over NULL (#360) and RangeLowerBoundComparer in a query (#385) #397) merge. Then PR docs: list every public query member in what-runs-where (#399) #400 → PR docs: give each in-memory operation its real reason (#402) #403 on main (docs: what-runs-where omits Equals, RangeSet.Count, the indexers, Values, Parse/ToString and the NodaTime conversions (found by #384) #399, docs: the in-memory reasons overstate what PostgreSQL lacks, and the Shift/Expand one is stale since #224 #402), and PR docs: list every public query member in what-runs-where (10.x, #399) #401 → PR docs: give each in-memory operation its real reason (10.x, #402) #404 on 10.x.
  8. Release 10.2.0: date the changelogs, tag v10.2.0, close the 10.x-only issues, carry the sections to main #365: check every lane, date the five changelogs and tag v10.2.0 (the nuget environment approval is the maintainer's), close the 10.x-only issues by hand, and carry 10.2.0 to main.

Not in scope

Release boundary

Decided 2026-10-24 after the release review: no seventh discovery round before the tag. The six composition sweeps (#375–#380) already cover several independent failure mechanisms. What is left before #365:

A new round becomes worthwhile when it can name a mechanism or a contract that no sweep covers yet. "Perhaps there is another bug" doesn't move this boundary.

Release

Tag v10.2.0 on release/10.x. The root changelog section opens with ### Changed answers, one row per issue (#354, #357, #356, #363, #387, #388), each linking its issue and its entry under docs/migration.md#changed-answers-in-1020. Issues fixed only there are closed by hand (Closes #n acts only on main).

Activity

  1. added this to the 10.2.0 milestone on Oct 24, 2026
  2. added
    epicTracks a release or a theme; its sub-issues are the work
    area/releaseVersioning, changelogs, release wiring
    on Oct 24, 2026
  3. CaffeinatedCoder commented on Oct 25, 2026

    @CaffeinatedCoder
    OwnerAuthor

    10.2.0 released 2026-10-25. v10.2.0 (annotated) is on 7dada5d (PR #411); release run 40183166630 is green. All four packages are on nuget.org, and the GitHub release v10.2.0 is Latest.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/releaseVersioning, changelogs, release wiringepicTracks a release or a theme; its sub-issues are the work

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions