Backport of:
---------------------------------------------------------- revno: 2630.13.6 committer: Konstantin Osipov <konstantin@mysql.com> branch nick: mysql-6.0-3288 timestamp: Fri 2008-07-11 20:22:44 +0400 message: WL#3288, step 1: ensure that the SQL layer always closes an open cursor (rnd or index read) before closing a handler.
This commit is contained in:
parent
8441517b52
commit
2ae359db4a
@ -1152,7 +1152,7 @@ public:
|
|||||||
virtual ~handler(void)
|
virtual ~handler(void)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(locked == FALSE);
|
DBUG_ASSERT(locked == FALSE);
|
||||||
/* TODO: DBUG_ASSERT(inited == NONE); */
|
DBUG_ASSERT(inited == NONE);
|
||||||
}
|
}
|
||||||
virtual handler *clone(MEM_ROOT *mem_root);
|
virtual handler *clone(MEM_ROOT *mem_root);
|
||||||
/** This is called after create to allow us to set up cached variables */
|
/** This is called after create to allow us to set up cached variables */
|
||||||
|
@ -1958,15 +1958,19 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Okay, got values for all arguments. Close tables that might be used by
|
Okay, got values for all arguments. Close tables that might be used by
|
||||||
arguments evaluation. If arguments evaluation required prelocking mode,
|
arguments evaluation. If arguments evaluation required prelocking mode,
|
||||||
we'll leave it here.
|
we'll leave it here.
|
||||||
*/
|
*/
|
||||||
if (!thd->in_sub_stmt)
|
if (!thd->in_sub_stmt)
|
||||||
{
|
{
|
||||||
thd->lex->unit.cleanup();
|
thd->lex->unit.cleanup();
|
||||||
close_thread_tables(thd);
|
|
||||||
|
thd_proc_info(thd, "closing tables");
|
||||||
|
close_thread_tables(thd);
|
||||||
|
thd_proc_info(thd, 0);
|
||||||
|
|
||||||
thd->rollback_item_tree_changes();
|
thd->rollback_item_tree_changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -991,13 +991,13 @@ JOIN::optimize()
|
|||||||
}
|
}
|
||||||
if (const_tables && !thd->locked_tables &&
|
if (const_tables && !thd->locked_tables &&
|
||||||
!(select_options & SELECT_NO_UNLOCK))
|
!(select_options & SELECT_NO_UNLOCK))
|
||||||
mysql_unlock_some_tables(thd, table, const_tables);
|
mysql_unlock_some_tables(thd, all_tables, const_tables);
|
||||||
if (!conds && outer_join)
|
if (!conds && outer_join)
|
||||||
{
|
{
|
||||||
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
||||||
conds=new Item_int((longlong) 1,1); // Always true
|
conds=new Item_int((longlong) 1,1); // Always true
|
||||||
}
|
}
|
||||||
select= make_select(*table, const_table_map,
|
select= make_select(*all_tables, const_table_map,
|
||||||
const_table_map, conds, 1, &error);
|
const_table_map, conds, 1, &error);
|
||||||
if (error)
|
if (error)
|
||||||
{ /* purecov: inspected */
|
{ /* purecov: inspected */
|
||||||
@ -2905,7 +2905,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
|||||||
|
|
||||||
join->join_tab=stat;
|
join->join_tab=stat;
|
||||||
join->map2table=stat_ref;
|
join->map2table=stat_ref;
|
||||||
join->table= join->all_tables=table_vector;
|
join->all_tables= table_vector;
|
||||||
join->const_tables=const_count;
|
join->const_tables=const_count;
|
||||||
join->found_const_table_map=found_const_table_map;
|
join->found_const_table_map=found_const_table_map;
|
||||||
|
|
||||||
@ -5595,7 +5595,7 @@ get_best_combination(JOIN *join)
|
|||||||
{
|
{
|
||||||
TABLE *form;
|
TABLE *form;
|
||||||
*j= *join->best_positions[tablenr].table;
|
*j= *join->best_positions[tablenr].table;
|
||||||
form=join->table[tablenr]=j->table;
|
form=join->all_tables[tablenr]=j->table;
|
||||||
used_tables|= form->map;
|
used_tables|= form->map;
|
||||||
form->reginfo.join_tab=j;
|
form->reginfo.join_tab=j;
|
||||||
if (!*j->on_expr_ref)
|
if (!*j->on_expr_ref)
|
||||||
@ -5867,7 +5867,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
|
|||||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||||
|
|
||||||
join_tab= parent->join_tab_reexec;
|
join_tab= parent->join_tab_reexec;
|
||||||
table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table;
|
parent->table_reexec[0]= tmp_table;
|
||||||
tables= 1;
|
tables= 1;
|
||||||
const_tables= 0;
|
const_tables= 0;
|
||||||
const_table_map= 0;
|
const_table_map= 0;
|
||||||
@ -6899,24 +6899,23 @@ void JOIN::cleanup(bool full)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::cleanup");
|
DBUG_ENTER("JOIN::cleanup");
|
||||||
|
|
||||||
if (table)
|
if (all_tables)
|
||||||
{
|
{
|
||||||
JOIN_TAB *tab,*end;
|
JOIN_TAB *tab,*end;
|
||||||
/*
|
/*
|
||||||
Only a sorted table may be cached. This sorted table is always the
|
Only a sorted table may be cached. This sorted table is always the
|
||||||
first non const table in join->table
|
first non const table in join->all_tables
|
||||||
*/
|
*/
|
||||||
if (tables > const_tables) // Test for not-const tables
|
if (tables > const_tables) // Test for not-const tables
|
||||||
{
|
{
|
||||||
free_io_cache(table[const_tables]);
|
free_io_cache(all_tables[const_tables]);
|
||||||
filesort_free_buffers(table[const_tables],full);
|
filesort_free_buffers(all_tables[const_tables],full);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full)
|
if (full)
|
||||||
{
|
{
|
||||||
for (tab= join_tab, end= tab+tables; tab != end; tab++)
|
for (tab= join_tab, end= tab+tables; tab != end; tab++)
|
||||||
tab->cleanup();
|
tab->cleanup();
|
||||||
table= 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -7245,7 +7244,7 @@ static void clear_tables(JOIN *join)
|
|||||||
are not re-calculated.
|
are not re-calculated.
|
||||||
*/
|
*/
|
||||||
for (uint i=join->const_tables ; i < join->tables ; i++)
|
for (uint i=join->const_tables ; i < join->tables ; i++)
|
||||||
mark_as_null_row(join->table[i]); // All fields are NULL
|
mark_as_null_row(join->all_tables[i]); // All fields are NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -10995,26 +10994,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
if (error == NESTED_LOOP_NO_MORE_ROWS)
|
if (error == NESTED_LOOP_NO_MORE_ROWS)
|
||||||
error= NESTED_LOOP_OK;
|
error= NESTED_LOOP_OK;
|
||||||
|
|
||||||
if (error == NESTED_LOOP_OK)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Sic: this branch works even if rc != 0, e.g. when
|
|
||||||
send_data above returns an error.
|
|
||||||
*/
|
|
||||||
if (!table) // If sending data to client
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
The following will unlock all cursors if the command wasn't an
|
|
||||||
update command
|
|
||||||
*/
|
|
||||||
join->join_free(); // Unlock all cursors
|
|
||||||
if (join->result->send_eof())
|
|
||||||
rc= 1; // Don't send error
|
|
||||||
}
|
|
||||||
DBUG_PRINT("info",("%ld records output", (long) join->send_records));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rc= -1;
|
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
int tmp, new_errno= 0;
|
int tmp, new_errno= 0;
|
||||||
@ -11031,6 +11011,29 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
if (new_errno)
|
if (new_errno)
|
||||||
table->file->print_error(new_errno,MYF(0));
|
table->file->print_error(new_errno,MYF(0));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The following will unlock all cursors if the command wasn't an
|
||||||
|
update command
|
||||||
|
*/
|
||||||
|
join->join_free(); // Unlock all cursors
|
||||||
|
}
|
||||||
|
if (error == NESTED_LOOP_OK)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Sic: this branch works even if rc != 0, e.g. when
|
||||||
|
send_data above returns an error.
|
||||||
|
*/
|
||||||
|
if (!table) // If sending data to client
|
||||||
|
{
|
||||||
|
if (join->result->send_eof())
|
||||||
|
rc= 1; // Don't send error
|
||||||
|
}
|
||||||
|
DBUG_PRINT("info",("%ld records output", (long) join->send_records));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc= -1;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
|
@ -280,7 +280,7 @@ public:
|
|||||||
JOIN_TAB *join_tab,**best_ref;
|
JOIN_TAB *join_tab,**best_ref;
|
||||||
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
||||||
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
|
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
|
||||||
TABLE **table,**all_tables,*sort_by_table;
|
TABLE **all_tables,*sort_by_table;
|
||||||
uint tables,const_tables;
|
uint tables,const_tables;
|
||||||
uint send_group_parts;
|
uint send_group_parts;
|
||||||
bool sort_and_group,first_record,full_join,group, no_field_update;
|
bool sort_and_group,first_record,full_join,group, no_field_update;
|
||||||
@ -427,7 +427,7 @@ public:
|
|||||||
select_result *result_arg)
|
select_result *result_arg)
|
||||||
{
|
{
|
||||||
join_tab= join_tab_save= 0;
|
join_tab= join_tab_save= 0;
|
||||||
table= 0;
|
all_tables= 0;
|
||||||
tables= 0;
|
tables= 0;
|
||||||
const_tables= 0;
|
const_tables= 0;
|
||||||
join_list= 0;
|
join_list= 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user