Skip to content

Commit f12d24e

Browse files
committed
Fix conversion of LastInsertedId. Fixes #422
The OK payload contains an unsigned 64-bit integer (for the last insert ID), which needs to be returned as a 64-bit signed integer (in the C# API). The client needs to determine how to interpret it, based on the signedness of the ID column.
1 parent 54ac30e commit f12d24e

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/MySqlConnector/Core/ResultSet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public async Task<ResultSet> ReadResultSetHeaderAsync(IOBehavior ioBehavior)
4747
{
4848
var ok = OkPayload.Create(payload);
4949
RecordsAffected = (RecordsAffected ?? 0) + ok.AffectedRowCount;
50-
LastInsertId = ok.LastInsertId;
50+
LastInsertId = unchecked((long) ok.LastInsertId);
5151
if (ok.NewSchema != null)
5252
Connection.Session.DatabaseOverride = ok.NewSchema;
5353
ColumnDefinitions = null;

src/MySqlConnector/Protocol/Payloads/OkPayload.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace MySqlConnector.Protocol.Payloads
88
internal sealed class OkPayload
99
{
1010
public int AffectedRowCount { get; }
11-
public long LastInsertId { get; }
11+
public ulong LastInsertId { get; }
1212
public ServerStatus ServerStatus { get; }
1313
public int WarningCount { get; }
1414
public string NewSchema { get; }
@@ -34,7 +34,7 @@ public static OkPayload Create(PayloadData payload, bool deprecateEof)
3434
if (signature != Signature && (!deprecateEof || signature != EofPayload.Signature))
3535
throw new FormatException("Expected to read 0x00 or 0xFE but got 0x{0:X2}".FormatInvariant(signature));
3636
var affectedRowCount = checked((int) reader.ReadLengthEncodedInteger());
37-
var lastInsertId = checked((long) reader.ReadLengthEncodedInteger());
37+
var lastInsertId = reader.ReadLengthEncodedInteger();
3838
var serverStatus = (ServerStatus) reader.ReadUInt16();
3939
var warningCount = (int) reader.ReadUInt16();
4040
string newSchema = null;
@@ -71,7 +71,7 @@ public static OkPayload Create(PayloadData payload, bool deprecateEof)
7171
return new OkPayload(affectedRowCount, lastInsertId, serverStatus, warningCount, newSchema);
7272
}
7373

74-
private OkPayload(int affectedRowCount, long lastInsertId, ServerStatus serverStatus, int warningCount, string newSchema)
74+
private OkPayload(int affectedRowCount, ulong lastInsertId, ServerStatus serverStatus, int warningCount, string newSchema)
7575
{
7676
AffectedRowCount = affectedRowCount;
7777
LastInsertId = lastInsertId;

tests/SideBySide/InsertTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,48 @@ public async Task LastInsertedId()
3636
}
3737
}
3838

39+
[Fact]
40+
public async Task LastInsertedIdNegative()
41+
{
42+
await m_database.Connection.ExecuteAsync(@"drop table if exists insert_ai;
43+
create table insert_ai(rowid integer not null primary key auto_increment);");
44+
try
45+
{
46+
await m_database.Connection.OpenAsync();
47+
using (var command = new MySqlCommand("INSERT INTO insert_ai(rowid) VALUES (@rowid);", m_database.Connection))
48+
{
49+
command.Parameters.AddWithValue("@rowid", -1);
50+
await command.ExecuteNonQueryAsync();
51+
Assert.Equal(-1L, command.LastInsertedId);
52+
}
53+
}
54+
finally
55+
{
56+
m_database.Connection.Close();
57+
}
58+
}
59+
60+
[Fact]
61+
public async Task LastInsertedIdUlong()
62+
{
63+
await m_database.Connection.ExecuteAsync(@"drop table if exists insert_ai;
64+
create table insert_ai(rowid bigint unsigned not null primary key auto_increment);");
65+
try
66+
{
67+
await m_database.Connection.OpenAsync();
68+
using (var command = new MySqlCommand("INSERT INTO insert_ai(rowid) VALUES (@rowid);", m_database.Connection))
69+
{
70+
command.Parameters.AddWithValue("@rowid", ((ulong) long.MaxValue) + 1);
71+
await command.ExecuteNonQueryAsync();
72+
Assert.Equal(long.MinValue, command.LastInsertedId);
73+
}
74+
}
75+
finally
76+
{
77+
m_database.Connection.Close();
78+
}
79+
}
80+
3981
[Fact]
4082
public async Task RowsAffected()
4183
{

0 commit comments

Comments
 (0)