Commit ef47b625 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-8827 Duplicate key with auto increment

fix innodb auto-increment handling
three bugs:
1. innobase_next_autoinc treated the case of current<offset incorrectly
2. ha_innobase::get_auto_increment didn't recalculate current when increment changed
3. ha_innobase::get_auto_increment didn't pass offset down to innobase_next_autoinc
parent c8652eef
...@@ -567,7 +567,7 @@ Variable_name Value ...@@ -567,7 +567,7 @@ Variable_name Value
auto_increment_increment 65535 auto_increment_increment 65535
auto_increment_offset 65535 auto_increment_offset 65535
INSERT INTO t1 VALUES (NULL),(NULL); INSERT INTO t1 VALUES (NULL),(NULL);
ERROR 22003: Out of range value for column 'c1' at row 1 ERROR HY000: Failed to read auto-increment value from storage engine
SELECT * FROM t1; SELECT * FROM t1;
c1 c1
1 1
...@@ -660,7 +660,7 @@ t2 CREATE TABLE `t2` ( ...@@ -660,7 +660,7 @@ t2 CREATE TABLE `t2` (
`n` int(10) unsigned NOT NULL, `n` int(10) unsigned NOT NULL,
`o` enum('FALSE','TRUE') DEFAULT NULL, `o` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`m`) PRIMARY KEY (`m`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ; INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
......
...@@ -349,7 +349,7 @@ INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2 ...@@ -349,7 +349,7 @@ INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2
SELECT * FROM t1; SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
SHOW VARIABLES LIKE "%auto_inc%"; SHOW VARIABLES LIKE "%auto_inc%";
--error 167 --error 1467
INSERT INTO t1 VALUES (NULL),(NULL); INSERT INTO t1 VALUES (NULL),(NULL);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
......
...@@ -1504,10 +1504,11 @@ innobase_next_autoinc( ...@@ -1504,10 +1504,11 @@ innobase_next_autoinc(
if (next_value == 0) { if (next_value == 0) {
ulonglong next; ulonglong next;
if (current > offset) { if (current >= offset) {
next = (current - offset) / step; next = (current - offset) / step;
} else { } else {
next = (offset - current) / step; next = 0;
block -= step;
} }
ut_a(max_value > next); ut_a(max_value > next);
...@@ -10445,15 +10446,12 @@ ha_innobase::get_auto_increment( ...@@ -10445,15 +10446,12 @@ ha_innobase::get_auto_increment(
current = *first_value; current = *first_value;
/* If the increment step of the auto increment column if (prebuilt->autoinc_increment != increment) {
decreases then it is not affecting the immediate
next value in the series. */
if (prebuilt->autoinc_increment > increment) {
current = autoinc - prebuilt->autoinc_increment; current = autoinc - prebuilt->autoinc_increment;
current = innobase_next_autoinc( current = innobase_next_autoinc(
current, 1, increment, 1, col_max_value); current, 1, increment, offset, col_max_value);
dict_table_autoinc_initialize(prebuilt->table, current); dict_table_autoinc_initialize(prebuilt->table, current);
......
...@@ -1748,10 +1748,11 @@ innobase_next_autoinc( ...@@ -1748,10 +1748,11 @@ innobase_next_autoinc(
if (next_value == 0) { if (next_value == 0) {
ulonglong next; ulonglong next;
if (current > offset) { if (current >= offset) {
next = (current - offset) / step; next = (current - offset) / step;
} else { } else {
next = (offset - current) / step; next = 0;
block -= step;
} }
ut_a(max_value > next); ut_a(max_value > next);
...@@ -11604,15 +11605,12 @@ ha_innobase::get_auto_increment( ...@@ -11604,15 +11605,12 @@ ha_innobase::get_auto_increment(
current = *first_value; current = *first_value;
/* If the increment step of the auto increment column if (prebuilt->autoinc_increment != increment) {
decreases then it is not affecting the immediate
next value in the series. */
if (prebuilt->autoinc_increment > increment) {
current = autoinc - prebuilt->autoinc_increment; current = autoinc - prebuilt->autoinc_increment;
current = innobase_next_autoinc( current = innobase_next_autoinc(
current, 1, increment, 1, col_max_value); current, 1, increment, offset, col_max_value);
dict_table_autoinc_initialize(prebuilt->table, current); dict_table_autoinc_initialize(prebuilt->table, current);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment