From 0bdae38efbf4696739e116c8fcc1f876b3ecc7fc Mon Sep 17 00:00:00 2001
From: "ramil@mysql.com" <>
Date: Wed, 7 Jun 2006 14:01:10 +0500
Subject: [PATCH] Fix for bug #6880: LAST_INSERT_ID() within a statement

---
 mysql-test/r/auto_increment.result | 22 ++++++++++++++++++++++
 mysql-test/r/rpl_log.result        | 17 +++++++++++++++++
 mysql-test/t/auto_increment.test   | 17 +++++++++++++++++
 mysql-test/t/rpl_log.test          | 14 ++++++++++++++
 sql/item_func.cc                   |  7 ++++---
 5 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result
index 426f20212c3..c1b7b753bd4 100644
--- a/mysql-test/r/auto_increment.result
+++ b/mysql-test/r/auto_increment.result
@@ -378,4 +378,26 @@ t1	CREATE TABLE `t1` (
   KEY `t1_name` (`t1_name`)
 ) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1
 DROP TABLE `t1`;
+create table t1(a int not null auto_increment primary key);
+create table t2(a int not null auto_increment primary key, t1a int);
+insert into t1 values(NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+select * from t2;
+a	t1a
+1	1
+2	1
+3	2
+4	2
+5	2
+6	3
+7	3
+8	3
+9	3
+drop table t1, t2;
 End of 4.1 tests
diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result
index 9fcab2a7cbe..3833800bfeb 100644
--- a/mysql-test/r/rpl_log.result
+++ b/mysql-test/r/rpl_log.result
@@ -99,3 +99,20 @@ Slave_IO_State	Master_Host	Master_User	Master_Port	Connect_Retry	Master_Log_File
 #	127.0.0.1	root	MASTER_PORT	1	master-bin.000002	276	slave-relay-bin.000003	214	master-bin.000002	Yes	Yes							0		0	276	214	None		0	No						#
 show binlog events in 'slave-bin.000005' from 4;
 ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
+create table t1(a int auto_increment primary key, b int);
+insert into t1 values (NULL, 1);
+reset master;
+set insert_id=5;
+insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id());
+show binlog events;
+Log_name	Pos	Event_type	Server_id	Orig_log_pos	Info
+slave-bin.000001	4	Start	2	4	Server ver: VERSION, Binlog ver: 3
+slave-bin.000001	79	Intvar	2	79	LAST_INSERT_ID=1
+slave-bin.000001	107	Intvar	2	107	INSERT_ID=5
+slave-bin.000001	135	Query	2	135	use `test`; insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id())
+select * from t1;
+a	b
+1	1
+5	1
+6	1
+drop table t1;
diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test
index eed2ea44d05..37b92b32bfb 100644
--- a/mysql-test/t/auto_increment.test
+++ b/mysql-test/t/auto_increment.test
@@ -238,4 +238,21 @@ SHOW CREATE TABLE `t1`;
 
 DROP TABLE `t1`;
 
+#
+# Bug #6880: LAST_INSERT_ID() within a statement
+#
+
+create table t1(a int not null auto_increment primary key);              
+create table t2(a int not null auto_increment primary key, t1a int);     
+insert into t1 values(NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID());
+insert into t1 values (NULL);                                            
+insert into t2 values (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID());
+select * from t2;
+drop table t1, t2;
+
 --echo End of 4.1 tests
diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test
index 7a67ab2311a..08aa3b28850 100644
--- a/mysql-test/t/rpl_log.test
+++ b/mysql-test/t/rpl_log.test
@@ -108,4 +108,18 @@ show slave status;
 --error 1220
 show binlog events in 'slave-bin.000005' from 4;
 
+#
+# Bug #6880: LAST_INSERT_ID() within a statement
+#
+
+create table t1(a int auto_increment primary key, b int);
+insert into t1 values (NULL, 1);
+reset master;
+set insert_id=5;
+insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id());
+--replace_result $VERSION VERSION
+show binlog events;
+select * from t1;
+drop table t1;
+
 # End of 4.1 tests
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 66300d129d4..91ccef6511f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2233,15 +2233,16 @@ longlong Item_func_release_lock::val_int()
 longlong Item_func_last_insert_id::val_int()
 {
   DBUG_ASSERT(fixed == 1);
+  THD* thd= current_thd;
   if (arg_count)
   {
     longlong value=args[0]->val_int();
-    current_thd->insert_id(value);
+    thd->insert_id(value);
     null_value=args[0]->null_value;
   }
   else
-    current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
-  return current_thd->insert_id();
+    thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+  return thd->last_insert_id_used ? thd->current_insert_id : thd->insert_id();
 }
 
 /* This function is just used to test speed of different functions */
-- 
2.30.9