Skip to content

Commit a40e52c

Browse files
committed
Avoid using ^ and ~ on value-converted expressions
The transformation of equality/in-equality in a (negated) XOR is only possible when the expressions are BIT or integer types on the SQL side (i.e. taking value conversion into account). Similarly, the Boolean negation `NOT` can be implemented as `~` only if the underlying expression is a BIT. Fixes #35093.
1 parent 3769433 commit a40e52c

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

src/EFCore.SqlServer/Query/Internal/SearchConditionConverter.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,11 @@ protected virtual Expression VisitSqlBinary(SqlBinaryExpression binary, bool inS
206206

207207
if (binary.OperatorType is ExpressionType.NotEqual or ExpressionType.Equal)
208208
{
209+
var leftType = newLeft.TypeMapping?.Converter?.ProviderClrType ?? newLeft.Type;
210+
var rightType = newRight.TypeMapping?.Converter?.ProviderClrType ?? newRight.Type;
209211
if (!inSearchConditionContext
210-
&& (newLeft.Type == typeof(bool) || newLeft.Type.IsEnum || newLeft.Type.IsInteger())
211-
&& (newRight.Type == typeof(bool) || newRight.Type.IsEnum || newRight.Type.IsInteger()))
212+
&& (leftType == typeof(bool) || leftType.IsInteger())
213+
&& (rightType == typeof(bool) || rightType.IsInteger()))
212214
{
213215
// "lhs != rhs" is the same as "CAST(lhs ^ rhs AS BIT)", except that
214216
// the first is a boolean, the second is a BIT
@@ -262,10 +264,13 @@ protected virtual Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpression
262264

263265
switch (sqlUnaryExpression.OperatorType)
264266
{
265-
case ExpressionType.Not when sqlUnaryExpression.Type == typeof(bool):
267+
case ExpressionType.Not
268+
when (sqlUnaryExpression.TypeMapping?.Converter?.ProviderClrType ?? sqlUnaryExpression.Type) == typeof(bool):
266269
{
267270
// when possible, avoid converting to/from predicate form
268-
if (!inSearchConditionContext && sqlUnaryExpression.Operand is not (ExistsExpression or InExpression or LikeExpression))
271+
if (!inSearchConditionContext &&
272+
sqlUnaryExpression.TypeMapping?.Converter is null &&
273+
sqlUnaryExpression.Operand is not (ExistsExpression or InExpression or LikeExpression))
269274
{
270275
var negatedOperand = (SqlExpression)Visit(sqlUnaryExpression.Operand);
271276

0 commit comments

Comments
 (0)