Skip to content

Commit 06d1f8c

Browse files
committed
Avoids SET NAMES commands if not needed
for MariaDB since 15.1 (https://jira.mariadb.org/browse/MDEV-31609) followed session variables are sent in initial OK_Packet. This permits to avoids  initial query SET NAMES command, since charset is really know, defaulting to server corresponding default collation. Signed-off-by: rusher <[email protected]>
1 parent 6794641 commit 06d1f8c

File tree

9 files changed

+138
-94
lines changed

9 files changed

+138
-94
lines changed

src/MySqlConnector/Core/ConcatenatedCommandPayloadCreator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public bool WriteQueryCommand(ref CommandListPosition commandListPosition, IDict
1717

1818
// ConcatenatedCommandPayloadCreator is only used by MySqlBatch, and MySqlBatchCommand doesn't expose attributes,
1919
// so just write an empty attribute set if the server needs it.
20-
if (commandListPosition.CommandAt(commandListPosition.CommandIndex).Connection!.Session.SupportsQueryAttributes)
20+
if (commandListPosition.CommandAt(commandListPosition.CommandIndex).Connection!.Session.Context.SupportsQueryAttributes)
2121
{
2222
// attribute count
2323
writer.WriteLengthEncodedInteger(0);

src/MySqlConnector/Core/ConnectionPool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection
6565
}
6666
else
6767
{
68-
if (ConnectionSettings.ConnectionReset || session.DatabaseOverride is not null)
68+
if (ConnectionSettings.ConnectionReset || !session.Context.IsInitialDatabase())
6969
{
7070
if (timeoutMilliseconds != 0)
7171
session.SetTimeout(Math.Max(1, timeoutMilliseconds - Utility.GetElapsedMilliseconds(startingTimestamp)));

src/MySqlConnector/Core/Context.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using MySqlConnector.Protocol;
2+
3+
namespace MySqlConnector.Core;
4+
5+
internal sealed class Context
6+
{
7+
public Context(ProtocolCapabilities protocolCapabilities, string? database, int connectionId)
8+
{
9+
SupportsDeprecateEof = (protocolCapabilities & ProtocolCapabilities.DeprecateEof) != 0;
10+
SupportsCachedPreparedMetadata = (protocolCapabilities & ProtocolCapabilities.MariaDbCacheMetadata) != 0;
11+
SupportsQueryAttributes = (protocolCapabilities & ProtocolCapabilities.QueryAttributes) != 0;
12+
SupportsSessionTrack = (protocolCapabilities & ProtocolCapabilities.SessionTrack) != 0;
13+
ConnectionId = connectionId;
14+
Database = database;
15+
m_initialDatabase = database;
16+
}
17+
18+
public bool SupportsDeprecateEof { get; }
19+
public bool SupportsQueryAttributes { get; }
20+
public bool SupportsSessionTrack { get; }
21+
public bool SupportsCachedPreparedMetadata { get; }
22+
public string? ClientCharset { get; set; }
23+
24+
public string? Database { get; set; }
25+
private readonly string? m_initialDatabase;
26+
public bool IsInitialDatabase() => string.Equals(m_initialDatabase, Database, StringComparison.Ordinal);
27+
28+
public int ConnectionId { get; set; }
29+
}

src/MySqlConnector/Core/ResultSet.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
3838
var firstByte = payload.HeaderByte;
3939
if (firstByte == OkPayload.Signature)
4040
{
41-
var ok = OkPayload.Create(payload.Span, Session.SupportsDeprecateEof, Session.SupportsSessionTrack);
41+
var ok = OkPayload.Create(payload.Span, Session.Context);
4242

4343
// if we've read a result set header then this is a SELECT statement, so we shouldn't overwrite RecordsAffected
4444
// (which should be -1 for SELECT) unless the server reports a non-zero count
@@ -48,8 +48,6 @@ public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
4848
if (ok.LastInsertId != 0)
4949
Command?.SetLastInsertedId((long) ok.LastInsertId);
5050
WarningCount = ok.WarningCount;
51-
if (ok.NewSchema is not null)
52-
Connection.Session.DatabaseOverride = ok.NewSchema;
5351
m_columnDefinitions = default;
5452
State = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0
5553
? ResultSetState.NoMoreData
@@ -109,7 +107,7 @@ public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
109107
}
110108
else
111109
{
112-
var columnCountPacket = ColumnCountPayload.Create(payload.Span, Session.SupportsCachedPreparedMetadata);
110+
var columnCountPacket = ColumnCountPayload.Create(payload.Span, Session.Context.SupportsCachedPreparedMetadata);
113111
var columnCount = columnCountPacket.ColumnCount;
114112
if (!columnCountPacket.MetadataFollows)
115113
{
@@ -132,7 +130,7 @@ public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
132130
m_columnDefinitions = m_columnDefinitionPayloadCache.AsMemory(0, columnCount);
133131

134132
// if the server supports metadata caching but has re-sent it, something has changed since last prepare/execution and we need to update the columns
135-
var preparedColumns = Session.SupportsCachedPreparedMetadata ? DataReader.LastUsedPreparedStatement?.Columns : null;
133+
var preparedColumns = Session.Context.SupportsCachedPreparedMetadata ? DataReader.LastUsedPreparedStatement?.Columns : null;
136134

137135
for (var column = 0; column < columnCount; column++)
138136
{
@@ -156,7 +154,7 @@ public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
156154
}
157155
}
158156

159-
if (!Session.SupportsDeprecateEof)
157+
if (!Session.Context.SupportsDeprecateEof)
160158
{
161159
payload = await Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);
162160
_ = EofPayload.Create(payload.Span);
@@ -252,13 +250,13 @@ public async Task<bool> ReadAsync(IOBehavior ioBehavior, CancellationToken cance
252250

253251
if (payload.HeaderByte == EofPayload.Signature)
254252
{
255-
if (Session.SupportsDeprecateEof && OkPayload.IsOk(payload.Span, Session.SupportsDeprecateEof))
253+
if (Session.Context.SupportsDeprecateEof && OkPayload.IsOk(payload.Span, Session.Context))
256254
{
257-
var ok = OkPayload.Create(payload.Span, Session.SupportsDeprecateEof, Session.SupportsSessionTrack);
255+
var ok = OkPayload.Create(payload.Span, Session.Context);
258256
BufferState = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData;
259257
return null;
260258
}
261-
if (!Session.SupportsDeprecateEof && EofPayload.IsEof(payload))
259+
if (!Session.Context.SupportsDeprecateEof && EofPayload.IsEof(payload))
262260
{
263261
var eof = EofPayload.Create(payload.Span);
264262
BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData;

0 commit comments

Comments
 (0)