Skip to content

Commit

Permalink
Use XOR to translate some == and != expressions
Browse files Browse the repository at this point in the history
When the parent expression is not a predicate, translate `x != y` to:
```sql
x ^ y
```

instead of

```sql
CASE
    WHEN x <> y THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END
```

Similarly, translate `x == y` to:

```sql
x ^ y ^ CAST(1 AS bit)
```

instead of

```sql
CASE
    WHEN x == y THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END
```

Contributes to dotnet#34001 for simple cases (comparison of BIT expressions).
  • Loading branch information
ranma42 committed Jun 30, 2024
1 parent 051c33a commit 1cab1dc
Showing 1 changed file with 25 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,31 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres

_isSearchCondition = parentIsSearchCondition;

if (!parentIsSearchCondition
&& newLeft.Type == typeof(bool) && newRight.Type == typeof(bool)
&& sqlBinaryExpression.OperatorType is ExpressionType.NotEqual or ExpressionType.Equal)
{
// on BIT, "lhs != rhs" is the same as "lhs ^ rhs", except that the
// first is a boolean, the second is a BIT
var result = _sqlExpressionFactory.MakeBinary(
ExpressionType.ExclusiveOr,
newLeft,
newRight,
sqlBinaryExpression.TypeMapping)!;

// "lhs == rhs" is the same as "NOT(lhs == rhs)" aka "lhs ^ rhs ^ 1"
if (sqlBinaryExpression.OperatorType is ExpressionType.Equal) {
result = _sqlExpressionFactory.MakeBinary(
ExpressionType.ExclusiveOr,
result,
_sqlExpressionFactory.Constant(true, result.TypeMapping),
result.TypeMapping
)!;
}

return result;
}

sqlBinaryExpression = sqlBinaryExpression.Update(newLeft, newRight);
var condition = sqlBinaryExpression.OperatorType is ExpressionType.AndAlso
or ExpressionType.OrElse
Expand Down

0 comments on commit 1cab1dc

Please sign in to comment.