diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerMathTranslator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerMathTranslator.cs index 11b2ad912de..3b5fe46023b 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerMathTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerMathTranslator.cs @@ -52,13 +52,31 @@ public class SqlServerMathTranslator : IMethodCallTranslator { typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Sign), new[] { typeof(int) }), "SIGN" }, { typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Sign), new[] { typeof(long) }), "SIGN" }, { typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Sign), new[] { typeof(sbyte) }), "SIGN" }, - { typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) }), "SIGN" } + { typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) }), "SIGN" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Abs), new[] { typeof(float) }), "ABS" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Ceiling), new[] { typeof(float) }), "CEILING" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Floor), new[] { typeof(float) }), "FLOOR" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Pow), new[] { typeof(float), typeof(float) }), "POWER" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Exp), new[] { typeof(float) }), "EXP" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Log10), new[] { typeof(float) }), "LOG10" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Log), new[] { typeof(float) }), "LOG" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Log), new[] { typeof(float), typeof(float) }), "LOG" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Sqrt), new[] { typeof(float) }), "SQRT" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Acos), new[] { typeof(float) }), "ACOS" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Asin), new[] { typeof(float) }), "ASIN" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Atan), new[] { typeof(float) }), "ATAN" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Atan2), new[] { typeof(float), typeof(float) }), "ATN2" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Cos), new[] { typeof(float) }), "COS" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Sin), new[] { typeof(float) }), "SIN" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Tan), new[] { typeof(float) }), "TAN" }, + { typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Sign), new[] { typeof(float) }), "SIGN" } }; private static readonly IEnumerable _truncateMethodInfos = new[] { typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Truncate), new[] { typeof(decimal) }), - typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Truncate), new[] { typeof(double) }) + typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Truncate), new[] { typeof(double) }), + typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Truncate), new[] { typeof(float) }) }; private static readonly IEnumerable _roundMethodInfos = new[] @@ -66,7 +84,9 @@ public class SqlServerMathTranslator : IMethodCallTranslator typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal) }), typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Round), new[] { typeof(double) }), typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal), typeof(int) }), - typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }) + typeof(Math).GetRequiredRuntimeMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }), + typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Round), new[] { typeof(float) }), + typeof(MathF).GetRequiredRuntimeMethod(nameof(MathF.Round), new[] { typeof(float), typeof(int) }) }; private readonly ISqlExpressionFactory _sqlExpressionFactory; diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs index effb424b087..ee4826daef8 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs @@ -48,7 +48,12 @@ public class SqliteMathTranslator : IMethodCallTranslator { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(uint), typeof(uint) }), "min" }, { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(ushort), typeof(ushort) }), "min" }, { typeof(Math).GetRequiredMethod(nameof(Math.Round), new[] { typeof(double) }), "round" }, - { typeof(Math).GetRequiredMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }), "round" } + { typeof(Math).GetRequiredMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }), "round" }, + { typeof(MathF).GetRequiredMethod(nameof(MathF.Abs), new[] { typeof(float) }), "abs" }, + { typeof(MathF).GetRequiredMethod(nameof(MathF.Max), new[] { typeof(float), typeof(float) }), "max" }, + { typeof(MathF).GetRequiredMethod(nameof(MathF.Min), new[] { typeof(float), typeof(float) }), "min" }, + { typeof(MathF).GetRequiredMethod(nameof(MathF.Round), new[] { typeof(float) }), "round" }, + { typeof(MathF).GetRequiredMethod(nameof(MathF.Round), new[] { typeof(float), typeof(int) }), "round" } }; private readonly ISqlExpressionFactory _sqlExpressionFactory; diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs index aaf146bf0ba..d769016a1cf 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs @@ -595,6 +595,215 @@ FROM root c WHERE ((c[""Discriminator""] = ""OrderDetail"") AND (c[""OrderID""] = 11077))"); } + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_abs1(bool async) + { + await base.Where_mathf_abs1(async); + + AssertSql( + @"SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[SupplierID], [p].[UnitPrice], [p].[UnitsInStock] +FROM [Products] AS [p] +WHERE ABS(CAST([p].[ProductID] AS real)) > CAST(10 AS real)"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_ceiling1(bool async) + { + await base.Where_mathf_ceiling1(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[UnitPrice] < 7.0) AND (CEILING([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_floor(bool async) + { + await base.Where_mathf_floor(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[Quantity] < CAST(5 AS smallint)) AND (FLOOR(CAST([o].[UnitPrice] AS real)) > CAST(10 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_power(bool async) + { + await base.Where_mathf_power(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE POWER([o].[Discount], CAST(2 AS real)) > CAST(0.05 AS real)"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_round2(bool async) + { + await base.Where_mathf_round2(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ROUND(CAST([o].[UnitPrice] AS real), 2) > CAST(100 AS real)"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_truncate(bool async) + { + await base.Where_mathf_truncate(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[Quantity] < CAST(5 AS smallint)) AND (ROUND(CAST([o].[UnitPrice] AS real), 0, 1) > CAST(10 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_exp(bool async) + { + await base.Where_mathf_exp(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (EXP([o].[Discount]) > CAST(1 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_log10(bool async) + { + await base.Where_mathf_log10(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE (([o].[OrderID] = 11077) AND ([o].[Discount] > CAST(0 AS real))) AND (LOG10([o].[Discount]) < CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_log(bool async) + { + await base.Where_mathf_log(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE (([o].[OrderID] = 11077) AND ([o].[Discount] > CAST(0 AS real))) AND (LOG([o].[Discount]) < CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_log_new_base(bool async) + { + await base.Where_mathf_log_new_base(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE (([o].[OrderID] = 11077) AND ([o].[Discount] > CAST(0 AS real))) AND (LOG([o].[Discount], CAST(7 AS real)) < CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_sqrt(bool async) + { + await base.Where_mathf_sqrt(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (SQRT([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_acos(bool async) + { + await base.Where_mathf_acos(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ACOS([o].[Discount]) > CAST(1 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_asin(bool async) + { + await base.Where_mathf_asin(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ASIN([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_atan(bool async) + { + await base.Where_mathf_atan(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ATAN([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_atan2(bool async) + { + await base.Where_mathf_atan2(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ATN2([o].[Discount], CAST(1 AS real)) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_cos(bool async) + { + await base.Where_mathf_cos(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (COS([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_sin(bool async) + { + await base.Where_mathf_sin(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (SIN([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_tan(bool async) + { + await base.Where_mathf_tan(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (TAN([o].[Discount]) > CAST(0 AS real))"); + } + + [ConditionalTheory(Skip = "Issue #17246")] + public override async Task Where_mathf_sign(bool async) + { + await base.Where_mathf_sign(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (SIGN([o].[Discount]) > 0)"); + } + [ConditionalTheory(Skip = "Issue #17246")] public override async Task Where_guid_newguid(bool async) { diff --git a/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs index 74cd4a34425..d3e4328ea5c 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs @@ -1045,6 +1045,203 @@ public virtual Task Where_math_min(bool async) entryCount: 25); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_abs1(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .Where(od => MathF.Abs(od.ProductID) > 10), + entryCount: 67); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_ceiling1(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .Where(od => od.UnitPrice < 7) + .Where(od => MathF.Ceiling(od.Discount) > 0), + entryCount: 51); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_floor(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .Where(od => od.Quantity < 5) + .Where(od => MathF.Floor((float)od.UnitPrice) > 10), + entryCount: 137); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_power(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => MathF.Pow(od.Discount, 2) > 0.05f), + entryCount: 154); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_round2(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => MathF.Round((float)od.UnitPrice, 2) > 100), + entryCount: 46); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_truncate(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .Where(od => od.Quantity < 5) + .Where(od => MathF.Truncate((float)od.UnitPrice) > 10), + entryCount: 137); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_exp(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Exp(od.Discount) > 1), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_log10(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077 && od.Discount > 0).Where(od => MathF.Log10(od.Discount) < 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_log(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077 && od.Discount > 0).Where(od => MathF.Log(od.Discount) < 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_log_new_base(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077 && od.Discount > 0).Where(od => MathF.Log(od.Discount, 7) < 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_sqrt(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Sqrt(od.Discount) > 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_acos(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Acos(od.Discount) > 1), + entryCount: 25); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_asin(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Asin(od.Discount) > 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_atan(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Atan(od.Discount) > 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_atan2(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Atan2(od.Discount, 1) > 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_cos(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Cos(od.Discount) > 0), + entryCount: 25); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_sin(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Sin(od.Discount) > 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_tan(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Tan(od.Discount) > 0), + entryCount: 13); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_mathf_sign(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Where(od => od.OrderID == 11077).Where(od => MathF.Sign(od.Discount) > 0), + entryCount: 13); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Where_guid_newguid(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs index 38311817695..70c8fa6af74 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs @@ -901,6 +901,196 @@ public override Task Where_math_min(bool async) public override Task Where_math_max(bool async) => base.Where_math_max(async); + public override async Task Where_mathf_abs1(bool async) + { + await base.Where_mathf_abs1(async); + + AssertSql( + @"SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[SupplierID], [p].[UnitPrice], [p].[UnitsInStock] +FROM [Products] AS [p] +WHERE ABS(CAST([p].[ProductID] AS real)) > CAST(10 AS real)"); + } + + public override async Task Where_mathf_ceiling1(bool async) + { + await base.Where_mathf_ceiling1(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[UnitPrice] < 7.0) AND (CEILING([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_floor(bool async) + { + await base.Where_mathf_floor(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[Quantity] < CAST(5 AS smallint)) AND (FLOOR(CAST([o].[UnitPrice] AS real)) > CAST(10 AS real))"); + } + + public override async Task Where_mathf_power(bool async) + { + await base.Where_mathf_power(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE POWER([o].[Discount], CAST(2 AS real)) > CAST(0.05 AS real)"); + } + + public override async Task Where_mathf_round2(bool async) + { + await base.Where_mathf_round2(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ROUND(CAST([o].[UnitPrice] AS real), 2) > CAST(100 AS real)"); + } + + public override async Task Where_mathf_truncate(bool async) + { + await base.Where_mathf_truncate(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[Quantity] < CAST(5 AS smallint)) AND (ROUND(CAST([o].[UnitPrice] AS real), 0, 1) > CAST(10 AS real))"); + } + + public override async Task Where_mathf_exp(bool async) + { + await base.Where_mathf_exp(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (EXP([o].[Discount]) > CAST(1 AS real))"); + } + + public override async Task Where_mathf_log10(bool async) + { + await base.Where_mathf_log10(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE (([o].[OrderID] = 11077) AND ([o].[Discount] > CAST(0 AS real))) AND (LOG10([o].[Discount]) < CAST(0 AS real))"); + } + + public override async Task Where_mathf_log(bool async) + { + await base.Where_mathf_log(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE (([o].[OrderID] = 11077) AND ([o].[Discount] > CAST(0 AS real))) AND (LOG([o].[Discount]) < CAST(0 AS real))"); + } + + public override async Task Where_mathf_log_new_base(bool async) + { + await base.Where_mathf_log_new_base(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE (([o].[OrderID] = 11077) AND ([o].[Discount] > CAST(0 AS real))) AND (LOG([o].[Discount], CAST(7 AS real)) < CAST(0 AS real))"); + } + + public override async Task Where_mathf_sqrt(bool async) + { + await base.Where_mathf_sqrt(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (SQRT([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_acos(bool async) + { + await base.Where_mathf_acos(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ACOS([o].[Discount]) > CAST(1 AS real))"); + } + + public override async Task Where_mathf_asin(bool async) + { + await base.Where_mathf_asin(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ASIN([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_atan(bool async) + { + await base.Where_mathf_atan(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ATAN([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_atan2(bool async) + { + await base.Where_mathf_atan2(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (ATN2([o].[Discount], CAST(1 AS real)) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_cos(bool async) + { + await base.Where_mathf_cos(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (COS([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_sin(bool async) + { + await base.Where_mathf_sin(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (SIN([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_tan(bool async) + { + await base.Where_mathf_tan(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (TAN([o].[Discount]) > CAST(0 AS real))"); + } + + public override async Task Where_mathf_sign(bool async) + { + await base.Where_mathf_sign(async); + + AssertSql( + @"SELECT [o].[OrderID], [o].[ProductID], [o].[Discount], [o].[Quantity], [o].[UnitPrice] +FROM [Order Details] AS [o] +WHERE ([o].[OrderID] = 11077) AND (SIGN([o].[Discount]) > 0)"); + } + public override async Task Where_guid_newguid(bool async) { await base.Where_guid_newguid(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs index 0449bbb7220..fe0eb321bd7 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs @@ -120,6 +120,57 @@ public override Task Where_math_tan(bool async) public override Task Where_math_truncate(bool async) => AssertTranslationFailed(() => base.Where_math_truncate(async)); + + public override Task Where_mathf_acos(bool async) + => AssertTranslationFailed(() => base.Where_mathf_acos(async)); + + public override Task Where_mathf_asin(bool async) + => AssertTranslationFailed(() => base.Where_mathf_asin(async)); + + public override Task Where_mathf_atan(bool async) + => AssertTranslationFailed(() => base.Where_mathf_atan(async)); + + public override Task Where_mathf_atan2(bool async) + => AssertTranslationFailed(() => base.Where_mathf_atan2(async)); + + public override Task Where_mathf_ceiling1(bool async) + => AssertTranslationFailed(() => base.Where_mathf_ceiling1(async)); + + public override Task Where_mathf_cos(bool async) + => AssertTranslationFailed(() => base.Where_mathf_cos(async)); + + public override Task Where_mathf_exp(bool async) + => AssertTranslationFailed(() => base.Where_mathf_exp(async)); + + public override Task Where_mathf_floor(bool async) + => AssertTranslationFailed(() => base.Where_mathf_floor(async)); + + public override Task Where_mathf_log(bool async) + => AssertTranslationFailed(() => base.Where_mathf_log(async)); + + public override Task Where_mathf_log_new_base(bool async) + => AssertTranslationFailed(() => base.Where_mathf_log_new_base(async)); + + public override Task Where_mathf_log10(bool async) + => AssertTranslationFailed(() => base.Where_mathf_log10(async)); + + public override Task Where_mathf_power(bool async) + => AssertTranslationFailed(() => base.Where_mathf_power(async)); + + public override Task Where_mathf_sign(bool async) + => AssertTranslationFailed(() => base.Where_mathf_sign(async)); + + public override Task Where_mathf_sin(bool async) + => AssertTranslationFailed(() => base.Where_mathf_sin(async)); + + public override Task Where_mathf_sqrt(bool async) + => AssertTranslationFailed(() => base.Where_mathf_sqrt(async)); + + public override Task Where_mathf_tan(bool async) + => AssertTranslationFailed(() => base.Where_mathf_tan(async)); + + public override Task Where_mathf_truncate(bool async) + => AssertTranslationFailed(() => base.Where_mathf_truncate(async)); public override async Task String_StartsWith_Literal(bool async) {