Skip to content

[release/11.0] Restore LEFT JOIN translation for correlated grouped DefaultIfEmpty - #39237

Merged
AndriySvyryd merged 4 commits into
release/11.0from
copilot/fix-regression-translated-to-outer-apply
Oct 14, 2026
Merged

AndriySvyryd merged 4 commits into
release/11.0from
copilot/fix-regression-translated-to-outer-apply

Conversation

Copilot AI commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #39220

Description
Since 10.0-rc.2, correlated SelectMany over a grouped subquery followed by DefaultIfEmpty() can produce OUTER APPLY instead of LEFT JOIN even when the key nullability doesn't match.

Customer impact
Affected queries are translated to OUTER APPLY, which causes providers without APPLY support (including SQLite and MariaDB) to throw instead of running the query. An explicit join … into … from … DefaultIfEmpty() is a workaround, but it's non-obvious and rewriting a complex query can require significant work.

Example of an affected query:

var grouped = from t in db.Transactions
              group t.Amount by t.UserId into g
              select new { g.Key, Amount = g.Sum() };

var query = from u in db.Users
            from t in grouped.Where(t => t.Key == u.Id).DefaultIfEmpty()
            select new { u.Id, Amount = (int?)t.Amount ?? 0 };

How found
Customer-reported on 10.0.12.

Regression
Yes, from 9.0.x.

Testing
Tests added

Risk
Low. The change is a narrow condition that reverts to previous behavior. Quirk mode added.

Copilot AI and others added 2 commits October 13, 2026 00:32
…IfEmpty queries

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix regression in correlation translation to LEFT JOIN [release/11.0] Restore LEFT JOIN translation for correlated grouped DefaultIfEmpty Oct 13, 2026
Copilot AI requested a review from AndriySvyryd October 13, 2026 00:39
@AndriySvyryd
AndriySvyryd requested a balanced review from Copilot October 13, 2026 18:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The servicing PR description omits the required customer impact, regression, testing, and risk sections.

0 open findings

What changed in this PR

Restores LEFT JOIN translation for correlated grouped or distinct DefaultIfEmpty queries while retaining a servicing opt-out.

Changes:

  • Accepts nullable projected join keys.
  • Adds shared behavioral tests and provider SQL baselines.
  • Documents the query-pipeline nullability behavior.
File Description
SelectExpression.cs Updates join-key matching and adds the compatibility switch.
NorthwindGroupByQueryRelationalTestBase.cs Adds shared GroupBy and Distinct tests.
NorthwindGroupByQuerySqlServerTest.cs Verifies SQL Server LEFT JOIN SQL.
NorthwindGroupByQuerySqliteTest.cs Verifies SQLite LEFT JOIN SQL.
query-pipeline/​SKILL.md Documents nullable column identity handling.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread .agents/skills/query-pipeline/SKILL.md Outdated
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI requested a review from AndriySvyryd October 13, 2026 20:06
@AndriySvyryd
AndriySvyryd marked this pull request as ready for review October 13, 2026 20:28
@AndriySvyryd
AndriySvyryd requested a review from a team as a code owner October 13, 2026 20:28
@AndriySvyryd
AndriySvyryd requested review from artl93 and cincuranet and a balanced review from Copilot October 13, 2026 20:28

@artl93 artl93 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Customer reported regression. Approved.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrowly scoped fix is covered by result assertions and provider-specific SQL baselines.

0 open findings

🧠 Review effort: Balanced

@github-code-quality

Copy link
Copy Markdown

Code Coverage Overview

Languages: C#

C# / code-coverage

The overall line coverage in commit dce40ae in the copilot/fix-regressi... branch is 67%. The line coverage in commit 2c982ae in the release/11.0 branch is 76%.

Show a line coverage summary of the most impacted files.
File release/11.0 2c982ae copilot/fix-regressi... dce40ae +/-
/Users/runner/w...nal/Snapshot.cs 0% 60% +60%
D:\a\efcore\efc...nal\Snapshot.cs 0% 64% +64%
/home/runner/wo...nal/Snapshot.cs 0% 66% +66%
/home/runner/wo...yTypeBuilder.cs 0% 88% +88%
D:\a\efcore\efc...yTypeBuilder.cs 0% 88% +88%
/Users/runner/w...ngs.Designer.cs 0% 92% +92%
/home/runner/wo...ctExpression.cs 0% 93% +93%
D:\a\efcore\efc...ctExpression.cs 0% 93% +93%
D:\a\efcore\efc...ngs.Designer.cs 0% 94% +94%
/home/runner/wo...ngs.Designer.cs 0% 95% +95%

@AndriySvyryd
AndriySvyryd merged commit c5fa679 into release/11.0 Oct 14, 2026
23 checks passed
@AndriySvyryd
AndriySvyryd deleted the copilot/fix-regression-translated-to-outer-apply branch October 14, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression in 10.0: correlated SelectMany + DefaultIfEmpty over a GroupBy subquery is translated to OUTER APPLY instead of LEFT JOIN

5 participants