diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs index dfb054b097f..73fd75e37c8 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs @@ -202,6 +202,53 @@ protected override Expression VisitValues(ValuesExpression valuesExpression) return valuesExpression; } + /// + /// 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. + /// + protected override Expression VisitSqlFunction(SqlFunctionExpression sqlFunctionExpression) + { + if (sqlFunctionExpression is { IsBuiltIn: true, Arguments: not null } + && string.Equals(sqlFunctionExpression.Name, "COALESCE", StringComparison.OrdinalIgnoreCase)) + { + var type = sqlFunctionExpression.Type; + var typeMapping = sqlFunctionExpression.TypeMapping; + var defaultTypeMapping = _typeMappingSource.FindMapping(type); + + // ISNULL always return a value having the same type as its first + // argument. Ideally we would convert the argument to have the + // desired type and type mapping, but currently EFCore has some + // trouble in computing types of non-homogeneous expressions + // (tracked in https://github.com/dotnet/efcore/issues/15586). To + // stay on the safe side we only use ISNULL if: + // - all sub-expressions have the same type as the expression + // - all sub-expressions have the same type mapping as the expression + // - the expression is using the default type mapping (combined + // with the two above, this implies that all of the expressions + // are using the default type mapping of the type) + if (defaultTypeMapping == typeMapping + && sqlFunctionExpression.Arguments.All(a => a.Type == type && a.TypeMapping == typeMapping)) { + + var head = sqlFunctionExpression.Arguments[0]; + 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); + } + /// /// 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 diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs index 49378dd26da..6e123d8488b 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs @@ -3229,6 +3229,49 @@ public override async Task Entity_equality_orderby_descending_subquery_composite AssertSql(); } + public override Task Coalesce_Correct_Multiple_Same_TypeMapping(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Coalesce_Correct_Multiple_Same_TypeMapping(async); + + AssertSql( + """ +SELECT VALUE +{ + "ReportsTo" : c["ReportsTo"], + "c" : 1, + "c0" : 2, + "c1" : 3 +} +FROM root c +ORDER BY c["EmployeeID"] +"""); + }); + + public override Task Coalesce_Correct_TypeMapping_Double(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Coalesce_Correct_TypeMapping_Double(async); + + AssertSql(); + }); + + public override Task Coalesce_Correct_TypeMapping_String(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Coalesce_Correct_TypeMapping_String(async); + + AssertSql( + """ +SELECT VALUE ((c["Region"] != null) ? c["Region"] : "no region specified") +FROM root c +ORDER BY c["id"] +"""); + }); + public override async Task Null_Coalesce_Short_Circuit(bool async) { // Cosmos client evaluation. Issue #17246. @@ -3347,7 +3390,7 @@ public override async Task SelectMany_primitive_select_subquery(bool async) // Cosmos client evaluation. Issue #17246. Assert.Equal( CoreStrings.ExpressionParameterizationExceptionSensitive( - "value(Microsoft.EntityFrameworkCore.Query.NorthwindMiscellaneousQueryTestBase`1+<>c__DisplayClass172_0[Microsoft.EntityFrameworkCore.Query.NorthwindQueryCosmosFixture`1[Microsoft.EntityFrameworkCore.TestUtilities.NoopModelCustomizer]]).ss.Set().Any()"), + "value(Microsoft.EntityFrameworkCore.Query.NorthwindMiscellaneousQueryTestBase`1+<>c__DisplayClass175_0[Microsoft.EntityFrameworkCore.Query.NorthwindQueryCosmosFixture`1[Microsoft.EntityFrameworkCore.TestUtilities.NoopModelCustomizer]]).ss.Set().Any()"), (await Assert.ThrowsAsync( () => base.SelectMany_primitive_select_subquery(async))).Message); diff --git a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs index e5305213272..fc017f483ce 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs @@ -723,6 +723,31 @@ public virtual Task Ternary_should_not_evaluate_both_sides_with_parameter(bool a })); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Coalesce_Correct_Multiple_Same_TypeMapping(bool async) + => AssertQuery( + async, + ss => ss.Set().OrderBy(e => e.EmployeeID) + .Select(e => (e.ReportsTo + 1L) ?? (e.ReportsTo + 2L) ?? (e.ReportsTo + 3L)), + assertOrder: true); + + [ConditionalTheory(Skip = "issue #15586")] + [MemberData(nameof(IsAsyncData))] + public virtual Task Coalesce_Correct_TypeMapping_Double(bool async) + => AssertQuery( + async, + ss => ss.Set().OrderBy(e => e.EmployeeID).Select(e => e.ReportsTo ?? 2.25), + assertOrder: true); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Coalesce_Correct_TypeMapping_String(bool async) + => AssertQuery( + async, + ss => ss.Set().OrderBy(c => c.CustomerID).Select(c => c.Region ?? "no region specified"), + assertOrder: true); + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Null_Coalesce_Short_Circuit(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs index 14af7a25c2d..23a69d6f6c0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs @@ -3980,7 +3980,7 @@ public override async Task Nested_object_constructed_from_group_key_properties(b AssertSql( """ -SELECT [l].[Id], [l].[Name], [l].[Date], [l0].[Id], [l1].[Name], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], COALESCE(SUM(CAST(LEN([l].[Name]) AS int)), 0) AS [Aggregate] +SELECT [l].[Id], [l].[Name], [l].[Date], [l0].[Id], [l1].[Name], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], ISNULL(SUM(CAST(LEN([l].[Name]) AS int)), 0) AS [Aggregate] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[Level1_Required_Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index a6e73d27634..12eff52e794 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -3980,7 +3980,7 @@ public override async Task Nested_object_constructed_from_group_key_properties(b AssertSql( """ -SELECT [l].[Id], [l].[Name], [l].[Date], [l0].[Id], [l1].[Name], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], COALESCE(SUM(CAST(LEN([l].[Name]) AS int)), 0) AS [Aggregate] +SELECT [l].[Id], [l].[Name], [l].[Date], [l0].[Id], [l1].[Name], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], ISNULL(SUM(CAST(LEN([l].[Name]) AS int)), 0) AS [Aggregate] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[Level1_Required_Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs index 0a59d9aed93..e1e3b9b920f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs @@ -781,7 +781,7 @@ public override async Task Nested_object_constructed_from_group_key_properties(b AssertSql( """ -SELECT [s].[Id], [s].[Name], [s].[Date], [s].[InnerId] AS [Id], [s].[Level2_Name0] AS [Name], [s].[OneToOne_Required_PK_Date] AS [Date], [s].[Level1_Optional_Id], [s].[Level1_Required_Id], COALESCE(SUM(CAST(LEN([s].[Name]) AS int)), 0) AS [Aggregate] +SELECT [s].[Id], [s].[Name], [s].[Date], [s].[InnerId] AS [Id], [s].[Level2_Name0] AS [Name], [s].[OneToOne_Required_PK_Date] AS [Date], [s].[Level1_Optional_Id], [s].[Level1_Required_Id], ISNULL(SUM(CAST(LEN([s].[Name]) AS int)), 0) AS [Aggregate] FROM ( SELECT [l].[Id], [l].[Date], [l].[Name], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l3].[Level2_Name] AS [Level2_Name0], CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs index c0d53dacabf..c0d96ba5534 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs @@ -783,7 +783,7 @@ public override async Task Nested_object_constructed_from_group_key_properties(b AssertSql( """ -SELECT [s].[Id], [s].[Name], [s].[Date], [s].[InnerId] AS [Id], [s].[Level2_Name0] AS [Name], [s].[OneToOne_Required_PK_Date] AS [Date], [s].[Level1_Optional_Id], [s].[Level1_Required_Id], COALESCE(SUM(CAST(LEN([s].[Name]) AS int)), 0) AS [Aggregate] +SELECT [s].[Id], [s].[Name], [s].[Date], [s].[InnerId] AS [Id], [s].[Level2_Name0] AS [Name], [s].[OneToOne_Required_PK_Date] AS [Date], [s].[Level1_Optional_Id], [s].[Level1_Required_Id], ISNULL(SUM(CAST(LEN([s].[Name]) AS int)), 0) AS [Aggregate] FROM ( SELECT [l].[Id], [l].[Date], [l].[Name], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l3].[Level2_Name] AS [Level2_Name0], CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index 53b862ff500..79f0259f396 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -3475,7 +3475,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END FROM [Weapons] AS [w] """); @@ -3504,7 +3504,7 @@ FROM [Weapons] AS [w] WHERE CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END LIKE N'%Cart%' """); } @@ -4883,7 +4883,7 @@ public override async Task Select_subquery_projecting_single_constant_int(bool a AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) 42 FROM [Gears] AS [g] WHERE [s].[Id] = [g].[SquadId] AND [g].[HasSoulPatch] = CAST(1 AS bit)), 0) AS [Gear] @@ -4911,7 +4911,7 @@ public override async Task Select_subquery_projecting_single_constant_bool(bool AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) CAST(1 AS bit) FROM [Gears] AS [g] WHERE [s].[Id] = [g].[SquadId] AND [g].[HasSoulPatch] = CAST(1 AS bit)), CAST(0 AS bit)) AS [Gear] @@ -5546,7 +5546,7 @@ public override async Task String_concat_on_various_types(bool async) AssertSql( """ -SELECT N'HasSoulPatch ' + CAST([g].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([g].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([g].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + COALESCE(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] +SELECT N'HasSoulPatch ' + CAST([g].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([g].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([g].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + ISNULL(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] FROM [Gears] AS [g] CROSS JOIN [Missions] AS [m] ORDER BY [g].[Nickname], [m].[Id] @@ -6616,7 +6616,7 @@ public override async Task Complex_GroupBy_after_set_operator(bool async) AssertSql( """ -SELECT [u].[Name], [u].[Count], COALESCE(SUM([u].[Count]), 0) AS [Sum] +SELECT [u].[Name], [u].[Count], ISNULL(SUM([u].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -6642,7 +6642,7 @@ public override async Task Complex_GroupBy_after_set_operator_using_result_selec AssertSql( """ -SELECT [u].[Name], [u].[Count], COALESCE(SUM([u].[Count]), 0) AS [Sum] +SELECT [u].[Name], [u].[Count], ISNULL(SUM([u].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -9062,7 +9062,7 @@ public override async Task Set_operator_with_navigation_in_projection_groupby_ag AssertSql( """ SELECT [s].[Name], ( - SELECT COALESCE(SUM(CAST(LEN([c].[Location]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([c].[Location]) AS int)), 0) FROM [Gears] AS [g2] INNER JOIN [Squads] AS [s0] ON [g2].[SquadId] = [s0].[Id] INNER JOIN [Cities] AS [c] ON [g2].[CityOfBirthName] = [c].[Name] @@ -9146,7 +9146,7 @@ LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId], ROW_NUMBER() OVER(PARTITION BY [w].[OwnerFullName] ORDER BY [w].[Id]) AS [row] FROM [Weapons] AS [w] ) AS [w0] - WHERE [w0].[row] <= COALESCE(( + WHERE [w0].[row] <= ISNULL(( SELECT [n].[value] FROM OPENJSON(@numbers) WITH ([value] int '$') AS [n] ORDER BY [n].[value] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs index b2f3e0cdfd1..1a306cc84aa 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs @@ -815,7 +815,7 @@ public override async Task Sum_over_uncorrelated_subquery(bool async) // #34256: rewrite query to avoid "Cannot perform an aggregate function on an expression containing an aggregate or a subquery" AssertSql( """ -SELECT COALESCE(SUM([s].[value]), 0) +SELECT ISNULL(SUM([s].[value]), 0) FROM [Customers] AS [c] CROSS JOIN ( SELECT COUNT(*) AS [value] @@ -2721,7 +2721,7 @@ public override async Task Project_constant_Sum(bool async) AssertSql( """ -SELECT COALESCE(SUM(1), 0) +SELECT ISNULL(SUM(1), 0) FROM [Employees] AS [e] """); } @@ -3081,7 +3081,7 @@ public override async Task Contains_inside_Sum_without_GroupBy(bool async) """ @cities='["London","Berlin"]' (Size = 4000) -SELECT COALESCE(SUM([s].[value]), 0) +SELECT ISNULL(SUM([s].[value]), 0) FROM [Customers] AS [c] OUTER APPLY ( SELECT CASE diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs index d34131a8b58..34d120cfd8e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs @@ -272,7 +272,7 @@ public override async Task GroupBy_aggregate_projecting_conditional_expression(b """ SELECT [o].[OrderDate] AS [Key], CASE WHEN COUNT(*) = 0 THEN 1 - ELSE COALESCE(SUM(CASE + ELSE ISNULL(SUM(CASE WHEN [o].[OrderID] % 2 = 0 THEN 1 ELSE 0 END), 0) / COUNT(*) @@ -1939,7 +1939,7 @@ public override async Task GroupBy_Sum_constant(bool async) AssertSql( """ -SELECT COALESCE(SUM(1), 0) +SELECT ISNULL(SUM(1), 0) FROM [Orders] AS [o] GROUP BY [o].[CustomerID] """); @@ -2699,7 +2699,7 @@ public override async Task GroupBy_aggregate_followed_by_another_GroupBy_aggrega AssertSql( """ -SELECT [o1].[Key0] AS [Key], COALESCE(SUM([o1].[Count]), 0) AS [Count] +SELECT [o1].[Key0] AS [Key], ISNULL(SUM([o1].[Count]), 0) AS [Count] FROM ( SELECT [o0].[Count], 1 AS [Key0] FROM ( diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs index ac1cddb3d45..c4e3126bb1f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs @@ -596,9 +596,9 @@ public override async Task GroupJoin_aggregate_anonymous_key_selectors(bool asyn await base.GroupJoin_aggregate_anonymous_key_selectors(async); AssertSql( -""" + """ SELECT [c].[CustomerID], ( - SELECT COALESCE(SUM(CAST(LEN([o].[CustomerID]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([o].[CustomerID]) AS int)), 0) FROM [Orders] AS [o] WHERE [c].[City] IS NOT NULL AND [c].[CustomerID] = [o].[CustomerID] AND [c].[City] = N'London') AS [Sum] FROM [Customers] AS [c] @@ -610,9 +610,9 @@ public override async Task GroupJoin_aggregate_anonymous_key_selectors2(bool asy await base.GroupJoin_aggregate_anonymous_key_selectors2(async); AssertSql( -""" + """ SELECT [c].[CustomerID], ( - SELECT COALESCE(SUM(CAST(LEN([o].[CustomerID]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([o].[CustomerID]) AS int)), 0) FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID] AND 1996 = DATEPART(year, [o].[OrderDate])) AS [Sum] FROM [Customers] AS [c] @@ -624,9 +624,9 @@ public override async Task GroupJoin_aggregate_anonymous_key_selectors_one_argum await base.GroupJoin_aggregate_anonymous_key_selectors_one_argument(async); AssertSql( -""" + """ SELECT [c].[CustomerID], ( - SELECT COALESCE(SUM(CAST(LEN([o].[CustomerID]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([o].[CustomerID]) AS int)), 0) FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID]) AS [Sum] FROM [Customers] AS [c] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindKeylessEntitiesQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindKeylessEntitiesQuerySqlServerTest.cs index afe17f5b27e..f44b09966be 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindKeylessEntitiesQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindKeylessEntitiesQuerySqlServerTest.cs @@ -148,7 +148,7 @@ public override async Task KeylessEntity_groupby(bool async) AssertSql( """ -SELECT [m].[City] AS [Key], COUNT(*) AS [Count], COALESCE(SUM(CAST(LEN([m].[Address]) AS int)), 0) AS [Sum] +SELECT [m].[City] AS [Key], COUNT(*) AS [Count], ISNULL(SUM(CAST(LEN([m].[Address]) AS int)), 0) AS [Sum] FROM ( SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] ) AS [m] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs index fa69cfcad75..ca5d72b7221 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs @@ -2844,6 +2844,41 @@ ELSE [c].[Region] """); } + public override async Task Coalesce_Correct_Multiple_Same_TypeMapping(bool async) + { + await base.Coalesce_Correct_Multiple_Same_TypeMapping(async); + + AssertSql( + """ +SELECT ISNULL(ISNULL(CAST([e].[ReportsTo] AS bigint) + CAST(1 AS bigint), CAST([e].[ReportsTo] AS bigint) + CAST(2 AS bigint)), CAST([e].[ReportsTo] AS bigint) + CAST(3 AS bigint)) +FROM [Employees] AS [e] +ORDER BY [e].[EmployeeID] +"""); + } + + public override async Task Coalesce_Correct_TypeMapping_Double(bool async) + { + await base.Coalesce_Correct_TypeMapping_Double(async); + + AssertSql( + """ +SELECT COALESCE([e].[ReportsTo], 2.25) +FROM [Employees] AS [e] +"""); + } + + public override async Task Coalesce_Correct_TypeMapping_String(bool async) + { + await base.Coalesce_Correct_TypeMapping_String(async); + + AssertSql( + """ +SELECT COALESCE([c].[Region], N'no region specified') +FROM [Customers] AS [c] +ORDER BY [c].[CustomerID] +"""); + } + public override async Task Null_Coalesce_Short_Circuit(bool async) { await base.Null_Coalesce_Short_Circuit(async); @@ -6985,7 +7020,7 @@ public override async Task Subquery_with_navigation_inside_inline_collection(boo SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE ( - SELECT COALESCE(SUM([v].[Value]), 0) + SELECT ISNULL(SUM([v].[Value]), 0) FROM (VALUES (CAST(100 AS int)), (( SELECT COUNT(*) FROM [Orders] AS [o] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindNavigationsQuerySqlServerTest.cs index ef977bd31de..e1f57a950f9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindNavigationsQuerySqlServerTest.cs @@ -330,7 +330,7 @@ public override async Task Select_count_plus_sum(bool async) AssertSql( """ SELECT ( - SELECT COALESCE(SUM(CAST([o0].[Quantity] AS int)), 0) + SELECT ISNULL(SUM(CAST([o0].[Quantity] AS int)), 0) FROM [Order Details] AS [o0] WHERE [o].[OrderID] = [o0].[OrderID]) + ( SELECT COUNT(*) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs index 922fa23af79..4475683bd2b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs @@ -398,7 +398,7 @@ public override async Task Select_nested_collection_multi_level4(bool async) AssertSql( """ -SELECT COALESCE(( +SELECT ISNULL(( SELECT TOP(1) ( SELECT COUNT(*) FROM [Order Details] AS [o0] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs index 05a96675e12..e35bd90e128 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs @@ -270,7 +270,7 @@ public override async Task Navigation_rewrite_on_owned_collection_with_compositi AssertSql( """ -SELECT COALESCE(( +SELECT ISNULL(( SELECT TOP(1) CAST([o0].[Id] ^ 42 AS bit) FROM [Order] AS [o0] WHERE [o].[Id] = [o0].[ClientId] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 84c3380ba7d..c05727e83fd 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -4639,7 +4639,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END FROM [Weapons] AS [w] """); @@ -4668,7 +4668,7 @@ FROM [Weapons] AS [w] WHERE CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END LIKE N'%Cart%' """); } @@ -6651,7 +6651,7 @@ public override async Task Select_subquery_projecting_single_constant_int(bool a AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) 42 FROM ( SELECT [g].[SquadId], [g].[HasSoulPatch] @@ -6691,7 +6691,7 @@ public override async Task Select_subquery_projecting_single_constant_bool(bool AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) CAST(1 AS bit) FROM ( SELECT [g].[SquadId], [g].[HasSoulPatch] @@ -7515,7 +7515,7 @@ public override async Task String_concat_on_various_types(bool async) AssertSql( """ -SELECT N'HasSoulPatch ' + CAST([u].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([u].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([u].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + COALESCE(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] +SELECT N'HasSoulPatch ' + CAST([u].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([u].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([u].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + ISNULL(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] FROM ( SELECT [g].[Nickname], [g].[SquadId], [g].[HasSoulPatch], [g].[Rank] FROM [Gears] AS [g] @@ -8810,7 +8810,7 @@ public override async Task Complex_GroupBy_after_set_operator(bool async) AssertSql( """ -SELECT [u1].[Name], [u1].[Count], COALESCE(SUM([u1].[Count]), 0) AS [Sum] +SELECT [u1].[Name], [u1].[Count], ISNULL(SUM([u1].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -8848,7 +8848,7 @@ public override async Task Complex_GroupBy_after_set_operator_using_result_selec AssertSql( """ -SELECT [u1].[Name], [u1].[Count], COALESCE(SUM([u1].[Count]), 0) AS [Sum] +SELECT [u1].[Name], [u1].[Count], ISNULL(SUM([u1].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -12077,7 +12077,7 @@ public override async Task Set_operator_with_navigation_in_projection_groupby_ag AssertSql( """ SELECT [s].[Name], ( - SELECT COALESCE(SUM(CAST(LEN([c].[Location]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([c].[Location]) AS int)), 0) FROM ( SELECT [g2].[SquadId], [g2].[CityOfBirthName] FROM [Gears] AS [g2] @@ -12203,7 +12203,7 @@ LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId], ROW_NUMBER() OVER(PARTITION BY [w].[OwnerFullName] ORDER BY [w].[Id]) AS [row] FROM [Weapons] AS [w] ) AS [w0] - WHERE [w0].[row] <= COALESCE(( + WHERE [w0].[row] <= ISNULL(( SELECT [n].[value] FROM OPENJSON(@numbers) WITH ([value] int '$') AS [n] ORDER BY [n].[value] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index 8155ea58a3a..ee90327970b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -4058,7 +4058,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END FROM [Weapons] AS [w] """); @@ -4087,7 +4087,7 @@ FROM [Weapons] AS [w] WHERE CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END LIKE N'%Cart%' """); } @@ -5622,7 +5622,7 @@ public override async Task Select_subquery_projecting_single_constant_int(bool a AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) 42 FROM [Gears] AS [g] WHERE [s].[Id] = [g].[SquadId] AND [g].[HasSoulPatch] = CAST(1 AS bit)), 0) AS [Gear] @@ -5650,7 +5650,7 @@ public override async Task Select_subquery_projecting_single_constant_bool(bool AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) CAST(1 AS bit) FROM [Gears] AS [g] WHERE [s].[Id] = [g].[SquadId] AND [g].[HasSoulPatch] = CAST(1 AS bit)), CAST(0 AS bit)) AS [Gear] @@ -6335,7 +6335,7 @@ public override async Task String_concat_on_various_types(bool async) AssertSql( """ -SELECT N'HasSoulPatch ' + CAST([g].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([g].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([g].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + COALESCE(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] +SELECT N'HasSoulPatch ' + CAST([g].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([g].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([g].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + ISNULL(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] FROM [Gears] AS [g] CROSS JOIN [Missions] AS [m] ORDER BY [g].[Nickname], [m].[Id] @@ -7527,7 +7527,7 @@ public override async Task Complex_GroupBy_after_set_operator(bool async) AssertSql( """ -SELECT [u].[Name], [u].[Count], COALESCE(SUM([u].[Count]), 0) AS [Sum] +SELECT [u].[Name], [u].[Count], ISNULL(SUM([u].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -7553,7 +7553,7 @@ public override async Task Complex_GroupBy_after_set_operator_using_result_selec AssertSql( """ -SELECT [u].[Name], [u].[Count], COALESCE(SUM([u].[Count]), 0) AS [Sum] +SELECT [u].[Name], [u].[Count], ISNULL(SUM([u].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -10267,7 +10267,7 @@ public override async Task Set_operator_with_navigation_in_projection_groupby_ag AssertSql( """ SELECT [s].[Name], ( - SELECT COALESCE(SUM(CAST(LEN([c].[Location]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([c].[Location]) AS int)), 0) FROM [Gears] AS [g2] INNER JOIN [Squads] AS [s0] ON [g2].[SquadId] = [s0].[Id] INNER JOIN [Cities] AS [c] ON [g2].[CityOfBirthName] = [c].[Name] @@ -10357,7 +10357,7 @@ LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId], ROW_NUMBER() OVER(PARTITION BY [w].[OwnerFullName] ORDER BY [w].[Id]) AS [row] FROM [Weapons] AS [w] ) AS [w0] - WHERE [w0].[row] <= COALESCE(( + WHERE [w0].[row] <= ISNULL(( SELECT [n].[value] FROM OPENJSON(@numbers) WITH ([value] int '$') AS [n] ORDER BY [n].[value] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index f6e550bed33..30b2c383b96 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -4148,7 +4148,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] """); @@ -4177,7 +4177,7 @@ SELECT [w].[Name] WHERE CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' - ELSE COALESCE(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') + ELSE ISNULL(CAST([w].[AmmunitionType] AS nvarchar(max)), N'') END LIKE N'%Cart%' """); } @@ -4216,7 +4216,7 @@ public override async Task Complex_GroupBy_after_set_operator(bool async) AssertSql( """ -SELECT [u].[Name], [u].[Count], COALESCE(SUM([u].[Count]), 0) AS [Sum] +SELECT [u].[Name], [u].[Count], ISNULL(SUM([u].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -4288,7 +4288,7 @@ public override async Task Select_subquery_projecting_single_constant_bool(bool AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) CAST(1 AS bit) FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] WHERE [s].[Id] = [g].[SquadId] AND [g].[HasSoulPatch] = CAST(1 AS bit)), CAST(0 AS bit)) AS [Gear] @@ -7507,7 +7507,7 @@ public override async Task String_concat_on_various_types(bool async) AssertSql( """ -SELECT N'HasSoulPatch ' + CAST([g].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([g].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([g].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + COALESCE(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] +SELECT N'HasSoulPatch ' + CAST([g].[HasSoulPatch] AS nvarchar(max)) + N' HasSoulPatch' AS [HasSoulPatch], N'Rank ' + CAST([g].[Rank] AS nvarchar(max)) + N' Rank' AS [Rank], N'SquadId ' + CAST([g].[SquadId] AS nvarchar(max)) + N' SquadId' AS [SquadId], N'Rating ' + ISNULL(CAST([m].[Rating] AS nvarchar(max)), N'') + N' Rating' AS [Rating], N'Timeline ' + CAST([m].[Timeline] AS nvarchar(max)) + N' Timeline' AS [Timeline] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] CROSS JOIN [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] ORDER BY [g].[Nickname], [m].[Id] @@ -8377,7 +8377,7 @@ public override async Task Complex_GroupBy_after_set_operator_using_result_selec AssertSql( """ -SELECT [u].[Name], [u].[Count], COALESCE(SUM([u].[Count]), 0) AS [Sum] +SELECT [u].[Name], [u].[Count], ISNULL(SUM([u].[Count]), 0) AS [Sum] FROM ( SELECT [c].[Name], ( SELECT COUNT(*) @@ -8434,7 +8434,7 @@ public override async Task Select_subquery_projecting_single_constant_int(bool a AssertSql( """ -SELECT [s].[Name], COALESCE(( +SELECT [s].[Name], ISNULL(( SELECT TOP(1) 42 FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] WHERE [s].[Id] = [g].[SquadId] AND [g].[HasSoulPatch] = CAST(1 AS bit)), 0) AS [Gear] @@ -8987,7 +8987,7 @@ public override async Task Set_operator_with_navigation_in_projection_groupby_ag AssertSql( """ SELECT [s].[Name], ( - SELECT COALESCE(SUM(CAST(LEN([c].[Location]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([c].[Location]) AS int)), 0) FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g2] INNER JOIN [Squads] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [s0] ON [g2].[SquadId] = [s0].[Id] INNER JOIN [Cities] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [c] ON [g2].[CityOfBirthName] = [c].[Name] @@ -9071,7 +9071,7 @@ LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId], ROW_NUMBER() OVER(PARTITION BY [w].[OwnerFullName] ORDER BY [w].[Id]) AS [row] FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] ) AS [w0] - WHERE [w0].[row] <= COALESCE(( + WHERE [w0].[row] <= ISNULL(( SELECT [n].[value] FROM OPENJSON(@numbers) WITH ([value] int '$') AS [n] ORDER BY [n].[value] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs index 78860365e07..7bf74ec7db7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs @@ -287,7 +287,7 @@ public override async Task Navigation_rewrite_on_owned_collection_with_compositi AssertSql( """ -SELECT COALESCE(( +SELECT ISNULL(( SELECT TOP(1) CAST([o0].[Id] ^ 42 AS bit) FROM [Order] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [o0] WHERE [o].[Id] = [o0].[ClientId] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/UdfDbFunctionSqlServerTests.cs b/test/EFCore.SqlServer.FunctionalTests/Query/UdfDbFunctionSqlServerTests.cs index 2b14825becb..661e354256e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/UdfDbFunctionSqlServerTests.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/UdfDbFunctionSqlServerTests.cs @@ -908,7 +908,7 @@ public override void TVF_with_navigation_in_projection_groupby_aggregate() AssertSql( """ SELECT [c].[LastName], ( - SELECT COALESCE(SUM(CAST(LEN([c1].[FirstName]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([c1].[FirstName]) AS int)), 0) FROM [Orders] AS [o0] INNER JOIN [Customers] AS [c0] ON [o0].[CustomerId] = [c0].[Id] INNER JOIN [Customers] AS [c1] ON [o0].[CustomerId] = [c1].[Id] @@ -933,7 +933,7 @@ public override void TVF_with_argument_being_a_subquery_with_navigation_in_proje AssertSql( """ SELECT [c0].[LastName], ( - SELECT COALESCE(SUM(CAST(LEN([c3].[FirstName]) AS int)), 0) + SELECT ISNULL(SUM(CAST(LEN([c3].[FirstName]) AS int)), 0) FROM [Orders] AS [o0] INNER JOIN [Customers] AS [c1] ON [o0].[CustomerId] = [c1].[Id] INNER JOIN [Customers] AS [c3] ON [o0].[CustomerId] = [c3].[Id]