summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-10-16 18:37:43 +0400
committerKonstantin Osipov <kostja@sun.com>2009-10-16 18:37:43 +0400
commit2ae359db4ade9df5e31cb0c0967f097fbd57ca07 (patch)
tree28962c8ac0508355f874fc75d20cd72fee0396a9
parent8441517b52fd7f3b392b451745aeedfb21c0d244 (diff)
downloadmariadb-git-2ae359db4ade9df5e31cb0c0967f097fbd57ca07.tar.gz
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.
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sp_head.cc12
-rw-r--r--sql/sql_select.cc65
-rw-r--r--sql/sql_select.h4
4 files changed, 45 insertions, 38 deletions
diff --git a/sql/handler.h b/sql/handler.h
index ed5cc952b5d..41360998a37 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1152,7 +1152,7 @@ public:
virtual ~handler(void)
{
DBUG_ASSERT(locked == FALSE);
- /* TODO: DBUG_ASSERT(inited == NONE); */
+ DBUG_ASSERT(inited == NONE);
}
virtual handler *clone(MEM_ROOT *mem_root);
/** This is called after create to allow us to set up cached variables */
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0cf3d37c230..c013037eef4 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -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
- arguments evaluation. If arguments evaluation required prelocking mode,
+ /*
+ Okay, got values for all arguments. Close tables that might be used by
+ arguments evaluation. If arguments evaluation required prelocking mode,
we'll leave it here.
*/
if (!thd->in_sub_stmt)
{
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();
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6426363d7a0..488bd823b6a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -991,13 +991,13 @@ JOIN::optimize()
}
if (const_tables && !thd->locked_tables &&
!(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)
{
/* Handle the case where we have an OUTER JOIN without a WHERE */
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);
if (error)
{ /* purecov: inspected */
@@ -2905,7 +2905,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
join->join_tab=stat;
join->map2table=stat_ref;
- join->table= join->all_tables=table_vector;
+ join->all_tables= table_vector;
join->const_tables=const_count;
join->found_const_table_map=found_const_table_map;
@@ -5595,7 +5595,7 @@ get_best_combination(JOIN *join)
{
TABLE *form;
*j= *join->best_positions[tablenr].table;
- form=join->table[tablenr]=j->table;
+ form=join->all_tables[tablenr]=j->table;
used_tables|= form->map;
form->reginfo.join_tab=j;
if (!*j->on_expr_ref)
@@ -5867,7 +5867,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
DBUG_RETURN(TRUE); /* purecov: inspected */
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;
const_tables= 0;
const_table_map= 0;
@@ -6899,24 +6899,23 @@ void JOIN::cleanup(bool full)
{
DBUG_ENTER("JOIN::cleanup");
- if (table)
+ if (all_tables)
{
JOIN_TAB *tab,*end;
/*
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
{
- free_io_cache(table[const_tables]);
- filesort_free_buffers(table[const_tables],full);
+ free_io_cache(all_tables[const_tables]);
+ filesort_free_buffers(all_tables[const_tables],full);
}
if (full)
{
for (tab= join_tab, end= tab+tables; tab != end; tab++)
tab->cleanup();
- table= 0;
}
else
{
@@ -7245,7 +7244,7 @@ static void clear_tables(JOIN *join)
are not re-calculated.
*/
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)
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)
{
int tmp, new_errno= 0;
@@ -11031,6 +11011,29 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
if (new_errno)
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
if (rc)
{
diff --git a/sql/sql_select.h b/sql/sql_select.h
index bb751c600ed..8311d7fdd2b 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -280,7 +280,7 @@ public:
JOIN_TAB *join_tab,**best_ref;
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
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 send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update;
@@ -427,7 +427,7 @@ public:
select_result *result_arg)
{
join_tab= join_tab_save= 0;
- table= 0;
+ all_tables= 0;
tables= 0;
const_tables= 0;
join_list= 0;