Skip to content

Commit 06484ed

Browse files
author
Anushree Prakash B
committed
BUG#22028117 - MYSQLCLIENT DOES NOT RETURN CORRECT
MYSQL_INSERT_ID VIA DATABASE HANDLE DESCRIPTION =========== mysql_insert_id() does not return correct values after performing inserts in a table containing an AUTO_INCREMENT field and then performing a SELECT operation. The value of insert_id is getting reset to 0 after performing SELECT. However, LAST_INSERT_ID() gives the correct value. ANALYSIS ======== An OK packet is sent from the server to the client to signal successful completion of a command. As of MySQL 5.7.5, OK packes are also used to indicate EOF, as EOF packets are deprecated. The packet identifier 0x00 represents an OK packet whereas the packet identifier OxFE represents an EOF packet. The EOF packet has valid values for the following fields: packet header, warnings and server status. The fields affected_rows and insert_id will have valid values only if it was an OK packet and not for an EOF packet. Reading the values of the above two fields for an EOF packet will result in inconsistent values being assigned to the connection handle. FIX ==== The fix is to assign the affected_rows and insert_id fields to the connection handle only if they were read from an OK packet. In case of an EOF packet, skip the assignment and proceed to the next valid fields. This way we can make sure that they don't get wrongly updated in the connection handle.
1 parent 1202cdb commit 06484ed

File tree

2 files changed

+93
-7
lines changed

2 files changed

+93
-7
lines changed

sql-common/client.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ void read_ok_ex(MYSQL *mysql, ulong length)
717717
{
718718
size_t total_len, len;
719719
uchar *pos, *saved_pos;
720+
my_ulonglong affected_rows, insert_id;
720721
char *db;
721722

722723
struct charset_info_st *saved_cs;
@@ -730,15 +731,29 @@ void read_ok_ex(MYSQL *mysql, ulong length)
730731

731732
pos= mysql->net.read_pos + 1;
732733

733-
/* affected rows */
734-
mysql->affected_rows= net_field_length_ll(&pos);
735-
/* insert id */
736-
mysql->insert_id= net_field_length_ll(&pos);
734+
affected_rows = net_field_length_ll(&pos); /* affected rows */
735+
insert_id = net_field_length_ll(&pos); /* insert id */
737736

738-
DBUG_PRINT("info",("affected_rows: %lu insert_id: %lu",
739-
(ulong) mysql->affected_rows,
740-
(ulong) mysql->insert_id));
737+
/*
738+
The following check ensures that we skip the assignment for the
739+
above read fields (i.e. affected_rows and insert_id) wherein the
740+
EOF packets are deprecated and the server sends OK packet instead
741+
with a packet header of 0xFE (254) to identify it as an EOF packet.
742+
We ignore this assignment as the valid contents of EOF packet include
743+
packet marker, server status and warning count only. However, we would
744+
assign these values to the connection handle if it was an OK packet
745+
with a packet header of 0x00.
746+
*/
747+
if (!((mysql->server_capabilities & CLIENT_DEPRECATE_EOF) &&
748+
mysql->net.read_pos[0] == 254))
749+
{
750+
mysql->affected_rows= affected_rows;
751+
mysql->insert_id= insert_id;
741752

753+
DBUG_PRINT("info",("affected_rows: %lu insert_id: %lu",
754+
(ulong) mysql->affected_rows,
755+
(ulong) mysql->insert_id));
756+
}
742757
/* server status */
743758
mysql->server_status= uint2korr(pos);
744759
pos += 2;

testclients/mysql_client_test.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15724,6 +15724,76 @@ static void test_mysql_insert_id()
1572415724
myquery(rc);
1572515725
}
1572615726

15727+
/*
15728+
Test for bug#22028117: MYSQLCLIENT DOES NOT RETURN CORRECT
15729+
MYSQL_INSERT_ID VIA DATABASE HANDLE
15730+
*/
15731+
15732+
static void test_bug22028117()
15733+
{
15734+
my_ulonglong res;
15735+
int rc;
15736+
MYSQL_STMT *stmt;
15737+
15738+
myheader("test_bug22028117");
15739+
15740+
rc = mysql_query(mysql, "USE test");
15741+
myquery(rc);
15742+
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15743+
myquery(rc);
15744+
rc= mysql_query(mysql, "CREATE TABLE t1 ("
15745+
"f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
15746+
"f2 VARCHAR(255))");
15747+
myquery(rc);
15748+
res= mysql_insert_id(mysql);
15749+
DIE_UNLESS(res == 0);
15750+
15751+
rc= mysql_query(mysql, "INSERT INTO t1 (f2) VALUES ('a')");
15752+
myquery(rc);
15753+
res= mysql_insert_id(mysql);
15754+
DIE_UNLESS(res == 1);
15755+
15756+
rc= mysql_query(mysql, "INSERT INTO t1 (f2) VALUES ('b')");
15757+
myquery(rc);
15758+
res= mysql_insert_id(mysql);
15759+
DIE_UNLESS(res == 2);
15760+
15761+
/* Make sure that the value of insert_id is not lost after SELECT */
15762+
stmt= mysql_simple_prepare(mysql, "SELECT MAX(f1) FROM t1");
15763+
check_stmt(stmt);
15764+
rc= mysql_stmt_execute(stmt);
15765+
check_execute(stmt, rc);
15766+
rc= my_process_stmt_result(stmt);
15767+
DIE_UNLESS(rc == 1);
15768+
mysql_stmt_close(stmt);
15769+
15770+
res= mysql_insert_id(mysql);
15771+
DIE_UNLESS(res == 2);
15772+
15773+
/* insert_id will be reset to 0 after a new table is created */
15774+
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
15775+
myquery(rc);
15776+
15777+
rc= mysql_query(mysql, "CREATE TABLE t2 ("
15778+
"f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
15779+
"f2 VARCHAR(255))");
15780+
myquery(rc);
15781+
res= mysql_insert_id(mysql);
15782+
DIE_UNLESS(res == 0);
15783+
15784+
/*
15785+
mysql_insert_id() should return expr when the INSERT query contains
15786+
last_insert_id(expr)
15787+
*/
15788+
rc= mysql_query(mysql, "INSERT INTO t1 (f1) VALUES (last_insert_id(100))");
15789+
myquery(rc);
15790+
res= mysql_insert_id(mysql);
15791+
DIE_UNLESS(res == 100);
15792+
15793+
rc= mysql_query(mysql, "DROP TABLE t1,t2");
15794+
myquery(rc);
15795+
}
15796+
1572715797
/*
1572815798
Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
1572915799
*/
@@ -21164,6 +21234,7 @@ static struct my_tests_st my_tests[]= {
2116421234
{ "test_bug17883203", test_bug17883203 },
2116521235
{ "test_bug22559575", test_bug22559575 },
2116621236
{ "test_bug19894382", test_bug19894382 },
21237+
{ "test_bug22028117", test_bug22028117 },
2116721238
{ 0, 0 }
2116821239
};
2116921240

0 commit comments

Comments
 (0)