Commit a348cac4 authored by sunny's avatar sunny

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
  
  
  ------------------------------------------------------------------------
parent 89f39b27
...@@ -1136,7 +1136,9 @@ innobase_next_autoinc( ...@@ -1136,7 +1136,9 @@ innobase_next_autoinc(
/* Should never be 0. */ /* Should never be 0. */
ut_a(increment > 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 /* Offset 0 and 1 are the same, because there must be at
least one node in the system. */ least one node in the system. */
if (max_value - current <= increment) { if (max_value - current <= increment) {
...@@ -4138,8 +4140,20 @@ no_commit: ...@@ -4138,8 +4140,20 @@ no_commit:
/* This is the case where the table has an auto-increment column */ /* This is the case where the table has an auto-increment column */
if (table->next_number_field && record == table->record[0]) { 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())) { 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; goto func_exit;
} }
...@@ -4241,6 +4255,7 @@ set_max_autoinc: ...@@ -4241,6 +4255,7 @@ set_max_autoinc:
innodb_srv_conc_exit_innodb(prebuilt->trx); innodb_srv_conc_exit_innodb(prebuilt->trx);
report_error:
error = convert_error_code_to_mysql(error, prebuilt->table->flags, error = convert_error_code_to_mysql(error, prebuilt->table->flags,
user_thd); user_thd);
...@@ -8371,49 +8386,22 @@ ha_innobase::innobase_get_autoinc( ...@@ -8371,49 +8386,22 @@ ha_innobase::innobase_get_autoinc(
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
ulonglong* value) /* out: autoinc value */ ulonglong* value) /* out: autoinc value */
{ {
ulint error;
*value = 0; *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 */ /* Determine the first value of the interval */
*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); 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 This function reads the global auto-inc counter. It doesn't use the
AUTOINC lock even if the lock mode is set to TRADITIONAL. */ AUTOINC lock even if the lock mode is set to TRADITIONAL. */
......
...@@ -707,6 +707,11 @@ struct row_prebuilt_struct { ...@@ -707,6 +707,11 @@ struct row_prebuilt_struct {
ulonglong autoinc_offset; /* The offset passed to ulonglong autoinc_offset; /* The offset passed to
get_auto_increment() by MySQL. Required get_auto_increment() by MySQL. Required
to calculate the next value */ 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; UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
/* list node of table->prebuilts */ /* list node of table->prebuilts */
......
...@@ -46,13 +46,6 @@ t1 CREATE TABLE `t1` ( ...@@ -46,13 +46,6 @@ t1 CREATE TABLE `t1` (
KEY `d2` (`d`), KEY `d2` (`d`),
KEY `b` (`b`) KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) 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); alter table t1 add unique index (c), add index (d);
show create table t1; show create table t1;
Table Create Table Table Create Table
......
...@@ -17,16 +17,6 @@ show create table t1; ...@@ -17,16 +17,6 @@ show create table t1;
alter table t1 add index (b); alter table t1 add index (b);
show create table t1; 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); alter table t1 add unique index (c), add index (d);
show create table t1; show create table t1;
explain select * from t1 force index(c) order by c; explain select * from t1 force index(c) order by c;
......
...@@ -625,6 +625,7 @@ row_create_prebuilt( ...@@ -625,6 +625,7 @@ row_create_prebuilt(
prebuilt->clust_ref = ref; prebuilt->clust_ref = ref;
prebuilt->autoinc_error = 0;
prebuilt->autoinc_offset = 0; prebuilt->autoinc_offset = 0;
/* Default to 1, we will set the actual value later in /* Default to 1, we will set the actual value later in
......
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