diff --git a/test/EFCore.MySql.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesMySqlTest.cs index fc1cd2d7c..b672fe785 100644 --- a/test/EFCore.MySql.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesMySqlTest.cs @@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore.TestUtilities; using MySqlConnector; using Pomelo.EntityFrameworkCore.MySql.FunctionalTests.TestUtilities; +using Pomelo.EntityFrameworkCore.MySql.Tests; using Xunit; namespace Pomelo.EntityFrameworkCore.MySql.FunctionalTests.BulkUpdates; @@ -53,9 +54,11 @@ public override async Task Delete_aggregate_root_when_table_sharing_with_non_own public override async Task Delete_predicate_based_on_optional_navigation(bool async) { - await base.Delete_predicate_based_on_optional_navigation(async); + if (AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + await base.Delete_predicate_based_on_optional_navigation(async); - AssertSql( + AssertSql( """ DELETE `p` FROM `Posts` AS `p` @@ -66,6 +69,14 @@ public override async Task Delete_predicate_based_on_optional_navigation(bool as WHERE `b`.`Title` LIKE 'Arthur%' ) """); + } + else + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'p' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_predicate_based_on_optional_navigation(async)); + } } public override async Task Update_non_owned_property_on_entity_with_owned(bool async) @@ -130,9 +141,11 @@ public override async Task Update_non_main_table_in_entity_with_entity_splitting public override async Task Delete_entity_with_auto_include(bool async) { - await base.Delete_entity_with_auto_include(async); + if (AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + await base.Delete_entity_with_auto_include(async); - AssertSql( + AssertSql( """ DELETE `c` FROM `Context30572_Principal` AS `c` @@ -142,6 +155,14 @@ public override async Task Delete_entity_with_auto_include(bool async) LEFT JOIN `Context30572_Dependent` AS `c1` ON `c0`.`DependentId` = `c1`.`Id` ) """); + } + else + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'c' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_entity_with_auto_include(async)); + } } public override async Task Update_with_alias_uniquification_in_setter_subquery(bool async) diff --git a/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs index a19a811dd..fb04a55bd 100644 --- a/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs @@ -76,9 +76,28 @@ WHERE FALSE public override async Task Delete_Where_OrderBy(bool async) { - await base.Delete_Where_OrderBy(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_OrderBy(async)); - AssertSql( + AssertSql( +""" +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM `Order Details` AS `o0` + WHERE (`o0`.`OrderID` < 10300) AND ((`o0`.`OrderID` = `o`.`OrderID`) AND (`o0`.`ProductID` = `o`.`ProductID`))) +"""); + } + else + { + await base.Delete_Where_OrderBy(async); + + AssertSql( """ DELETE `o` FROM `Order Details` AS `o` @@ -87,13 +106,41 @@ SELECT 1 FROM `Order Details` AS `o0` WHERE (`o0`.`OrderID` < 10300) AND ((`o0`.`OrderID` = `o`.`OrderID`) AND (`o0`.`ProductID` = `o`.`ProductID`))) """); + } } public override async Task Delete_Where_OrderBy_Skip(bool async) { - await base.Delete_Where_OrderBy_Skip(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_OrderBy_Skip(async)); - AssertSql( + AssertSql( +""" +@p='100' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o0`.`OrderID` < 10300 + ORDER BY `o0`.`OrderID` + LIMIT 18446744073709551610 OFFSET @p + ) AS `o1` + WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) +"""); + } + else + { + await base.Delete_Where_OrderBy_Skip(async); + + AssertSql( """ @p='100' @@ -110,13 +157,19 @@ LIMIT 18446744073709551610 OFFSET @p ) AS `o1` WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) """); + } } public override async Task Delete_Where_OrderBy_Take(bool async) { - await base.Delete_Where_OrderBy_Take(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_OrderBy_Take(async)); - AssertSql( + AssertSql( """ @p='100' @@ -133,13 +186,41 @@ LIMIT @p ) AS `o1` WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) """); + } + else + { + await base.Delete_Where_OrderBy_Take(async); + + AssertSql( +""" +@p='100' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o0`.`OrderID` < 10300 + ORDER BY `o0`.`OrderID` + LIMIT @p + ) AS `o1` + WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) +"""); + } } public override async Task Delete_Where_OrderBy_Skip_Take(bool async) { - await base.Delete_Where_OrderBy_Skip_Take(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_OrderBy_Skip_Take(async)); - AssertSql( + AssertSql( """ @p='100' @@ -156,13 +237,62 @@ LIMIT @p OFFSET @p ) AS `o1` WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) """); + } + else + { + await base.Delete_Where_OrderBy_Skip_Take(async); + + AssertSql( +""" +@p='100' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o0`.`OrderID` < 10300 + ORDER BY `o0`.`OrderID` + LIMIT @p OFFSET @p + ) AS `o1` + WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) +"""); + } } public override async Task Delete_Where_Skip(bool async) { - await base.Delete_Where_Skip(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_Skip(async)); - AssertSql( + AssertSql( +""" +@p='100' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o0`.`OrderID` < 10300 + LIMIT 18446744073709551610 OFFSET @p + ) AS `o1` + WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) +"""); + } + else + { + await base.Delete_Where_Skip(async); + + AssertSql( """ @p='100' @@ -178,13 +308,40 @@ LIMIT 18446744073709551610 OFFSET @p ) AS `o1` WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) """); + } } public override async Task Delete_Where_Take(bool async) { - await base.Delete_Where_Take(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_Take(async)); - AssertSql( + AssertSql( +""" +@p='100' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o0`.`OrderID` < 10300 + LIMIT @p + ) AS `o1` + WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) +"""); + } + else + { + await base.Delete_Where_Take(async); + + AssertSql( """ @p='100' @@ -200,13 +357,40 @@ LIMIT @p ) AS `o1` WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) """); + } } public override async Task Delete_Where_Skip_Take(bool async) { - await base.Delete_Where_Skip_Take(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_Skip_Take(async)); - AssertSql( + AssertSql( +""" +@p='100' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM `Order Details` AS `o0` + WHERE `o0`.`OrderID` < 10300 + LIMIT @p OFFSET @p + ) AS `o1` + WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) +"""); + } + else + { + await base.Delete_Where_Skip_Take(async); + + AssertSql( """ @p='100' @@ -222,6 +406,7 @@ LIMIT @p OFFSET @p ) AS `o1` WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`)) """); + } } public override async Task Delete_Where_predicate_with_GroupBy_aggregate(bool async) @@ -283,9 +468,14 @@ public override async Task Delete_GroupBy_Where_Select_2(bool async) public override async Task Delete_Where_Skip_Take_Skip_Take_causing_subquery(bool async) { - await base.Delete_Where_Skip_Take_Skip_Take_causing_subquery(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_Where_Skip_Take_Skip_Take_causing_subquery(async)); - AssertSql( + AssertSql( """ @p='100' @p2='5' @@ -307,6 +497,34 @@ LIMIT @p2 OFFSET @p1 ) AS `o2` WHERE (`o2`.`OrderID` = `o`.`OrderID`) AND (`o2`.`ProductID` = `o`.`ProductID`)) """); + } + else + { + await base.Delete_Where_Skip_Take_Skip_Take_causing_subquery(async); + + AssertSql( +""" +@p='100' +@p2='5' +@p1='20' + +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM ( + SELECT `o0`.`OrderID`, `o0`.`ProductID` + FROM ( + SELECT `o1`.`OrderID`, `o1`.`ProductID` + FROM `Order Details` AS `o1` + WHERE `o1`.`OrderID` < 10300 + LIMIT @p OFFSET @p + ) AS `o0` + LIMIT @p2 OFFSET @p1 + ) AS `o2` + WHERE (`o2`.`OrderID` = `o`.`OrderID`) AND (`o2`.`ProductID` = `o`.`ProductID`)) +"""); + } } public override async Task Delete_Where_Distinct(bool async) @@ -610,9 +828,14 @@ LIMIT @p0 OFFSET @p public override async Task Delete_with_cross_join(bool async) { - await base.Delete_with_cross_join(async); + if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery) + { + // Not supported by MySQL and older MariaDB versions: + // Error Code: 1093. You can't specify target table 'o' for update in FROM clause + await Assert.ThrowsAsync( + () => base.Delete_with_cross_join(async)); - AssertSql( + AssertSql( """ DELETE `o` FROM `Order Details` AS `o` @@ -628,6 +851,28 @@ LIMIT 100 OFFSET 0 ) AS `o1` WHERE (`o0`.`OrderID` < 10276) AND ((`o0`.`OrderID` = `o`.`OrderID`) AND (`o0`.`ProductID` = `o`.`ProductID`))) """); + } + else + { + await base.Delete_with_cross_join(async); + + AssertSql( +""" +DELETE `o` +FROM `Order Details` AS `o` +WHERE EXISTS ( + SELECT 1 + FROM `Order Details` AS `o0` + CROSS JOIN ( + SELECT 1 + FROM `Orders` AS `o2` + WHERE `o2`.`OrderID` < 10300 + ORDER BY `o2`.`OrderID` + LIMIT 100 OFFSET 0 + ) AS `o1` + WHERE (`o0`.`OrderID` < 10276) AND ((`o0`.`OrderID` = `o`.`OrderID`) AND (`o0`.`ProductID` = `o`.`ProductID`))) +"""); + } } public override async Task Delete_with_cross_apply(bool async)