mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
10.0-base -> 10.0-monty
This commit is contained in:
130
sql/handler.cc
130
sql/handler.cc
@ -642,6 +642,43 @@ void ha_checkpoint_state(bool disable)
|
||||
}
|
||||
|
||||
|
||||
struct st_commit_checkpoint_request {
|
||||
void *cookie;
|
||||
void (*pre_hook)(void *);
|
||||
};
|
||||
|
||||
static my_bool commit_checkpoint_request_handlerton(THD *unused1, plugin_ref plugin,
|
||||
void *data)
|
||||
{
|
||||
st_commit_checkpoint_request *st= (st_commit_checkpoint_request *)data;
|
||||
handlerton *hton= plugin_data(plugin, handlerton *);
|
||||
if (hton->state == SHOW_OPTION_YES && hton->commit_checkpoint_request)
|
||||
{
|
||||
void *cookie= st->cookie;
|
||||
if (st->pre_hook)
|
||||
(*st->pre_hook)(cookie);
|
||||
(*hton->commit_checkpoint_request)(hton, cookie);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Invoke commit_checkpoint_request() in all storage engines that implement it.
|
||||
|
||||
If pre_hook is non-NULL, the hook will be called prior to each invocation.
|
||||
*/
|
||||
void
|
||||
ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *))
|
||||
{
|
||||
st_commit_checkpoint_request st;
|
||||
st.cookie= cookie;
|
||||
st.pre_hook= pre_hook;
|
||||
plugin_foreach(NULL, commit_checkpoint_request_handlerton,
|
||||
MYSQL_STORAGE_ENGINE_PLUGIN, &st);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
|
||||
void *unused)
|
||||
@ -1287,11 +1324,13 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
goto done;
|
||||
}
|
||||
|
||||
DEBUG_SYNC(thd, "ha_commit_trans_before_log_and_order");
|
||||
cookie= tc_log->log_and_order(thd, xid, all, need_prepare_ordered,
|
||||
need_commit_ordered);
|
||||
if (!cookie)
|
||||
goto err;
|
||||
|
||||
DEBUG_SYNC(thd, "ha_commit_trans_after_log_and_order");
|
||||
DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
|
||||
|
||||
error= commit_one_phase_2(thd, all, trans, is_real_trans) ? 2 : 0;
|
||||
@ -1783,6 +1822,17 @@ bool mysql_xa_recover(THD *thd)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Called by engine to notify TC that a new commit checkpoint has been reached.
|
||||
See comments on handlerton method commit_checkpoint_request() for details.
|
||||
*/
|
||||
void
|
||||
commit_checkpoint_notify_ha(handlerton *hton, void *cookie)
|
||||
{
|
||||
tc_log->commit_checkpoint_notify(cookie);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@details
|
||||
This function should be called when MySQL sends rows of a SELECT result set
|
||||
@ -2698,6 +2748,8 @@ int handler::update_auto_increment()
|
||||
bool append= FALSE;
|
||||
THD *thd= table->in_use;
|
||||
struct system_variables *variables= &thd->variables;
|
||||
int result=0, tmp;
|
||||
enum enum_check_fields save_count_cuted_fields;
|
||||
DBUG_ENTER("handler::update_auto_increment");
|
||||
|
||||
/*
|
||||
@ -2715,8 +2767,10 @@ int handler::update_auto_increment()
|
||||
statement (case of INSERT VALUES(null),(3763),(null):
|
||||
the last NULL needs to insert 3764, not the value of the first NULL plus
|
||||
1).
|
||||
Ignore negative values.
|
||||
*/
|
||||
adjust_next_insert_id_after_explicit_value(nr);
|
||||
if ((longlong) nr > 0 || (table->next_number_field->flags & UNSIGNED_FLAG))
|
||||
adjust_next_insert_id_after_explicit_value(nr);
|
||||
insert_id_for_cur_row= 0; // didn't generate anything
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@ -2750,8 +2804,19 @@ int handler::update_auto_increment()
|
||||
reservation means potentially losing unused values).
|
||||
Note that in prelocked mode no estimation is given.
|
||||
*/
|
||||
|
||||
if ((auto_inc_intervals_count == 0) && (estimation_rows_to_insert > 0))
|
||||
nb_desired_values= estimation_rows_to_insert;
|
||||
else if ((auto_inc_intervals_count == 0) &&
|
||||
(thd->lex->many_values.elements > 0))
|
||||
{
|
||||
/*
|
||||
For multi-row inserts, if the bulk inserts cannot be started, the
|
||||
handler::estimation_rows_to_insert will not be set. But we still
|
||||
want to reserve the autoinc values.
|
||||
*/
|
||||
nb_desired_values= thd->lex->many_values.elements;
|
||||
}
|
||||
else /* go with the increasing defaults */
|
||||
{
|
||||
/* avoid overflow in formula, with this if() */
|
||||
@ -2764,7 +2829,6 @@ int handler::update_auto_increment()
|
||||
else
|
||||
nb_desired_values= AUTO_INC_DEFAULT_NB_MAX;
|
||||
}
|
||||
/* This call ignores all its parameters but nr, currently */
|
||||
get_auto_increment(variables->auto_increment_offset,
|
||||
variables->auto_increment_increment,
|
||||
nb_desired_values, &nr,
|
||||
@ -2801,29 +2865,24 @@ int handler::update_auto_increment()
|
||||
}
|
||||
|
||||
if (unlikely(nr == ULONGLONG_MAX))
|
||||
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
|
||||
|
||||
DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr));
|
||||
|
||||
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
|
||||
{
|
||||
/*
|
||||
first test if the query was aborted due to strict mode constraints
|
||||
*/
|
||||
if (killed_mask_hard(thd->killed) == KILL_BAD_DATA)
|
||||
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
|
||||
|
||||
DBUG_PRINT("info",("auto_increment: %llu nb_reserved_values: %llu",
|
||||
nr, nb_reserved_values));
|
||||
|
||||
/* Store field without warning (Warning will be printed by insert) */
|
||||
save_count_cuted_fields= thd->count_cuted_fields;
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
tmp= table->next_number_field->store((longlong) nr, TRUE);
|
||||
thd->count_cuted_fields= save_count_cuted_fields;
|
||||
|
||||
if (unlikely(tmp)) // Out of range value in store
|
||||
{
|
||||
/*
|
||||
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).
|
||||
It's better to return an error here than getting a confusing
|
||||
'duplicate key error' later.
|
||||
*/
|
||||
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();
|
||||
result= HA_ERR_AUTOINC_ERANGE;
|
||||
}
|
||||
if (append)
|
||||
{
|
||||
@ -2845,6 +2904,10 @@ int handler::update_auto_increment()
|
||||
already set.
|
||||
*/
|
||||
insert_id_for_cur_row= nr;
|
||||
|
||||
if (result) // overflow
|
||||
DBUG_RETURN(result);
|
||||
|
||||
/*
|
||||
Set next insert id to point to next auto-increment value to be able to
|
||||
handle multi-row statements.
|
||||
@ -2968,7 +3031,7 @@ void handler::ha_release_auto_increment()
|
||||
}
|
||||
|
||||
|
||||
void handler::print_keydup_error(uint key_nr, const char *msg)
|
||||
void handler::print_keydup_error(uint key_nr, const char *msg, myf errflag)
|
||||
{
|
||||
/* Write the duplicated key in the error message */
|
||||
char key[MAX_KEY_LENGTH];
|
||||
@ -2978,7 +3041,7 @@ void handler::print_keydup_error(uint key_nr, const char *msg)
|
||||
{
|
||||
/* Key is unknown */
|
||||
str.copy("", 0, system_charset_info);
|
||||
my_printf_error(ER_DUP_ENTRY, msg, MYF(0), str.c_ptr(), "*UNKNOWN*");
|
||||
my_printf_error(ER_DUP_ENTRY, msg, errflag, str.c_ptr(), "*UNKNOWN*");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2991,7 +3054,7 @@ void handler::print_keydup_error(uint key_nr, const char *msg)
|
||||
str.append(STRING_WITH_LEN("..."));
|
||||
}
|
||||
my_printf_error(ER_DUP_ENTRY, msg,
|
||||
MYF(0), str.c_ptr_safe(), table->key_info[key_nr].name);
|
||||
errflag, str.c_ptr_safe(), table->key_info[key_nr].name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3059,7 +3122,7 @@ void handler::print_error(int error, myf errflag)
|
||||
uint key_nr=get_dup_key(error);
|
||||
if ((int) key_nr >= 0)
|
||||
{
|
||||
print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
|
||||
print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME), errflag);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
@ -3178,7 +3241,7 @@ void handler::print_error(int error, myf errflag)
|
||||
textno=ER_TABLE_DEF_CHANGED;
|
||||
break;
|
||||
case HA_ERR_NO_SUCH_TABLE:
|
||||
my_error(ER_NO_SUCH_TABLE, errflag, table_share->db.str,
|
||||
my_error(ER_NO_SUCH_TABLE_IN_ENGINE, errflag, table_share->db.str,
|
||||
table_share->table_name.str);
|
||||
DBUG_VOID_RETURN;
|
||||
case HA_ERR_RBR_LOGGING_FAILED:
|
||||
@ -3206,7 +3269,10 @@ void handler::print_error(int error, myf errflag)
|
||||
textno= ER_AUTOINC_READ_FAILED;
|
||||
break;
|
||||
case HA_ERR_AUTOINC_ERANGE:
|
||||
textno= ER_WARN_DATA_OUT_OF_RANGE;
|
||||
textno= error;
|
||||
my_error(textno, errflag, table->next_number_field->field_name,
|
||||
table->in_use->warning_info->current_row_for_warning());
|
||||
DBUG_VOID_RETURN;
|
||||
break;
|
||||
case HA_ERR_TOO_MANY_CONCURRENT_TRXS:
|
||||
textno= ER_TOO_MANY_CONCURRENT_TRXS;
|
||||
@ -4991,10 +5057,14 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
|
||||
db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
/*
|
||||
We also check thd->is_error() as Innodb may return 0 even if
|
||||
there was an error.
|
||||
*/
|
||||
if (!result && !thd->is_error())
|
||||
my_eof(thd);
|
||||
else if (!thd->is_error())
|
||||
my_error(ER_GET_ERRNO, MYF(0), 0);
|
||||
my_error(ER_GET_ERRNO, MYF(0), errno);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -5283,6 +5353,8 @@ int handler::ha_write_row(uchar *buf)
|
||||
rows_changed++;
|
||||
if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
|
||||
DBUG_RETURN(error); /* purecov: inspected */
|
||||
|
||||
DEBUG_SYNC_C("ha_write_row_end");
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user