Skip to content

Fix LeftJoin, RightJoin and FullJoin matching null keys - #623

Merged
SimonCropp merged 1 commit into
mainfrom
fix/join-null-keys
Oct 11, 2026
Merged

SimonCropp merged 1 commit into
mainfrom
fix/join-null-keys

Conversation

@SimonCropp

Copy link
Copy Markdown
Owner

Bug

The LeftJoin, RightJoin and FullJoin polyfills were built on ToLookup + lookup[key]. ToLookup keeps a group for the null key, so an element with a null key was joined to every element on the other side that also had a null key.

The BCL never matches a null key, not even with another null key. For outer [(1,"a"),(2,null),(3,"b")] and inner [(10,"a"),(20,null),(30,"c")], LeftJoin gives 1-10, 2-0, 3-0, while the polyfill gave 1-10, 2-20, 3-0.

FullJoin had a second problem: it recorded null as a seen outer key, so null keyed inner elements were dropped from the unmatched tail.

Fix

  • LeftJoin / RightJoin: only probe the lookup when the key is not null.
  • FullJoin: null keyed inner elements are kept out of the lookup and yielded last as unmatched (the order net11 uses), and null is not recorded as a seen outer key.

Test

IEnumerableLeftJoinNullKeysDoNotMatch, IEnumerableRightJoinNullKeysDoNotMatch and IEnumerableFullJoinNullKeysDoNotMatch join two sequences that both contain null keys and duplicated keys, and assert the full ordered result. The expected values were taken from the BCL on net11. All three failed on net48 before the fix, and pass on net48, net8.0 (polyfill), net10.0 (BCL LeftJoin/RightJoin, polyfilled FullJoin) and net11.0 (BCL).

@SimonCropp SimonCropp added this to the 11.4.4 milestone Oct 11, 2026
@SimonCropp
SimonCropp merged commit 9e16850 into main Oct 11, 2026
5 checks passed
@SimonCropp
SimonCropp deleted the fix/join-null-keys branch October 11, 2026 22:12
This was referenced Oct 12, 2026
This was referenced Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant