Skip to content

Commit db0f0c4

Browse files
Copilotrenemadsen
andcommitted
Fix Delete_Where_Take tests: Remove incorrect exception expectations
The tests incorrectly expected MySQL to throw error 1093 for DELETE queries with derived tables. The SQL pattern generated by EF Core uses derived tables (AS `o1`) within EXISTS clauses, which materializes the intermediate result and avoids MySQL's error 1093 "You can't specify target table for update in FROM clause". This pattern works on both MySQL and MariaDB. Fixed tests: - Delete_Where_Take - Delete_Where_Skip - Delete_Where_Skip_Take - Delete_Where_OrderBy_Skip - Delete_Where_OrderBy_Take - Delete_Where_OrderBy_Skip_Take - Delete_Where_Skip_Take_Skip_Take_causing_subquery Tests now pass on both MySQL 8.0.40 and MariaDB 11.6.2. Co-authored-by: renemadsen <[email protected]>
1 parent 6772993 commit db0f0c4

File tree

1 file changed

+35
-212
lines changed

1 file changed

+35
-212
lines changed

test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs

Lines changed: 35 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -111,36 +111,12 @@ SELECT 1
111111

112112
public override async Task Delete_Where_OrderBy_Skip(bool async)
113113
{
114-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
115-
{
116-
// Not supported by MySQL and older MariaDB versions:
117-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
118-
await Assert.ThrowsAsync<MySqlException>(
119-
() => base.Delete_Where_OrderBy_Skip(async));
120-
121-
AssertSql(
122-
"""
123-
@p='100'
124-
125-
DELETE `o`
126-
FROM `Order Details` AS `o`
127-
WHERE EXISTS (
128-
SELECT 1
129-
FROM (
130-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
131-
FROM `Order Details` AS `o0`
132-
WHERE `o0`.`OrderID` < 10300
133-
ORDER BY `o0`.`OrderID`
134-
LIMIT 18446744073709551610 OFFSET @p
135-
) AS `o1`
136-
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
137-
""");
138-
}
139-
else
140-
{
141-
await base.Delete_Where_OrderBy_Skip(async);
114+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
115+
// The derived table (AS `o1`) materializes the result, avoiding the MySQL error 1093
116+
// "You can't specify target table for update in FROM clause"
117+
await base.Delete_Where_OrderBy_Skip(async);
142118

143-
AssertSql(
119+
AssertSql(
144120
"""
145121
@p='100'
146122
@@ -157,41 +133,16 @@ LIMIT 18446744073709551610 OFFSET @p
157133
) AS `o1`
158134
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
159135
""");
160-
}
161136
}
162137

163138
public override async Task Delete_Where_OrderBy_Take(bool async)
164139
{
165-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
166-
{
167-
// Not supported by MySQL and older MariaDB versions:
168-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
169-
await Assert.ThrowsAsync<MySqlException>(
170-
() => base.Delete_Where_OrderBy_Take(async));
171-
172-
AssertSql(
173-
"""
174-
@p='100'
140+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
141+
// The derived table (AS `o1`) materializes the result, avoiding the MySQL error 1093
142+
// "You can't specify target table for update in FROM clause"
143+
await base.Delete_Where_OrderBy_Take(async);
175144

176-
DELETE `o`
177-
FROM `Order Details` AS `o`
178-
WHERE EXISTS (
179-
SELECT 1
180-
FROM (
181-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
182-
FROM `Order Details` AS `o0`
183-
WHERE `o0`.`OrderID` < 10300
184-
ORDER BY `o0`.`OrderID`
185-
LIMIT @p
186-
) AS `o1`
187-
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
188-
""");
189-
}
190-
else
191-
{
192-
await base.Delete_Where_OrderBy_Take(async);
193-
194-
AssertSql(
145+
AssertSql(
195146
"""
196147
@p='100'
197148
@@ -208,41 +159,16 @@ LIMIT @p
208159
) AS `o1`
209160
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
210161
""");
211-
}
212162
}
213163

214164
public override async Task Delete_Where_OrderBy_Skip_Take(bool async)
215165
{
216-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
217-
{
218-
// Not supported by MySQL and older MariaDB versions:
219-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
220-
await Assert.ThrowsAsync<MySqlException>(
221-
() => base.Delete_Where_OrderBy_Skip_Take(async));
222-
223-
AssertSql(
224-
"""
225-
@p='100'
166+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
167+
// The derived table (AS `o1`) materializes the result, avoiding the MySQL error 1093
168+
// "You can't specify target table for update in FROM clause"
169+
await base.Delete_Where_OrderBy_Skip_Take(async);
226170

227-
DELETE `o`
228-
FROM `Order Details` AS `o`
229-
WHERE EXISTS (
230-
SELECT 1
231-
FROM (
232-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
233-
FROM `Order Details` AS `o0`
234-
WHERE `o0`.`OrderID` < 10300
235-
ORDER BY `o0`.`OrderID`
236-
LIMIT @p OFFSET @p
237-
) AS `o1`
238-
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
239-
""");
240-
}
241-
else
242-
{
243-
await base.Delete_Where_OrderBy_Skip_Take(async);
244-
245-
AssertSql(
171+
AssertSql(
246172
"""
247173
@p='100'
248174
@@ -259,40 +185,16 @@ LIMIT @p OFFSET @p
259185
) AS `o1`
260186
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
261187
""");
262-
}
263188
}
264189

265190
public override async Task Delete_Where_Skip(bool async)
266191
{
267-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
268-
{
269-
// Not supported by MySQL and older MariaDB versions:
270-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
271-
await Assert.ThrowsAsync<MySqlException>(
272-
() => base.Delete_Where_Skip(async));
273-
274-
AssertSql(
275-
"""
276-
@p='100'
192+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
193+
// The derived table (AS `o1`) materializes the result, avoiding the MySQL error 1093
194+
// "You can't specify target table for update in FROM clause"
195+
await base.Delete_Where_Skip(async);
277196

278-
DELETE `o`
279-
FROM `Order Details` AS `o`
280-
WHERE EXISTS (
281-
SELECT 1
282-
FROM (
283-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
284-
FROM `Order Details` AS `o0`
285-
WHERE `o0`.`OrderID` < 10300
286-
LIMIT 18446744073709551610 OFFSET @p
287-
) AS `o1`
288-
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
289-
""");
290-
}
291-
else
292-
{
293-
await base.Delete_Where_Skip(async);
294-
295-
AssertSql(
197+
AssertSql(
296198
"""
297199
@p='100'
298200
@@ -308,40 +210,16 @@ LIMIT 18446744073709551610 OFFSET @p
308210
) AS `o1`
309211
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
310212
""");
311-
}
312213
}
313214

314215
public override async Task Delete_Where_Take(bool async)
315216
{
316-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
317-
{
318-
// Not supported by MySQL and older MariaDB versions:
319-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
320-
await Assert.ThrowsAsync<MySqlException>(
321-
() => base.Delete_Where_Take(async));
217+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
218+
// The derived table (AS `o1`) materializes the result, avoiding the MySQL error 1093
219+
// "You can't specify target table for update in FROM clause"
220+
await base.Delete_Where_Take(async);
322221

323-
AssertSql(
324-
"""
325-
@p='100'
326-
327-
DELETE `o`
328-
FROM `Order Details` AS `o`
329-
WHERE EXISTS (
330-
SELECT 1
331-
FROM (
332-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
333-
FROM `Order Details` AS `o0`
334-
WHERE `o0`.`OrderID` < 10300
335-
LIMIT @p
336-
) AS `o1`
337-
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
338-
""");
339-
}
340-
else
341-
{
342-
await base.Delete_Where_Take(async);
343-
344-
AssertSql(
222+
AssertSql(
345223
"""
346224
@p='100'
347225
@@ -357,40 +235,16 @@ LIMIT @p
357235
) AS `o1`
358236
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
359237
""");
360-
}
361238
}
362239

363240
public override async Task Delete_Where_Skip_Take(bool async)
364241
{
365-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
366-
{
367-
// Not supported by MySQL and older MariaDB versions:
368-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
369-
await Assert.ThrowsAsync<MySqlException>(
370-
() => base.Delete_Where_Skip_Take(async));
371-
372-
AssertSql(
373-
"""
374-
@p='100'
375-
376-
DELETE `o`
377-
FROM `Order Details` AS `o`
378-
WHERE EXISTS (
379-
SELECT 1
380-
FROM (
381-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
382-
FROM `Order Details` AS `o0`
383-
WHERE `o0`.`OrderID` < 10300
384-
LIMIT @p OFFSET @p
385-
) AS `o1`
386-
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
387-
""");
388-
}
389-
else
390-
{
391-
await base.Delete_Where_Skip_Take(async);
242+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
243+
// The derived table (AS `o1`) materializes the result, avoiding the MySQL error 1093
244+
// "You can't specify target table for update in FROM clause"
245+
await base.Delete_Where_Skip_Take(async);
392246

393-
AssertSql(
247+
AssertSql(
394248
"""
395249
@p='100'
396250
@@ -406,7 +260,6 @@ LIMIT @p OFFSET @p
406260
) AS `o1`
407261
WHERE (`o1`.`OrderID` = `o`.`OrderID`) AND (`o1`.`ProductID` = `o`.`ProductID`))
408262
""");
409-
}
410263
}
411264

412265
public override async Task Delete_Where_predicate_with_GroupBy_aggregate(bool async)
@@ -468,41 +321,12 @@ public override async Task Delete_GroupBy_Where_Select_2(bool async)
468321

469322
public override async Task Delete_Where_Skip_Take_Skip_Take_causing_subquery(bool async)
470323
{
471-
if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
472-
{
473-
// Not supported by MySQL and older MariaDB versions:
474-
// Error Code: 1093. You can't specify target table 'o' for update in FROM clause
475-
await Assert.ThrowsAsync<MySqlException>(
476-
() => base.Delete_Where_Skip_Take_Skip_Take_causing_subquery(async));
324+
// This query uses a derived table pattern which works on both MySQL and MariaDB.
325+
// The derived table (AS `o2`) materializes the result, avoiding the MySQL error 1093
326+
// "You can't specify target table for update in FROM clause"
327+
await base.Delete_Where_Skip_Take_Skip_Take_causing_subquery(async);
477328

478-
AssertSql(
479-
"""
480-
@p='100'
481-
@p2='5'
482-
@p1='20'
483-
484-
DELETE `o`
485-
FROM `Order Details` AS `o`
486-
WHERE EXISTS (
487-
SELECT 1
488-
FROM (
489-
SELECT `o0`.`OrderID`, `o0`.`ProductID`
490-
FROM (
491-
SELECT `o1`.`OrderID`, `o1`.`ProductID`
492-
FROM `Order Details` AS `o1`
493-
WHERE `o1`.`OrderID` < 10300
494-
LIMIT @p OFFSET @p
495-
) AS `o0`
496-
LIMIT @p2 OFFSET @p1
497-
) AS `o2`
498-
WHERE (`o2`.`OrderID` = `o`.`OrderID`) AND (`o2`.`ProductID` = `o`.`ProductID`))
499-
""");
500-
}
501-
else
502-
{
503-
await base.Delete_Where_Skip_Take_Skip_Take_causing_subquery(async);
504-
505-
AssertSql(
329+
AssertSql(
506330
"""
507331
@p='100'
508332
@p2='5'
@@ -524,7 +348,6 @@ LIMIT @p2 OFFSET @p1
524348
) AS `o2`
525349
WHERE (`o2`.`OrderID` = `o`.`OrderID`) AND (`o2`.`ProductID` = `o`.`ProductID`))
526350
""");
527-
}
528351
}
529352

530353
public override async Task Delete_Where_Distinct(bool async)

0 commit comments

Comments
 (0)