Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/9.0-staging] Fix to #35393 - GroupJoin in EF Core 9 Returns Null for Joined Entities #35448

Closed
wants to merge 1 commit into from

Conversation

maumar
Copy link
Contributor

@maumar maumar commented Jan 10, 2025

Problem was that in EF9 we moved some optimizations from sql nullability processor to SqlExpressionFactory (so that we optimize things early). One of the optimizations:

!(true = a) -> false = a
!(false = a) -> true = a

In principle, this should be valid in 3-value logic

a	(true = a) !(true = a) (false = a)
0	    0		1	  1
1	    1		0	  0
N	    N		N	  N

but not in c# semantics, both null == true and null == false are evaluated to false, so !(true == a) is not the same as false = a (first one is true, second one is false)

Fix is to drop this optimization from SqlExpressionFactory and instead compensate in nullability processor (where we have full nullability information), so that we don't regress performance for cases in which this optimization happened to be valid.

Fixes #35393

if (!UseOldBehavior35393)
{
// prefer equality in predicates when comparing to constants
if (optimize && notEqual && left.Type == typeof(bool) && (left is SqlConstantExpression || right is SqlConstantExpression))
Copy link
Contributor Author

@maumar maumar Jan 10, 2025

Choose a reason for hiding this comment

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

this is the port of @ranma42 's #34166 but I constrained the new optimization to constants to prevent changes in generated SQL for the patch

@maumar maumar requested review from a team and Copilot January 10, 2025 13:00

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • src/EFCore.Relational/Query/SqlNullabilityProcessor.cs: Evaluated as low risk
Comments suppressed due to low confidence (1)

test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs:2484

  • [nitpick] The variable name prm is ambiguous. It should be renamed to nullableBoolParam.
var prm = default(bool?);
@maumar
Copy link
Contributor Author

maumar commented Jan 10, 2025

We could also go with a simpler version, which just removes the faulty optimization. There are some other queries which are affected and perf could regress on them. Thoughts? - see #35449

Problem was that in EF9 we moved some optimizations from sql nullability processor to SqlExpressionFactory (so that we optimize things early). One of the optimizations:

!(true = a) -> false = a
!(false = a) -> true = a

In principle, this should be valid in 3-value logic

	a	(true = a) !(true = a) (false = a)
	0	    0		1	  1
	1	    1		0	  0
	N	    N		N	  N

but not in c# semantics, both null == true and null == false are evaluated to false, so !(true == a) is not the same as false = a (first one is true, second one is false)

Fix is to drop this optimization from SqlExpressionFactory and instead compensate in nullability processor (where we have full nullability information), so that we don't regress performance for cases in which this optimization happened to be valid.

Fixes #35393
@maumar maumar force-pushed the fix35393_90_take2 branch from a6a4f9f to e81aba0 Compare January 10, 2025 13:48
@maumar maumar marked this pull request as draft January 10, 2025 13:58
@maumar maumar closed this Jan 14, 2025
@maumar
Copy link
Contributor Author

maumar commented Jan 14, 2025

closing in favor of the simpler version

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