1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Fix for MDEV-5531: double call procedure in one session - hard shutdown the server

Main fix was to not cache derivied tables as they may be temporary tables that are deleted before the next query.
This was a bit tricky as Item_field::fix_fields depended on cached_tables to be set to resolve some columns.



mysql-test/r/sp-bugs.result:
  Added test case
mysql-test/t/sp-bugs.test:
  Added test case
sql/item.cc:
  Fixed fix_outer_field to handle case where found field did not have in cached_table
  Idea is that if cached_table is not avaliable, use from_field->table->pos_in_table_list instead
sql/records.cc:
  Also accept INTERNAL_TMP_TABLE for memmap
sql/sql_base.cc:
  More DBUG_PRINT
  Fixed that setup_natural_join_row_types() is not run twice.
  Original code modified context->first_name_resolution_table also for second executions.
  This was wrong as this could give wrong results if some joins had been optimized away between calls.
sql/sql_derived.cc:
  Mark derived tables as internal temporary tables (INTERNAL_TMP_TABLE), not as NON_TRANSACTIONAL_TMP_TABLE.
  This is more correct as the tables are not visible by the end user.
sql/sql_insert.cc:
  Reset pos_in_table_list before calling fix_fields.
  One of the consequences of the change of not caching all generated tables in Item_ident is that
  pos_in_table_list needs to be correct in calls to fix_fields.
sql/sql_lex.cc:
  More DBUG_PRINT
sql/sql_parse.cc:
  Don't cache derivied tables as they may be temporary tables that are deleted before the next query
sql/sql_select.cc:
  Reset table_vector. This was required as some code checked the vector to see if temporary tables had already been created.
sql/table.cc:
  Mark tables with field translations as cacheable (as these will not disapper between stmt executions.
This commit is contained in:
Michael Widenius
2014-01-24 14:50:18 +02:00
parent 7335c6f2a4
commit d15b3386db
11 changed files with 213 additions and 46 deletions

View File

@@ -2127,14 +2127,15 @@ void st_select_lex_unit::exclude_tree()
this to 'last' as dependent
SYNOPSIS
last - pointer to last st_select_lex struct, before wich all
last - pointer to last st_select_lex struct, before which all
st_select_lex have to be marked as dependent
NOTE
'last' should be reachable from this st_select_lex_node
*/
bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last, Item *dependency)
bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last,
Item *dependency)
{
DBUG_ASSERT(this != last);
@@ -2325,7 +2326,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
If we need a bigger array, we must allocate a new one.
*/
if (ref_pointer_array_size >= n_elems)
{
DBUG_PRINT("info", ("reusing old ref_array"));
return false;
}
}
ref_pointer_array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems));
if (ref_pointer_array != NULL)
@@ -3328,6 +3332,7 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
Item **having_conds)
{
DBUG_ENTER("st_select_lex::fix_prepare_information");
if (!thd->stmt_arena->is_conventional() && first_execution)
{
first_execution= 0;
@@ -3356,6 +3361,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
}
fix_prepare_info_in_table_list(thd, table_list.first);
}
DBUG_VOID_RETURN;
}