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

[SMALL] Fix to #30996 - Incorrect translation of comparison of current value with owned type default value #31714

Merged
merged 1 commit into from
Sep 14, 2023

Conversation

maumar
Copy link
Contributor

@maumar maumar commented Sep 12, 2023

In optional dependent table sharing scenario, when comparing the dependent to null we first look for any required properties (at least one of them needs to be null), and if we don't have any required properties we look at optional ones (even though this is somewhat ambiguous). Error was that we did similar check as with required properties (i.e. at least one of them must be null, but what we should be doing is checking that all of them are null.

Fixes #30996

@@ -1797,7 +1797,7 @@ bool TryRewriteEntityEquality([NotNullWhen(true)] out Expression? result)
CreatePropertyAccessExpression(nonNullEntityReference, p),
Expression.Constant(null, p.ClrType.MakeNullable()),
nodeType != ExpressionType.Equal))
.Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.OrElse(l, r) : Expression.AndAlso(l, r));
.Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.AndAlso(l, r) : Expression.OrElse(l, r));
Copy link
Member

Choose a reason for hiding this comment

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

There's a very similar Aggregate just above and another one below - do these also need to be changed or is it specific to this one only?

I'm also not sure I fully understand this (but who does understand optional dependents...)... Isn't the point here that at least one required property is null (as per the variable name atLeastOneNonNullValueInNullablePropertyCondition), and therefore OrElse is the right thing to do for Equal?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the aggregate above is for the required properties (at least one must be null to satisfy the entity == null condition), and the aggregate below is for a regular case (i.e. non optional dependant with table sharing), where we just compare keys to null - also only one of them must be null to conclude that the entity itself is null.

In the aggregate that is changed we are comparing nullable properties, since there were no non-nullable properties we could rely on. Will change the variable name as it's confusing. Depending on the nodeType of the entity comparison it does different things :) if we check that entity is null, we need to check that all the nullable properties are null. In case of entity != null we need to check that at least one of them is non null.

Also, see #29206 for extra context

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for explaining @maumar! FWIW having that text as comments in the source would help a lot in this non-obvious piece of logic. Still not sure about everything in this area but looks good enough :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, I added some comments above. Don't fully understand the whole logic either but this this part I'm fairly confident about.

…with owned type default value

In optional dependent table sharing scenario, when comparing the dependent to null we first look for any required properties (at least one of them needs to be null), and if we don't have any required properties we look at optional ones (even though this is somewhat ambiguous).
Error was that we did similar check as with required properties (i.e. at least one of them must be null), but what we should be doing is checking that all of them are null.

Fixes #30996
@@ -1797,7 +1797,7 @@ bool TryRewriteEntityEquality([NotNullWhen(true)] out Expression? result)
CreatePropertyAccessExpression(nonNullEntityReference, p),
Expression.Constant(null, p.ClrType.MakeNullable()),
nodeType != ExpressionType.Equal))
.Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.OrElse(l, r) : Expression.AndAlso(l, r));
.Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.AndAlso(l, r) : Expression.OrElse(l, r));
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for explaining @maumar! FWIW having that text as comments in the source would help a lot in this non-obvious piece of logic. Still not sure about everything in this area but looks good enough :)

@maumar maumar merged commit 47f8393 into release/8.0 Sep 14, 2023
7 checks passed
@maumar maumar deleted the fix30996 branch September 14, 2023 15:57
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.

Incorrect translation of comparison of current value with owned type default value
2 participants