Skip to content

Commit

Permalink
Prefer equality in boolean comparisons
Browse files Browse the repository at this point in the history
They can take advantage of indexing.
  • Loading branch information
ranma42 committed Jul 12, 2024
1 parent bc170c7 commit 0f40cf7
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion src/EFCore.Relational/Query/SqlNullabilityProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,7 @@ protected virtual SqlExpression VisitSqlBinary(
right,
leftNullable,
rightNullable,
optimize,
out nullable);

if (optimized is SqlUnaryExpression { Operand: ColumnExpression optimizedUnaryColumnOperand } optimizedUnary)
Expand Down Expand Up @@ -1623,6 +1624,7 @@ private SqlExpression ProcessJoinPredicate(SqlExpression predicate)
right,
leftNullable,
rightNullable,
optimize: true,
out _);

return result;
Expand All @@ -1649,6 +1651,7 @@ private SqlExpression OptimizeComparison(
SqlExpression right,
bool leftNullable,
bool rightNullable,
bool optimize,
out bool nullable)
{
var leftNullValue = leftNullable && left is SqlConstantExpression or SqlParameterExpression;
Expand Down Expand Up @@ -1752,7 +1755,24 @@ private SqlExpression OptimizeComparison(

nullable = false;

return sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ leftNegated == rightNegated
var notEqual = sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ leftNegated == rightNegated;

// prefer equality in predicates
if (optimize && notEqual && left.Type == typeof(bool))
{
if (right is ColumnExpression && (left is not ColumnExpression || leftNegated))
{
left = _sqlExpressionFactory.Not(left);
}
else
{
right = _sqlExpressionFactory.Not(right);
}

return _sqlExpressionFactory.Equal(left, right);
}

return notEqual
? _sqlExpressionFactory.NotEqual(left, right)
: _sqlExpressionFactory.Equal(left, right);
}
Expand Down Expand Up @@ -1798,6 +1818,10 @@ private SqlExpression RewriteNullSemantics(
{
body = _sqlExpressionFactory.Equal(left, right);
}
else if (optimize && sqlBinaryExpression.OperatorType == ExpressionType.Equal)
{
body = _sqlExpressionFactory.Equal(leftUnary ?? left, rightUnary ?? right);
}
else
{
// a == !b and !a == b in SQL evaluate the same as a != b
Expand Down

0 comments on commit 0f40cf7

Please sign in to comment.