diff --git a/test/EFCore.Jet.FunctionalTests/Query/ComplexNavigationsQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/ComplexNavigationsQueryJetTest.cs index 85ec68b..a541141 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/ComplexNavigationsQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/ComplexNavigationsQueryJetTest.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using EntityFrameworkCore.Jet.FunctionalTests.TestUtilities; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; @@ -762,11 +763,16 @@ WHERE `l`.`Id` = `l0`.`Id`"); await base.SelectMany_navigation_comparison2(isAsync); AssertSql( - $@"SELECT `l`.`Id` AS `Id1`, `l0`.`Id` AS `Id2` -FROM `LevelOne` AS `l`, -`LevelTwo` AS `l0` -LEFT JOIN `LevelOne` AS `l1` ON `l0`.`Level1_Optional_Id` = `l1`.`Id` -WHERE `l`.`Id` = `l1`.`Id`"); + """ + SELECT `t`.`Id` AS `Id1`, `t`.`Id0` AS `Id2` + FROM ( + SELECT `l`.`Id`, `l0`.`Id` AS `Id0`, `l0`.`Level1_Optional_Id` + FROM `LevelOne` AS `l`, + `LevelTwo` AS `l0` + ) AS `t` + LEFT JOIN `LevelOne` AS `l1` ON `t`.`Level1_Optional_Id` = `l1`.`Id` + WHERE `t`.`Id` = `l1`.`Id` + """); } public override async Task SelectMany_navigation_comparison3(bool isAsync) @@ -774,11 +780,16 @@ WHERE `l`.`Id` = `l1`.`Id`"); await base.SelectMany_navigation_comparison3(isAsync); AssertSql( - $@"SELECT `l`.`Id` AS `Id1`, `l0`.`Id` AS `Id2` -FROM `LevelOne` AS `l`, -`LevelTwo` AS `l0` -LEFT JOIN `LevelTwo` AS `l1` ON `l`.`Id` = `l1`.`Level1_Optional_Id` -WHERE `l1`.`Id` = `l0`.`Id`"); + """ + SELECT `t`.`Id` AS `Id1`, `t`.`Id0` AS `Id2` + FROM ( + SELECT `l`.`Id`, `l0`.`Id` AS `Id0` + FROM `LevelOne` AS `l`, + `LevelTwo` AS `l0` + ) AS `t` + LEFT JOIN `LevelTwo` AS `l1` ON `t`.`Id` = `l1`.`Level1_Optional_Id` + WHERE `l1`.`Id` = `t`.`Id0` + """); } public override async Task Where_complex_predicate_with_with_nav_prop_and_OrElse1(bool isAsync) @@ -786,12 +797,17 @@ WHERE `l1`.`Id` = `l0`.`Id`"); await base.Where_complex_predicate_with_with_nav_prop_and_OrElse1(isAsync); AssertSql( - $@"SELECT `l`.`Id` AS `Id1`, `l0`.`Id` AS `Id2` -FROM `LevelOne` AS `l`, -`LevelTwo` AS `l0` -LEFT JOIN `LevelTwo` AS `l1` ON `l`.`Id` = `l1`.`Level1_Optional_Id` -INNER JOIN `LevelOne` AS `l2` ON `l0`.`Level1_Required_Id` = `l2`.`Id` -WHERE `l1`.`Name` = 'L2 01' OR (`l2`.`Name` <> 'Bar' OR (`l2`.`Name` IS NULL))"); + """ + SELECT `t`.`Id` AS `Id1`, `t`.`Id0` AS `Id2` + FROM (( + SELECT `l`.`Id`, `l0`.`Id` AS `Id0`, `l0`.`Level1_Required_Id` + FROM `LevelOne` AS `l`, + `LevelTwo` AS `l0` + ) AS `t` + LEFT JOIN `LevelTwo` AS `l1` ON `t`.`Id` = `l1`.`Level1_Optional_Id`) + INNER JOIN `LevelOne` AS `l2` ON `t`.`Level1_Required_Id` = `l2`.`Id` + WHERE `l1`.`Name` = 'L2 01' OR `l2`.`Name` <> 'Bar' OR (`l2`.`Name` IS NULL) + """); } public override async Task Where_complex_predicate_with_with_nav_prop_and_OrElse2(bool isAsync) @@ -2063,12 +2079,13 @@ LEFT JOIN `LevelTwo` AS `l0` ON `l`.`Id` = `l0`.`Level1_Optional_Id`"); public override async Task GroupJoin_client_method_in_OrderBy(bool isAsync) { - await base.GroupJoin_client_method_in_OrderBy(isAsync); + await AssertTranslationFailedWithDetails( + () => base.GroupJoin_client_method_in_OrderBy(isAsync), + CoreStrings.QueryUnableToTranslateMethod( + "Microsoft.EntityFrameworkCore.Query.ComplexNavigationsQueryTestBase", + "ClientMethodNullableInt")); - AssertSql( - $@"SELECT `l1`.`Id`, `l2`.`Id` -FROM `LevelOne` AS `l1` -LEFT JOIN `LevelTwo` AS `l2` ON `l1`.`Id` = `l2`.`Level1_Optional_Id`"); + AssertSql(); } public override async Task GroupJoin_without_DefaultIfEmpty(bool isAsync) diff --git a/test/EFCore.Jet.FunctionalTests/Query/GearsOfWarQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/GearsOfWarQueryJetTest.cs index 7797a66..bbbc61b 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/GearsOfWarQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/GearsOfWarQueryJetTest.cs @@ -1021,20 +1021,20 @@ FROM `Gears` AS `g` { await base.Select_null_propagation_optimization9(isAsync); AssertSql( -""" -SELECT CLNG(LEN(`g`.`FullName`)) -FROM `Gears` AS `g` -"""); + """ + SELECT IIF(LEN(`g`.`FullName`) IS NULL, NULL, CLNG(LEN(`g`.`FullName`))) + FROM `Gears` AS `g` + """); } public override async Task Select_null_propagation_negative1(bool isAsync) { await base.Select_null_propagation_negative1(isAsync); AssertSql( -""" -SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(CLNG(LEN(`g`.`Nickname`)) = 5, TRUE, FALSE), NULL) -FROM `Gears` AS `g` -"""); + """ + SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))) = 5, TRUE, FALSE), NULL) + FROM `Gears` AS `g` + """); } public override async Task Select_null_propagation_negative2(bool isAsync) @@ -1106,9 +1106,9 @@ ORDER BY `t`.`Nickname`"); AssertSql( """ -SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(CLNG(LEN(`g`.`LeaderNickname`)) <> CLNG(LEN(`g`.`LeaderNickname`)), TRUE, FALSE), NULL) -FROM `Gears` AS `g` -"""); + SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(IIF(LEN(`g`.`LeaderNickname`) IS NULL, NULL, CLNG(LEN(`g`.`LeaderNickname`))) <> IIF(LEN(`g`.`LeaderNickname`) IS NULL, NULL, CLNG(LEN(`g`.`LeaderNickname`))), TRUE, FALSE), NULL) + FROM `Gears` AS `g` + """); } public override async Task Select_null_propagation_negative7(bool isAsync) @@ -1235,11 +1235,17 @@ WHERE 0 = 1 await base.Select_Where_Navigation_Scalar_Equals_Navigation_Scalar(isAsync); AssertSql( -""" -SELECT `g`.`Nickname` -FROM `Gears` AS `g` -WHERE 0 = 1 -"""); + """ + SELECT `t1`.`Id`, `t1`.`GearNickName`, `t1`.`GearSquadId`, `t1`.`IssueDate`, `t1`.`Note`, `t1`.`Id0`, `t1`.`GearNickName0`, `t1`.`GearSquadId0`, `t1`.`IssueDate0`, `t1`.`Note0` + FROM (( + SELECT `t`.`Id`, `t`.`GearNickName`, `t`.`GearSquadId`, `t`.`IssueDate`, `t`.`Note`, `t0`.`Id` AS `Id0`, `t0`.`GearNickName` AS `GearNickName0`, `t0`.`GearSquadId` AS `GearSquadId0`, `t0`.`IssueDate` AS `IssueDate0`, `t0`.`Note` AS `Note0` + FROM `Tags` AS `t`, + `Tags` AS `t0` + ) AS `t1` + LEFT JOIN `Gears` AS `g` ON `t1`.`GearNickName` = `g`.`Nickname` AND `t1`.`GearSquadId` = `g`.`SquadId`) + LEFT JOIN `Gears` AS `g0` ON `t1`.`GearNickName0` = `g0`.`Nickname` AND `t1`.`GearSquadId0` = `g0`.`SquadId` + WHERE `g`.`Nickname` = `g0`.`Nickname` OR ((`g`.`Nickname` IS NULL) AND (`g0`.`Nickname` IS NULL)) + """); } public override async Task Select_Singleton_Navigation_With_Member_Access(bool isAsync) @@ -1273,20 +1279,17 @@ WHERE `g`.`Nickname` = 'Marcus' await base.Select_Where_Navigation_Equals_Navigation(isAsync); AssertSql( - $@"SELECT `t`.`Id`, `t`.`GearNickName`, `t`.`GearSquadId`, `t`.`Note`, `t0`.`Id`, `t0`.`GearNickName`, `t0`.`GearSquadId`, `t0`.`Note` -FROM `Tags` AS `t`, -`Tags` AS `t0` -LEFT JOIN ( - SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`AssignedCityName`, `g`.`CityOfBirthName`, `g`.`Discriminator`, `g`.`FullName`, `g`.`HasSoulPatch`, `g`.`LeaderNickname`, `g`.`LeaderSquadId`, `g`.`Rank` - FROM `Gears` AS `g` - WHERE `g`.`Discriminator` IN ('Gear', 'Officer') -) AS `t1` ON (`t`.`GearNickName` = `t1`.`Nickname`) AND (`t`.`GearSquadId` = `t1`.`SquadId`) -LEFT JOIN ( - SELECT `g0`.`Nickname`, `g0`.`SquadId`, `g0`.`AssignedCityName`, `g0`.`CityOfBirthName`, `g0`.`Discriminator`, `g0`.`FullName`, `g0`.`HasSoulPatch`, `g0`.`LeaderNickname`, `g0`.`LeaderSquadId`, `g0`.`Rank` - FROM `Gears` AS `g0` - WHERE `g0`.`Discriminator` IN ('Gear', 'Officer') -) AS `t2` ON (`t0`.`GearNickName` = `t2`.`Nickname`) AND (`t0`.`GearSquadId` = `t2`.`SquadId`) -WHERE ((`t1`.`Nickname` = `t2`.`Nickname`) OR (`t1`.`Nickname` IS NULL AND `t2`.`Nickname` IS NULL)) AND ((`t1`.`SquadId` = `t2`.`SquadId`) OR (`t1`.`SquadId` IS NULL AND `t2`.`SquadId` IS NULL))"); + """ + SELECT `t1`.`Id`, `t1`.`GearNickName`, `t1`.`GearSquadId`, `t1`.`IssueDate`, `t1`.`Note`, `t1`.`Id0`, `t1`.`GearNickName0`, `t1`.`GearSquadId0`, `t1`.`IssueDate0`, `t1`.`Note0` + FROM (( + SELECT `t`.`Id`, `t`.`GearNickName`, `t`.`GearSquadId`, `t`.`IssueDate`, `t`.`Note`, `t0`.`Id` AS `Id0`, `t0`.`GearNickName` AS `GearNickName0`, `t0`.`GearSquadId` AS `GearSquadId0`, `t0`.`IssueDate` AS `IssueDate0`, `t0`.`Note` AS `Note0` + FROM `Tags` AS `t`, + `Tags` AS `t0` + ) AS `t1` + LEFT JOIN `Gears` AS `g` ON `t1`.`GearNickName` = `g`.`Nickname` AND `t1`.`GearSquadId` = `g`.`SquadId`) + LEFT JOIN `Gears` AS `g0` ON `t1`.`GearNickName0` = `g0`.`Nickname` AND `t1`.`GearSquadId0` = `g0`.`SquadId` + WHERE (`g`.`Nickname` = `g0`.`Nickname` OR ((`g`.`Nickname` IS NULL) AND (`g0`.`Nickname` IS NULL))) AND (`g`.`SquadId` = `g0`.`SquadId` OR ((`g`.`SquadId` IS NULL) AND (`g0`.`SquadId` IS NULL))) + """); } public override async Task Select_Where_Navigation_Null(bool isAsync) @@ -1320,20 +1323,17 @@ WHERE (`g`.`Nickname` IS NULL) OR (`g`.`SquadId` IS NULL) await base.Select_Where_Navigation_Scalar_Equals_Navigation_Scalar_Projected(isAsync); AssertSql( - $@"SELECT `t`.`Id` AS `Id1`, `t0`.`Id` AS `Id2` -FROM `Tags` AS `t`, -`Tags` AS `t0` -LEFT JOIN ( - SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`AssignedCityName`, `g`.`CityOfBirthName`, `g`.`Discriminator`, `g`.`FullName`, `g`.`HasSoulPatch`, `g`.`LeaderNickname`, `g`.`LeaderSquadId`, `g`.`Rank` - FROM `Gears` AS `g` - WHERE `g`.`Discriminator` IN ('Gear', 'Officer') -) AS `t1` ON (`t`.`GearNickName` = `t1`.`Nickname`) AND (`t`.`GearSquadId` = `t1`.`SquadId`) -LEFT JOIN ( - SELECT `g0`.`Nickname`, `g0`.`SquadId`, `g0`.`AssignedCityName`, `g0`.`CityOfBirthName`, `g0`.`Discriminator`, `g0`.`FullName`, `g0`.`HasSoulPatch`, `g0`.`LeaderNickname`, `g0`.`LeaderSquadId`, `g0`.`Rank` - FROM `Gears` AS `g0` - WHERE `g0`.`Discriminator` IN ('Gear', 'Officer') -) AS `t2` ON (`t0`.`GearNickName` = `t2`.`Nickname`) AND (`t0`.`GearSquadId` = `t2`.`SquadId`) -WHERE (`t1`.`Nickname` = `t2`.`Nickname`) OR (`t1`.`Nickname` IS NULL AND `t2`.`Nickname` IS NULL)"); + """ + SELECT `t1`.`Id` AS `Id1`, `t1`.`Id0` AS `Id2` + FROM (( + SELECT `t`.`Id`, `t`.`GearNickName`, `t`.`GearSquadId`, `t0`.`Id` AS `Id0`, `t0`.`GearNickName` AS `GearNickName0`, `t0`.`GearSquadId` AS `GearSquadId0` + FROM `Tags` AS `t`, + `Tags` AS `t0` + ) AS `t1` + LEFT JOIN `Gears` AS `g` ON `t1`.`GearNickName` = `g`.`Nickname` AND `t1`.`GearSquadId` = `g`.`SquadId`) + LEFT JOIN `Gears` AS `g0` ON `t1`.`GearNickName0` = `g0`.`Nickname` AND `t1`.`GearSquadId0` = `g0`.`SquadId` + WHERE `g`.`Nickname` = `g0`.`Nickname` OR ((`g`.`Nickname` IS NULL) AND (`g0`.`Nickname` IS NULL)) + """); } public override async Task Optional_Navigation_Null_Coalesce_To_Clr_Type(bool isAsync) @@ -3113,10 +3113,10 @@ ORDER BY `t`.`Rank`"); await base.Select_length_of_string_property(isAsync); AssertSql( -""" -SELECT `w`.`Name`, CLNG(LEN(`w`.`Name`)) AS `Length` -FROM `Weapons` AS `w` -"""); + """ + SELECT `w`.`Name`, IIF(LEN(`w`.`Name`) IS NULL, NULL, CLNG(LEN(`w`.`Name`))) AS `Length` + FROM `Weapons` AS `w` + """); } public override async Task Client_method_on_collection_navigation_in_outer_join_key(bool isAsync) @@ -3427,24 +3427,26 @@ FROM `Factions` AS `f`"); await base.Comparing_two_collection_navigations_inheritance(isAsync); AssertSql( - $@"SELECT `f`.`Name`, `t`.`Nickname` -FROM `Factions` AS `f`, -( - SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`AssignedCityName`, `g`.`CityOfBirthName`, `g`.`Discriminator`, `g`.`FullName`, `g`.`HasSoulPatch`, `g`.`LeaderNickname`, `g`.`LeaderSquadId`, `g`.`Rank` - FROM `Gears` AS `g` - WHERE `g`.`Discriminator` IN ('Gear', 'Officer') AND (`g`.`Discriminator` = 'Officer') -) AS `t` + """ +SELECT `t0`.`Name`, `t0`.`Nickname` +FROM (( + SELECT `f`.`Name`, `f`.`CommanderName`, `t`.`Nickname`, `t`.`SquadId` + FROM `Factions` AS `f`, + ( + SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`HasSoulPatch` + FROM `Gears` AS `g` + WHERE `g`.`Discriminator` = 'Officer' + ) AS `t` + WHERE `t`.`HasSoulPatch` = TRUE +) AS `t0` LEFT JOIN ( - SELECT `l`.`Name`, `l`.`Discriminator`, `l`.`LocustHordeId`, `l`.`ThreatLevel`, `l`.`DefeatedByNickname`, `l`.`DefeatedBySquadId`, `l`.`HighCommandId` + SELECT `l`.`Name`, `l`.`DefeatedByNickname`, `l`.`DefeatedBySquadId` FROM `LocustLeaders` AS `l` WHERE `l`.`Discriminator` = 'LocustCommander' -) AS `t0` ON `f`.`CommanderName` = `t0`.`Name` -LEFT JOIN ( - SELECT `g0`.`Nickname`, `g0`.`SquadId`, `g0`.`AssignedCityName`, `g0`.`CityOfBirthName`, `g0`.`Discriminator`, `g0`.`FullName`, `g0`.`HasSoulPatch`, `g0`.`LeaderNickname`, `g0`.`LeaderSquadId`, `g0`.`Rank` - FROM `Gears` AS `g0` - WHERE `g0`.`Discriminator` IN ('Gear', 'Officer') -) AS `t1` ON (`t0`.`DefeatedByNickname` = `t1`.`Nickname`) AND (`t0`.`DefeatedBySquadId` = `t1`.`SquadId`) -WHERE ((`f`.`Discriminator` = 'LocustHorde') AND ((`f`.`Discriminator` = 'LocustHorde') AND (`t`.`HasSoulPatch` = True))) AND ((`t1`.`Nickname` = `t`.`Nickname`) AND (`t1`.`SquadId` = `t`.`SquadId`))"); +) AS `t1` ON `t0`.`CommanderName` = `t1`.`Name`) +LEFT JOIN `Gears` AS `g0` ON `t1`.`DefeatedByNickname` = `g0`.`Nickname` AND `t1`.`DefeatedBySquadId` = `g0`.`SquadId` +WHERE `g0`.`Nickname` = `t0`.`Nickname` AND `g0`.`SquadId` = `t0`.`SquadId` +"""); } public override async Task Comparing_entities_using_Equals_inheritance(bool isAsync) @@ -6071,10 +6073,10 @@ ORDER BY `s`.`Id`, `t`.`Nickname`, `t`.`SquadId`, `t`.`Id`"); AssertSql( """ -SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(CLNG(LEN(`g`.`Nickname`)) = 5, TRUE, FALSE), NULL) -FROM `Gears` AS `g` -ORDER BY NOT (IIF(IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(CLNG(LEN(`g`.`Nickname`)) = 5, TRUE, FALSE), NULL) IS NOT NULL, TRUE, FALSE)) -"""); + SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))) = 5, TRUE, FALSE), NULL) + FROM `Gears` AS `g` + ORDER BY NOT (IIF(IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))) = 5, TRUE, FALSE), NULL) IS NOT NULL, TRUE, FALSE)) + """); } @@ -6137,7 +6139,7 @@ ORDER BY IIF(`w`.`SynergyWithId` IS NULL, 0, `w`.`SynergyWithId`), `w`.`Id`"); """ SELECT `w`.`Id`, `w`.`AmmunitionType`, `w`.`IsAutomatic`, `w`.`Name`, `w`.`OwnerFullName`, `w`.`SynergyWithId` FROM `Weapons` AS `w` - WHERE IIF(`w`.`SynergyWithId` IS NULL, CLNG(LEN(`w`.`Name`)) + 42, `w`.`SynergyWithId`) > 10 + WHERE IIF(`w`.`SynergyWithId` IS NULL, IIF(LEN(`w`.`Name`) IS NULL, NULL, CLNG(LEN(`w`.`Name`))) + 42, `w`.`SynergyWithId`) > 10 """); } @@ -6199,7 +6201,7 @@ WHERE `g`.`Nickname` <> 'Dom' FROM (`Tags` AS `t` LEFT JOIN `Gears` AS `g` ON `t`.`GearNickName` = `g`.`Nickname` AND `t`.`GearSquadId` = `g`.`SquadId`) LEFT JOIN `Squads` AS `s` ON `g`.`SquadId` = `s`.`Id` - WHERE IIF(LEN(`s`.`Name`) IS NULL, NULL, MID(`t`.`Note`, 0 + 1, CLNG(LEN(`s`.`Name`)))) = `t`.`GearNickName` OR (((`t`.`Note` IS NULL) OR (`s`.`Name` IS NULL)) AND (`t`.`GearNickName` IS NULL)) + WHERE IIF(LEN(`s`.`Name`) IS NULL, NULL, MID(`t`.`Note`, 0 + 1, IIF(LEN(`s`.`Name`) IS NULL, NULL, CLNG(LEN(`s`.`Name`))))) = `t`.`GearNickName` OR (((`t`.`Note` IS NULL) OR (`s`.`Name` IS NULL)) AND (`t`.`GearNickName` IS NULL)) """); } @@ -6597,7 +6599,23 @@ WHERE `t`.`Name` IS NOT NULL await base.Navigation_based_on_complex_expression4(isAsync); AssertSql( - $@""); + """ + SELECT TRUE, `t1`.`Name`, `t1`.`Discriminator`, `t1`.`LocustHordeId`, `t1`.`ThreatLevel`, `t1`.`ThreatLevelByte`, `t1`.`ThreatLevelNullableByte`, `t1`.`DefeatedByNickname`, `t1`.`DefeatedBySquadId`, `t1`.`HighCommandId`, `t0`.`Name0`, `t0`.`Discriminator0`, `t0`.`LocustHordeId`, `t0`.`ThreatLevel`, `t0`.`ThreatLevelByte`, `t0`.`ThreatLevelNullableByte`, `t0`.`DefeatedByNickname`, `t0`.`DefeatedBySquadId`, `t0`.`HighCommandId` + FROM ( + SELECT `f`.`CommanderName`, `t`.`Name` AS `Name0`, `t`.`Discriminator` AS `Discriminator0`, `t`.`LocustHordeId`, `t`.`ThreatLevel`, `t`.`ThreatLevelByte`, `t`.`ThreatLevelNullableByte`, `t`.`DefeatedByNickname`, `t`.`DefeatedBySquadId`, `t`.`HighCommandId` + FROM `Factions` AS `f`, + ( + SELECT `l`.`Name`, `l`.`Discriminator`, `l`.`LocustHordeId`, `l`.`ThreatLevel`, `l`.`ThreatLevelByte`, `l`.`ThreatLevelNullableByte`, `l`.`DefeatedByNickname`, `l`.`DefeatedBySquadId`, `l`.`HighCommandId` + FROM `LocustLeaders` AS `l` + WHERE `l`.`Discriminator` = 'LocustCommander' + ) AS `t` + ) AS `t0` + LEFT JOIN ( + SELECT `l0`.`Name`, `l0`.`Discriminator`, `l0`.`LocustHordeId`, `l0`.`ThreatLevel`, `l0`.`ThreatLevelByte`, `l0`.`ThreatLevelNullableByte`, `l0`.`DefeatedByNickname`, `l0`.`DefeatedBySquadId`, `l0`.`HighCommandId` + FROM `LocustLeaders` AS `l0` + WHERE `l0`.`Discriminator` = 'LocustCommander' + ) AS `t1` ON `t0`.`CommanderName` = `t1`.`Name` + """); } public override async Task Navigation_based_on_complex_expression5(bool isAsync) @@ -8163,13 +8181,13 @@ WHERE IIF(`t`.`GearNickName` IS NOT NULL, `g`.`Nickname`, NULL) IS NOT NULL await base.Projecting_property_converted_to_nullable_into_element_init(async); AssertSql( -""" -SELECT IIF(`t`.`GearNickName` IS NOT NULL, CLNG(LEN(`g`.`Nickname`)), NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL) + 1 -FROM `Tags` AS `t` -LEFT JOIN `Gears` AS `g` ON `t`.`GearNickName` = `g`.`Nickname` AND `t`.`GearSquadId` = `g`.`SquadId` -WHERE IIF(`t`.`GearNickName` IS NOT NULL, `g`.`Nickname`, NULL) IS NOT NULL -ORDER BY `t`.`Note` -"""); + """ + SELECT IIF(`t`.`GearNickName` IS NOT NULL, IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))), NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL) + 1 + FROM `Tags` AS `t` + LEFT JOIN `Gears` AS `g` ON `t`.`GearNickName` = `g`.`Nickname` AND `t`.`GearSquadId` = `g`.`SquadId` + WHERE IIF(`t`.`GearNickName` IS NOT NULL, `g`.`Nickname`, NULL) IS NOT NULL + ORDER BY `t`.`Note` + """); } public override async Task Projecting_property_converted_to_nullable_into_member_assignment(bool async) @@ -8191,13 +8209,13 @@ ORDER BY `t`.`Note` await base.Projecting_property_converted_to_nullable_into_new_array(async); AssertSql( -""" -SELECT IIF(`t`.`GearNickName` IS NOT NULL, CLNG(LEN(`g`.`Nickname`)), NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL) + 1 -FROM `Tags` AS `t` -LEFT JOIN `Gears` AS `g` ON `t`.`GearNickName` = `g`.`Nickname` AND `t`.`GearSquadId` = `g`.`SquadId` -WHERE IIF(`t`.`GearNickName` IS NOT NULL, `g`.`Nickname`, NULL) IS NOT NULL -ORDER BY `t`.`Note` -"""); + """ + SELECT IIF(`t`.`GearNickName` IS NOT NULL, IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))), NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL), IIF(`t`.`GearNickName` IS NOT NULL, `g`.`SquadId`, NULL) + 1 + FROM `Tags` AS `t` + LEFT JOIN `Gears` AS `g` ON `t`.`GearNickName` = `g`.`Nickname` AND `t`.`GearSquadId` = `g`.`SquadId` + WHERE IIF(`t`.`GearNickName` IS NOT NULL, `g`.`Nickname`, NULL) IS NOT NULL + ORDER BY `t`.`Note` + """); } public override async Task Projecting_property_converted_to_nullable_into_unary(bool async) @@ -9263,6 +9281,218 @@ ORDER BY `g`.`Nickname`, `g`.`SquadId`, `g0`.`Nickname` """); } + public override async Task Project_discriminator_columns(bool async) + { + await base.Project_discriminator_columns(async); + + AssertSql( + """ + SELECT `g`.`Nickname`, `g`.`Discriminator` + FROM `Gears` AS `g` + """, + // + """ + SELECT `g`.`Nickname`, `g`.`Discriminator` + FROM `Gears` AS `g` + WHERE `g`.`Discriminator` = 'Officer' + """, + // + """ + SELECT `f`.`Id`, `f`.`Discriminator` + FROM `Factions` AS `f` + """, + // + """ + SELECT `f`.`Id`, `f`.`Discriminator` + FROM `Factions` AS `f` + """, + // + """ + SELECT `l`.`Name`, `l`.`Discriminator` + FROM `LocustLeaders` AS `l` + """, + // + """ + SELECT `l`.`Name`, `l`.`Discriminator` + FROM `LocustLeaders` AS `l` + WHERE `l`.`Discriminator` = 'LocustCommander' + """); + } + + public override async Task ToString_boolean_property_non_nullable(bool async) + { + await base.ToString_boolean_property_non_nullable(async); + + AssertSql( + """ + SELECT IIF(`w`.`IsAutomatic` <> TRUE, 'False', 'True') + FROM `Weapons` AS `w` + """); + } + + public override async Task ToString_boolean_property_nullable(bool async) + { + await base.ToString_boolean_property_nullable(async); + + AssertSql( + """ + SELECT IIF(`f`.`Eradicated` = FALSE, 'False', IIF(`f`.`Eradicated` = TRUE, 'True', NULL)) + FROM `Factions` AS `f` + """); + } + + public override async Task Select_null_propagation_negative9(bool async) + { + await base.Select_null_propagation_negative9(async); + + AssertSql( + """ + SELECT IIF(`g`.`LeaderNickname` IS NOT NULL, IIF(IIF(IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))) = 5, TRUE, FALSE) IS NULL, FALSE, IIF(IIF(LEN(`g`.`Nickname`) IS NULL, NULL, CLNG(LEN(`g`.`Nickname`))) = 5, TRUE, FALSE)), NULL) + FROM `Gears` AS `g` + """); + } + + public override async Task Where_conditional_equality_1(bool async) + { + await base.Where_conditional_equality_1(async); + + AssertSql( + """ + SELECT `g`.`Nickname` + FROM `Gears` AS `g` + WHERE `g`.`LeaderNickname` IS NULL + ORDER BY `g`.`Nickname` + """); + } + + public override async Task Where_conditional_equality_2(bool async) + { + await base.Where_conditional_equality_2(async); + + AssertSql( + """ + SELECT `g`.`Nickname` + FROM `Gears` AS `g` + WHERE `g`.`LeaderNickname` IS NULL + ORDER BY `g`.`Nickname` + """); + } + + public override async Task Where_conditional_equality_3(bool async) + { + await base.Where_conditional_equality_3(async); + + AssertSql( + """ + SELECT `g`.`Nickname` + FROM `Gears` AS `g` + ORDER BY `g`.`Nickname` + """); + } + + public override async Task DateTimeOffsetNow_minus_timespan(bool async) + { + await base.DateTimeOffsetNow_minus_timespan(async); + + AssertSql(); + } + + public override async Task SelectMany_Where_DefaultIfEmpty_with_navigation_in_the_collection_selector_not_equal(bool async) + { + await base.SelectMany_Where_DefaultIfEmpty_with_navigation_in_the_collection_selector_not_equal(async); + + AssertSql( + $""" + {AssertSqlHelper.Parameter("@__isAutomatic_0='True'")} + + SELECT `g`.`Nickname`, `g`.`FullName`, IIF(`t`.`Id` IS NOT NULL, TRUE, FALSE) AS `Collection` + FROM `Gears` AS `g` + LEFT JOIN ( + SELECT `w`.`Id`, `w`.`OwnerFullName` + FROM `Weapons` AS `w` + WHERE `w`.`IsAutomatic` <> {AssertSqlHelper.Declaration("@__isAutomatic_0")} + ) AS `t` ON `g`.`FullName` = `t`.`OwnerFullName` + """); + } + + public override async Task SelectMany_Where_DefaultIfEmpty_with_navigation_in_the_collection_selector_order_comparison(bool async) + { + await base.SelectMany_Where_DefaultIfEmpty_with_navigation_in_the_collection_selector_order_comparison(async); + + AssertSql( + $""" +{AssertSqlHelper.Parameter("@__prm_0='1'")} + +SELECT `g`.`Nickname`, `g`.`FullName`, IIF(`t`.`Id` IS NOT NULL, TRUE, FALSE) AS `Collection` +FROM `Gears` AS `g` +LEFT JOIN ( + SELECT `w`.`Id`, `w`.`OwnerFullName` + FROM `Weapons` AS `w` + WHERE `w`.`Id` > {AssertSqlHelper.Declaration("@__prm_0")} +) AS `t` ON `g`.`FullName` = `t`.`OwnerFullName` +"""); + } + + public override async Task Query_reusing_parameter_with_inner_query_doesnt_declare_duplicate_parameter(bool async) + { + await base.Query_reusing_parameter_with_inner_query_doesnt_declare_duplicate_parameter(async); + + AssertSql( + $""" + {AssertSqlHelper.Parameter("@__squadId_0='1'")} + {AssertSqlHelper.Parameter("@__squadId_0='1'")} + + SELECT `t`.`Nickname`, `t`.`SquadId`, `t`.`AssignedCityName`, `t`.`CityOfBirthName`, `t`.`Discriminator`, `t`.`FullName`, `t`.`HasSoulPatch`, `t`.`LeaderNickname`, `t`.`LeaderSquadId`, `t`.`Rank` + FROM ( + SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`AssignedCityName`, `g`.`CityOfBirthName`, `g`.`Discriminator`, `g`.`FullName`, `g`.`HasSoulPatch`, `g`.`LeaderNickname`, `g`.`LeaderSquadId`, `g`.`Rank` + FROM `Gears` AS `g` + INNER JOIN `Squads` AS `s` ON `g`.`SquadId` = `s`.`Id` + WHERE EXISTS ( + SELECT 1 + FROM `Squads` AS `s0` + WHERE `s0`.`Id` = {AssertSqlHelper.Declaration("@__squadId_0")} AND `s0`.`Id` = `s`.`Id`) + UNION ALL + SELECT `g0`.`Nickname`, `g0`.`SquadId`, `g0`.`AssignedCityName`, `g0`.`CityOfBirthName`, `g0`.`Discriminator`, `g0`.`FullName`, `g0`.`HasSoulPatch`, `g0`.`LeaderNickname`, `g0`.`LeaderSquadId`, `g0`.`Rank` + FROM `Gears` AS `g0` + INNER JOIN `Squads` AS `s1` ON `g0`.`SquadId` = `s1`.`Id` + WHERE EXISTS ( + SELECT 1 + FROM `Squads` AS `s2` + WHERE `s2`.`Id` = {AssertSqlHelper.Declaration("@__squadId_0")} AND `s2`.`Id` = `s1`.`Id`) + ) AS `t` + ORDER BY `t`.`FullName` + """); + } + + public override async Task Query_reusing_parameter_with_inner_query_expression_doesnt_declare_duplicate_parameter(bool async) + { + await base.Query_reusing_parameter_with_inner_query_expression_doesnt_declare_duplicate_parameter(async); + + AssertSql( + $""" + {AssertSqlHelper.Parameter("@__gearId_0='1'")} + {AssertSqlHelper.Parameter("@__gearId_0='1'")} + + SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name` + FROM `Squads` AS `s` + WHERE EXISTS ( + SELECT 1 + FROM `Gears` AS `g` + WHERE `s`.`Id` = `g`.`SquadId` AND `g`.`SquadId` = {AssertSqlHelper.Declaration("@__gearId_0")} AND `g`.`SquadId` = {AssertSqlHelper.Declaration("@__gearId_0")}) + """); + } + + public override async Task OrderBy_Contains_empty_list(bool async) + { + await base.OrderBy_Contains_empty_list(async); + + AssertSql( + """ +SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`AssignedCityName`, `g`.`CityOfBirthName`, `g`.`Discriminator`, `g`.`FullName`, `g`.`HasSoulPatch`, `g`.`LeaderNickname`, `g`.`LeaderSquadId`, `g`.`Rank` +FROM `Gears` AS `g` +"""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); } diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindAggregateOperatorsQueryJetTest.ResultOperators.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindAggregateOperatorsQueryJetTest.ResultOperators.cs index 8290461..52b2c8a 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindAggregateOperatorsQueryJetTest.ResultOperators.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindAggregateOperatorsQueryJetTest.ResultOperators.cs @@ -265,11 +265,16 @@ WHERE `p`.`ProductID` < 40"); await base.Average_over_subquery_is_client_eval(isAsync); AssertSql( - $@"SELECT AVG(CDBL(( - SELECT IIF(SUM(`o`.`OrderID`) IS NULL, 0, SUM(`o`.`OrderID`)) - FROM `Orders` AS `o` - WHERE `c`.`CustomerID` = `o`.`CustomerID`))) -FROM `Customers` AS `c`"); + """ + SELECT AVG(IIF(( + SELECT IIF(SUM(`o`.`OrderID`) IS NULL, 0, SUM(`o`.`OrderID`)) + FROM `Orders` AS `o` + WHERE `c`.`CustomerID` = `o`.`CustomerID`) IS NULL, NULL, CDBL(( + SELECT IIF(SUM(`o`.`OrderID`) IS NULL, 0, SUM(`o`.`OrderID`)) + FROM `Orders` AS `o` + WHERE `c`.`CustomerID` = `o`.`CustomerID`)))) + FROM `Customers` AS `c` + """); } public override async Task Average_over_nested_subquery_is_client_eval(bool isAsync) diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindFunctionsQueryJetTest.Functions.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindFunctionsQueryJetTest.Functions.cs index 61fbde4..baecf8c 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindFunctionsQueryJetTest.Functions.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindFunctionsQueryJetTest.Functions.cs @@ -306,7 +306,7 @@ ORDER BY `t`.`City` await base.String_Join_with_predicate(async); AssertSql( -""" + """ SELECT `t`.`City`, `t0`.`CustomerID` FROM ( SELECT `c`.`City` @@ -316,7 +316,7 @@ FROM ( LEFT JOIN ( SELECT `c0`.`CustomerID`, `c0`.`City` FROM `Customers` AS `c0` - WHERE CLNG(LEN(`c0`.`ContactName`)) > 10 + WHERE IIF(LEN(`c0`.`ContactName`) IS NULL, NULL, CLNG(LEN(`c0`.`ContactName`))) > 10 ) AS `t0` ON `t`.`City` = `t0`.`City` ORDER BY `t`.`City` """); @@ -1229,11 +1229,11 @@ WHERE `o`.`Quantity` < 5 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` < 5 AND CSNG(INT(CSNG(`o`.`UnitPrice`))) > 10 -"""); + """ + SELECT `o`.`OrderID`, `o`.`ProductID`, `o`.`Discount`, `o`.`Quantity`, `o`.`UnitPrice` + FROM `Order Details` AS `o` + WHERE `o`.`Quantity` < 5 AND IIF(INT(CSNG(`o`.`UnitPrice`)) IS NULL, NULL, CSNG(INT(CSNG(`o`.`UnitPrice`)))) > 10 + """); } public override async Task Select_mathf_truncate(bool async) @@ -1241,11 +1241,11 @@ WHERE `o`.`Quantity` < 5 AND CSNG(INT(CSNG(`o`.`UnitPrice`))) > 10 await base.Select_mathf_truncate(async); AssertSql( - """ -SELECT CSNG(INT(CSNG(`o`.`UnitPrice`))) -FROM `Order Details` AS `o` -WHERE `o`.`Quantity` < 5 -"""); + """ + SELECT IIF(INT(CSNG(`o`.`UnitPrice`)) IS NULL, NULL, CSNG(INT(CSNG(`o`.`UnitPrice`)))) + FROM `Order Details` AS `o` + WHERE `o`.`Quantity` < 5 + """); } public override async Task Where_mathf_exp(bool async) @@ -1440,10 +1440,10 @@ WHERE LCASE(`c`.`CustomerID`) = 'alfki'"); AssertSql( """ -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 CDBL(CLNG(LEN(`c`.`CustomerID`)))^2.0 = 25.0 -"""); + 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 CDBL(IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))))^2.0 = 25.0 + """); } public override async Task Convert_ToBoolean(bool async) @@ -2154,9 +2154,11 @@ WHERE TRIM(`c`.`ContactTitle`) = 'Owner'"); await base.Order_by_length_twice(isAsync); AssertSql( - $@"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` -ORDER BY CLNG(LEN(`c`.`CustomerID`)), `c`.`CustomerID`"); + """ + 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` + ORDER BY IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))), `c`.`CustomerID` + """); } public override async Task Order_by_length_twice_followed_by_projection_of_naked_collection_navigation(bool isAsync) @@ -2164,10 +2166,12 @@ ORDER BY CLNG(LEN(`c`.`CustomerID`)), `c`.`CustomerID`"); await base.Order_by_length_twice_followed_by_projection_of_naked_collection_navigation(isAsync); AssertSql( - $@"SELECT `c`.`CustomerID`, `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate` -FROM `Customers` AS `c` -LEFT JOIN `Orders` AS `o` ON `c`.`CustomerID` = `o`.`CustomerID` -ORDER BY CLNG(LEN(`c`.`CustomerID`)), `c`.`CustomerID`"); + """ + SELECT `c`.`CustomerID`, `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate` + FROM `Customers` AS `c` + LEFT JOIN `Orders` AS `o` ON `c`.`CustomerID` = `o`.`CustomerID` + ORDER BY IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))), `c`.`CustomerID` + """); } public override async Task Static_string_equals_in_predicate(bool isAsync) diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindGroupByQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindGroupByQueryJetTest.cs index fdec5a4..07c6101 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindGroupByQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindGroupByQueryJetTest.cs @@ -474,9 +474,11 @@ GROUP BY `o`.`CustomerID`, `o`.`EmployeeID`"); await base.GroupBy_Dto_as_element_selector_Select_Sum(isAsync); AssertSql( - $@"SELECT IIF(SUM(CLNG(`o`.`EmployeeID`)) IS NULL, 0, SUM(CLNG(`o`.`EmployeeID`))) AS `Sum`, `o`.`CustomerID` AS `Key` -FROM `Orders` AS `o` -GROUP BY `o`.`CustomerID`"); + """ + SELECT IIF(SUM(IIF(`o`.`EmployeeID` IS NULL, NULL, CLNG(`o`.`EmployeeID`))) IS NULL, 0, SUM(IIF(`o`.`EmployeeID` IS NULL, NULL, CLNG(`o`.`EmployeeID`)))) AS `Sum`, `o`.`CustomerID` AS `Key` + FROM `Orders` AS `o` + GROUP BY `o`.`CustomerID` + """); } public override async Task GroupBy_Composite_Select_Dto_Sum_Min_Key_flattened_Max_Avg(bool isAsync) @@ -1022,11 +1024,13 @@ GROUP BY `t0`.`CustomerID`"); await base.GroupJoin_GroupBy_Aggregate(isAsync); AssertSql( - $@"SELECT `o`.`CustomerID` AS `Key`, AVG(CDBL(`o`.`OrderID`)) AS `Average` -FROM `Customers` AS `c` -LEFT JOIN `Orders` AS `o` ON `c`.`CustomerID` = `o`.`CustomerID` -WHERE `o`.`OrderID` IS NOT NULL -GROUP BY `o`.`CustomerID`"); + """ + SELECT `o`.`CustomerID` AS `Key`, AVG(IIF(`o`.`OrderID` IS NULL, NULL, CDBL(`o`.`OrderID`))) AS `Average` + FROM `Customers` AS `c` + LEFT JOIN `Orders` AS `o` ON `c`.`CustomerID` = `o`.`CustomerID` + WHERE `o`.`OrderID` IS NOT NULL + GROUP BY `o`.`CustomerID` + """); } public override async Task GroupJoin_GroupBy_Aggregate_2(bool isAsync) @@ -1944,9 +1948,11 @@ GROUP BY `o`.`CustomerID`"); await base.Group_by_with_arithmetic_operation_inside_aggregate(isAsync); AssertSql( - $@"SELECT `o`.`CustomerID` AS `Key`, IIF(SUM(`o`.`OrderID` + CLNG(LEN(`o`.`CustomerID`))) IS NULL, 0, SUM(`o`.`OrderID` + CLNG(LEN(`o`.`CustomerID`)))) AS `Sum` -FROM `Orders` AS `o` -GROUP BY `o`.`CustomerID`"); + """ + SELECT `o`.`CustomerID` AS `Key`, IIF(SUM(`o`.`OrderID` + IIF(LEN(`o`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`o`.`CustomerID`)))) IS NULL, 0, SUM(`o`.`OrderID` + IIF(LEN(`o`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`o`.`CustomerID`))))) AS `Sum` + FROM `Orders` AS `o` + GROUP BY `o`.`CustomerID` + """); } private void AssertSql(params string[] expected) diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindMiscellaneousQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindMiscellaneousQueryJetTest.cs index 582c86d..20b3724 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindMiscellaneousQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindMiscellaneousQueryJetTest.cs @@ -4018,13 +4018,19 @@ ORDER BY `o`.`OrderID`, `o0`.`OrderID`"); await base.Comparing_navigations_using_static_Equals(isAsync); AssertSql( - $@"SELECT `o`.`OrderID` AS `Id1`, `o0`.`OrderID` AS `Id2` -FROM `Orders` AS `o`, -`Orders` AS `o0` -LEFT JOIN `Customers` AS `c` ON `o`.`CustomerID` = `c`.`CustomerID` -LEFT JOIN `Customers` AS `c0` ON `o0`.`CustomerID` = `c0`.`CustomerID` -WHERE (`o`.`CustomerID` IS NOT NULL AND (`o`.`CustomerID` LIKE 'A' & '%')) AND ((`c`.`CustomerID` = `c0`.`CustomerID`) OR (`c`.`CustomerID` IS NULL AND `c0`.`CustomerID` IS NULL)) -ORDER BY `o`.`OrderID`, `o0`.`OrderID`"); + """ + SELECT `t`.`OrderID` AS `Id1`, `t`.`OrderID0` AS `Id2` + FROM (( + SELECT `o`.`OrderID`, `o`.`CustomerID`, `o0`.`OrderID` AS `OrderID0`, `o0`.`CustomerID` AS `CustomerID0` + FROM `Orders` AS `o`, + `Orders` AS `o0` + WHERE (`o`.`CustomerID` IS NOT NULL) AND (`o`.`CustomerID` LIKE 'A%') + ) AS `t` + LEFT JOIN `Customers` AS `c` ON `t`.`CustomerID` = `c`.`CustomerID`) + LEFT JOIN `Customers` AS `c0` ON `t`.`CustomerID0` = `c0`.`CustomerID` + WHERE `c`.`CustomerID` = `c0`.`CustomerID` OR ((`c`.`CustomerID` IS NULL) AND (`c0`.`CustomerID` IS NULL)) + ORDER BY `t`.`OrderID`, `t`.`OrderID0` + """); } public override async Task Comparing_non_matching_entities_using_Equals(bool isAsync) diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindNavigationsQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindNavigationsQueryJetTest.cs index c5f97e0..bcf5685 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindNavigationsQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindNavigationsQueryJetTest.cs @@ -14,9 +14,10 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.Query NorthwindQueryJetFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) { - fixture.TestSqlLoggerFactory.Clear(); + ClearLog(); + //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } - + public override async Task Select_Where_Navigation(bool isAsync) { await base.Select_Where_Navigation(isAsync); @@ -314,16 +315,22 @@ WHERE `c`.`City` = 'Seattle' AND (`c`.`Phone` <> '555 555 5555' OR (`c`.`Phone` await base.Select_Where_Navigation_Scalar_Equals_Navigation_Scalar_Projected(isAsync); AssertSql( - $@"SELECT `o`.`CustomerID`, `t`.`CustomerID` AS `C2` -FROM `Orders` AS `o`, -( - SELECT `o0`.`OrderID`, `o0`.`CustomerID`, `o0`.`EmployeeID`, `o0`.`OrderDate` - FROM `Orders` AS `o0` - WHERE `o0`.`OrderID` < 10400 -) AS `t` -LEFT JOIN `Customers` AS `c` ON `o`.`CustomerID` = `c`.`CustomerID` -LEFT JOIN `Customers` AS `c0` ON `t`.`CustomerID` = `c0`.`CustomerID` -WHERE (`o`.`OrderID` < 10300) AND ((`c`.`City` = `c0`.`City`) OR (`c`.`City` IS NULL AND `c0`.`City` IS NULL))"); + """ + SELECT `t0`.`CustomerID`, `t0`.`CustomerID0` AS `C2` + FROM (( + SELECT `o`.`CustomerID`, `t`.`CustomerID` AS `CustomerID0` + FROM `Orders` AS `o`, + ( + SELECT `o0`.`CustomerID` + FROM `Orders` AS `o0` + WHERE `o0`.`OrderID` < 10400 + ) AS `t` + WHERE `o`.`OrderID` < 10300 + ) AS `t0` + LEFT JOIN `Customers` AS `c` ON `t0`.`CustomerID` = `c`.`CustomerID`) + LEFT JOIN `Customers` AS `c0` ON `t0`.`CustomerID0` = `c0`.`CustomerID` + WHERE `c`.`City` = `c0`.`City` OR ((`c`.`City` IS NULL) AND (`c0`.`City` IS NULL)) + """); } public override async Task Select_Where_Navigation_Equals_Navigation(bool isAsync) @@ -331,12 +338,18 @@ WHERE (`o`.`OrderID` < 10300) AND ((`c`.`City` = `c0`.`City`) OR (`c`.`City` IS await base.Select_Where_Navigation_Equals_Navigation(isAsync); AssertSql( - $@"SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`, `o0`.`OrderID`, `o0`.`CustomerID`, `o0`.`EmployeeID`, `o0`.`OrderDate` -FROM `Orders` AS `o`, -`Orders` AS `o0` -LEFT JOIN `Customers` AS `c` ON `o`.`CustomerID` = `c`.`CustomerID` -LEFT JOIN `Customers` AS `c0` ON `o0`.`CustomerID` = `c0`.`CustomerID` -WHERE ((`o`.`CustomerID` IS NOT NULL AND (`o`.`CustomerID` LIKE 'A' & '%')) AND (`o0`.`CustomerID` IS NOT NULL AND (`o0`.`CustomerID` LIKE 'A' & '%'))) AND ((`c`.`CustomerID` = `c0`.`CustomerID`) OR (`c`.`CustomerID` IS NULL AND `c0`.`CustomerID` IS NULL))"); + """ + SELECT `t`.`OrderID`, `t`.`CustomerID`, `t`.`EmployeeID`, `t`.`OrderDate`, `t`.`OrderID0`, `t`.`CustomerID0`, `t`.`EmployeeID0`, `t`.`OrderDate0` + FROM (( + SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`, `o0`.`OrderID` AS `OrderID0`, `o0`.`CustomerID` AS `CustomerID0`, `o0`.`EmployeeID` AS `EmployeeID0`, `o0`.`OrderDate` AS `OrderDate0` + FROM `Orders` AS `o`, + `Orders` AS `o0` + WHERE (`o`.`CustomerID` IS NOT NULL) AND (`o`.`CustomerID` LIKE 'A%') AND (`o0`.`CustomerID` IS NOT NULL) AND (`o0`.`CustomerID` LIKE 'A%') + ) AS `t` + LEFT JOIN `Customers` AS `c` ON `t`.`CustomerID` = `c`.`CustomerID`) + LEFT JOIN `Customers` AS `c0` ON `t`.`CustomerID0` = `c0`.`CustomerID` + WHERE `c`.`CustomerID` = `c0`.`CustomerID` OR ((`c`.`CustomerID` IS NULL) AND (`c0`.`CustomerID` IS NULL)) + """); } public override async Task Select_Where_Navigation_Null(bool isAsync) diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindSelectQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindSelectQueryJetTest.cs index ed606a0..2e8682e 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindSelectQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindSelectQueryJetTest.cs @@ -196,8 +196,10 @@ FROM `Customers` AS `c`"); await base.Select_anonymous_constant_in_expression(isAsync); AssertSql( - $@"SELECT `c`.`CustomerID`, CLNG(LEN(`c`.`CustomerID`)) + 5 AS `Expression` -FROM `Customers` AS `c`"); + """ + SELECT `c`.`CustomerID`, IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))) + 5 AS `Expression` + FROM `Customers` AS `c` + """); } public override async Task Select_anonymous_conditional_expression(bool isAsync) @@ -430,34 +432,36 @@ ORDER BY `c`.`CustomerID`"); await base.Select_nested_collection_multi_level6(isAsync); AssertSql( - $@"SELECT IIF(( - SELECT TOP 1 IIF(( - SELECT TOP 1 `o0`.`ProductID` - FROM `Order Details` AS `o0` - WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> CLNG(LEN(`c`.`CustomerID`)) - ORDER BY `o0`.`OrderID`, `o0`.`ProductID`) IS NULL, 0, ( - SELECT TOP 1 `o0`.`ProductID` - FROM `Order Details` AS `o0` - WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> CLNG(LEN(`c`.`CustomerID`)) - ORDER BY `o0`.`OrderID`, `o0`.`ProductID`)) - FROM `Orders` AS `o` - WHERE `c`.`CustomerID` = `o`.`CustomerID` AND `o`.`OrderID` < 10500 - ORDER BY `o`.`OrderID`) IS NULL, 0, ( - SELECT TOP 1 IIF(( - SELECT TOP 1 `o0`.`ProductID` - FROM `Order Details` AS `o0` - WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> CLNG(LEN(`c`.`CustomerID`)) - ORDER BY `o0`.`OrderID`, `o0`.`ProductID`) IS NULL, 0, ( - SELECT TOP 1 `o0`.`ProductID` - FROM `Order Details` AS `o0` - WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> CLNG(LEN(`c`.`CustomerID`)) - ORDER BY `o0`.`OrderID`, `o0`.`ProductID`)) - FROM `Orders` AS `o` - WHERE `c`.`CustomerID` = `o`.`CustomerID` AND `o`.`OrderID` < 10500 - ORDER BY `o`.`OrderID`)) AS `Order` -FROM `Customers` AS `c` -WHERE `c`.`CustomerID` LIKE 'A%' -ORDER BY `c`.`CustomerID`"); + """ + SELECT IIF(( + SELECT TOP 1 IIF(( + SELECT TOP 1 `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))) + ORDER BY `o0`.`OrderID`, `o0`.`ProductID`) IS NULL, 0, ( + SELECT TOP 1 `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))) + ORDER BY `o0`.`OrderID`, `o0`.`ProductID`)) + FROM `Orders` AS `o` + WHERE `c`.`CustomerID` = `o`.`CustomerID` AND `o`.`OrderID` < 10500 + ORDER BY `o`.`OrderID`) IS NULL, 0, ( + SELECT TOP 1 IIF(( + SELECT TOP 1 `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))) + ORDER BY `o0`.`OrderID`, `o0`.`ProductID`) IS NULL, 0, ( + SELECT TOP 1 `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o`.`OrderID` = `o0`.`OrderID` AND `o0`.`OrderID` <> IIF(LEN(`c`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`c`.`CustomerID`))) + ORDER BY `o0`.`OrderID`, `o0`.`ProductID`)) + FROM `Orders` AS `o` + WHERE `c`.`CustomerID` = `o`.`CustomerID` AND `o`.`OrderID` < 10500 + ORDER BY `o`.`OrderID`)) AS `Order` + FROM `Customers` AS `c` + WHERE `c`.`CustomerID` LIKE 'A%' + ORDER BY `c`.`CustomerID` + """); } public override async Task Select_nested_collection_count_using_anonymous_type(bool isAsync) @@ -499,10 +503,12 @@ ORDER BY `o`.`OrderID`"); await base.Select_non_matching_value_types_nullable_int_to_long_introduces_explicit_cast(isAsync); AssertSql( - $@"SELECT CLNG(`o`.`EmployeeID`) -FROM `Orders` AS `o` -WHERE `o`.`CustomerID` = 'ALFKI' -ORDER BY `o`.`OrderID`"); + """ + SELECT IIF(`o`.`EmployeeID` IS NULL, NULL, CLNG(`o`.`EmployeeID`)) + FROM `Orders` AS `o` + WHERE `o`.`CustomerID` = 'ALFKI' + ORDER BY `o`.`OrderID` + """); } public override async Task Select_non_matching_value_types_nullable_int_to_int_doesnt_introduce_explicit_cast(bool isAsync) @@ -577,10 +583,12 @@ ORDER BY `o`.`OrderID`"); await base.Select_non_matching_value_types_from_length_introduces_explicit_cast(isAsync); AssertSql( - $@"SELECT CLNG(CLNG(LEN(`o`.`CustomerID`))) -FROM `Orders` AS `o` -WHERE `o`.`CustomerID` = 'ALFKI' -ORDER BY `o`.`OrderID`"); + """ + SELECT CLNG(IIF(LEN(`o`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`o`.`CustomerID`)))) + FROM `Orders` AS `o` + WHERE `o`.`CustomerID` = 'ALFKI' + ORDER BY `o`.`OrderID` + """); } public override async Task Select_non_matching_value_types_from_method_call_introduces_explicit_cast(bool isAsync) @@ -588,10 +596,12 @@ ORDER BY `o`.`OrderID`"); await base.Select_non_matching_value_types_from_method_call_introduces_explicit_cast(isAsync); AssertSql( - $@"SELECT CLNG(ABS(`o`.`OrderID`)) -FROM `Orders` AS `o` -WHERE `o`.`CustomerID` = 'ALFKI' -ORDER BY `o`.`OrderID`"); + """ + SELECT IIF(ABS(`o`.`OrderID`) IS NULL, NULL, CLNG(ABS(`o`.`OrderID`))) + FROM `Orders` AS `o` + WHERE `o`.`CustomerID` = 'ALFKI' + ORDER BY `o`.`OrderID` + """); } public override async Task Select_non_matching_value_types_from_anonymous_type_introduces_explicit_cast(bool isAsync) @@ -995,8 +1005,10 @@ FROM `Orders` AS `o`"); await base.Projecting_nullable_struct(isAsync); AssertSql( - $@"SELECT `o`.`CustomerID`, IIF(`o`.`CustomerID` = 'ALFKI' AND (`o`.`CustomerID` IS NOT NULL), TRUE, FALSE), `o`.`OrderID`, CLNG(LEN(`o`.`CustomerID`)) -FROM `Orders` AS `o`"); + """ + SELECT `o`.`CustomerID`, IIF(`o`.`CustomerID` = 'ALFKI' AND (`o`.`CustomerID` IS NOT NULL), TRUE, FALSE), `o`.`OrderID`, IIF(LEN(`o`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`o`.`CustomerID`))) + FROM `Orders` AS `o` + """); } public override async Task Multiple_select_many_with_predicate(bool isAsync) @@ -1423,13 +1435,15 @@ LEFT JOIN `Customers` AS `c` ON `o`.`CustomerID` = `c`.`CustomerID`"); await base.Projecting_Length_of_a_string_property_after_FirstOrDefault_on_correlated_collection(async); AssertSql( - @"SELECT ( - SELECT TOP 1 CLNG(LEN(`o`.`CustomerID`)) - FROM `Orders` AS `o` - WHERE `c`.`CustomerID` = `o`.`CustomerID` - ORDER BY `o`.`OrderID`) -FROM `Customers` AS `c` -ORDER BY `c`.`CustomerID`"); + """ + SELECT ( + SELECT TOP 1 IIF(LEN(`o`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`o`.`CustomerID`))) + FROM `Orders` AS `o` + WHERE `c`.`CustomerID` = `o`.`CustomerID` + ORDER BY `o`.`OrderID`) + FROM `Customers` AS `c` + ORDER BY `c`.`CustomerID` + """); } public override async Task Projecting_count_of_navigation_which_is_generic_list(bool async) diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs index dcb06a1..a36c450 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs @@ -654,9 +654,11 @@ WHERE `e`.`ReportsTo` IS NULL"); await base.Where_string_length(isAsync); AssertSql( - $@"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 CLNG(LEN(`c`.`City`)) = 6"); + """ + 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 IIF(LEN(`c`.`City`) IS NULL, NULL, CLNG(LEN(`c`.`City`))) = 6 + """); } public override async Task Where_string_indexof(bool isAsync) @@ -1709,12 +1711,14 @@ WHERE `c`.`City` = 'Seattle'"); await base.Filter_non_nullable_value_after_FirstOrDefault_on_empty_collection(isAsync); AssertSql( - $@"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 TOP 1 CLNG(LEN(`o`.`CustomerID`)) - FROM `Orders` AS `o` - WHERE `o`.`CustomerID` = 'John Doe') = 0"); + """ + 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 TOP 1 IIF(LEN(`o`.`CustomerID`) IS NULL, NULL, CLNG(LEN(`o`.`CustomerID`))) + FROM `Orders` AS `o` + WHERE `o`.`CustomerID` = 'John Doe') = 0 + """); } public override async Task Like_with_non_string_column_using_ToString(bool isAsync) diff --git a/test/EFCore.Jet.FunctionalTests/Query/QueryBugsTest.cs b/test/EFCore.Jet.FunctionalTests/Query/QueryBugsTest.cs index 773c660..f33dee7 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/QueryBugsTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/QueryBugsTest.cs @@ -4084,28 +4084,34 @@ WHERE (`t`.`Name` <> 'Bar') OR `t`.`Name` IS NULL"); $@"SELECT AVG(`p`.`Price`) FROM `Prices` AS `p`", // - $@"SELECT AVG(IIF(`p`.`IntColumn` IS NULL, NULL, CDBL(`p`.`IntColumn`))) + $@"SELECT AVG(CDBL(`p`.`IntColumn`)) FROM `Prices` AS `p`", // $@"SELECT AVG(IIF(`p`.`NullableIntColumn` IS NULL, NULL, CDBL(`p`.`NullableIntColumn`))) FROM `Prices` AS `p`", // - $@"SELECT AVG(IIF(`p`.`LongColumn` IS NULL, NULL, CDBL(`p`.`LongColumn`))) + $@"SELECT AVG(CDBL(`p`.`LongColumn`)) FROM `Prices` AS `p`", // $@"SELECT AVG(IIF(`p`.`NullableLongColumn` IS NULL, NULL, CDBL(`p`.`NullableLongColumn`))) FROM `Prices` AS `p`", // - $@"SELECT IIF(AVG(`p`.`FloatColumn`) IS NULL, NULL, CSNG(AVG(`p`.`FloatColumn`))) + $@"SELECT CSNG(AVG(`p`.`FloatColumn`)) FROM `Prices` AS `p`", // - $@"SELECT IIF(AVG(`p`.`NullableFloatColumn`) IS NULL, NULL, CSNG(AVG(`p`.`NullableFloatColumn`))) + $@"SELECT CSNG(AVG(`p`.`NullableFloatColumn`)) FROM `Prices` AS `p`", // $@"SELECT AVG(`p`.`DoubleColumn`) FROM `Prices` AS `p`", // $@"SELECT AVG(`p`.`NullableDoubleColumn`) +FROM `Prices` AS `p`", + // + $@"SELECT AVG(`p`.`DecimalColumn`) +FROM `Prices` AS `p`", + // + $@"SELECT AVG(`p`.`NullableDecimalColumn`) FROM `Prices` AS `p`"); } }