Commit b94d70a6 authored by unknown's avatar unknown

BUG#19188 incorrect temporary table name of DROP query in replication

manual merge of 5.0 patch and fixing an issue with closing temp tables when no binlog or RBR.
Note, that despite temporary_tables is indeed double-linked list in 5.1 (patch for bug #19881) it is still enough to use only 'next' reference, as it was done for 5.0, when the list is sorted and 
destoyed after.


mysql-test/r/rpl_temporary.result:
  results changed
mysql-test/t/rpl_temporary.test:
  fixing kill stmt for a thread with temp tables. Restoring check of temp table with accent char.
sql/sql_base.cc:
  manual merge part 2. Leaving only extensively refactored close_temporary_tables from local rep.
parent 1730c0c7
......@@ -76,16 +76,11 @@ drop table t1,t2;
create temporary table t3 (f int);
create temporary table t4 (f int);
create table t5 (f int);
drop table if exists t999;
create temporary table t999 (f int);
LOAD DATA INFILE "./tmp/bl_dump_thread_id" into table t999;
drop table t999;
insert into t4 values (1);
kill `select id from information_schema.processlist where command='Binlog Dump'`;
select id from information_schema.processlist where command='Binlog Dump' into @id;
kill @id;
insert into t5 select * from t4;
select * from t5 /* must be 1 after reconnection */;
f
1
drop temporary table t4;
drop table t5;
set @@session.pseudo_thread_id=100;
......@@ -105,4 +100,7 @@ select * from t1 /* must be 1 */;
f
1
drop table t1;
End of 5.1 tests
select * from t1;
a
1
drop table t1;
......@@ -142,11 +142,8 @@ create temporary table t4 (f int);
create table t5 (f int);
sync_with_master;
# find dumper's $id
source include/get_binlog_dump_thread_id.inc;
insert into t4 values (1);
# a hint how to do that in 5.1
--replace_result $id "`select id from information_schema.processlist where command='Binlog Dump'`"
eval kill $id; # to stimulate reconnection by slave w/o timeout
select id from information_schema.processlist where command='Binlog Dump' into @id;
kill @id; # to stimulate reconnection by slave w/o timeout
insert into t5 select * from t4;
save_master_pos;
......@@ -190,5 +187,17 @@ select * from t1 /* must be 1 */;
connection master;
drop table t1;
--echo End of 5.1 tests
#
#14157: utf8 encoding in binlog without set character_set_client
#
--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=latin1 test -e 'create table t1 (a int); set names latin1; create temporary table `äöüÄÖÜ` (a int); insert into `äöüÄÖÜ` values (1); insert into t1 select * from `äöüÄÖÜ`'
sync_slave_with_master;
#connection slave;
select * from t1;
connection master;
drop table t1;
# End of 5.1 tests
......@@ -879,7 +879,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
bool found=1;
/* Wait until all threads has closed all the tables we had locked */
DBUG_PRINT("info",
("Waiting for others threads to close their open tables"));
("Waiting for other threads to close their open tables"));
while (found && ! thd->killed)
{
found=0;
......@@ -890,6 +890,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
((table->s->version) < refresh_version && table->db_stat))
{
found=1;
DBUG_PRINT("signal", ("Waiting for COND_refresh"));
pthread_cond_wait(&COND_refresh,&LOCK_open);
break;
}
......@@ -947,8 +948,13 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
{
for (; table ; table= table->next)
{
if (table->query_id == thd->query_id)
{
table->query_id= 0;
table->file->ha_reset();
}
}
}
......@@ -1028,21 +1034,13 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
*/
ha_commit_stmt(thd);
/* We are under simple LOCK TABLES so should not do anything else. */
if (!prelocked_mode)
DBUG_VOID_RETURN;
if (!thd->lex->requires_prelocking())
{
/*
If we are executing one of substatements we have to mark
all tables which it used as free for reuse.
*/
/* Ensure we are calling ha_reset() for all used tables */
mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
/* We are under simple LOCK TABLES so should not do anything else. */
if (!prelocked_mode || !thd->lex->requires_prelocking())
DBUG_VOID_RETURN;
}
DBUG_ASSERT(prelocked_mode);
/*
We are in prelocked mode, so we have to leave it now with doing
implicit UNLOCK TABLES if need.
......@@ -1096,7 +1094,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
found_old_table= 0;
while (thd->open_tables)
found_old_table|=close_thread_table(thd, &thd->open_tables);
found_old_table|= close_thread_table(thd, &thd->open_tables);
thd->some_tables_deleted=0;
/* Free tables to hold down open files */
......@@ -1125,6 +1123,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
DBUG_VOID_RETURN;
}
/* move one table to free list */
bool close_thread_table(THD *thd, TABLE **table_ptr)
......@@ -1149,11 +1148,8 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
table->s->flush_version= flush_version;
table->file->extra(HA_EXTRA_FLUSH);
}
else
{
// Free memory and reset for next loop
table->file->ha_reset();
}
table->in_use=0;
if (unused_tables)
{
......@@ -1189,8 +1185,10 @@ void close_temporary_tables(THD *thd)
if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
{
for (table= thd->temporary_tables; table; table= table->next)
TABLE *next;
for (table= thd->temporary_tables; table; table= next)
{
next=table->next;
close_temporary(table, 1, 1);
}
thd->temporary_tables= 0;
......@@ -1198,7 +1196,9 @@ void close_temporary_tables(THD *thd)
}
TABLE *next,
*prev_table /* prev link is not maintained in TABLE's double-linked list */;
*prev_table /* TODO: 5.1 maintaines prev link in temporary_tables
double-linked list so we could fix it. But it is not necessary
at this time when the list is being destroyed */;
bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
// Better add "if exists", in case a RESET MASTER has been done
const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
......@@ -1310,7 +1310,6 @@ void close_temporary_tables(THD *thd)
thd->temporary_tables=0;
}
/*
Find table in list.
......@@ -1526,17 +1525,37 @@ bool close_temporary_table(THD *thd, TABLE_LIST *table_list)
}
/*
Close temporary table and unlink from thd->temporary tables
unlink from thd->temporary tables and close temporary table
*/
void close_temporary_table(THD *thd, TABLE *table,
bool free_share, bool delete_table)
{
TABLE **prev= table->open_prev;
if ((*table->open_prev= table->next))
table->next->open_prev= prev;
if (table->prev)
{
table->prev->next= table->next;
if (table->prev->next)
table->next->prev= table->prev;
}
else
{
/* removing the item from the list */
DBUG_ASSERT(table == thd->temporary_tables);
/*
slave must reset its temporary list pointer to zero to exclude
passing non-zero value to end_slave via rli->save_temporary_tables
when no temp tables opened, see an invariant below.
*/
thd->temporary_tables= table->next;
if (thd->temporary_tables)
table->next->prev= 0;
}
if (thd->slave_thread)
{
/* natural invariant of temporary_tables */
DBUG_ASSERT(slave_open_temp_tables || !thd->temporary_tables);
slave_open_temp_tables--;
}
close_temporary(table, free_share, delete_table);
}
......@@ -1678,6 +1697,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
thd->mysys_var->current_cond= cond;
proc_info=thd->proc_info;
thd->proc_info="Waiting for table";
DBUG_ENTER("wait_for_condition");
if (!thd->killed)
(void) pthread_cond_wait(cond, mutex);
......@@ -1698,6 +1718,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
thd->mysys_var->current_cond= 0;
thd->proc_info= proc_info;
pthread_mutex_unlock(&thd->mysys_var->mutex);
DBUG_VOID_RETURN;
}
......@@ -1786,6 +1807,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
MYSQL_LOCK_IGNORE_FLUSH - Open table even if
someone has done a flush or namelock on it.
No version number checking is done.
MYSQL_OPEN_IGNORE_LOCKED_TABLES - Open table
ignoring set of locked tables and prelocked mode.
IMPLEMENTATION
Uses a cache of open tables to find a table not in use.
......@@ -1845,7 +1868,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
if (thd->locked_tables || thd->prelocked_mode)
if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) &&
(thd->locked_tables || thd->prelocked_mode))
{ // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN;
......@@ -1973,6 +1997,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
{
if (table->s->version != refresh_version)
{
DBUG_PRINT("note",
("Found table '%s.%s' with different refresh version",
table_list->db, table_list->table_name));
/*
Don't close tables if we are working with a log table or were
asked not to close the table explicitly
......@@ -2080,6 +2108,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if (table->timestamp_field)
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
table->clear_column_bitmaps();
DBUG_ASSERT(table->key_read == 0);
DBUG_RETURN(table);
}
......@@ -2177,6 +2206,7 @@ static bool reopen_table(TABLE *table)
VOID(closefrm(table, 1)); // close file, free everything
*table= tmp;
table->default_column_bitmaps();
table->file->change_table_ptr(table, table->s);
DBUG_ASSERT(table->alias != 0);
......@@ -2675,7 +2705,7 @@ retry:
goto err;
// Code below is for repairing a crashed file
if ((error= lock_table_name(thd, table_list)))
if ((error= lock_table_name(thd, table_list, TRUE)))
{
if (error < 0)
goto err;
......@@ -3493,10 +3523,12 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
if (link_in_list)
{
tmp_table->open_prev= &thd->temporary_tables;
if ((tmp_table->next= thd->temporary_tables))
thd->temporary_tables->open_prev= &tmp_table->next;
/* growing temp list at the head */
tmp_table->next= thd->temporary_tables;
if (tmp_table->next)
tmp_table->next->prev= tmp_table;
thd->temporary_tables= tmp_table;
thd->temporary_tables->prev= 0;
if (thd->slave_thread)
slave_open_temp_tables++;
}
......@@ -3544,22 +3576,50 @@ Field *view_ref_found= (Field*) 0x2;
static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
{
if (thd->set_query_id)
DBUG_ENTER("update_field_dependencies");
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
{
table->file->ha_set_bit_in_rw_set(field->fieldnr,
(bool)(thd->set_query_id-1));
if (field->query_id != thd->query_id)
MY_BITMAP *current_bitmap, *other_bitmap;
/*
We always want to register the used keys, as the column bitmap may have
been set for all fields (for example for view).
*/
table->used_keys.intersect(field->part_of_key);
table->merge_keys.merge(field->part_of_key);
if (thd->mark_used_columns == MARK_COLUMNS_READ)
{
current_bitmap= table->read_set;
other_bitmap= table->write_set;
}
else
{
current_bitmap= table->write_set;
other_bitmap= table->read_set;
}
if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
{
if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
{
DBUG_PRINT("warning", ("Found duplicated field"));
thd->dup_field= field;
}
else
{
DBUG_PRINT("note", ("Field found before"));
}
DBUG_VOID_RETURN;
}
if (table->get_fields_in_item_tree)
field->flags|= GET_FIXED_FIELDS_FLAG;
field->query_id= thd->query_id;
table->used_fields++;
table->used_keys.intersect(field->part_of_key);
}
else
thd->dupp_field= field;
} else if (table->get_fields_in_item_tree)
else if (table->get_fields_in_item_tree)
field->flags|= GET_FIXED_FIELDS_FLAG;
DBUG_VOID_RETURN;
}
......@@ -3968,12 +4028,12 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
fld= WRONG_GRANT;
else
#endif
if (thd->set_query_id)
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
{
/*
* get rw_set correct for this field so that the handler
* knows that this field is involved in the query and gets
* retrieved/updated
Get rw_set correct for this field so that the handler
knows that this field is involved in the query and gets
retrieved/updated
*/
Field *field_to_set= NULL;
if (fld == view_ref_found)
......@@ -3981,13 +4041,22 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
Item *it= (*ref)->real_item();
if (it->type() == Item::FIELD_ITEM)
field_to_set= ((Item_field*)it)->field;
else
{
if (thd->mark_used_columns == MARK_COLUMNS_READ)
it->walk(&Item::register_field_in_read_map, 1, (byte *) 0);
}
}
else
field_to_set= fld;
if (field_to_set)
field_to_set->table->file->
ha_set_bit_in_rw_set(field_to_set->fieldnr,
(bool)(thd->set_query_id-1));
{
TABLE *table= field_to_set->table;
if (thd->mark_used_columns == MARK_COLUMNS_READ)
bitmap_set_bit(table->read_set, field_to_set->field_index);
else
bitmap_set_bit(table->write_set, field_to_set->field_index);
}
}
}
DBUG_RETURN(fld);
......@@ -4680,17 +4749,17 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
{
TABLE *table_1= nj_col_1->table_ref->table;
/* Mark field_1 used for table cache. */
field_1->query_id= thd->query_id;
table_1->file->ha_set_bit_in_read_set(field_1->fieldnr);
bitmap_set_bit(table_1->read_set, field_1->field_index);
table_1->used_keys.intersect(field_1->part_of_key);
table_1->merge_keys.merge(field_1->part_of_key);
}
if (field_2)
{
TABLE *table_2= nj_col_2->table_ref->table;
/* Mark field_2 used for table cache. */
field_2->query_id= thd->query_id;
table_2->file->ha_set_bit_in_read_set(field_2->fieldnr);
bitmap_set_bit(table_2->read_set, field_2->field_index);
table_2->used_keys.intersect(field_2->part_of_key);
table_2->merge_keys.merge(field_2->part_of_key);
}
if (using_fields != NULL)
......@@ -5036,10 +5105,6 @@ static bool setup_natural_join_row_types(THD *thd,
if (from_clause->elements == 0)
return FALSE; /* We come here in the case of UNIONs. */
/* For stored procedures do not redo work if already done. */
if (!context->select_lex->first_execution)
return FALSE;
List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause);
TABLE_LIST *table_ref; /* Current table reference. */
/* Table reference to the left of the current. */
......@@ -5052,6 +5117,9 @@ static bool setup_natural_join_row_types(THD *thd,
{
table_ref= left_neighbor;
left_neighbor= table_ref_it++;
/* For stored procedures do not redo work if already done. */
if (context->select_lex->first_execution)
{
if (store_top_level_join_columns(thd, table_ref,
left_neighbor, right_neighbor))
return TRUE;
......@@ -5061,6 +5129,7 @@ static bool setup_natural_join_row_types(THD *thd,
first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
}
}
right_neighbor= table_ref;
}
......@@ -5158,17 +5227,17 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
****************************************************************************/
bool setup_fields(THD *thd, Item **ref_pointer_array,
List<Item> &fields, ulong set_query_id,
List<Item> &fields, enum_mark_columns mark_used_columns,
List<Item> *sum_func_list, bool allow_sum_func)
{
reg2 Item *item;
ulong save_set_query_id= thd->set_query_id;
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
List_iterator<Item> it(fields);
DBUG_ENTER("setup_fields");
thd->set_query_id=set_query_id;
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
thd->mark_used_columns= mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
if (allow_sum_func)
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
thd->where= THD::DEFAULT_WHERE;
......@@ -5194,8 +5263,8 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
(item= *(it.ref()))->check_cols(1))
{
thd->lex->allow_sum_func= save_allow_sum_func;
thd->set_query_id= save_set_query_id;
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
thd->mark_used_columns= save_mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
DBUG_RETURN(TRUE); /* purecov: inspected */
}
if (ref)
......@@ -5206,8 +5275,8 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->used_tables|= item->used_tables();
}
thd->lex->allow_sum_func= save_allow_sum_func;
thd->set_query_id= save_set_query_id;
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
thd->mark_used_columns= save_mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
DBUG_RETURN(test(thd->net.report_error));
}
......@@ -5251,7 +5320,6 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
context name resolution contest to setup table list there
from_clause Top-level list of table references in the FROM clause
tables Table list (select_lex->table_list)
conds Condition of current SELECT (can be changed by VIEW)
leaves List of join table leaves list (select_lex->leaf_tables)
refresh It is onle refresh for subquery
select_insert It is SELECT ... INSERT command
......@@ -5273,7 +5341,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
bool setup_tables(THD *thd, Name_resolution_context *context,
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
Item **conds, TABLE_LIST **leaves, bool select_insert)
TABLE_LIST **leaves, bool select_insert)
{
uint tablenr= 0;
DBUG_ENTER("setup_tables");
......@@ -5296,6 +5364,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
table_list= table_list->next_leaf, tablenr++)
{
TABLE *table= table_list->table;
table->pos_in_table_list= table_list;
if (first_select_table &&
table_list->top_table() == first_select_table)
{
......@@ -5305,6 +5374,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
}
setup_table_map(table, table_list, tablenr);
table->used_keys= table->s->keys_for_keyread;
table->merge_keys.clear_all();
if (table_list->use_index)
{
key_map map;
......@@ -5358,6 +5428,58 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
}
/*
prepare tables and check access for the view tables
SYNOPSIS
setup_tables_and_check_view_access()
thd Thread handler
context name resolution contest to setup table list there
from_clause Top-level list of table references in the FROM clause
tables Table list (select_lex->table_list)
conds Condition of current SELECT (can be changed by VIEW)
leaves List of join table leaves list (select_lex->leaf_tables)
refresh It is onle refresh for subquery
select_insert It is SELECT ... INSERT command
want_access what access is needed
NOTE
a wrapper for check_tables that will also check the resulting
table leaves list for access to all the tables that belong to a view
RETURN
FALSE ok; In this case *map will include the chosen index
TRUE error
*/
bool setup_tables_and_check_access(THD *thd,
Name_resolution_context *context,
List<TABLE_LIST> *from_clause,
TABLE_LIST *tables,
TABLE_LIST **leaves,
bool select_insert,
ulong want_access)
{
TABLE_LIST *leaves_tmp= NULL;
if (setup_tables(thd, context, from_clause, tables,
&leaves_tmp, select_insert))
return TRUE;
*leaves= leaves_tmp;
for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
{
if (leaves_tmp->belong_to_view &&
check_single_table_access(thd, want_access, leaves_tmp))
{
tables->hide_view_error(thd);
return TRUE;
}
}
return FALSE;
}
/*
Create a key_map from a list of index names
......@@ -5387,8 +5509,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
name->length(), 1)) <=
0)
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
table->s->table_name.str);
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
table->pos_in_table_list->alias);
map->set_all();
return 1;
}
......@@ -5478,7 +5600,6 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
#endif
/*
Update the tables used in the query based on the referenced fields. For
views and natural joins this update is performed inside the loop below.
......@@ -5544,18 +5665,13 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
if ((field= field_iterator.field()))
{
/*
Mark if field used before in this select.
Used by 'insert' to verify if a field name is used twice.
*/
if (field->query_id == thd->query_id)
thd->dupp_field= field;
field->query_id= thd->query_id;
field->table->file->ha_set_bit_in_read_set(field->fieldnr);
/* Mark fields as used to allow storage engine to optimze access */
bitmap_set_bit(field->table->read_set, field->field_index);
if (table)
{
table->used_keys.intersect(field->part_of_key);
table->merge_keys.merge(field->part_of_key);
}
if (tables->is_natural_join)
{
TABLE *field_table;
......@@ -5572,16 +5688,13 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
{
thd->used_tables|= field_table->map;
field_table->used_keys.intersect(field->part_of_key);
field_table->merge_keys.merge(field->part_of_key);
field_table->used_fields++;
}
}
}
else
{
thd->used_tables|= item->used_tables();
item->walk(&Item::reset_query_id_processor,
(byte *)(&thd->query_id));
}
}
/*
In case of stored tables, all fields are considered as used,
......@@ -5590,10 +5703,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
For NATURAL joins, used_tables is updated in the IF above.
*/
if (table)
{
table->used_fields= table->s->fields;
table->file->ha_set_all_bits_in_read_set();
}
}
if (found)
DBUG_RETURN(FALSE);
......@@ -5652,8 +5762,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
arena->is_conventional())
arena= 0; // For easier test
thd->set_query_id=1;
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
thd->mark_used_columns= MARK_COLUMNS_READ;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
select_lex->cond_count= 0;
for (table= tables; table; table= table->next_local)
......@@ -5908,7 +6018,7 @@ static void mysql_rm_tmp_tables(void)
if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length))
{
sprintf(filePath,"%s%s",tmpdir,file->name);
sprintf(filePath,"%s%c%s",tmpdir,FN_LIBCHAR,file->name);
VOID(my_delete(filePath,MYF(MY_WME)));
}
}
......@@ -5994,6 +6104,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
TABLE_SHARE *share;
bool result= 0, signalled= 0;
DBUG_ENTER("remove_table_from_cache");
DBUG_PRINT("enter", ("Table: '%s.%s' flags: %u", db, table_name, flags));
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
for (;;)
......@@ -6020,7 +6131,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
DBUG_PRINT("info", ("Table was in use by other thread"));
in_use->some_tables_deleted=1;
if (table->db_stat)
{
DBUG_PRINT("info", ("Found another active instance of the table"));
result=1;
}
/* Kill delayed insert threads */
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed)
......@@ -6075,6 +6189,12 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
{
/*
Signal any thread waiting for tables to be freed to
reopen their tables
*/
(void) pthread_cond_broadcast(&COND_refresh);
DBUG_PRINT("info", ("Waiting for refresh signal"));
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
{
dropping_tables++;
......@@ -6154,7 +6274,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
alias alias for table
db database
table_name name of table
db_stat open flags (for example HA_OPEN_KEYFILE|HA_OPEN_RNDFILE..)
db_stat open flags (for example ->OPEN_KEYFILE|HA_OPEN_RNDFILE..)
can be 0 (example in ha_example_table)
prgflag READ_ALL etc..
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
......
Markdown is supported
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