fixed opening temporary tables.
This commit is contained in:
parent
2ac068d7f4
commit
f231edcda3
@ -4603,7 +4603,35 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
|
|||||||
*/
|
*/
|
||||||
No_such_table_error_handler no_such_table_handler;
|
No_such_table_error_handler no_such_table_handler;
|
||||||
thd->push_internal_handler(&no_such_table_handler);
|
thd->push_internal_handler(&no_such_table_handler);
|
||||||
|
|
||||||
|
/*
|
||||||
|
We're opening a table from the prelocking list.
|
||||||
|
|
||||||
|
Since this table list element might have been added after pre-opening
|
||||||
|
of temporary tables we have to try to open temporary table for it.
|
||||||
|
|
||||||
|
We can't simply skip this table list element and postpone opening of
|
||||||
|
temporary tabletill the execution of substatement for several reasons:
|
||||||
|
- Temporary table can be a MERGE table with base underlying tables,
|
||||||
|
so its underlying tables has to be properly open and locked at
|
||||||
|
prelocking stage.
|
||||||
|
- Temporary table can be a MERGE table and we might be in PREPARE
|
||||||
|
phase for a prepared statement. In this case it is important to call
|
||||||
|
HA_ATTACH_CHILDREN for all merge children.
|
||||||
|
This is necessary because merge children remember "TABLE_SHARE ref type"
|
||||||
|
and "TABLE_SHARE def version" in the HA_ATTACH_CHILDREN operation.
|
||||||
|
If HA_ATTACH_CHILDREN is not called, these attributes are not set.
|
||||||
|
Then, during the first EXECUTE, those attributes need to be updated.
|
||||||
|
That would cause statement re-preparing (because changing those
|
||||||
|
attributes during EXECUTE is caught by THD::m_reprepare_observers).
|
||||||
|
The problem is that since those attributes are not set in merge
|
||||||
|
children, another round of PREPARE will not help.
|
||||||
|
*/
|
||||||
|
error= open_temporary_table(thd, tables);
|
||||||
|
|
||||||
|
if (!error && !tables->table)
|
||||||
error= open_table(thd, tables, new_frm_mem, ot_ctx);
|
error= open_table(thd, tables, new_frm_mem, ot_ctx);
|
||||||
|
|
||||||
thd->pop_internal_handler();
|
thd->pop_internal_handler();
|
||||||
safe_to_ignore_table= no_such_table_handler.safely_trapped_errors();
|
safe_to_ignore_table= no_such_table_handler.safely_trapped_errors();
|
||||||
}
|
}
|
||||||
@ -4617,12 +4645,29 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
|
|||||||
*/
|
*/
|
||||||
Repair_mrg_table_error_handler repair_mrg_table_handler;
|
Repair_mrg_table_error_handler repair_mrg_table_handler;
|
||||||
thd->push_internal_handler(&repair_mrg_table_handler);
|
thd->push_internal_handler(&repair_mrg_table_handler);
|
||||||
|
|
||||||
|
error= open_temporary_table(thd, tables);
|
||||||
|
if (!error && !tables->table)
|
||||||
error= open_table(thd, tables, new_frm_mem, ot_ctx);
|
error= open_table(thd, tables, new_frm_mem, ot_ctx);
|
||||||
|
|
||||||
thd->pop_internal_handler();
|
thd->pop_internal_handler();
|
||||||
safe_to_ignore_table= repair_mrg_table_handler.safely_trapped_errors();
|
safe_to_ignore_table= repair_mrg_table_handler.safely_trapped_errors();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (tables->parent_l)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Even if we are opening table not from the prelocking list we
|
||||||
|
still might need to look for a temporary table if this table
|
||||||
|
list element corresponds to underlying table of a merge table.
|
||||||
|
*/
|
||||||
|
error= open_temporary_table(thd, tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error && !tables->table)
|
||||||
error= open_table(thd, tables, new_frm_mem, ot_ctx);
|
error= open_table(thd, tables, new_frm_mem, ot_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
free_root(new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
free_root(new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user