Commit 4d305fb9 authored by Otto Kekäläinen's avatar Otto Kekäläinen
Browse files

Imported Upstream version 5.5.52

parent 95c6357a
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2010, 2016, MariaDB
This program is free software; you can redistribute it and/or modify
......@@ -5371,6 +5371,15 @@ handle_view(THD *thd, Query_tables_list *prelocking_ctx,
&table_list->view->sroutines_list,
table_list->top_table());
}
/*
If a trigger was defined on one of the associated tables then assign the
'trg_event_map' value of the view to the next table in table_list. When a
Stored function is invoked, all the associated tables including the tables
associated with the trigger are prelocked.
*/
if (table_list->trg_event_map && table_list->next_global)
table_list->next_global->trg_event_map= table_list->trg_event_map;
return FALSE;
}
......
......@@ -4736,9 +4736,11 @@ int THD::decide_logging_format(TABLE_LIST *tables)
{
static const char *prelocked_mode_name[] = {
"NON_PRELOCKED",
"LOCK_TABLES",
"PRELOCKED",
"PRELOCKED_UNDER_LOCK_TABLES",
};
compile_time_assert(array_elements(prelocked_mode_name) == LTM_always_last);
DBUG_PRINT("debug", ("prelocked_mode: %s",
prelocked_mode_name[locked_tables_mode]));
}
......
......@@ -1075,7 +1075,8 @@ enum enum_locked_tables_mode
LTM_NONE= 0,
LTM_LOCK_TABLES,
LTM_PRELOCKED,
LTM_PRELOCKED_UNDER_LOCK_TABLES
LTM_PRELOCKED_UNDER_LOCK_TABLES,
LTM_always_last
};
......@@ -3607,6 +3608,11 @@ class TMP_TABLE_PARAM :public Sql_alloc
save_copy_field_end= copy_field_end= NULL;
}
}
void free_copy_field_data()
{
for (Copy_field *ptr= copy_field ; ptr != copy_field_end ; ptr++)
ptr->tmp.free();
}
};
class select_union :public select_result_interceptor
......
......@@ -3238,6 +3238,7 @@ bool Delayed_insert::handle_inserts(void)
max_rows= 0; // For DBUG output
#endif
/* Remove all not used rows */
mysql_mutex_lock(&mutex);
while ((row=rows.get()))
{
if (table->s->blob_fields)
......@@ -3254,7 +3255,6 @@ bool Delayed_insert::handle_inserts(void)
}
DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows));
thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
mysql_mutex_lock(&mutex);
DBUG_RETURN(1);
}
#endif /* EMBEDDED_LIBRARY */
......
......@@ -1389,8 +1389,8 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
set_if_bigger(length,line_start.length());
stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(0))))
error=1; /* purecov: inspected */
if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(MY_WME))))
error= true; /* purecov: inspected */
else
{
end_of_buff=buffer+buff_length;
......@@ -1581,16 +1581,23 @@ int READ_INFO::read_field()
}
}
#ifdef USE_MB
if (my_mbcharlen(read_charset, chr) > 1 &&
to + my_mbcharlen(read_charset, chr) <= end_of_buff)
uint ml= my_mbcharlen(read_charset, chr);
if (ml == 0)
{
*to= '\0';
my_error(ER_INVALID_CHARACTER_STRING, MYF(0),
read_charset->csname, buffer);
error= true;
return 1;
}
if (ml > 1 &&
to + ml <= end_of_buff)
{
uchar* p= to;
int ml, i;
*to++ = chr;
ml= my_mbcharlen(read_charset, chr);
for (i= 1; i < ml; i++)
for (uint i= 1; i < ml; i++)
{
chr= GET;
if (chr == my_b_EOF)
......@@ -1608,10 +1615,16 @@ int READ_INFO::read_field()
(const char *)p,
(const char *)to))
continue;
for (i= 0; i < ml; i++)
for (uint i= 0; i < ml; i++)
PUSH(*--to);
chr= GET;
}
else if (ml > 1)
{
// Buffer is too small, exit while loop, and reallocate.
PUSH(chr);
break;
}
#endif
*to++ = (uchar) chr;
}
......@@ -1855,7 +1868,15 @@ int READ_INFO::read_value(int delim, String *val)
for (chr= GET; my_tospace(chr) != delim && chr != my_b_EOF;)
{
#ifdef USE_MB
if (my_mbcharlen(read_charset, chr) > 1)
uint ml= my_mbcharlen(read_charset, chr);
if (ml == 0)
{
chr= my_b_EOF;
val->length(0);
return chr;
}
if (ml > 1)
{
DBUG_PRINT("read_xml",("multi byte"));
int i, ml= my_mbcharlen(read_charset, chr);
......
......@@ -2896,68 +2896,8 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
if (!thd->variables.dynamic_variables_ptr ||
(uint)offset > thd->variables.dynamic_variables_head)
{
uint idx;
mysql_rwlock_rdlock(&LOCK_system_variables_hash);
thd->variables.dynamic_variables_ptr= (char*)
my_realloc(thd->variables.dynamic_variables_ptr,
global_variables_dynamic_size,
MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
if (global_lock)
mysql_mutex_lock(&LOCK_global_system_variables);
mysql_mutex_assert_owner(&LOCK_global_system_variables);
memcpy(thd->variables.dynamic_variables_ptr +
thd->variables.dynamic_variables_size,
global_system_variables.dynamic_variables_ptr +
thd->variables.dynamic_variables_size,
global_system_variables.dynamic_variables_size -
thd->variables.dynamic_variables_size);
/*
now we need to iterate through any newly copied 'defaults'
and if it is a string type with MEMALLOC flag, we need to strdup
*/
for (idx= 0; idx < bookmark_hash.records; idx++)
{
sys_var_pluginvar *pi;
sys_var *var;
st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
if (v->version <= thd->variables.dynamic_variables_version)
continue; /* already in thd->variables */
if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
!(pi= var->cast_pluginvar()) ||
v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags))
continue;
/* Here we do anything special that may be required of the data types */
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
{
char **pp= (char**) (thd->variables.dynamic_variables_ptr +
*(int*)(pi->plugin_var + 1));
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
*(int*)(pi->plugin_var + 1))))
*pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
}
}
if (global_lock)
mysql_mutex_unlock(&LOCK_global_system_variables);
thd->variables.dynamic_variables_version=
global_system_variables.dynamic_variables_version;
thd->variables.dynamic_variables_head=
global_system_variables.dynamic_variables_head;
thd->variables.dynamic_variables_size=
global_system_variables.dynamic_variables_size;
sync_dynamic_session_variables(thd, global_lock);
mysql_rwlock_unlock(&LOCK_system_variables_hash);
}
DBUG_RETURN((uchar*)thd->variables.dynamic_variables_ptr + offset);
......@@ -3037,6 +2977,70 @@ void plugin_thdvar_init(THD *thd)
}
void sync_dynamic_session_variables(THD* thd, bool global_lock)
{
uint idx;
thd->variables.dynamic_variables_ptr= (char*)
my_realloc(thd->variables.dynamic_variables_ptr,
global_variables_dynamic_size,
MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
if (global_lock)
mysql_mutex_lock(&LOCK_global_system_variables);
mysql_mutex_assert_owner(&LOCK_global_system_variables);
memcpy(thd->variables.dynamic_variables_ptr +
thd->variables.dynamic_variables_size,
global_system_variables.dynamic_variables_ptr +
thd->variables.dynamic_variables_size,
global_system_variables.dynamic_variables_size -
thd->variables.dynamic_variables_size);
/*
now we need to iterate through any newly copied 'defaults'
and if it is a string type with MEMALLOC flag, we need to strdup
*/
for (idx= 0; idx < bookmark_hash.records; idx++)
{
sys_var_pluginvar *pi;
sys_var *var;
st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
if (v->version <= thd->variables.dynamic_variables_version)
continue; /* already in thd->variables */
if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
!(pi= var->cast_pluginvar()) ||
v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags))
continue;
/* Here we do anything special that may be required of the data types */
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
{
int offset= ((thdvar_str_t *)(pi->plugin_var))->offset;
char **pp= (char**) (thd->variables.dynamic_variables_ptr + offset);
if (*pp)
*pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
}
}
if (global_lock)
mysql_mutex_unlock(&LOCK_global_system_variables);
thd->variables.dynamic_variables_version=
global_system_variables.dynamic_variables_version;
thd->variables.dynamic_variables_head=
global_system_variables.dynamic_variables_head;
thd->variables.dynamic_variables_size=
global_system_variables.dynamic_variables_size;
}
/*
Unlocks all system variables which hold a reference
*/
......
......@@ -174,4 +174,6 @@ typedef my_bool (plugin_foreach_func)(THD *thd,
#define plugin_foreach(A,B,C,D) plugin_foreach_with_mask(A,B,C,PLUGIN_IS_READY,D)
extern bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
int type, uint state_mask, void *arg);
extern void sync_dynamic_session_variables(THD* thd, bool global_lock);
#endif
......@@ -8277,7 +8277,24 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
*/
if (!tmp_join || tmp_join != this)
tmp_table_param.cleanup();
else
{
/*
Free data buffered in copy_fields, but keep data pointed by copy_field
around for next iteration (possibly stored in save_copy_fields).
It would be logically simpler to not clear copy_field
below, but as we have loops that runs over copy_field to
copy_field_end that should not be done anymore, it's simpler to
just clear the pointers.
Another option would be to just clear copy_field_end and not run
the loops if this is not set or to have tmp_table_param.cleanup()
to run cleanup on save_copy_field if copy_field is not set.
*/
tmp_table_param.free_copy_field_data();
tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
}
first_record= sort_and_group=0;
send_records= (ha_rows) 0;
 
......@@ -10866,7 +10883,7 @@ void JOIN::join_free()
/**
Free resources of given join.
 
@param fill true if we should free all resources, call with full==1
@param full true if we should free all resources, call with full==1
should be last, before it this function can be called with
full==0
 
......@@ -10982,7 +10999,7 @@ void JOIN::cleanup(bool full)
/*
If we have tmp_join and 'this' JOIN is not tmp_join and
tmp_table_param.copy_field's of them are equal then we have to remove
pointer to tmp_table_param.copy_field from tmp_join, because it qill
pointer to tmp_table_param.copy_field from tmp_join, because it will
be removed in tmp_table_param.cleanup().
*/
if (tmp_join &&
......@@ -14816,6 +14833,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item::VARBIN_ITEM:
case Item::CACHE_ITEM:
case Item::EXPR_CACHE_ITEM:
case Item::PARAM_ITEM:
if (make_copy_field)
{
DBUG_ASSERT(((Item_result_field*)item)->result_field);
......@@ -21397,7 +21415,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
err:
if (copy)
delete [] param->copy_field; // This is never 0
param->copy_field=0;
param->copy_field= 0;
err2:
DBUG_RETURN(TRUE);
}
......
......@@ -6937,19 +6937,30 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
enum enum_schema_tables schema_table_idx=
get_schema_table_idx(tables->schema_table);
enum enum_var_type option_type= OPT_SESSION;
enum enum_var_type scope= OPT_SESSION;
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
if ((sorted_vars && lex->option_type == OPT_GLOBAL) ||
schema_table_idx == SCH_GLOBAL_VARIABLES)
option_type= OPT_GLOBAL;
scope= OPT_GLOBAL;
COND *partial_cond= make_cond_for_info_schema(cond, tables);
mysql_rwlock_rdlock(&LOCK_system_variables_hash);
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, option_type),
option_type, NULL, "", tables->table,
/*
Avoid recursive LOCK_system_variables_hash acquisition in
intern_sys_var_ptr() by pre-syncing dynamic session variables.
*/
if (scope == OPT_SESSION &&
(!thd->variables.dynamic_variables_ptr ||
global_system_variables.dynamic_variables_head >
thd->variables.dynamic_variables_head))
sync_dynamic_session_variables(thd, true);
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope),
scope, NULL, "", tables->table,
upper_case_names, partial_cond);
mysql_rwlock_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
......
......@@ -887,6 +887,12 @@ bool st_select_lex_unit::cleanup()
join->tables_list= 0;
join->table_count= 0;
join->top_join_tab_count= 0;
if (join->tmp_join && join->tmp_join != join)
{
join->tmp_join->tables_list= 0;
join->tmp_join->table_count= 0;
join->tmp_join->top_join_tab_count= 0;
}
}
error|= fake_select_lex->cleanup();
/*
......
......@@ -3025,18 +3025,31 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var)
if (!var->save_result.string_value.str)
return true;
if (var->save_result.string_value.length > FN_REFLEN)
LEX_STRING *val= &var->save_result.string_value;
if (val->length > FN_REFLEN)
{ // path is too long
my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
return true;
}
char path[FN_REFLEN];
size_t path_length= unpack_filename(path, var->save_result.string_value.str);
size_t path_length= unpack_filename(path, val->str);
if (!path_length)
return true;
static const LEX_CSTRING my_cnf= { STRING_WITH_LEN("my.cnf") };
static const LEX_CSTRING my_ini= { STRING_WITH_LEN("my.ini") };
if (path_length >= my_cnf.length)
{
if (strcasecmp(path + path_length - my_cnf.length, my_cnf.str) == 0)
return true; // log file name ends with "my.cnf"
DBUG_ASSERT(my_cnf.length == my_ini.length);
if (strcasecmp(path + path_length - my_ini.length, my_ini.str) == 0)
return true; // log file name ends with "my.ini"
}
MY_STAT f_stat;
if (my_stat(path, &f_stat, MYF(0)))
......@@ -3046,9 +3059,9 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var)
return false;
}
(void) dirname_part(path, var->save_result.string_value.str, &path_length);
(void) dirname_part(path, val->str, &path_length);
if (var->save_result.string_value.length - path_length >= FN_LEN)
if (val->length - path_length >= FN_LEN)
{ // filename is too long
my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
return true;
......
......@@ -1242,14 +1242,14 @@ dict_create_or_check_foreign_constraint_tables(void)
fprintf(stderr,
"InnoDB: dropping incompletely created"
" SYS_FOREIGN table\n");
row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE);
}
if (table2) {
fprintf(stderr,
"InnoDB: dropping incompletely created"
" SYS_FOREIGN_COLS table\n");
row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE);
}
fprintf(stderr,
......@@ -1298,8 +1298,8 @@ dict_create_or_check_foreign_constraint_tables(void)
"InnoDB: dropping incompletely created"
" SYS_FOREIGN tables\n");
row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE);
row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE);
error = DB_MUST_GET_MORE_FILE_SPACE;
}
......
......@@ -7644,7 +7644,8 @@ ha_innobase::delete_table(
error = row_drop_table_for_mysql(norm_name, trx,
thd_sql_command(thd)
== SQLCOM_DROP_DB);
== SQLCOM_DROP_DB,
FALSE);
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs
......
......@@ -348,20 +348,13 @@ os_atomic_test_and_set(volatile lock_word_t* ptr)
}
/** Do an atomic release.
In theory __sync_lock_release should be used to release the lock.
Unfortunately, it does not work properly alone. The workaround is
that more conservative __sync_lock_test_and_set is used instead.
Performance regression was observed at some conditions for Intel
architecture. Disable release barrier on Intel architecture for now.
@param[in,out] ptr Memory location to write to
@return the previous value */
static inline
lock_word_t
void
os_atomic_clear(volatile lock_word_t* ptr)
{
return(__sync_lock_test_and_set(ptr, 0));
__sync_lock_release(ptr);
}
# elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET)
......
......@@ -454,7 +454,10 @@ row_drop_table_for_mysql(
/*=====================*/
const char* name, /*!< in: table name */
trx_t* trx, /*!< in: transaction handle */
ibool drop_db);/*!< in: TRUE=dropping whole database */
ibool drop_db,/*!< in: TRUE=dropping whole database */
ibool create_failed);/*!<in: TRUE=create table failed
because e.g. foreign key column
type mismatch. */
/*********************************************************************//**
Drop all temporary tables during crash recovery. */
UNIV_INTERN
......
......@@ -178,6 +178,11 @@ mutex_exit_func(
to wake up possible hanging threads if
they are missed in mutex_signal_object. */
/* We add a memory barrier to prevent reading of the
number of waiters before releasing the lock. */
os_mb;
if (mutex_get_waiters(mutex) != 0) {
mutex_signal_object(mutex);
......
......@@ -1048,6 +1048,26 @@ page_cur_insert_rec_low(
insert_rec = rec_copy(insert_buf, rec, offsets);
rec_offs_make_valid(insert_rec, index, offsets);
/* This is because assertion below is debug assertion */
#ifdef UNIV_DEBUG
if (UNIV_UNLIKELY(current_rec == insert_rec)) {
ulint extra_len, data_len;
extra_len = rec_offs_extra_size(offsets);
data_len = rec_offs_data_size(offsets);
fprintf(stderr, "InnoDB: Error: current_rec == insert_rec "
" extra_len %lu data_len %lu insert_buf %p rec %p\n",
extra_len, data_len, insert_buf, rec);
fprintf(stderr, "InnoDB; Physical record: \n");
rec_print(stderr, rec, index);
fprintf(stderr, "InnoDB: Inserted record: \n");
rec_print(stderr, insert_rec, index);
fprintf(stderr, "InnoDB: Current record: \n");
rec_print(stderr, current_rec, index);
ut_a(current_rec != insert_rec);
}
#endif /* UNIV_DEBUG */
/* 4. Insert the record in the linked list of records */
ut_ad(current_rec != insert_rec);
......
......@@ -2685,7 +2685,7 @@ row_merge_drop_table(
/* There must be no open transactions on the table. */
ut_a(table->n_mysql_handles_opened == 0);
return(row_drop_table_for_mysql(table->name, trx, FALSE));
return(row_drop_table_for_mysql(table->name, trx, FALSE, FALSE));
}
/*********************************************************************//**
......
......@@ -1987,7 +1987,7 @@ row_create_table_for_mysql(
if (dict_table_get_low(table->name, DICT_ERR_IGNORE_NONE)) {
row_drop_table_for_mysql(table->name, trx, FALSE);
row_drop_table_for_mysql(table->name, trx, FALSE, TRUE);
trx_commit_for_mysql(trx);
} else {
dict_mem_table_free(table);
......@@ -2117,7 +2117,7 @@ row_create_index_for_mysql(
trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(table_name, trx, FALSE);
row_drop_table_for_mysql(table_name, trx, FALSE, TRUE);
trx_commit_for_mysql(trx);
......@@ -2187,7 +2187,7 @@ row_table_add_foreign_constraints(
trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(name, trx, FALSE);
row_drop_table_for_mysql(name, trx, FALSE, TRUE);
trx_commit_for_mysql(trx);
......@@ -2228,7 +2228,7 @@ row_drop_table_for_mysql_in_background(
/* Try to drop the table in InnoDB */
error = row_drop_table_for_mysql(name, trx, FALSE);
error = row_drop_table_for_mysql(name, trx, FALSE, FALSE);
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs
......@@ -3078,7 +3078,10 @@ row_drop_table_for_mysql(
/*=====================*/
const char* name, /*!< in: table name */
trx_t* trx, /*!< in: transaction handle */
ibool drop_db)/*!< in: TRUE=dropping whole database */
ibool drop_db,/*!< in: TRUE=dropping whole database */
ibool create_failed) /*!<in: TRUE=create table failed
because e.g. foreign key column
type mismatch. */
{
dict_foreign_t* foreign;
dict_table_t* table;
......@@ -3193,7 +3196,11 @@ row_drop_table_for_mysql(
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
if (foreign && trx->check_foreigns
/* We should allow dropping a referenced table if creating
that referenced table has failed for some reason. For example
if referenced table is created but it column types that are
referenced do not match. */
if (foreign && trx->check_foreigns && !create_failed
&& !(drop_db && dict_tables_have_same_db(
name, foreign->foreign_table_name_lookup))) {
FILE* ef = dict_foreign_err_file;
......@@ -3578,7 +3585,7 @@ row_mysql_drop_temp_tables(void)
table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE);
if (table) {
row_drop_table_for_mysql(table_name, trx, FALSE);
row_drop_table_for_mysql(table_name, trx, FALSE, FALSE);
trx_commit_for_mysql(trx);
}
......@@ -3708,7 +3715,7 @@ row_drop_database_for_mysql(
goto loop;
}
err = row_drop_table_for_mysql(table_name, trx, TRUE);
err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE);
trx_commit_for_mysql(trx);
if (err != DB_SUCCESS) {
......
......@@ -504,7 +504,7 @@ trx_rollback_active(
ut_print_name(stderr, trx, TRUE, table->name);
fputs(" in recovery\n", stderr);
err = row_drop_table_for_mysql(table->name, trx, TRUE);
err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE);
trx_commit_for_mysql(trx);
ut_a(err == (int) DB_SUCCESS);
......
Supports Markdown
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