diff --git a/src/MySqlConnector/Core/BatchedCommandPayloadCreator.cs b/src/MySqlConnector/Core/BatchedCommandPayloadCreator.cs deleted file mode 100644 index c17c53335..000000000 --- a/src/MySqlConnector/Core/BatchedCommandPayloadCreator.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Buffers.Binary; -using MySqlConnector.Protocol; -using MySqlConnector.Protocol.Serialization; - -namespace MySqlConnector.Core; - -internal sealed class BatchedCommandPayloadCreator : ICommandPayloadCreator -{ - public static ICommandPayloadCreator Instance { get; } = new BatchedCommandPayloadCreator(); - - public bool WriteQueryCommand(ref CommandListPosition commandListPosition, IDictionary cachedProcedures, ByteBufferWriter writer, bool appendSemicolon) - { - writer.Write((byte) CommandKind.Multi); - bool? firstResult = default; - bool wroteCommand; - ReadOnlySpan padding = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; - do - { - // save room for command length - var position = writer.Position; - writer.Write(padding); - - wroteCommand = SingleCommandPayloadCreator.Instance.WriteQueryCommand(ref commandListPosition, cachedProcedures, writer, appendSemicolon); - firstResult ??= wroteCommand; - - // write command length - var commandLength = writer.Position - position - padding.Length; - var span = writer.ArraySegment.AsSpan(position); - span[0] = 0xFE; - BinaryPrimitives.WriteUInt64LittleEndian(span[1..], (ulong) commandLength); - } while (wroteCommand); - - // remove the padding that was saved for the final command (which wasn't written) - writer.TrimEnd(padding.Length); - return firstResult.Value; - } -} diff --git a/src/MySqlConnector/Core/ServerSession.cs b/src/MySqlConnector/Core/ServerSession.cs index 351eda129..9ba24fd8c 100644 --- a/src/MySqlConnector/Core/ServerSession.cs +++ b/src/MySqlConnector/Core/ServerSession.cs @@ -62,7 +62,6 @@ public ServerSession(ILogger logger, ConnectionPool? pool, int poolGeneration, i public IPEndPoint? IPEndPoint => m_tcpClient?.Client.RemoteEndPoint as IPEndPoint; public string? UserID { get; private set; } public WeakReference? OwningConnection { get; set; } - public bool SupportsComMulti => m_supportsComMulti; public bool SupportsDeprecateEof => m_supportsDeprecateEof; public bool SupportsCachedPreparedMetadata { get; private set; } public bool SupportsQueryAttributes { get; private set; } @@ -485,7 +484,6 @@ public async Task DisposeAsync(IOBehavior ioBehavior, CancellationToken cancella activity.SetTag(ActivitySourceHelper.DatabaseConnectionIdTagName, connectionId); } - m_supportsComMulti = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.MariaDbComMulti) != 0; m_supportsConnectionAttributes = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.ConnectionAttributes) != 0; m_supportsDeprecateEof = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.DeprecateEof) != 0; SupportsCachedPreparedMetadata = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.MariaDbCacheMetadata) != 0; @@ -1933,7 +1931,6 @@ protected override void OnStatementBegin(int index) private IPayloadHandler? m_payloadHandler; private bool m_useCompression; private bool m_isSecureConnection; - private bool m_supportsComMulti; private bool m_supportsConnectionAttributes; private bool m_supportsDeprecateEof; private bool m_supportsSessionTrack; diff --git a/src/MySqlConnector/MySqlBatch.cs b/src/MySqlConnector/MySqlBatch.cs index 1aa0a1731..b3ed8d0cb 100644 --- a/src/MySqlConnector/MySqlBatch.cs +++ b/src/MySqlConnector/MySqlBatch.cs @@ -160,8 +160,7 @@ private ValueTask ExecuteReaderAsync(CommandBehavior behavior, foreach (MySqlBatchCommand batchCommand in BatchCommands) batchCommand.Batch = this; - var payloadCreator = Connection!.Session.SupportsComMulti ? BatchedCommandPayloadCreator.Instance : - IsPrepared ? SingleCommandPayloadCreator.Instance : + var payloadCreator = IsPrepared ? SingleCommandPayloadCreator.Instance : ConcatenatedCommandPayloadCreator.Instance; return CommandExecutor.ExecuteReaderAsync(new(BatchCommands!.Commands), payloadCreator, behavior, default, ioBehavior, cancellationToken); } diff --git a/src/MySqlConnector/Protocol/CommandKind.cs b/src/MySqlConnector/Protocol/CommandKind.cs index 8b232707f..6e384a733 100644 --- a/src/MySqlConnector/Protocol/CommandKind.cs +++ b/src/MySqlConnector/Protocol/CommandKind.cs @@ -10,5 +10,4 @@ internal enum CommandKind StatementPrepare = 22, StatementExecute = 23, ResetConnection = 31, - Multi = 254, } diff --git a/src/MySqlConnector/Protocol/Payloads/HandshakeResponse41Payload.cs b/src/MySqlConnector/Protocol/Payloads/HandshakeResponse41Payload.cs index cc8dce3af..bd048f0ee 100644 --- a/src/MySqlConnector/Protocol/Payloads/HandshakeResponse41Payload.cs +++ b/src/MySqlConnector/Protocol/Payloads/HandshakeResponse41Payload.cs @@ -28,7 +28,6 @@ private static ByteBufferWriter CreateCapabilitiesPayload(ProtocolCapabilities s ProtocolCapabilities.SessionTrack | ProtocolCapabilities.DeprecateEof | ProtocolCapabilities.QueryAttributes | - ProtocolCapabilities.MariaDbComMulti | ProtocolCapabilities.MariaDbCacheMetadata | additionalCapabilities) & serverCapabilities; diff --git a/tests/IntegrationTests/BatchTests.cs b/tests/IntegrationTests/BatchTests.cs index 04b5bb17c..dc0b5a947 100644 --- a/tests/IntegrationTests/BatchTests.cs +++ b/tests/IntegrationTests/BatchTests.cs @@ -223,29 +223,6 @@ public void ExecuteBatch(string suffix) Assert.Equal(16, total); } - [Fact(Skip = "COM_MULTI")] - public void ExecuteInvalidSqlBatch() - { - using var connection = new MySqlConnection(AppConfig.ConnectionString); - connection.Open(); - using var batch = new MySqlBatch(connection) - { - BatchCommands = - { - new MySqlBatchCommand("SELECT 1;"), - new MySqlBatchCommand("SELECT 2 /* incomplete"), - new MySqlBatchCommand("SELECT 3;"), - }, - }; - using var reader = batch.ExecuteReader(); - Assert.True(reader.Read()); - Assert.Equal(1, reader.GetInt32(0)); - Assert.False(reader.Read()); - - var ex = Assert.Throws(() => reader.NextResult()); - Assert.Equal(MySqlErrorCode.ParseError, ex.ErrorCode); - } - [Theory] [InlineData(false)] [InlineData(true)] diff --git a/tests/IntegrationTests/CancelTests.cs b/tests/IntegrationTests/CancelTests.cs index 6c37a310d..28f9d4e61 100644 --- a/tests/IntegrationTests/CancelTests.cs +++ b/tests/IntegrationTests/CancelTests.cs @@ -519,50 +519,6 @@ public void CancelBatchBeforeRead() Assert.InRange(rows, 0, 10000000); } - [SkippableFact(ServerFeatures.StreamingResults | ServerFeatures.Timeout, Skip = "COM_MULTI")] - public void CancelMultiCommandBatchReader() - { - using var barrier = new Barrier(2); - using var batch = new MySqlBatch(m_database.Connection) - { - BatchCommands = - { - new MySqlBatchCommand(c_hugeQuery), - new MySqlBatchCommand(c_hugeQuery), - new MySqlBatchCommand(c_hugeQuery), - }, - }; - var task = Task.Run(() => - { - barrier.SignalAndWait(); - batch.Cancel(); - }); - - int rows = 0; - using (var reader = batch.ExecuteReader()) - { - Assert.True(reader.Read()); - - barrier.SignalAndWait(); - try - { - while (reader.Read()) - rows++; - } - catch (MySqlException ex) - { - Assert.Equal(MySqlErrorCode.QueryInterrupted, ex.ErrorCode); - } - - // query returns 25 billion rows; we shouldn't have read many of them - Assert.InRange(rows, 0, 10000000); - - Assert.False(reader.NextResult()); - } - - task.Wait(); // shouldn't throw - } - [Fact] public async Task CancelBatchWithTokenBeforeExecuteScalar() { @@ -688,41 +644,6 @@ public async Task CancelHugeQueryBatchWithTokenAfterExecuteReader() Assert.False(reader.NextResult()); } - [SkippableFact(ServerFeatures.StreamingResults | ServerFeatures.Timeout, Skip = "COM_MULTI")] - public async Task CancelHugeQueryBatchWithTokenInNextResult() - { - using var batch = new MySqlBatch(m_database.Connection) - { - BatchCommands = - { - new MySqlBatchCommand(c_hugeQuery), - new MySqlBatchCommand("select 1, 2, 3;"), - }, - }; - using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(0.5)); - using var reader = await batch.ExecuteReaderAsync(cts.Token); - - // read first result set - Assert.True(await reader.ReadAsync(cts.Token)); - - try - { - // skip to the next result set - Assert.True(await reader.NextResultAsync(cts.Token)); - - // shouldn't get here - Assert.True(false); - } - catch (OperationCanceledException ex) - { - Assert.Equal(cts.Token, ex.CancellationToken); - } - - // no more result sets - Assert.False(reader.Read()); - Assert.False(reader.NextResult()); - } - [SkippableFact(ServerFeatures.Timeout)] public async Task CancelSlowQueryBatchWithTokenAfterExecuteReader() { @@ -796,39 +717,6 @@ public async Task CancelSlowQueryBatchWithTokenAfterNextResult() Assert.False(await reader.NextResultAsync()); } - - [SkippableFact(ServerFeatures.StreamingResults | ServerFeatures.Timeout, Skip = "COM_MULTI")] - public async Task CancelMultiStatementBatchInRead() - { - using var batch = new MySqlBatch(m_database.Connection) - { - BatchCommands = - { - new MySqlBatchCommand(c_hugeQuery), - new MySqlBatchCommand(c_hugeQuery), - new MySqlBatchCommand(c_hugeQuery), - }, - }; - using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(0.5)); - using var reader = await batch.ExecuteReaderAsync(); - var rows = 0; - try - { - while (await reader.ReadAsync(cts.Token)) - rows++; - - Assert.True(false); - } - catch (OperationCanceledException ex) - { - Assert.Equal(cts.Token, ex.CancellationToken); - Assert.InRange(rows, 0, 10000000); - } - - // no more result sets; the whole command was cancelled - Assert.False(reader.Read()); - Assert.False(reader.NextResult()); - } #endif private static CancellationToken GetCanceledToken()