Skip to content

Conversation

Copy link

Copilot AI commented Dec 16, 2025

MySQL and MariaDB < 11.0 throw error 1093 "You can't specify target table for update in FROM clause" when executing DELETE statements that reference the target table in a subquery. MariaDB 11.0+ lifted this limitation. UPDATE statements behave differently: they fail on MySQL but work on all MariaDB versions.

Changes

  • Added DeleteWithSelfReferencingSubquery server capability flag

    • MySqlServerVersion: always false
    • MariaDbServerVersion: true for version >= 11.0.0
  • Updated DELETE tests to conditionally expect MySqlException

    • Delete_with_LeftJoin
    • Delete_with_LeftJoin_via_flattened_GroupJoin
    • Delete_GroupBy_Where_Select_First_3 (multiple test classes)
  • Preserved UPDATE test behavior

    • Update_Where_GroupBy_First_set_constant_3 continues checking ServerType.MySql since UPDATE works on all MariaDB versions

Example

public override async Task Delete_with_LeftJoin(bool async)
{
    if (!AppConfig.ServerVersion.Supports.DeleteWithSelfReferencingSubquery)
    {
        // MySQL and MariaDB < 11.0
        await Assert.ThrowsAsync<MySqlException>(
            () => base.Delete_with_LeftJoin(async));
    }
    else
    {
        // MariaDB >= 11.0
        await base.Delete_with_LeftJoin(async);
    }
}

Tests now pass on MySQL 8.0.40, MariaDB 10.5.27, and MariaDB 11.6.2.

Original prompt

This section details on the original issue you should resolve

<issue_title>You can't specify target table 'o' for update in FROM clause</issue_title>
<issue_description>With respect to the difference in MySQL and Mariadb, this is broken for MySQL v8.0.40, MariaDB 10.5.27, but it works in MariaDB 11.6.2:

  Failed Pomelo.EntityFrameworkCore.MySql.FunctionalTests.BulkUpdates.NorthwindBulkUpdatesMySqlTest.Delete_with_LeftJoin(async: False) [161 ms]
  Error Message:
   MySqlConnector.MySqlException : You can't specify target table 'o' for update in FROM clause
  Stack Trace:
     at MySqlConnector.Core.ServerSession.ReceiveReplyAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1125
   at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /_/src/MySqlConnector/Core/ResultSet.cs:line 37
   at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 133
   at MySqlConnector.MySqlDataReader.InitAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 489
   at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 58
   at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 304
   at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 108
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.<>c.<NonQueryResult>b__30_0(DbContext _, ValueTuple`3 state)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.NonQueryResult(RelationalQueryContext relationalQueryContext, RelationalCommandResolver relationalCommandResolver, Type contextType, CommandSource commandSource, Boolean threadSafetyChecksEnabled)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteDelete[TSource](IQueryable`1 source)
   at Microsoft.EntityFrameworkCore.TestUtilities.BulkUpdatesAsserter.<>c__DisplayClass6_0`1.<<AssertDelete>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.TestUtilities.TestHelpers.<>c__DisplayClass41_0`1.<<ExecuteWithStrategyInTransactionAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__7`1.<<ExecuteAsync>b__7_0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass30_0`2.<<ExecuteAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.TestUtilities.TestHelpers.ExecuteWithStrategyInTransactionAsync[TContext](Func`1 createContext, Action`2 useTransaction, Func`2 testOperation, Func`2 nestedTestOperation1, Func`2 nestedTestOperation2, Func`2 nestedTestOperation3)
   at Pomelo.EntityFrameworkCore.MySql.FunctionalTests.BulkUpdates.NorthwindBulkUpdatesMySqlTest.Delete_with_LeftJoin(Boolean async) in /home/runner/work/Pomelo.EntityFrameworkCore.MySql/Pomelo.EntityFrameworkCore.MySql/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs:line 5...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes microting/Pomelo.EntityFrameworkCore.MySql#212

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

Copilot AI changed the title [WIP] Fix target table update error in MySQL Handle MySQL/MariaDB DELETE with self-referencing subquery limitation Dec 16, 2025
Copilot AI requested a review from renemadsen December 16, 2025 05:44
@renemadsen renemadsen marked this pull request as ready for review December 16, 2025 06:12
@renemadsen renemadsen merged commit ced65d4 into master Dec 16, 2025
24 of 55 checks passed
@renemadsen
Copy link
Member

@copilot This is related I guess:

Failed Pomelo.EntityFrameworkCore.MySql.FunctionalTests.BulkUpdates.NonSharedModelBulkUpdatesMySqlTest.Delete_predicate_based_on_optional_navigation(async: False) [3 s]
Error Message:
MySqlConnector.MySqlException : You can't specify target table 'p' for update in FROM clause
Stack Trace:
at MySqlConnector.Core.ServerSession.ReceiveReplyAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ServerSession.cs:line 1125
at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /
/src/MySqlConnector/Core/ResultSet.cs:line 37
at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 133
at MySqlConnector.MySqlDataReader.InitAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 489 at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 58 at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 304 at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 108 at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject) at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.<>c.<NonQueryResult>b__30_0(DbContext _, ValueTuple3 state)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.NonQueryResult(RelationalQueryContext relationalQueryContext, RelationalCommandResolver relationalCommandResolver, Type contextType, CommandSource commandSource, Boolean threadSafetyChecksEnabled)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteDelete[TSource](IQueryable1 source) at Microsoft.EntityFrameworkCore.BulkUpdates.NonSharedModelBulkUpdatesTestBase.<>c__DisplayClass28_02.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.EntityFrameworkCore.TestUtilities.TestHelpers.<>c__DisplayClass41_01.<<ExecuteWithStrategyInTransactionAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__71.<b__7_0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass30_02.<<ExecuteAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func4 operation, Func4 verifySucceeded, TState state, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func4 operation, Func4 verifySucceeded, TState state, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.TestUtilities.TestHelpers.ExecuteWithStrategyInTransactionAsync[TContext](Func1 createContext, Action2 useTransaction, Func2 testOperation, Func2 nestedTestOperation1, Func2 nestedTestOperation2, Func`2 nestedTestOperation3)
at Microsoft.EntityFrameworkCore.BulkUpdates.NonSharedModelBulkUpdatesTestBase.Delete_predicate_based_on_optional_navigation(Boolean async)
at Pomelo.EntityFrameworkCore.MySql.FunctionalTests.BulkUpdates.NonSharedModelBulkUpdatesMySqlTest.Delete_predicate_based_on_optional_navigation(Boolean async) in /home/runner/work/Pomelo.EntityFrameworkCore.MySql/Pomelo.EntityFrameworkCore.MySql/test/EFCore.MySql.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesMySqlTest.cs:line 56
--- End of stack trace from previous location ---

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants