Loading mysql-test/extra/rpl_tests/rpl_insert_id.test +129 −0 Original line number Diff line number Diff line Loading @@ -276,10 +276,139 @@ connection master; drop table t1; sync_slave_with_master; # # BUG#20339: stored procedure using LAST_INSERT_ID() does not # replicate statement-based. # # There is another version of the test for bug#20339 above that is # actually originates in 5.1, and this is the version that is merged # from 5.0. # connection master; --disable_warnings DROP PROCEDURE IF EXISTS p1; DROP TABLE IF EXISTS t1, t2; --enable_warnings # Reset result of LAST_INSERT_ID(). SELECT LAST_INSERT_ID(0); CREATE TABLE t1 ( id INT NOT NULL DEFAULT 0, last_id INT, PRIMARY KEY (id) ); CREATE TABLE t2 ( id INT NOT NULL AUTO_INCREMENT, last_id INT, PRIMARY KEY (id) ); delimiter |; CREATE PROCEDURE p1() BEGIN INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID()); END| delimiter ;| CALL p1(); SELECT * FROM t1; SELECT * FROM t2; sync_slave_with_master; SELECT * FROM t1; SELECT * FROM t2; connection master; DROP PROCEDURE p1; DROP TABLE t1, t2; # # BUG#21726: Incorrect result with multiple invocations of # LAST_INSERT_ID # --disable_warnings DROP PROCEDURE IF EXISTS p1; DROP FUNCTION IF EXISTS f1; DROP FUNCTION IF EXISTS f2; DROP TABLE IF EXISTS t1, t2; --enable_warnings CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, j INT DEFAULT 0 ); CREATE TABLE t2 (i INT); delimiter |; CREATE PROCEDURE p1() BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); END | CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); RETURN 0; END | CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC RETURN LAST_INSERT_ID() | delimiter ;| INSERT INTO t1 VALUES (NULL, -1); CALL p1(); SELECT f1(); INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2()); INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)), (NULL, @@LAST_INSERT_ID); # Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID". INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); UPDATE t1 SET j= -1 WHERE i IS NULL; SELECT * FROM t1; SELECT * FROM t2; sync_slave_with_master; SELECT * FROM t1; SELECT * FROM t2; connection master; DROP PROCEDURE p1; DROP FUNCTION f1; DROP FUNCTION f2; DROP TABLE t1, t2; sync_slave_with_master; --echo # --echo # End of 5.0 tests --echo # # Tests in this file are tightly bound together. Recreate t2. connection master; create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); # Test for BUG#20341 "stored function inserting into one # auto_increment puts bad data in slave" Loading mysql-test/r/rpl_insert_id.result +134 −0 Original line number Diff line number Diff line Loading @@ -263,9 +263,143 @@ n b 2 100 3 350 drop table t1; DROP PROCEDURE IF EXISTS p1; DROP TABLE IF EXISTS t1, t2; SELECT LAST_INSERT_ID(0); LAST_INSERT_ID(0) 0 CREATE TABLE t1 ( id INT NOT NULL DEFAULT 0, last_id INT, PRIMARY KEY (id) ); CREATE TABLE t2 ( id INT NOT NULL AUTO_INCREMENT, last_id INT, PRIMARY KEY (id) ); CREATE PROCEDURE p1() BEGIN INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID()); END| CALL p1(); SELECT * FROM t1; id last_id 0 1 SELECT * FROM t2; id last_id 1 0 SELECT * FROM t1; id last_id 0 1 SELECT * FROM t2; id last_id 1 0 DROP PROCEDURE p1; DROP TABLE t1, t2; DROP PROCEDURE IF EXISTS p1; DROP FUNCTION IF EXISTS f1; DROP FUNCTION IF EXISTS f2; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, j INT DEFAULT 0 ); CREATE TABLE t2 (i INT); CREATE PROCEDURE p1() BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); END | CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); RETURN 0; END | CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC RETURN LAST_INSERT_ID() | INSERT INTO t1 VALUES (NULL, -1); CALL p1(); SELECT f1(); f1() 0 INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2()); INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)), (NULL, @@LAST_INSERT_ID); INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); UPDATE t1 SET j= -1 WHERE i IS NULL; SELECT * FROM t1; i j 1 -1 2 0 3 0 4 0 5 0 6 0 7 0 8 3 9 3 10 3 11 3 12 3 13 8 14 13 15 5 16 13 17 -1 18 14 SELECT * FROM t2; i 2 3 5 6 SELECT * FROM t1; i j 1 -1 2 0 3 0 4 0 5 0 6 0 7 0 8 3 9 3 10 3 11 3 12 3 13 8 14 13 15 5 16 13 17 -1 18 14 SELECT * FROM t2; i 2 3 5 6 DROP PROCEDURE p1; DROP FUNCTION f1; DROP FUNCTION f2; DROP TABLE t1, t2; # # End of 5.0 tests # create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); truncate table t2; create table t1 (id tinyint primary key); create function insid() returns int Loading sql/sql_class.cc +14 −1 Original line number Diff line number Diff line Loading @@ -630,8 +630,21 @@ bool THD::store_globals() } /* Cleanup after a query */ /* Cleanup after query. SYNOPSIS THD::cleanup_after_query() DESCRIPTION This function is used to reset thread data to it's default state. NOTE This function is not suitable for setting thread data to some non-default values, as there is only one replication thread, so different master threads may overwrite data of each other on slave. */ void THD::cleanup_after_query() { if (!in_sub_stmt) /* stored functions and triggers are a special case */ Loading tests/mysql_client_test.c +40 −2 Original line number Diff line number Diff line Loading @@ -15438,6 +15438,43 @@ static void test_bug21206() DBUG_VOID_RETURN; } /* Bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Test that client gets updated value of insert_id on UPDATE that uses LAST_INSERT_ID(expr). */ static void test_bug21726() { const char *create_table[]= { "DROP TABLE IF EXISTS t1", "CREATE TABLE t1 (i INT)", "INSERT INTO t1 VALUES (1)", }; const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)"; int rc; my_ulonglong insert_id; DBUG_ENTER("test_bug21726"); myheader("test_bug21726"); fill_tables(create_table, sizeof(create_table) / sizeof(*create_table)); rc= mysql_query(mysql, update_query); myquery(rc); insert_id= mysql_insert_id(mysql); DIE_UNLESS(insert_id == 2); rc= mysql_query(mysql, update_query); myquery(rc); insert_id= mysql_insert_id(mysql); DIE_UNLESS(insert_id == 3); DBUG_VOID_RETURN; } /* Read and parse arguments and MySQL options from my.cnf Loading Loading @@ -15715,6 +15752,7 @@ static struct my_tests_st my_tests[]= { { "test_mysql_insert_id", test_mysql_insert_id }, { "test_bug19671", test_bug19671 }, { "test_bug21206", test_bug21206 }, { "test_bug21726", test_bug21726 }, { 0, 0 } }; Loading Loading
mysql-test/extra/rpl_tests/rpl_insert_id.test +129 −0 Original line number Diff line number Diff line Loading @@ -276,10 +276,139 @@ connection master; drop table t1; sync_slave_with_master; # # BUG#20339: stored procedure using LAST_INSERT_ID() does not # replicate statement-based. # # There is another version of the test for bug#20339 above that is # actually originates in 5.1, and this is the version that is merged # from 5.0. # connection master; --disable_warnings DROP PROCEDURE IF EXISTS p1; DROP TABLE IF EXISTS t1, t2; --enable_warnings # Reset result of LAST_INSERT_ID(). SELECT LAST_INSERT_ID(0); CREATE TABLE t1 ( id INT NOT NULL DEFAULT 0, last_id INT, PRIMARY KEY (id) ); CREATE TABLE t2 ( id INT NOT NULL AUTO_INCREMENT, last_id INT, PRIMARY KEY (id) ); delimiter |; CREATE PROCEDURE p1() BEGIN INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID()); END| delimiter ;| CALL p1(); SELECT * FROM t1; SELECT * FROM t2; sync_slave_with_master; SELECT * FROM t1; SELECT * FROM t2; connection master; DROP PROCEDURE p1; DROP TABLE t1, t2; # # BUG#21726: Incorrect result with multiple invocations of # LAST_INSERT_ID # --disable_warnings DROP PROCEDURE IF EXISTS p1; DROP FUNCTION IF EXISTS f1; DROP FUNCTION IF EXISTS f2; DROP TABLE IF EXISTS t1, t2; --enable_warnings CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, j INT DEFAULT 0 ); CREATE TABLE t2 (i INT); delimiter |; CREATE PROCEDURE p1() BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); END | CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); RETURN 0; END | CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC RETURN LAST_INSERT_ID() | delimiter ;| INSERT INTO t1 VALUES (NULL, -1); CALL p1(); SELECT f1(); INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2()); INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)), (NULL, @@LAST_INSERT_ID); # Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID". INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); UPDATE t1 SET j= -1 WHERE i IS NULL; SELECT * FROM t1; SELECT * FROM t2; sync_slave_with_master; SELECT * FROM t1; SELECT * FROM t2; connection master; DROP PROCEDURE p1; DROP FUNCTION f1; DROP FUNCTION f2; DROP TABLE t1, t2; sync_slave_with_master; --echo # --echo # End of 5.0 tests --echo # # Tests in this file are tightly bound together. Recreate t2. connection master; create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); # Test for BUG#20341 "stored function inserting into one # auto_increment puts bad data in slave" Loading
mysql-test/r/rpl_insert_id.result +134 −0 Original line number Diff line number Diff line Loading @@ -263,9 +263,143 @@ n b 2 100 3 350 drop table t1; DROP PROCEDURE IF EXISTS p1; DROP TABLE IF EXISTS t1, t2; SELECT LAST_INSERT_ID(0); LAST_INSERT_ID(0) 0 CREATE TABLE t1 ( id INT NOT NULL DEFAULT 0, last_id INT, PRIMARY KEY (id) ); CREATE TABLE t2 ( id INT NOT NULL AUTO_INCREMENT, last_id INT, PRIMARY KEY (id) ); CREATE PROCEDURE p1() BEGIN INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID()); END| CALL p1(); SELECT * FROM t1; id last_id 0 1 SELECT * FROM t2; id last_id 1 0 SELECT * FROM t1; id last_id 0 1 SELECT * FROM t2; id last_id 1 0 DROP PROCEDURE p1; DROP TABLE t1, t2; DROP PROCEDURE IF EXISTS p1; DROP FUNCTION IF EXISTS f1; DROP FUNCTION IF EXISTS f2; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, j INT DEFAULT 0 ); CREATE TABLE t2 (i INT); CREATE PROCEDURE p1() BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); END | CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA BEGIN INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); INSERT INTO t1 (i) VALUES (NULL), (NULL); INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); RETURN 0; END | CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC RETURN LAST_INSERT_ID() | INSERT INTO t1 VALUES (NULL, -1); CALL p1(); SELECT f1(); f1() 0 INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2()); INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)), (NULL, @@LAST_INSERT_ID); INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); UPDATE t1 SET j= -1 WHERE i IS NULL; SELECT * FROM t1; i j 1 -1 2 0 3 0 4 0 5 0 6 0 7 0 8 3 9 3 10 3 11 3 12 3 13 8 14 13 15 5 16 13 17 -1 18 14 SELECT * FROM t2; i 2 3 5 6 SELECT * FROM t1; i j 1 -1 2 0 3 0 4 0 5 0 6 0 7 0 8 3 9 3 10 3 11 3 12 3 13 8 14 13 15 5 16 13 17 -1 18 14 SELECT * FROM t2; i 2 3 5 6 DROP PROCEDURE p1; DROP FUNCTION f1; DROP FUNCTION f2; DROP TABLE t1, t2; # # End of 5.0 tests # create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); truncate table t2; create table t1 (id tinyint primary key); create function insid() returns int Loading
sql/sql_class.cc +14 −1 Original line number Diff line number Diff line Loading @@ -630,8 +630,21 @@ bool THD::store_globals() } /* Cleanup after a query */ /* Cleanup after query. SYNOPSIS THD::cleanup_after_query() DESCRIPTION This function is used to reset thread data to it's default state. NOTE This function is not suitable for setting thread data to some non-default values, as there is only one replication thread, so different master threads may overwrite data of each other on slave. */ void THD::cleanup_after_query() { if (!in_sub_stmt) /* stored functions and triggers are a special case */ Loading
tests/mysql_client_test.c +40 −2 Original line number Diff line number Diff line Loading @@ -15438,6 +15438,43 @@ static void test_bug21206() DBUG_VOID_RETURN; } /* Bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Test that client gets updated value of insert_id on UPDATE that uses LAST_INSERT_ID(expr). */ static void test_bug21726() { const char *create_table[]= { "DROP TABLE IF EXISTS t1", "CREATE TABLE t1 (i INT)", "INSERT INTO t1 VALUES (1)", }; const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)"; int rc; my_ulonglong insert_id; DBUG_ENTER("test_bug21726"); myheader("test_bug21726"); fill_tables(create_table, sizeof(create_table) / sizeof(*create_table)); rc= mysql_query(mysql, update_query); myquery(rc); insert_id= mysql_insert_id(mysql); DIE_UNLESS(insert_id == 2); rc= mysql_query(mysql, update_query); myquery(rc); insert_id= mysql_insert_id(mysql); DIE_UNLESS(insert_id == 3); DBUG_VOID_RETURN; } /* Read and parse arguments and MySQL options from my.cnf Loading Loading @@ -15715,6 +15752,7 @@ static struct my_tests_st my_tests[]= { { "test_mysql_insert_id", test_mysql_insert_id }, { "test_bug19671", test_bug19671 }, { "test_bug21206", test_bug21206 }, { "test_bug21726", test_bug21726 }, { 0, 0 } }; Loading