Commit ae9752c3 authored by marko's avatar marko

branches/zip: Merge revisions 6471:6538 from branches/5.1:

  ------------------------------------------------------------------------
  r6488 | sunny | 2010-01-21 02:55:08 +0200 (Thu, 21 Jan 2010) | 2 lines
  Changed paths:
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test

  branches/5.1: Factor out test for bug#44030 from innodb-autoinc.test
  into a separate test/result files.
  ------------------------------------------------------------------------
  r6489 | sunny | 2010-01-21 02:57:50 +0200 (Thu, 21 Jan 2010) | 2 lines
  Changed paths:
     A /branches/5.1/mysql-test/innodb-autoinc-44030.result
     A /branches/5.1/mysql-test/innodb-autoinc-44030.test

  branches/5.1: Factor out test for bug#44030 from innodb-autoinc.test
  into a separate test/result files.
  ------------------------------------------------------------------------
  r6492 | sunny | 2010-01-21 09:38:35 +0200 (Thu, 21 Jan 2010) | 1 line
  Changed paths:
     M /branches/5.1/mysql-test/innodb-autoinc-44030.test

  branches/5.1: Add reference to bug#47621 in the comment.
  ------------------------------------------------------------------------
  r6535 | sunny | 2010-01-30 00:08:40 +0200 (Sat, 30 Jan 2010) | 11 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc

  branches/5.1: Undo the change from r6424. We need to return DB_SUCCESS even
  if we were unable to initialize the tabe autoinc value. This is required for
  the open to succeed. The only condition we currently treat as a hard error
  is if the autoinc field instance passed in by MySQL is NULL.

  Previously if the table autoinc value was 0 and the next value was requested
  we had an assertion that would fail. Change that assertion and treat a value
  of 0 to mean that the autoinc system is unavailable. Generation of next
  value will now return failure.

  rb://237
  ------------------------------------------------------------------------
  r6536 | sunny | 2010-01-30 00:13:42 +0200 (Sat, 30 Jan 2010) | 6 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test

  branches/5.1: Check *first_value everytime against the column max
  value and  set *first_value to next autoinc if it's > col max value.
  ie.  not rely on what is passed in from MySQL.

  [49497] Error 1467 (ER_AUTOINC_READ_FAILED) on inserting a negative value
  rb://236
  ------------------------------------------------------------------------
  r6537 | sunny | 2010-01-30 00:35:00 +0200 (Sat, 30 Jan 2010) | 2 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test

  branches/5.1: Undo r6536.
  ------------------------------------------------------------------------
  r6538 | sunny | 2010-01-30 00:43:06 +0200 (Sat, 30 Jan 2010) | 6 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test

  branches/5.1: Check *first_value every time against the column max
  value and  set *first_value to next autoinc if it's > col max value.
  ie.  not rely on what is passed in from MySQL.

  [49497] Error 1467 (ER_AUTOINC_READ_FAILED) on inserting a negative value
  rb://236
  ------------------------------------------------------------------------
parent 01bb13a3
...@@ -3266,9 +3266,9 @@ ha_innobase::innobase_initialize_autoinc() ...@@ -3266,9 +3266,9 @@ ha_innobase::innobase_initialize_autoinc()
auto_inc = innobase_get_int_col_max_value(field); auto_inc = innobase_get_int_col_max_value(field);
} else { } else {
/* We have no idea what's been passed in to us as the /* We have no idea what's been passed in to us as the
autoinc column. We set it to the MAX_INT of our table autoinc column. We set it to the 0, effectively disabling
autoinc type. */ updates to the table. */
auto_inc = 0xFFFFFFFFFFFFFFFFULL; auto_inc = 0;
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Unable to determine the AUTOINC " fprintf(stderr, " InnoDB: Unable to determine the AUTOINC "
...@@ -3277,7 +3277,7 @@ ha_innobase::innobase_initialize_autoinc() ...@@ -3277,7 +3277,7 @@ ha_innobase::innobase_initialize_autoinc()
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
/* If the recovery level is set so high that writes /* If the recovery level is set so high that writes
are disabled we force the AUTOINC counter to the MAX are disabled we force the AUTOINC counter to 0
value effectively disabling writes to the table. value effectively disabling writes to the table.
Secondly, we avoid reading the table in case the read Secondly, we avoid reading the table in case the read
results in failure due to a corrupted table/index. results in failure due to a corrupted table/index.
...@@ -3286,7 +3286,10 @@ ha_innobase::innobase_initialize_autoinc() ...@@ -3286,7 +3286,10 @@ ha_innobase::innobase_initialize_autoinc()
tables can be dumped with minimal hassle. If an error tables can be dumped with minimal hassle. If an error
were returned in this case, the first attempt to read were returned in this case, the first attempt to read
the table would fail and subsequent SELECTs would succeed. */ the table would fail and subsequent SELECTs would succeed. */
auto_inc = 0;
} else if (field == NULL) { } else if (field == NULL) {
/* This is a far more serious error, best to avoid
opening the table and return failure. */
my_error(ER_AUTOINC_READ_FAILED, MYF(0)); my_error(ER_AUTOINC_READ_FAILED, MYF(0));
} else { } else {
dict_index_t* index; dict_index_t* index;
...@@ -3315,7 +3318,7 @@ ha_innobase::innobase_initialize_autoinc() ...@@ -3315,7 +3318,7 @@ ha_innobase::innobase_initialize_autoinc()
"InnoDB: Unable to find the AUTOINC column " "InnoDB: Unable to find the AUTOINC column "
"%s in the InnoDB table %s.\n" "%s in the InnoDB table %s.\n"
"InnoDB: We set the next AUTOINC column " "InnoDB: We set the next AUTOINC column "
"value to the maximum possible value,\n" "value to 0,\n"
"InnoDB: in effect disabling the AUTOINC " "InnoDB: in effect disabling the AUTOINC "
"next value generation.\n" "next value generation.\n"
"InnoDB: You can either set the next " "InnoDB: You can either set the next "
...@@ -3324,7 +3327,13 @@ ha_innobase::innobase_initialize_autoinc() ...@@ -3324,7 +3327,13 @@ ha_innobase::innobase_initialize_autoinc()
"recreating the table.\n", "recreating the table.\n",
col_name, index->table->name); col_name, index->table->name);
my_error(ER_AUTOINC_READ_FAILED, MYF(0)); /* This will disable the AUTOINC generation. */
auto_inc = 0;
/* We want the open to succeed, so that the user can
take corrective action. ie. reads should succeed but
updates should fail. */
err = DB_SUCCESS;
break; break;
default: default:
/* row_search_max_autoinc() should only return /* row_search_max_autoinc() should only return
...@@ -4594,11 +4603,17 @@ ha_innobase::write_row( ...@@ -4594,11 +4603,17 @@ ha_innobase::write_row(
prebuilt->autoinc_error = DB_SUCCESS; prebuilt->autoinc_error = DB_SUCCESS;
if ((error = update_auto_increment())) { if ((error = update_auto_increment())) {
/* We don't want to mask autoinc overflow errors. */ /* We don't want to mask autoinc overflow errors. */
if (prebuilt->autoinc_error != DB_SUCCESS) {
error = (int) prebuilt->autoinc_error;
/* Handle the case where the AUTOINC sub-system
failed during initialization. */
if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
error_result = ER_AUTOINC_READ_FAILED;
/* Set the error message to report too. */
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
goto func_exit;
} else if (prebuilt->autoinc_error != DB_SUCCESS) {
error = (int) prebuilt->autoinc_error;
goto report_error; goto report_error;
} }
...@@ -8954,7 +8969,10 @@ ha_innobase::innobase_get_autoinc( ...@@ -8954,7 +8969,10 @@ ha_innobase::innobase_get_autoinc(
*value = dict_table_autoinc_read(prebuilt->table); *value = dict_table_autoinc_read(prebuilt->table);
/* It should have been initialized during open. */ /* It should have been initialized during open. */
ut_a(*value != 0); if (*value == 0) {
prebuilt->autoinc_error = DB_UNSUPPORTED;
dict_table_autoinc_unlock(prebuilt->table);
}
} }
return(prebuilt->autoinc_error); return(prebuilt->autoinc_error);
...@@ -9034,6 +9052,11 @@ ha_innobase::get_auto_increment( ...@@ -9034,6 +9052,11 @@ ha_innobase::get_auto_increment(
invoking this method. So we are not sure if it's guaranteed to invoking this method. So we are not sure if it's guaranteed to
be 0 or not. */ be 0 or not. */
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
ulonglong col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
/* Called for the first time ? */ /* Called for the first time ? */
if (trx->n_autoinc_rows == 0) { if (trx->n_autoinc_rows == 0) {
...@@ -9050,6 +9073,11 @@ ha_innobase::get_auto_increment( ...@@ -9050,6 +9073,11 @@ ha_innobase::get_auto_increment(
/* Not in the middle of a mult-row INSERT. */ /* Not in the middle of a mult-row INSERT. */
} else if (prebuilt->autoinc_last_value == 0) { } else if (prebuilt->autoinc_last_value == 0) {
set_if_bigger(*first_value, autoinc); set_if_bigger(*first_value, autoinc);
/* Check for -ve values. */
} else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
/* Set to next logical value. */
ut_a(autoinc > trx->n_autoinc_rows);
*first_value = (autoinc - trx->n_autoinc_rows) - 1;
} }
*nb_reserved_values = trx->n_autoinc_rows; *nb_reserved_values = trx->n_autoinc_rows;
...@@ -9060,12 +9088,6 @@ ha_innobase::get_auto_increment( ...@@ -9060,12 +9088,6 @@ ha_innobase::get_auto_increment(
ulonglong need; ulonglong need;
ulonglong current; ulonglong current;
ulonglong next_value; ulonglong next_value;
ulonglong col_max_value;
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
current = *first_value > col_max_value ? autoinc : *first_value; current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment; need = *nb_reserved_values * increment;
......
drop table if exists t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (null);
INSERT INTO t1 VALUES (null);
ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
SELECT * FROM t1;
d1
1
2
SELECT * FROM t1;
d1
1
2
INSERT INTO t1 VALUES(null);
Got one of the listed errors
ALTER TABLE t1 AUTO_INCREMENT = 3;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`d1`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(null);
SELECT * FROM t1;
d1
1
2
3
DROP TABLE t1;
-- 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
#
# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
# the index (PRIMARY)
# This test requires a restart of the server
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (null);
INSERT INTO t1 VALUES (null);
ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
SELECT * FROM t1;
# Restart the server
-- source include/restart_mysqld.inc
# The MySQL and InnoDB data dictionaries should now be out of sync.
# The select should print message to the error log
SELECT * FROM t1;
# MySQL have made a change (http://lists.mysql.com/commits/75268) that no
# longer results in the two data dictionaries being out of sync. If they
# revert their changes then this check for ER_AUTOINC_READ_FAILED will need
# to be enabled. Also, see http://bugs.mysql.com/bug.php?id=47621.
-- error ER_AUTOINC_READ_FAILED,1467
INSERT INTO t1 VALUES(null);
ALTER TABLE t1 AUTO_INCREMENT = 3;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES(null);
SELECT * FROM t1;
DROP TABLE t1;
...@@ -868,35 +868,6 @@ Got one of the listed errors ...@@ -868,35 +868,6 @@ Got one of the listed errors
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (null);
INSERT INTO t1 VALUES (null);
ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
SELECT * FROM t1;
d1
1
2
SELECT * FROM t1;
d1
1
2
INSERT INTO t1 VALUES(null);
Got one of the listed errors
ALTER TABLE t1 AUTO_INCREMENT = 3;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`d1`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(null);
SELECT * FROM t1;
d1
1
2
3
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SHOW VARIABLES LIKE "%auto_inc%"; SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value Variable_name Value
auto_increment_increment 1 auto_increment_increment 1
...@@ -1190,3 +1161,86 @@ t1 CREATE TABLE `t1` ( ...@@ -1190,3 +1161,86 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`) PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (-685113344), (1), (NULL), (NULL);
SELECT * FROM t1;
c1
-685113344
1
2
3
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (-685113344), (2), (NULL), (NULL);
SELECT * FROM t1;
c1
-685113344
2
3
4
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (NULL);
INSERT INTO t1 VALUES (4), (5), (6), (NULL);
SELECT * FROM t1;
c1
-685113344
1
2
3
4
5
6
7
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (5);
SELECT * FROM t1;
c1
-685113344
1
2
5
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL);
SELECT * FROM t1;
c1
-685113344
1
2
3
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
DROP TABLE t1;
...@@ -478,28 +478,6 @@ INSERT INTO t2 SELECT c1 FROM t1; ...@@ -478,28 +478,6 @@ INSERT INTO t2 SELECT c1 FROM t1;
INSERT INTO t2 SELECT NULL FROM t1; INSERT INTO t2 SELECT NULL FROM t1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
#
# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
# the index (PRIMARY)
# This test requires a restart of the server
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (null);
INSERT INTO t1 VALUES (null);
ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
SELECT * FROM t1;
# Restart the server
-- source include/restart_mysqld.inc
# The MySQL and InnoDB data dictionaries should now be out of sync.
# The select should print message to the error log
SELECT * FROM t1;
-- error ER_AUTOINC_READ_FAILED,1467
INSERT INTO t1 VALUES(null);
ALTER TABLE t1 AUTO_INCREMENT = 3;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES(null);
SELECT * FROM t1;
DROP TABLE t1;
# If the user has specified negative values for an AUTOINC column then # If the user has specified negative values for an AUTOINC column then
# InnoDB should ignore those values when setting the table's max value. # InnoDB should ignore those values when setting the table's max value.
...@@ -653,3 +631,34 @@ REPLACE INTO t1 VALUES (-1); ...@@ -653,3 +631,34 @@ REPLACE INTO t1 VALUES (-1);
SELECT * FROM t1; SELECT * FROM t1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
##
# 49497: Error 1467 (ER_AUTOINC_READ_FAILED) on inserting a negative value
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (-685113344), (1), (NULL), (NULL);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (-685113344), (2), (NULL), (NULL);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (NULL);
INSERT INTO t1 VALUES (4), (5), (6), (NULL);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (5);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
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