Skip to content

Commit

Permalink
Query: Fix double negation in SQL generation
Browse files Browse the repository at this point in the history
Resolves #26309
  • Loading branch information
smitpatel committed Nov 17, 2021
1 parent 02f2450 commit 9e4eb9a
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -676,20 +676,56 @@ protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpressio
case ExpressionType.Not:
{
_relationalCommandBuilder.Append("~");

var requiresBrackets = RequiresParentheses(sqlUnaryExpression, sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append("(");
}

Visit(sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append(")");
}

break;
}

case ExpressionType.Equal:
{

var requiresBrackets = RequiresParentheses(sqlUnaryExpression, sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append("(");
}

Visit(sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append(")");
}

_relationalCommandBuilder.Append(" IS NULL");
break;
}

case ExpressionType.NotEqual:
{

var requiresBrackets = RequiresParentheses(sqlUnaryExpression, sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append("(");
}

Visit(sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append(")");
}

_relationalCommandBuilder.Append(" IS NOT NULL");
break;
}
Expand Down Expand Up @@ -799,6 +835,13 @@ protected virtual bool RequiresParentheses(SqlExpression outerExpression, SqlExp
return true;
}

if (sqlUnaryExpression.OperatorType == ExpressionType.Negate
&& outerExpression is SqlUnaryExpression { OperatorType: ExpressionType.Negate })
{
// double negative sign has different meaning so we need to enclose it in brackets
return true;
}

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ public virtual Task Negate_on_column(bool async)
ss => ss.Set<Squad>().Where(s => s.Id == -s.Id));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Double_negate_on_column(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Squad>().Where(s => -(-s.Id) == s.Id));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Negate_on_like_expression(bool async)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ FROM [Squads] AS [s]
WHERE [s].[Id] = -[s].[Id]");
}

public override async Task Double_negate_on_column(bool async)
{
await base.Double_negate_on_column(async);

AssertSql(
@"SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE -(-[s].[Id]) = [s].[Id]");
}

public override async Task Negate_on_like_expression(bool async)
{
await base.Negate_on_like_expression(async);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ FROM [Squads] AS [s]
WHERE [s].[Id] = -[s].[Id]");
}

public override async Task Double_negate_on_column(bool async)
{
await base.Double_negate_on_column(async);

AssertSql(
@"SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE -(-[s].[Id]) = [s].[Id]");
}

public override async Task Negate_on_like_expression(bool async)
{
await base.Negate_on_like_expression(async);
Expand Down

0 comments on commit 9e4eb9a

Please sign in to comment.