diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_berkeley.cc | 5 | ||||
-rw-r--r-- | sql/ha_heap.cc | 5 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 3 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 6 | ||||
-rw-r--r-- | sql/ha_myisammrg.cc | 6 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 4 | ||||
-rw-r--r-- | sql/handler.cc | 23 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 |
9 files changed, 44 insertions, 12 deletions
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 72af402a0dc..4209bc93d30 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -953,7 +953,10 @@ int ha_berkeley::write_row(byte * record) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && record == table->record[0]) - update_auto_increment(); + { + if ((error= update_auto_increment())) + DBUG_RETURN(error); + } if ((error=pack_row(&row, record,1))) DBUG_RETURN(error); /* purecov: inspected */ diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 79d4575ff1b..3aaa0287098 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -176,7 +176,10 @@ int ha_heap::write_row(byte * buf) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) - update_auto_increment(); + { + if ((res= update_auto_increment())) + return res; + } res= heap_write(file,buf); if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index c56be6376d0..4e73d4fb285 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3252,7 +3252,8 @@ no_commit: /* We must use the handler code to update the auto-increment value to be sure that we increment it correctly. */ - update_auto_increment(); + if ((error= update_auto_increment())) + goto func_exit; auto_inc_used = 1; } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 128cc191434..f35d7efce0b 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -316,7 +316,11 @@ int ha_myisam::write_row(byte * buf) or a new row, then update the auto_increment value in the record. */ if (table->next_number_field && buf == table->record[0]) - update_auto_increment(); + { + int error; + if ((error= update_auto_increment())) + return error; + } return mi_write(file,buf); } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 0b6e05fcbd4..cb11d9b0452 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -139,7 +139,11 @@ int ha_myisammrg::write_row(byte * buf) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) - update_auto_increment(); + { + int error; + if ((error= update_auto_increment())) + return error; + } return myrg_write(file,buf); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 5d6fe5f984f..d8f33394e1a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2130,9 +2130,11 @@ int ha_ndbcluster::write_row(byte *record) if (has_auto_increment) { THD *thd= table->in_use; + int error; m_skip_auto_increment= FALSE; - update_auto_increment(); + if ((error= update_auto_increment())) + DBUG_RETURN(error); /* Ensure that handler is always called for auto_increment values */ thd->next_insert_id= 0; m_skip_auto_increment= !auto_increment_column_changed; diff --git a/sql/handler.cc b/sql/handler.cc index b0051b02d91..d29ae5e4026 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -429,6 +429,8 @@ static int ha_init_errors(void) SETMSG(HA_ERR_TABLE_DEF_CHANGED, ER(ER_TABLE_DEF_CHANGED)); SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE, ER(ER_TABLE_NEEDS_UPGRADE)); SETMSG(HA_ERR_TABLE_READONLY, ER(ER_OPEN_AS_READONLY)); + SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER(ER_AUTOINC_READ_FAILED)); + SETMSG(HA_ERR_AUTOINC_ERANGE, ER(ER_WARN_DATA_OUT_OF_RANGE)); /* Register the error messages for use with my_error(). */ return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -1542,7 +1544,10 @@ prev_insert_id(ulonglong nr, struct system_variables *variables) RETURN 0 ok - 1 get_auto_increment() was called and returned ~(ulonglong) 0 + HA_ERR_AUTOINC_READ_FAILED + get_auto_increment() was called and returned ~(ulonglong) 0 + HA_ERR_AUTOINC_ERANGE + storing value in field caused strict mode failure. IMPLEMENTATION @@ -1586,13 +1591,12 @@ prev_insert_id(ulonglong nr, struct system_variables *variables) thd->next_insert_id is cleared after it's been used for a statement. */ -bool handler::update_auto_increment() +int handler::update_auto_increment() { ulonglong nr; THD *thd= table->in_use; struct system_variables *variables= &thd->variables; bool auto_increment_field_not_null; - bool result= 0; DBUG_ENTER("handler::update_auto_increment"); /* @@ -1616,7 +1620,7 @@ bool handler::update_auto_increment() if (!(nr= thd->next_insert_id)) { if ((nr= get_auto_increment()) == ~(ulonglong) 0) - result= 1; // Mark failure + DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED); // Mark failure if (variables->auto_increment_increment != 1) nr= next_insert_id(nr-1, variables); @@ -1636,6 +1640,7 @@ bool handler::update_auto_increment() if (likely(!table->next_number_field->store((longlong) nr, TRUE))) thd->insert_id((ulonglong) nr); else + if (thd->killed != THD::KILL_BAD_DATA) /* did we fail strict mode? */ { /* overflow of the field; we'll use the max value, however we try to @@ -1646,6 +1651,8 @@ bool handler::update_auto_increment() if (unlikely(table->next_number_field->store((longlong) nr, TRUE))) thd->insert_id(nr= table->next_number_field->val_int()); } + else + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); /* We can't set next_insert_id if the auto-increment key is not the @@ -1666,7 +1673,7 @@ bool handler::update_auto_increment() /* Mark that we generated a new value */ auto_increment_column_changed=1; - DBUG_RETURN(result); + DBUG_RETURN(0); } /* @@ -1864,6 +1871,12 @@ void handler::print_error(int error, myf errflag) case HA_ERR_TABLE_READONLY: textno= ER_OPEN_AS_READONLY; break; + case HA_ERR_AUTOINC_READ_FAILED: + textno= ER_AUTOINC_READ_FAILED; + break; + case HA_ERR_AUTOINC_ERANGE: + textno= ER_WARN_DATA_OUT_OF_RANGE; + break; default: { /* The error was "unknown" to this function. diff --git a/sql/handler.h b/sql/handler.h index 44de0cc715a..051f5bd31bf 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -565,7 +565,7 @@ public: virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ } int ha_open(const char *name, int mode, int test_if_locked); void adjust_next_insert_id_after_explicit_value(ulonglong nr); - bool update_auto_increment(); + int update_auto_increment(); virtual void print_error(int error, myf errflag); virtual bool get_error_message(int error, String *buf); uint get_dup_key(int error); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index e90f54608e1..94e0d6e0db5 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5623,3 +5623,5 @@ ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA eng "Triggers can not be created on system tables" ER_REMOVED_SPACES eng "Leading spaces are removed from name '%s'" +ER_AUTOINC_READ_FAILED + eng "Failed to read auto-increment value from storage engine" |