Bug#15728: LAST_INSERT_ID function inside a stored function returns 0
Do not reset value of LAST_INSERT_ID() in sub-statement. mysql-test/r/rpl_insert_id.result: Add result for bug#15728. mysql-test/r/sp.result: Add result for bug#15728. mysql-test/t/rpl_insert_id.test: Add test case for bug#15728. mysql-test/t/sp.test: Add test case for bug#15728. sql/sql_class.cc: Do not reset value of LAST_INSERT_ID() in sub-statement.
This commit is contained in:
parent
90ecf9b698
commit
10eac46a52
@ -74,3 +74,61 @@ SET FOREIGN_KEY_CHECKS=0;
|
|||||||
INSERT INTO t1 VALUES (1),(1);
|
INSERT INTO t1 VALUES (1),(1);
|
||||||
ERROR 23000: Duplicate entry '1' for key 1
|
ERROR 23000: Duplicate entry '1' for key 1
|
||||||
drop table t1;
|
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;
|
||||||
|
@ -4848,6 +4848,23 @@ c 2
|
|||||||
b 3
|
b 3
|
||||||
a 1
|
a 1
|
||||||
delete from t1|
|
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|
|
drop procedure if exists bug18787|
|
||||||
create procedure bug18787()
|
create procedure bug18787()
|
||||||
begin
|
begin
|
||||||
|
@ -78,3 +78,73 @@ connection master;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
# End of 4.1 tests
|
# 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
|
||||||
|
@ -5698,6 +5698,31 @@ select * from t1 order by @x|
|
|||||||
delete from t1|
|
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
|
# BUG#18787: Server crashed when calling a stored procedure containing
|
||||||
# a misnamed function
|
# a misnamed function
|
||||||
|
@ -2025,7 +2025,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
|
|||||||
The following things is done
|
The following things is done
|
||||||
- Disable binary logging for the duration of the statement
|
- Disable binary logging for the duration of the statement
|
||||||
- Disable multi-result-sets 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 set by 'SET INSERT_ID=#' is reset and restored
|
||||||
- Value for found_rows() is reset and restored
|
- Value for found_rows() is reset and restored
|
||||||
- examined_row_count is added to the total
|
- examined_row_count is added to the total
|
||||||
@ -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
|
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
|
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.
|
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,
|
void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
||||||
@ -2062,7 +2064,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
|||||||
/* Disable result sets */
|
/* Disable result sets */
|
||||||
client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
||||||
in_sub_stmt|= new_state;
|
in_sub_stmt|= new_state;
|
||||||
last_insert_id= 0;
|
|
||||||
next_insert_id= 0;
|
next_insert_id= 0;
|
||||||
insert_id_used= 0;
|
insert_id_used= 0;
|
||||||
examined_row_count= 0;
|
examined_row_count= 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user