Skip to content

Commit a9c2f36

Browse files
committed
Jet conversion functions like Cdbl/Csng/CLng don't accept or propogate null values. Normally we can just use an IIF to check if the expression is null or not. That does work fine but here we also check if the base expression is nullable. If the base expression will never return null we can simplify and just use the base expression rather than test for null
1 parent 6963a16 commit a9c2f36

1 file changed

Lines changed: 53 additions & 3 deletions

File tree

src/EFCore.Jet/Query/Sql/Internal/JetQuerySqlGenerator.cs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ protected Expression VisitJetConvertExpression(SqlUnaryExpression convertExpress
340340
SqlExpression checksqlexp = convertExpression.Operand;
341341

342342
SqlFunctionExpression notnullsqlexp = new SqlFunctionExpression(function, new SqlExpression[] { convertExpression.Operand },
343-
true, new[] { true }, typeMapping.ClrType, null);
343+
false, new[] { false }, typeMapping.ClrType, null);
344344

345345
SqlConstantExpression nullcons = new SqlConstantExpression(Expression.Constant(null), RelationalTypeMapping.NullMapping);
346346
SqlUnaryExpression isnullexp = new SqlUnaryExpression(ExpressionType.Equal, checksqlexp, typeof(bool), null);
@@ -349,8 +349,58 @@ protected Expression VisitJetConvertExpression(SqlUnaryExpression convertExpress
349349
new CaseWhenClause(isnullexp, nullcons)
350350
};
351351
CaseExpression caseexp = new CaseExpression(whenclause, notnullsqlexp);
352-
//Visit(caseexp);
353-
Visit(notnullsqlexp);
352+
if (checksqlexp is ColumnExpression columnExpression)
353+
{
354+
if (columnExpression.IsNullable)
355+
{
356+
Visit(caseexp);
357+
}
358+
else
359+
{
360+
Visit(notnullsqlexp);
361+
}
362+
}
363+
else if (checksqlexp is SqlFunctionExpression functionExpression)
364+
{
365+
if (functionExpression is { IsNullable: true, ArgumentsPropagateNullability: not null } && functionExpression.ArgumentsPropagateNullability.Any(d => d))
366+
{
367+
Visit(caseexp);
368+
}
369+
else
370+
{
371+
Visit(notnullsqlexp);
372+
}
373+
}
374+
else if (checksqlexp is SqlBinaryExpression binaryExpression)
375+
{
376+
bool leftnull = false, rightnull = false;
377+
ColumnExpression? columnExpressionLeft = binaryExpression.Left as ColumnExpression;
378+
SqlFunctionExpression? functionExpressionLeft = binaryExpression.Left as SqlFunctionExpression;
379+
ColumnExpression? columnExpressionRight = binaryExpression.Right as ColumnExpression;
380+
SqlFunctionExpression? functionExpressionRight = binaryExpression.Right as SqlFunctionExpression;
381+
leftnull = columnExpressionLeft != null && columnExpressionLeft.IsNullable ||
382+
functionExpressionLeft != null && functionExpressionLeft.IsNullable;
383+
rightnull = columnExpressionRight != null && columnExpressionRight.IsNullable ||
384+
functionExpressionRight != null && functionExpressionRight.IsNullable;
385+
386+
if (leftnull || rightnull)
387+
{
388+
Visit(caseexp);
389+
}
390+
else
391+
{
392+
Visit(notnullsqlexp);
393+
}
394+
}
395+
else if (checksqlexp is SqlUnaryExpression unaryExpression)
396+
{
397+
Visit(notnullsqlexp);
398+
}
399+
else
400+
{
401+
Visit(caseexp);
402+
}
403+
354404
return notnullsqlexp;
355405
}
356406

0 commit comments

Comments
 (0)