Loading mysql-test/r/rpl_insert_id.result +58 −0 Original line number Diff line number Diff line Loading @@ -74,3 +74,61 @@ SET FOREIGN_KEY_CHECKS=0; INSERT INTO t1 VALUES (1),(1); ERROR 23000: Duplicate entry '1' for key 1 drop table t1; drop function if exists bug15728; drop function if exists bug15728_insert; drop table if exists t1, t2; create table t1 ( id int not null auto_increment, last_id int, primary key (id) ); create function bug15728() returns int(11) return last_insert_id(); insert into t1 (last_id) values (0); insert into t1 (last_id) values (last_insert_id()); insert into t1 (last_id) values (bug15728()); create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); create function bug15728_insert() returns int(11) modifies sql data begin insert into t2 (last_id) values (bug15728()); return bug15728(); end| create trigger t1_bi before insert on t1 for each row begin declare res int; select bug15728_insert() into res; set NEW.last_id = res; end| insert into t1 (last_id) values (0); drop trigger t1_bi; select last_insert_id(); last_insert_id() 4 select bug15728_insert(); bug15728_insert() 2 select last_insert_id(); last_insert_id() 4 insert into t1 (last_id) values (bug15728()); select last_insert_id(); last_insert_id() 5 select * from t1; id last_id 1 0 2 1 3 2 4 1 5 4 select * from t2; id last_id 1 3 2 4 drop function bug15728; drop function bug15728_insert; drop table t1, t2; mysql-test/r/sp.result +17 −0 Original line number Diff line number Diff line Loading @@ -4848,6 +4848,23 @@ c 2 b 3 a 1 delete from t1| drop function if exists bug15728| drop table if exists t3| create table t3 ( id int not null auto_increment, primary key (id) )| create function bug15728() returns int(11) return last_insert_id()| insert into t3 values (0)| select last_insert_id()| last_insert_id() 1 select bug15728()| bug15728() 1 drop function bug15728| drop table t3| drop procedure if exists bug18787| create procedure bug18787() begin Loading mysql-test/t/rpl_insert_id.test +70 −0 Original line number Diff line number Diff line Loading @@ -78,3 +78,73 @@ connection master; drop table t1; sync_slave_with_master; # End of 4.1 tests # # BUG#15728: LAST_INSERT_ID function inside a stored function returns 0 # # The solution is not to reset last_insert_id on enter to sub-statement. # connection master; --disable_warnings drop function if exists bug15728; drop function if exists bug15728_insert; drop table if exists t1, t2; --enable_warnings create table t1 ( id int not null auto_increment, last_id int, primary key (id) ); create function bug15728() returns int(11) return last_insert_id(); insert into t1 (last_id) values (0); insert into t1 (last_id) values (last_insert_id()); insert into t1 (last_id) values (bug15728()); # Check that nested call replicates too. create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); delimiter |; create function bug15728_insert() returns int(11) modifies sql data begin insert into t2 (last_id) values (bug15728()); return bug15728(); end| create trigger t1_bi before insert on t1 for each row begin declare res int; select bug15728_insert() into res; set NEW.last_id = res; end| delimiter ;| insert into t1 (last_id) values (0); drop trigger t1_bi; # Check that nested call doesn't affect outer context. select last_insert_id(); select bug15728_insert(); select last_insert_id(); insert into t1 (last_id) values (bug15728()); # This should be exactly one greater than in the previous call. select last_insert_id(); save_master_pos; connection slave; sync_with_master; select * from t1; select * from t2; connection master; drop function bug15728; drop function bug15728_insert; drop table t1, t2; # End of 5.0 tests mysql-test/t/sp.test +25 −0 Original line number Diff line number Diff line Loading @@ -5698,6 +5698,31 @@ select * from t1 order by @x| delete from t1| # # BUG#15728: LAST_INSERT_ID function inside a stored function returns 0 # # The solution is not to reset last_insert_id on enter to sub-statement. # --disable_warnings drop function if exists bug15728| drop table if exists t3| --enable_warnings create table t3 ( id int not null auto_increment, primary key (id) )| create function bug15728() returns int(11) return last_insert_id()| insert into t3 values (0)| select last_insert_id()| select bug15728()| drop function bug15728| drop table t3| # # BUG#18787: Server crashed when calling a stored procedure containing # a misnamed function Loading sql/sql_class.cc +3 −2 Original line number Diff line number Diff line Loading @@ -2025,7 +2025,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) The following things is done - Disable binary logging for the duration of the statement - Disable multi-result-sets for the duration of the statement - Value of last_insert_id() is reset and restored - Value of last_insert_id() is saved and restored - Value set by 'SET INSERT_ID=#' is reset and restored - Value for found_rows() is reset and restored - examined_row_count is added to the total Loading @@ -2037,6 +2037,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) We reset examined_row_count and cuted_fields and add these to the result to ensure that if we have a bug that would reset these within a function, we are not loosing any rows from the main statement. We do not reset value of last_insert_id(). ****************************************************************************/ void THD::reset_sub_statement_state(Sub_statement_state *backup, Loading @@ -2062,7 +2064,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, /* Disable result sets */ client_capabilities &= ~CLIENT_MULTI_RESULTS; in_sub_stmt|= new_state; last_insert_id= 0; next_insert_id= 0; insert_id_used= 0; examined_row_count= 0; Loading Loading
mysql-test/r/rpl_insert_id.result +58 −0 Original line number Diff line number Diff line Loading @@ -74,3 +74,61 @@ SET FOREIGN_KEY_CHECKS=0; INSERT INTO t1 VALUES (1),(1); ERROR 23000: Duplicate entry '1' for key 1 drop table t1; drop function if exists bug15728; drop function if exists bug15728_insert; drop table if exists t1, t2; create table t1 ( id int not null auto_increment, last_id int, primary key (id) ); create function bug15728() returns int(11) return last_insert_id(); insert into t1 (last_id) values (0); insert into t1 (last_id) values (last_insert_id()); insert into t1 (last_id) values (bug15728()); create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); create function bug15728_insert() returns int(11) modifies sql data begin insert into t2 (last_id) values (bug15728()); return bug15728(); end| create trigger t1_bi before insert on t1 for each row begin declare res int; select bug15728_insert() into res; set NEW.last_id = res; end| insert into t1 (last_id) values (0); drop trigger t1_bi; select last_insert_id(); last_insert_id() 4 select bug15728_insert(); bug15728_insert() 2 select last_insert_id(); last_insert_id() 4 insert into t1 (last_id) values (bug15728()); select last_insert_id(); last_insert_id() 5 select * from t1; id last_id 1 0 2 1 3 2 4 1 5 4 select * from t2; id last_id 1 3 2 4 drop function bug15728; drop function bug15728_insert; drop table t1, t2;
mysql-test/r/sp.result +17 −0 Original line number Diff line number Diff line Loading @@ -4848,6 +4848,23 @@ c 2 b 3 a 1 delete from t1| drop function if exists bug15728| drop table if exists t3| create table t3 ( id int not null auto_increment, primary key (id) )| create function bug15728() returns int(11) return last_insert_id()| insert into t3 values (0)| select last_insert_id()| last_insert_id() 1 select bug15728()| bug15728() 1 drop function bug15728| drop table t3| drop procedure if exists bug18787| create procedure bug18787() begin Loading
mysql-test/t/rpl_insert_id.test +70 −0 Original line number Diff line number Diff line Loading @@ -78,3 +78,73 @@ connection master; drop table t1; sync_slave_with_master; # End of 4.1 tests # # BUG#15728: LAST_INSERT_ID function inside a stored function returns 0 # # The solution is not to reset last_insert_id on enter to sub-statement. # connection master; --disable_warnings drop function if exists bug15728; drop function if exists bug15728_insert; drop table if exists t1, t2; --enable_warnings create table t1 ( id int not null auto_increment, last_id int, primary key (id) ); create function bug15728() returns int(11) return last_insert_id(); insert into t1 (last_id) values (0); insert into t1 (last_id) values (last_insert_id()); insert into t1 (last_id) values (bug15728()); # Check that nested call replicates too. create table t2 ( id int not null auto_increment, last_id int, primary key (id) ); delimiter |; create function bug15728_insert() returns int(11) modifies sql data begin insert into t2 (last_id) values (bug15728()); return bug15728(); end| create trigger t1_bi before insert on t1 for each row begin declare res int; select bug15728_insert() into res; set NEW.last_id = res; end| delimiter ;| insert into t1 (last_id) values (0); drop trigger t1_bi; # Check that nested call doesn't affect outer context. select last_insert_id(); select bug15728_insert(); select last_insert_id(); insert into t1 (last_id) values (bug15728()); # This should be exactly one greater than in the previous call. select last_insert_id(); save_master_pos; connection slave; sync_with_master; select * from t1; select * from t2; connection master; drop function bug15728; drop function bug15728_insert; drop table t1, t2; # End of 5.0 tests
mysql-test/t/sp.test +25 −0 Original line number Diff line number Diff line Loading @@ -5698,6 +5698,31 @@ select * from t1 order by @x| delete from t1| # # BUG#15728: LAST_INSERT_ID function inside a stored function returns 0 # # The solution is not to reset last_insert_id on enter to sub-statement. # --disable_warnings drop function if exists bug15728| drop table if exists t3| --enable_warnings create table t3 ( id int not null auto_increment, primary key (id) )| create function bug15728() returns int(11) return last_insert_id()| insert into t3 values (0)| select last_insert_id()| select bug15728()| drop function bug15728| drop table t3| # # BUG#18787: Server crashed when calling a stored procedure containing # a misnamed function Loading
sql/sql_class.cc +3 −2 Original line number Diff line number Diff line Loading @@ -2025,7 +2025,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) The following things is done - Disable binary logging for the duration of the statement - Disable multi-result-sets for the duration of the statement - Value of last_insert_id() is reset and restored - Value of last_insert_id() is saved and restored - Value set by 'SET INSERT_ID=#' is reset and restored - Value for found_rows() is reset and restored - examined_row_count is added to the total Loading @@ -2037,6 +2037,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) We reset examined_row_count and cuted_fields and add these to the result to ensure that if we have a bug that would reset these within a function, we are not loosing any rows from the main statement. We do not reset value of last_insert_id(). ****************************************************************************/ void THD::reset_sub_statement_state(Sub_statement_state *backup, Loading @@ -2062,7 +2064,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, /* Disable result sets */ client_capabilities &= ~CLIENT_MULTI_RESULTS; in_sub_stmt|= new_state; last_insert_id= 0; next_insert_id= 0; insert_id_used= 0; examined_row_count= 0; Loading