summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-04-27 08:08:06 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-04-27 08:08:06 +0300
commit44a27a26e910c9fb27731bd2cb267262949ea2da (patch)
tree196e64e99f192469aef887b0856795755a88db40
parentf21a87560091a8149752b13e097d382ba30786d2 (diff)
downloadmariadb-git-44a27a26e910c9fb27731bd2cb267262949ea2da.tar.gz
MDEV-28416 Incorrect AUTO_INCREMENT may be issued when close to UINT64_MAX
ha_innobase::get_auto_increment(): In the overflow check, account for 64-bit unsigned integer wrap-around. Based on mysql/mysql-server@25ecfe7f49b5a649e96d462cb90602de9de3b919
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc-part.result34
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc.result25
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc-part.test24
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc.test23
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
5 files changed, 101 insertions, 9 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc-part.result b/mysql-test/suite/innodb/r/innodb-autoinc-part.result
new file mode 100644
index 00000000000..6872b5e02f5
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-autoinc-part.result
@@ -0,0 +1,34 @@
+#
+# MDEV-28416 Incorrect AUTO_INCREMENT may be issued
+#
+SET @aii=@@auto_increment_increment;
+SET auto_increment_increment=300;
+CREATE TABLE t1 (a SERIAL) ENGINE=innodb
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (6),
+PARTITION p1 VALUES LESS THAN MAXVALUE
+);
+INSERT INTO t1 VALUES (18446744073709551613);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551614 DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`a`)
+(PARTITION `p0` VALUES LESS THAN (6) ENGINE = InnoDB,
+ PARTITION `p1` VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
+INSERT INTO t1 VALUES (NULL);
+ERROR 22003: Out of range value for column 'a' at row 1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=298 DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`a`)
+(PARTITION `p0` VALUES LESS THAN (6) ENGINE = InnoDB,
+ PARTITION `p1` VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
+DROP TABLE t1;
+SET auto_increment_increment=@aii;
+# End of 10.2 tests
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result
index 6c405627e08..00690ecaff7 100644
--- a/mysql-test/suite/innodb/r/innodb-autoinc.result
+++ b/mysql-test/suite/innodb/r/innodb-autoinc.result
@@ -1,4 +1,3 @@
-drop table if exists t1;
CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (9223372036854775807, null);
INSERT INTO t1 (c2) VALUES ('innodb');
@@ -1619,3 +1618,27 @@ id name
-1 dog
2 cat
DROP PROCEDURE autoinc_mdev15353_one;
+#
+# MDEV-28416 Incorrect AUTO_INCREMENT may be issued
+#
+SET @aii=@@auto_increment_increment;
+SET auto_increment_increment=300;
+CREATE TABLE t1 (a SERIAL) ENGINE=innodb;
+INSERT INTO t1 VALUES (18446744073709551613);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551614 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (NULL);
+ERROR 22003: Out of range value for column 'a' at row 1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET auto_increment_increment=@aii;
+# End of 10.2 tests
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-part.test b/mysql-test/suite/innodb/t/innodb-autoinc-part.test
new file mode 100644
index 00000000000..100546704ce
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-autoinc-part.test
@@ -0,0 +1,24 @@
+--source include/have_partition.inc
+--source include/have_innodb.inc
+
+--echo #
+--echo # MDEV-28416 Incorrect AUTO_INCREMENT may be issued
+--echo #
+
+SET @aii=@@auto_increment_increment;
+SET auto_increment_increment=300;
+
+CREATE TABLE t1 (a SERIAL) ENGINE=innodb
+PARTITION BY RANGE (a) (
+ PARTITION p0 VALUES LESS THAN (6),
+ PARTITION p1 VALUES LESS THAN MAXVALUE
+);
+INSERT INTO t1 VALUES (18446744073709551613);
+SHOW CREATE TABLE t1;
+--error HA_ERR_AUTOINC_ERANGE
+INSERT INTO t1 VALUES (NULL);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET auto_increment_increment=@aii;
+
+--echo # End of 10.2 tests
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test
index ca7727d4cef..158460558d5 100644
--- a/mysql-test/suite/innodb/t/innodb-autoinc.test
+++ b/mysql-test/suite/innodb/t/innodb-autoinc.test
@@ -1,10 +1,4 @@
--source include/have_innodb.inc
-# embedded server ignores 'delayed', so skip this
--- source include/not_embedded.inc
-
---disable_warnings
-drop table if exists t1;
---enable_warnings
#
# Bug #34335
@@ -770,3 +764,20 @@ DROP TABLE t1;
SET @engine='INNODB';
--source include/autoinc_mdev15353.inc
+
+--echo #
+--echo # MDEV-28416 Incorrect AUTO_INCREMENT may be issued
+--echo #
+
+SET @aii=@@auto_increment_increment;
+SET auto_increment_increment=300;
+CREATE TABLE t1 (a SERIAL) ENGINE=innodb;
+INSERT INTO t1 VALUES (18446744073709551613);
+SHOW CREATE TABLE t1;
+--error HA_ERR_AUTOINC_ERANGE
+INSERT INTO t1 VALUES (NULL);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET auto_increment_increment=@aii;
+
+--echo # End of 10.2 tests
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 1884250ee48..53d5a07b79f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -16970,8 +16970,8 @@ ha_innobase::get_auto_increment(
(3) It is restricted only for insert operations. */
- if (increment > 1 && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE
- && autoinc < col_max_value) {
+ if (increment > 1 && increment <= ~autoinc && autoinc < col_max_value
+ && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE) {
ulonglong prev_auto_inc = autoinc;