From a348cac442de9f401b045477cb8f59df2645c51b Mon Sep 17 00:00:00 2001 From: sunny Date: Thu, 23 Oct 2008 05:29:46 +0000 Subject: [PATCH] branches/zip: Merge revisions 2837:2852 from branches/5.1: ------------------------------------------------------------------------ r2849 | sunny | 2008-10-22 12:01:18 +0300 (Wed, 22 Oct 2008) | 8 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/include/row0mysql.h M /branches/5.1/row/row0mysql.c branches/5.1: Return the actual error code encountered when allocating a new autoinc value. The change in behavior (bug) was introduced in 5.1.22 when we introduced the new AUTOINC locking model. rb://31 Bug#40224 New AUTOINC changes mask reporting of deadlock/timeout errors ------------------------------------------------------------------------ r2852 | sunny | 2008-10-23 01:42:24 +0300 (Thu, 23 Oct 2008) | 9 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/handler/ha_innodb.h branches/5.1: Backport r2724 from branches/zip Check column value against the col max value before updating the table's global autoinc counter value. This is part of simplifying the AUTOINC sub-system. We extract the type info from MySQL data structures at runtime. This fixes Bug#37788 InnoDB Plugin: AUTO_INCREMENT wrong for compressed tables ------------------------------------------------------------------------ --- handler/ha_innodb.cc | 54 +++++++++++++--------------------- include/row0mysql.h | 5 ++++ mysql-test/innodb-index.result | 7 ----- mysql-test/innodb-index.test | 10 ------- row/row0mysql.c | 1 + 5 files changed, 27 insertions(+), 50 deletions(-) diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index e36b09865c6..c79084f8fc7 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -1136,7 +1136,9 @@ innobase_next_autoinc( /* Should never be 0. */ ut_a(increment > 0); - if (offset <= 1) { + if (current >= max_value) { + next_value = max_value; + } else if (offset <= 1) { /* Offset 0 and 1 are the same, because there must be at least one node in the system. */ if (max_value - current <= increment) { @@ -4138,8 +4140,20 @@ no_commit: /* This is the case where the table has an auto-increment column */ if (table->next_number_field && record == table->record[0]) { + /* Reset the error code before calling + innobase_get_auto_increment(). */ + prebuilt->autoinc_error = DB_SUCCESS; + if ((error = update_auto_increment())) { + /* We don't want to mask autoinc overflow errors. */ + if (prebuilt->autoinc_error != DB_SUCCESS) { + error = prebuilt->autoinc_error; + + goto report_error; + } + + /* MySQL errors are passed straight back. */ goto func_exit; } @@ -4241,6 +4255,7 @@ set_max_autoinc: innodb_srv_conc_exit_innodb(prebuilt->trx); +report_error: error = convert_error_code_to_mysql(error, prebuilt->table->flags, user_thd); @@ -8371,49 +8386,22 @@ ha_innobase::innobase_get_autoinc( /* out: DB_SUCCESS or error code */ ulonglong* value) /* out: autoinc value */ { - ulint error; - *value = 0; - error = innobase_lock_autoinc(); + prebuilt->autoinc_error = innobase_lock_autoinc(); - if (error == DB_SUCCESS) { + if (prebuilt->autoinc_error == DB_SUCCESS) { /* Determine the first value of the interval */ *value = dict_table_autoinc_read(prebuilt->table); /* It should have been initialized during open. */ ut_a(*value != 0); - - /* We need to send the messages to the client because - handler::get_auto_increment() doesn't allow a way - to return the specific error for why it failed. */ - } else if (error == DB_DEADLOCK) { - THD* thd = ha_thd(); - - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_LOCK_DEADLOCK, - "InnoDB: Deadlock in " - "innobase_get_autoinc()"); - } else if (error == DB_LOCK_WAIT_TIMEOUT) { - THD* thd = ha_thd(); - - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_LOCK_WAIT_TIMEOUT, - "InnoDB: Lock wait timeout in " - "innobase_get_autoinc()"); - } else { - sql_print_error( - "InnoDB: Error: %lu in " - "innobase_get_autoinc()", - error); } - - return(error); + + return(prebuilt->autoinc_error); } - + /*********************************************************************** This function reads the global auto-inc counter. It doesn't use the AUTOINC lock even if the lock mode is set to TRADITIONAL. */ diff --git a/include/row0mysql.h b/include/row0mysql.h index 7a361c99070..579414715fe 100644 --- a/include/row0mysql.h +++ b/include/row0mysql.h @@ -707,6 +707,11 @@ struct row_prebuilt_struct { ulonglong autoinc_offset; /* The offset passed to get_auto_increment() by MySQL. Required to calculate the next value */ + ulint autoinc_error; /* The actual error code encountered + while trying to init or read the + autoinc value from the table. We + store it here so that we can return + it to MySQL */ /*----------------------*/ UT_LIST_NODE_T(row_prebuilt_t) prebuilts; /* list node of table->prebuilts */ diff --git a/mysql-test/innodb-index.result b/mysql-test/innodb-index.result index 21e15705b33..91a9387a0a8 100644 --- a/mysql-test/innodb-index.result +++ b/mysql-test/innodb-index.result @@ -46,13 +46,6 @@ t1 CREATE TABLE `t1` ( KEY `d2` (`d`), KEY `b` (`b`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB; -alter table t1 add unique index (c), add index (d); -ERROR HY000: Table 'test.t1#1' already exists -rename table `t1#1` to `t1#2`; -alter table t1 add unique index (c), add index (d); -ERROR HY000: Table 'test.t1#2' already exists -drop table `t1#2`; alter table t1 add unique index (c), add index (d); show create table t1; Table Create Table diff --git a/mysql-test/innodb-index.test b/mysql-test/innodb-index.test index 07f709eee38..d421530bf03 100644 --- a/mysql-test/innodb-index.test +++ b/mysql-test/innodb-index.test @@ -17,16 +17,6 @@ show create table t1; alter table t1 add index (b); show create table t1; -# Check how existing tables interfere with temporary tables. -CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB; - ---error 156 -alter table t1 add unique index (c), add index (d); -rename table `t1#1` to `t1#2`; ---error 156 -alter table t1 add unique index (c), add index (d); -drop table `t1#2`; - alter table t1 add unique index (c), add index (d); show create table t1; explain select * from t1 force index(c) order by c; diff --git a/row/row0mysql.c b/row/row0mysql.c index 4daebba16fa..ef2d45a37d5 100644 --- a/row/row0mysql.c +++ b/row/row0mysql.c @@ -625,6 +625,7 @@ row_create_prebuilt( prebuilt->clust_ref = ref; + prebuilt->autoinc_error = 0; prebuilt->autoinc_offset = 0; /* Default to 1, we will set the actual value later in