Skip to content

Commit

Permalink
Translate COALESCE as ISNULL
Browse files Browse the repository at this point in the history
`COALESCE`is a syntactic shortcut for the CASE expression. As such, the input
values are evaluated multiple times.

`ISNULL` does not have this shortcoming.

Fixes dotnet#32519.
  • Loading branch information
ranma42 committed Jul 5, 2024
1 parent 20edb63 commit 8a6afce
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,43 @@ protected override Expression VisitValues(ValuesExpression valuesExpression)
return valuesExpression;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitSqlFunction(SqlFunctionExpression sqlFunctionExpression)
{
if (sqlFunctionExpression is { IsBuiltIn: true, Arguments: not null }
&& string.Equals(sqlFunctionExpression.Name, "COALESCE", StringComparison.OrdinalIgnoreCase))
{
var head = sqlFunctionExpression.Arguments[0];
if (head.TypeMapping != sqlFunctionExpression.TypeMapping)
{
head = new SqlUnaryExpression(
ExpressionType.Convert,
head,
sqlFunctionExpression.Type,
sqlFunctionExpression.TypeMapping);
}

sqlFunctionExpression = (SqlFunctionExpression)sqlFunctionExpression
.Arguments
.Skip(1)
.Aggregate(head, (l, r) => new SqlFunctionExpression(
"ISNULL",
arguments: [l, r],
nullable: true,
argumentsPropagateNullability: [false, false],
sqlFunctionExpression.Type,
sqlFunctionExpression.TypeMapping
));
}

return base.VisitSqlFunction(sqlFunctionExpression);
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand Down

0 comments on commit 8a6afce

Please sign in to comment.