summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/insert_update.result22
-rw-r--r--mysql-test/t/insert_update.test17
-rw-r--r--sql/handler.cc7
-rw-r--r--sql/sql_class.h4
4 files changed, 50 insertions, 0 deletions
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index fd70fcb9084..4a3e87d9d48 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -336,3 +336,25 @@ id f1
0 test1
DROP TABLE t1;
SET SQL_MODE='';
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT PRIMARY KEY,
+c1 CHAR(1) UNIQUE KEY,
+cnt INT DEFAULT 1
+);
+INSERT INTO t1 (c1) VALUES ('A'), ('B'), ('C');
+SELECT * FROM t1;
+id c1 cnt
+1 A 1
+2 B 1
+3 C 1
+INSERT INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
+ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+id c1 cnt
+1 A 2
+2 B 1
+3 C 1
+4 X 1
+5 Y 1
+6 Z 1
+DROP TABLE t1;
diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test
index 76df4502769..0e199dab4bd 100644
--- a/mysql-test/t/insert_update.test
+++ b/mysql-test/t/insert_update.test
@@ -247,3 +247,20 @@ REPLACE INTO t1 VALUES (0,"test1",null);
SELECT id, f1 FROM t1;
DROP TABLE t1;
SET SQL_MODE='';
+
+#
+# Bug#27954: multi-row INSERT ... ON DUPLICATE with duplicated
+# row at the first place into table with AUTO_INCREMENT and
+# additional UNIQUE key.
+#
+CREATE TABLE t1 (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ c1 CHAR(1) UNIQUE KEY,
+ cnt INT DEFAULT 1
+);
+INSERT INTO t1 (c1) VALUES ('A'), ('B'), ('C');
+SELECT * FROM t1;
+INSERT INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
+ ON DUPLICATE KEY UPDATE cnt=cnt+1;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/sql/handler.cc b/sql/handler.cc
index c6c31593a5f..867ac7ff778 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1685,7 +1685,14 @@ void handler::restore_auto_increment()
{
THD *thd= table->in_use;
if (thd->next_insert_id)
+ {
thd->next_insert_id= thd->prev_insert_id;
+ if (thd->next_insert_id == 0)
+ {
+ /* we didn't generate a value, engine will be called again */
+ thd->clear_next_insert_id= 0;
+ }
+ }
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 12d7cb2368f..7dd46e2efe7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1431,6 +1431,10 @@ public:
*/
bool insert_id_used;
+ /*
+ clear_next_insert_id is set if engine was called at least once
+ for this statement to generate auto_increment value.
+ */
bool clear_next_insert_id;
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
bool substitute_null_with_insert_id;