diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 112 |
1 files changed, 96 insertions, 16 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index a9688fb96b4..914a4dc07b1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -11,8 +11,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ /** @file handler.cc @@ -210,6 +210,40 @@ redo: } +bool +Storage_engine_name::resolve_storage_engine_with_error(THD *thd, + handlerton **ha, + bool tmp_table) +{ +#if MYSQL_VERSION_ID < 100300 + /* + Please remove tmp_name when merging to 10.3 and pass m_storage_engine_name + directly to ha_resolve_by_name(). + */ + LEX_STRING tmp_name; + tmp_name.str= const_cast<char*>(m_storage_engine_name.str); + tmp_name.length= m_storage_engine_name.length; +#endif + if (plugin_ref plugin= ha_resolve_by_name(thd, &tmp_name, tmp_table)) + { + *ha= plugin_hton(plugin); + return false; + } + + *ha= NULL; + if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION) + { + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), m_storage_engine_name.str); + return true; + } + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_UNKNOWN_STORAGE_ENGINE, + ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE), + m_storage_engine_name.str); + return false; +} + + plugin_ref ha_lock_engine(THD *thd, const handlerton *hton) { if (hton) @@ -1996,6 +2030,7 @@ int ha_recover(HASH *commit_list) for (info.len= MAX_XID_LIST_SIZE ; info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2) { + DBUG_EXECUTE_IF("min_xa_len", info.len = 16;); info.list=(XID *)my_malloc(info.len*sizeof(XID), MYF(0)); } if (!info.list) @@ -2648,8 +2683,7 @@ int handler::ha_rnd_pos(uchar *buf, uchar *pos) DBUG_ENTER("handler::ha_rnd_pos"); DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || m_lock_type != F_UNLCK); - /* TODO: Find out how to solve ha_rnd_pos when finding duplicate update. */ - /* DBUG_ASSERT(inited == RND); */ + DBUG_ASSERT(inited == RND); TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0, { result= rnd_pos(buf, pos); }) @@ -2902,11 +2936,17 @@ compute_next_insert_id(ulonglong nr,struct system_variables *variables) nr= nr + 1; // optimization of the formula below else { - nr= (((nr+ variables->auto_increment_increment - - variables->auto_increment_offset)) / - (ulonglong) variables->auto_increment_increment); - nr= (nr* (ulonglong) variables->auto_increment_increment + - variables->auto_increment_offset); + /* + Calculating the number of complete auto_increment_increment extents: + */ + nr= (nr + variables->auto_increment_increment - + variables->auto_increment_offset) / + (ulonglong) variables->auto_increment_increment; + /* + Adding an offset to the auto_increment_increment extent boundary: + */ + nr= nr * (ulonglong) variables->auto_increment_increment + + variables->auto_increment_offset; } if (unlikely(nr <= save_nr)) @@ -2960,8 +3000,14 @@ prev_insert_id(ulonglong nr, struct system_variables *variables) } if (variables->auto_increment_increment == 1) return nr; // optimization of the formula below - nr= (((nr - variables->auto_increment_offset)) / - (ulonglong) variables->auto_increment_increment); + /* + Calculating the number of complete auto_increment_increment extents: + */ + nr= (nr - variables->auto_increment_offset) / + (ulonglong) variables->auto_increment_increment; + /* + Adding an offset to the auto_increment_increment extent boundary: + */ return (nr * (ulonglong) variables->auto_increment_increment + variables->auto_increment_offset); } @@ -3184,10 +3230,32 @@ int handler::update_auto_increment() if (unlikely(tmp)) // Out of range value in store { /* - It's better to return an error here than getting a confusing - 'duplicate key error' later. + First, test if the query was aborted due to strict mode constraints + or new field value greater than maximum integer value: */ - result= HA_ERR_AUTOINC_ERANGE; + if (thd->killed == KILL_BAD_DATA || + nr > table->next_number_field->get_max_int_value()) + { + /* + It's better to return an error here than getting a confusing + 'duplicate key error' later. + */ + result= HA_ERR_AUTOINC_ERANGE; + } + else + { + /* + Field refused this value (overflow) and truncated it, use the result + of the truncation (which is going to be inserted); however we try to + decrease it to honour auto_increment_* variables. + That will shift the left bound of the reserved interval, we don't + bother shifting the right bound (anyway any other value from this + interval will cause a duplicate key). + */ + nr= prev_insert_id(table->next_number_field->val_int(), variables); + if (unlikely(table->next_number_field->store((longlong)nr, TRUE))) + nr= table->next_number_field->val_int(); + } } if (append) { @@ -3273,6 +3341,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nr; int error; MY_BITMAP *old_read_set; + bool rnd_inited= (inited == RND); + + if (rnd_inited && ha_rnd_end()) + return; old_read_set= table->prepare_for_keyread(table->s->next_number_index); @@ -3282,6 +3354,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, DBUG_ASSERT(0); (void) extra(HA_EXTRA_NO_KEYREAD); *first_value= ULONGLONG_MAX; + if (rnd_inited && ha_rnd_init_with_error(0)) + { + //TODO: it would be nice to return here an error + } return; } @@ -3328,6 +3404,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, ha_index_end(); table->restore_column_maps_after_keyread(old_read_set); *first_value= nr; + if (rnd_inited && ha_rnd_init_with_error(0)) + { + //TODO: it would be nice to return here an error + } return; } @@ -5984,8 +6064,8 @@ int handler::ha_reset() table->default_column_bitmaps(); pushed_cond= NULL; tracker= NULL; - mark_trx_read_write_done= check_table_binlog_row_based_done= - check_table_binlog_row_based_result= 0; + mark_trx_read_write_done= 0; + clear_cached_table_binlog_row_based_flag(); /* Reset information about pushed engine conditions */ cancel_pushed_idx_cond(); /* Reset information about pushed index conditions */ |