summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc112
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 */