Repository navigation
feat: CMTK0009 reports the side of an outer join with no match - #278
Open
CaffeinatedCoder wants to merge 5 commits into
Open
CaffeinatedCoder wants to merge 5 commits into
CaffeinatedCoder wants to merge 5 commits into
Conversation
LinqJoins resolves Join, GroupJoin, LeftJoin, RightJoin and FullJoin of Enumerable, Queryable and AsyncEnumerable by symbol, maps a call's arguments to the definition's parameters (receiver, position, name, conditional access), and, where a call does not bind, takes the candidate whose outer sequence the receiver is, the most derived one, as overload resolution would. CMTK0008's key check uses it in place of its own copy, with no change in what it reports; CMTK0009's outer joins (#261) build on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LeftJoin and RightJoin (.NET 10) and FullJoin (.NET 11) hand their result selector, or their tuple, the default of the side with no match. CMTK0009 now reports every overload of LeftJoin whose inner element, RightJoin whose outer element, and FullJoin where either element is a no-default struct, a warning per side, on Enumerable, Queryable and AsyncEnumerable, the .NET 11 tuple-returning overloads included. The message names an Option of each element in memory and a nullable projection in a query. Warning, no code fix. An Option element of a join is not reported: its default is None, which is the way out the message names, and reporting it would flag that rewrite in turn. A join that does not bind, because a lambda reads a generated member before weaving, is read from its candidates. Input class: the receiver and arguments of a LINQ join call, and what its element type is. Catalogues: the call forms (extension, static, named, conditional access, unbound, a list, an array, a query, a sequence-constrained type parameter, sync and async key selectors, with and without a comparer, tuple forms) on each host and side, and TypeArgumentKinds, 79 kinds, against NoDefaultKindTests' oracle. The FullJoin rows compile against Microsoft.NETCore.App.Ref 11.0.0-rc.3.26522.148. Siblings found and fixed here: the unbound call on a query took Enumerable's candidate and gave the in-memory advice, and conditional access was silent. CMTK0008 not listing FullJoin is #273. Closes #261 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…JOIN The .NET 11 join surface CMTK0009 resolves, and EF Core 11.0.0-rc.3.26522.148 on SQLite: a nullable projection under FullJoin is a FULL JOIN reading null for the side with no match, and without it EF throws "Nullable object must have a value." Measured in a scratch net11.0 project outside the solution (11.0.100-rc.1 SDK and runtime, the only ones installed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings #277 (the RC3 spike, KB-060). Both knowledge index rows are kept, KB-059 before KB-060. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #261
Problem
LeftJoinandRightJoin(.NET 10), and .NET 11'sFullJoin, hand their result selector (or their tuple) thedefaultof the side with no match. Over a value object,Resultor[RequireCustomInitialization]struct that is an instance no factory made, and nothing reported it.Change
DefaultProducingCallAnalyzer) reports every overload ofLeftJoinwhose inner element,RightJoinwhose outer element, andFullJoinwhere either element is a no-default struct, a warning per side, onEnumerable,QueryableandAsyncEnumerable. That includes .NET 11's tuple-returning overloads. The message names anOptionof each element in memory (inner.Select(Option.Some)) and a nullable projection in a query (inner.Select(x => (OrderId?)x)). Warning, no code fix.Optionelement of a join is not reported. ItsdefaultisNone, and the advised rewrite produces exactly that element type, so reporting it would flag the way out. Recorded on CMTK0009: report LeftJoin, RightJoin and FullJoin whose unmatched side is a no-default struct #261, in the README and indesign/analyzers.md..Value, as before weaving) is read from its candidates: the elements from the sequences passed, and the candidate whose outer sequence the receiver is (Queryable's for a query, which the first test run caught giving in-memory advice).LinqJoins(new, internal): resolves the joins by symbol, maps arguments to parameters, and ranks candidates. CMTK0008's join check now uses it in place of its own copy (no behaviour change; its tests pass).design/analyzers.md, a changelog line in 2.4.0's "Changed" (warnings-as-errors builds can newly fail), claimsK09-*intest/oracles/claims.json, and KB-059. KB-059 records the .NET 11 join surface, and that EF Core 11.0.0-rc.3.26522.148 translates the nullable projection underFULL JOINon SQLite and throws without it. That was measured in a scratchnet11.0project outside the solution, built by the 11.0.100-rc.1 SDK and run on the 11.0.0-rc.1 runtime, the only ones on this machine.Tests
OuterJoinDefaultTests: a row per method, host and side, with and without a comparer, async key selectors, static and named forms, conditional access, and the unbound form. Controls: the side a join never fills, a class element, a nullable element, an ordinary struct, anOptionelement, both ways out,JoinandGroupJoin. A theory overTypeArgumentKinds(79 kinds) usesNoDefaultKindTests.HasNoDefaultas the oracle.FullJoinand the tuple forms compile against the realMicrosoft.NETCore.App.Ref11.0.0-rc.3.26522.148 through the verifier'sReferenceAssemblies, resolved from nuget.org asNet100is; no stub.net11.0project with the built analyzer): the same forms reported and both ways out stayed silent.Optionexemption dropped: the silent test;LeftJoinside swapped: 10 failures;rows?.LeftJoin(…)) silent, now fixed with a row. A join reached as a method group converted to a delegate has no invocation and isn't reported.tools/BuildVerdict(SQL Server tests onazure-sql-edge, as AGENTS says for an arm64 Mac).Follow-up: #273 (CMTK0008 doesn't list
FullJoinamong its joins).🤖 Generated with Claude Code