1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID

Non-upper-level INSERTs (the ones in the body of stored procedure,
stored function, or trigger) into a table that have AUTO_INCREMENT
column didn't affected the result of LAST_INSERT_ID() on this level.

The problem was introduced with the fix of bug 6880, which in turn was
introduced with the fix of bug 3117, where current insert_id value was
remembered on the first call to LAST_INSERT_ID() (bug 3117) and was
returned from that function until it was reset before the next
_upper-level_ statement (bug 6880).

The fix for bug#21726 brings back the behaviour of version 4.0, and
implements the following: remember insert_id value at the beginning
of the statement or expression (which at that point equals to
the first insert_id value generated by the previous statement), and
return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID.

Thus, the value returned by LAST_INSERT_ID() is not affected by values
generated by current statement, nor by LAST_INSERT_ID(expr) calls in
this statement.

Version 5.1 does not have this bug (it was fixed by WL 3146).
This commit is contained in:
kroki/tomash@moonlight.intranet
2006-10-02 14:28:23 +04:00
parent dead2e0f14
commit 5ea8adfae7
14 changed files with 405 additions and 41 deletions

View File

@ -244,6 +244,118 @@ select * from t1 order by n;
connection master;
drop table t1;
#
# BUG#20339: stored procedure using LAST_INSERT_ID() does not
# replicate statement-based
#
--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