diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs index 7ad9ecba..e48e3cba 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs @@ -652,14 +652,29 @@ private static Expression ToExpression(BooleanBinaryExpression bin, ExpressionCo var lhs = bin.InvokeSubExpression(x => x.FirstExpression, x => x.FirstExpression, context, contextParam, exprParam, createExpression, out _, out var lhsCacheKey); var rhs = bin.InvokeSubExpression(x => x.SecondExpression, x => x.SecondExpression, context, contextParam, exprParam, createExpression, out _, out var rhsCacheKey); + if (createExpression) + { + lhs = Expression.IsTrue(lhs); + rhs = Expression.IsTrue(rhs); + } + + Expression binary; + if (bin.BinaryExpressionType == BooleanBinaryExpressionType.And) { cacheKey = lhsCacheKey + " AND " + rhsCacheKey; - return createExpression ? Expression.AndAlso(lhs, rhs) : null; + binary = createExpression ? Expression.AndAlso(lhs, rhs) : null; } + else + { + cacheKey = lhsCacheKey + " OR " + rhsCacheKey; + binary = createExpression ? Expression.OrElse(lhs, rhs) : null; + } + + if (createExpression) + binary = Expression.Convert(binary, typeof(SqlBoolean)); - cacheKey = lhsCacheKey + " OR " + rhsCacheKey; - return createExpression ? Expression.OrElse(lhs, rhs) : null; + return binary; } private static Expression ToExpression(BooleanParenthesisExpression paren, ExpressionCompilationContext context, ParameterExpression contextParam, ParameterExpression exprParam, bool createExpression, out DataTypeReference sqlType, out string cacheKey) @@ -813,6 +828,7 @@ rhsSqlType is SqlDataTypeReferenceWithCollation rhsSql && expr = Expression.Divide(lhs, rhs); expr = Expression.TryCatch(expr, Expression.Catch(typeof(DivideByZeroException), Expression.Throw(Expression.New(typeof(QueryExecutionException).GetConstructor(new[] { typeof(Sql4CdsError) }), Expr.Call(() => Sql4CdsError.DivideByZero())), expr.Type))); + //expr = Expression.Invoke(Expression.Lambda(expr)); break; case BinaryExpressionType.Modulo: @@ -1888,7 +1904,7 @@ private static Expression ToExpression(this BooleanNotExpression not, Expression { var value = not.InvokeSubExpression(x => x.Expression, x => x.Expression, context, contextParam, exprParam, createExpression, out sqlType, out cacheKey); cacheKey = "NOT " + cacheKey; - return createExpression ? Expression.Not(value) : null; + return createExpression ? Expression.Convert(Expression.IsFalse(value), typeof(SqlBoolean)) : null; } private static readonly Dictionary _typeMapping = new Dictionary diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/SqlTypeConverter.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/SqlTypeConverter.cs index 12b861c2..d7d09477 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/SqlTypeConverter.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/SqlTypeConverter.cs @@ -662,6 +662,7 @@ public static Expression Convert(Expression expr, DataTypeReference from, DataTy var catchOverflowExceptionBlock = Expression.Catch(typeof(OverflowException), Expression.Throw(Expression.New(typeof(QueryExecutionException).GetConstructor(new[] { typeof(Sql4CdsError) }), overflowError), targetType)); expr = Expression.TryCatch(expr, catchFormatExceptionBlock, catchOverflowExceptionBlock); + //expr = Expression.Invoke(Expression.Lambda(expr)); } if (toSqlType == null) @@ -1374,6 +1375,7 @@ private static Func CompileConversion(Type sourceType, Type dest var block = Expression.Block(destType, variables, body); var catchBlock = Expression.Catch(typeof(ArgumentException), block); parsedValue = Expression.TryCatch(parsedValue, catchBlock); + //parsedValue = Expression.Invoke(Expression.Lambda(parsedValue)); expression = Expression.Condition(nullCheck, nullValue, parsedValue); } @@ -1395,6 +1397,7 @@ private static Func CompileConversion(Type sourceType, Type dest var block = Expression.Block(destType, variables, body); var catchBlock = Expression.Catch(typeof(ArgumentException), block); expression = Expression.TryCatch(expression, catchBlock); + //expression = Expression.Invoke(Expression.Lambda(expression)); } else if (expression.Type == typeof(SqlInt32) && destType == typeof(OptionSetValue)) {