Skip to content

Commit

Permalink
Fix comparison of nullable values
Browse files Browse the repository at this point in the history
In C# an ordered comparison (<, >, <=, >=) between two nullable values always
returns a boolean value: if either operand is null, the result is false;
otherwise, the result is that of the comparison of the (non-null) values.

Fixes dotnet#33752
  • Loading branch information
ranma42 committed May 20, 2024
1 parent d3cee1b commit b1719dc
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/EFCore.Relational/Query/SqlNullabilityProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,28 @@ protected virtual SqlExpression VisitSqlBinary(
nullable = leftNullable || rightNullable;
var result = sqlBinaryExpression.Update(left, right);

if (nullable && !optimize && result.OperatorType
is ExpressionType.GreaterThan
or ExpressionType.GreaterThanOrEqual
or ExpressionType.LessThan
or ExpressionType.LessThanOrEqual)
{
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/nullable-value-types#lifted-operators
// For the comparison operators <, >, <=, and >=, if one or both
// operands are null, the result is false; otherwise, the contained
// values of operands are compared.

// if either operand is NULL, the SQL comparison would return NULL;
// to match the C# semantics, replace expr -> COALESCE(expr, FALSE)

nullable = false;
return _sqlExpressionFactory.Coalesce(
result,
_sqlExpressionFactory.Constant(false),
result.TypeMapping
);
}

return result is SqlBinaryExpression sqlBinaryResult
&& sqlBinaryExpression.OperatorType is ExpressionType.AndAlso or ExpressionType.OrElse
? SimplifyLogicalSqlBinaryExpression(sqlBinaryResult)
Expand Down

0 comments on commit b1719dc

Please sign in to comment.