Skip to content

Commit 25ecfe7

Browse files
author
Aditya A
committed
Bug 26906787 - INCORRECT AUTO_INCREMENT IDS ISSUED WHEN CLOSE TO ULLONG_MAX
PROBLEM ------- 1) ha_innobase::get_auto_increment() is supposed to return the previous auto inc value if the increment causes overflow ( i.e maximum size of the column) 2) We were not recognizing the maximum value of the column and proceeding to calculate the auto inc value which causes wrong values to be generated. FIX --- 1) Recognize if the increment causes overflow and return the previous auto inc value #rb 27654 Reviewed-by : Debarun Banerjee <debarun.banerjee@oracle.com>
1 parent 46d9054 commit 25ecfe7

File tree

3 files changed

+102
-11
lines changed

3 files changed

+102
-11
lines changed

mysql-test/suite/innodb/r/innodb-autoinc.result

+56
Original file line numberDiff line numberDiff line change
@@ -1525,3 +1525,59 @@ t CREATE TABLE `t` (
15251525
INSERT INTO t(b) VALUES('S4');
15261526
ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
15271527
DROP TABLE t;
1528+
#
1529+
# Bug 26906787 - INCORRECT AUTO_INCREMENT IDS ISSUED WHEN CLOSE TO ULLONG_MAX
1530+
#
1531+
SET auto_increment_increment = 300;
1532+
CREATE TABLE t1 (a BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, b CHAR(8))
1533+
ENGINE=innodb;
1534+
INSERT INTO t1 VALUES (18446744073709551613, 'a');
1535+
SHOW CREATE TABLE t1;
1536+
Table Create Table
1537+
t1 CREATE TABLE `t1` (
1538+
`a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
1539+
`b` char(8) DEFAULT NULL,
1540+
PRIMARY KEY (`a`)
1541+
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551614 DEFAULT CHARSET=latin1
1542+
INSERT INTO t1 VALUES (NULL, 'b');
1543+
ERROR 22003: Out of range value for column 't1' at row 167
1544+
SHOW CREATE TABLE t1;
1545+
Table Create Table
1546+
t1 CREATE TABLE `t1` (
1547+
`a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
1548+
`b` char(8) DEFAULT NULL,
1549+
PRIMARY KEY (`a`)
1550+
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
1551+
DROP TABLE t1;
1552+
CREATE TABLE t1 (
1553+
a BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
1554+
b CHAR(8)
1555+
) ENGINE=innodb
1556+
PARTITION BY RANGE (a) (
1557+
PARTITION p0 VALUES LESS THAN (6),
1558+
PARTITION p1 VALUES LESS THAN MAXVALUE
1559+
);
1560+
INSERT INTO t1 VALUES (18446744073709551613, 'a');
1561+
SHOW CREATE TABLE t1;
1562+
Table Create Table
1563+
t1 CREATE TABLE `t1` (
1564+
`a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
1565+
`b` char(8) DEFAULT NULL,
1566+
PRIMARY KEY (`a`)
1567+
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551614 DEFAULT CHARSET=latin1
1568+
/*!50100 PARTITION BY RANGE (a)
1569+
(PARTITION p0 VALUES LESS THAN (6) ENGINE = InnoDB,
1570+
PARTITION p1 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1571+
INSERT INTO t1 VALUES (NULL, 'b');
1572+
ERROR 22003: Out of range value for column 't1' at row 167
1573+
SHOW CREATE TABLE t1;
1574+
Table Create Table
1575+
t1 CREATE TABLE `t1` (
1576+
`a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
1577+
`b` char(8) DEFAULT NULL,
1578+
PRIMARY KEY (`a`)
1579+
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
1580+
/*!50100 PARTITION BY RANGE (a)
1581+
(PARTITION p0 VALUES LESS THAN (6) ENGINE = InnoDB,
1582+
PARTITION p1 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1583+
DROP TABLE t1;

mysql-test/suite/innodb/t/innodb-autoinc.test

+30
Original file line numberDiff line numberDiff line change
@@ -765,3 +765,33 @@ SHOW CREATE TABLE t;
765765
--error ER_DUP_ENTRY
766766
INSERT INTO t(b) VALUES('S4');
767767
DROP TABLE t;
768+
769+
--echo #
770+
--echo # Bug 26906787 - INCORRECT AUTO_INCREMENT IDS ISSUED WHEN CLOSE TO ULLONG_MAX
771+
--echo #
772+
773+
SET auto_increment_increment = 300;
774+
CREATE TABLE t1 (a BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, b CHAR(8))
775+
ENGINE=innodb;
776+
INSERT INTO t1 VALUES (18446744073709551613, 'a');
777+
SHOW CREATE TABLE t1;
778+
--error ER_WARN_DATA_OUT_OF_RANGE
779+
INSERT INTO t1 VALUES (NULL, 'b');
780+
SHOW CREATE TABLE t1;
781+
DROP TABLE t1;
782+
783+
CREATE TABLE t1 (
784+
a BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
785+
b CHAR(8)
786+
) ENGINE=innodb
787+
PARTITION BY RANGE (a) (
788+
PARTITION p0 VALUES LESS THAN (6),
789+
PARTITION p1 VALUES LESS THAN MAXVALUE
790+
);
791+
INSERT INTO t1 VALUES (18446744073709551613, 'a');
792+
SHOW CREATE TABLE t1;
793+
--error ER_WARN_DATA_OUT_OF_RANGE
794+
INSERT INTO t1 VALUES (NULL, 'b');
795+
SHOW CREATE TABLE t1;
796+
DROP TABLE t1;
797+

storage/innobase/handler/ha_innodb.cc

+16-11
Original file line numberDiff line numberDiff line change
@@ -16812,26 +16812,31 @@ ha_innobase::get_auto_increment(
1681216812

1681316813
(3) It is restricted only for insert operations. */
1681416814

16815+
1681516816
if (increment > 1 && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE
1681616817
&& autoinc < col_max_value) {
1681716818

16818-
ulonglong prev_auto_inc = autoinc;
16819+
ulonglong diff = ULLONG_MAX - autoinc;
16820+
/* Check for overflow */
16821+
if (increment <= diff) {
1681916822

16820-
autoinc = ((autoinc - 1) + increment - offset)/ increment;
16823+
ulonglong prev_auto_inc = autoinc;
1682116824

16822-
autoinc = autoinc * increment + offset;
16825+
autoinc = ((autoinc - 1) + increment - offset)/ increment;
1682316826

16824-
/* If autoinc exceeds the col_max_value then reset
16825-
to old autoinc value. Because in case of non-strict
16826-
sql mode, boundary value is not considered as error. */
16827+
autoinc = autoinc * increment + offset;
1682716828

16828-
if (autoinc >= col_max_value) {
16829-
autoinc = prev_auto_inc;
16830-
}
16829+
/* If autoinc exceeds the col_max_value then reset
16830+
to old autoinc value. Because in case of non-strict
16831+
sql mode, boundary value is not considered as error. */
1683116832

16832-
ut_ad(autoinc > 0);
16833-
}
16833+
if (autoinc >= col_max_value) {
16834+
autoinc = prev_auto_inc;
16835+
}
1683416836

16837+
ut_ad(autoinc > 0);
16838+
}
16839+
}
1683516840
/* Called for the first time ? */
1683616841
if (trx->n_autoinc_rows == 0) {
1683716842

0 commit comments

Comments
 (0)