Commit 30aadd6b authored by Aditya A's avatar Aditya A

Bug#14145950 AUTO_INCREMENT ON DOUBLE WILL FAIL ON WINDOWS

Backport from mysql-5.6 the fix
(revision-id sunny.bains@oracle.com-20120315045831-20rgfa4cozxmz7kz)

  Bug#13839886 - CRASH IN INNOBASE_NEXT_AUTOINC
  
  The assertion introduce in the fix for Bug#13817703 
  is too strong, a negative  number can be greater 
  than the column max value, when the column value is
  a negative number.
  
  rb://978 Approved by Jimmy Yang.

rb:1236 approved by Marko Makela
parent 42827de4
......@@ -1269,3 +1269,91 @@ SELECT * FROM t1;
c1 c2
1 NULL
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (2147483648, 'a');
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(10) unsigned NOT NULL AUTO_INCREMENT,
`c2` varchar(10) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=2147483649 DEFAULT CHARSET=latin1
SELECT * FROM t1;
c1 c2
2147483648 a
ALTER TABLE t1 CHANGE c1 c1 INT;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL DEFAULT '0',
`c2` varchar(10) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO t1(c2) VALUES('b');
SELECT * FROM t1;
c1 c2
0 b
2147483647 a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL DEFAULT '0',
`c2` varchar(10) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY, c2 INT) ENGINE = MyISAM;
INSERT INTO t1 (c1) VALUES (NULL), (-290783232), (NULL);
Warnings:
Warning 1264 Out of range value for column 'c1' at row 3
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=MyISAM AUTO_INCREMENT=2147483648 DEFAULT CHARSET=latin1
SELECT * FROM t1;
c1 c2
1 NULL
-290783232 NULL
2147483647 NULL
ALTER TABLE t1 ENGINE = InnoDB;
SELECT * FROM t1;
c1 c2
-290783232 NULL
1 NULL
2147483647 NULL
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=2147483648 DEFAULT CHARSET=latin1
REPLACE INTO t1 (c2 ) VALUES (0);
ERROR HY000: Failed to read auto-increment value from storage engine
SELECT * FROM t1;
c1 c2
-290783232 NULL
1 NULL
2147483647 NULL
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
AUTO_INCREMENT=10000000000000000000;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` double NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000 DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ();
ERROR HY000: Failed to read auto-increment value from storage engine
DROP TABLE t1;
......@@ -139,7 +139,7 @@ DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1);
INSERT INTO t1 VALUES (2,1);
INSERT INTO t1 VALUES (NULL,8);
SELECT * FROM t1;
DROP TABLE t1;
......@@ -639,7 +639,7 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
# Check if we handl offset > column max value properly
# Check if we handle offset > column max value properly
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=256;
SHOW VARIABLES LIKE "%auto_inc%";
# TINYINT
......@@ -648,3 +648,40 @@ INSERT INTO t1 VALUES (1, NULL);
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;
# Check if we handle the case where a current value is greater than the max
# of the column. IMO, this should not be allowed and the assertion that fails
# is actually an invariant.
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SHOW VARIABLES LIKE "%auto_inc%";
# TINYINT
CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (2147483648, 'a');
SHOW CREATE TABLE t1;
SELECT * FROM t1;
ALTER TABLE t1 CHANGE c1 c1 INT;
SHOW CREATE TABLE t1;
INSERT INTO t1(c2) VALUES('b');
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY, c2 INT) ENGINE = MyISAM;
INSERT INTO t1 (c1) VALUES (NULL), (-290783232), (NULL);
SHOW CREATE TABLE t1;
SELECT * FROM t1;
ALTER TABLE t1 ENGINE = InnoDB;
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--error ER_AUTOINC_READ_FAILED
REPLACE INTO t1 (c2 ) VALUES (0);
SELECT * FROM t1;
DROP TABLE t1;
#DOUBLE
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
AUTO_INCREMENT=10000000000000000000;
SHOW CREATE TABLE t1;
--error 1467
INSERT INTO t1 VALUES ();
DROP TABLE t1;
......@@ -1473,19 +1473,19 @@ innobase_next_autoinc(
ut_a(block > 0);
ut_a(max_value > 0);
/* Current value should never be greater than the maximum. */
ut_a(current <= max_value);
/* According to MySQL documentation, if the offset is greater than
the step then the offset is ignored. */
if (offset > block) {
offset = 0;
}
/* Check for overflow. */
/* Check for overflow. Current can be > max_value if the value is
in reality a negative value.The visual studio compilers converts
large double values automatically into unsigned long long datatype
maximum value */
if (block >= max_value
|| offset > max_value
|| current == max_value
|| current >= max_value
|| max_value - offset <= offset) {
next_value = max_value;
......
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