#At file:///opt/local/work/mysql-6.0-3288/
2677 Konstantin Osipov 2008-07-11
WL#3288, step 1: ensure that the SQL layer always closes an open
cursor (rnd or index read) before closing a handler.
modified:
sql/handler.cc
sql/handler.h
sql/sql_select.cc
sql/sql_select.h
per-file messages:
sql/handler.cc
End the read in DsMrr before deleting the handler.
sql/handler.h
Assert that the read is closed in handler destructor.
sql/sql_select.cc
Remove JOIN::table which was a piece of redundancy. The problem was
that JOIN::cleanup() works only if JOIN::table is not null,
but JOIN::cleanup also assigns JOIN::table to NULL. This assignment
is apparently there for safety, from the times when we had no support for correlated
subqueries. Indeed, in case of a evaluation of a correlated subquery more than once it led
to JOIN::cleanup doing nothing, and leaving the rnd or index read open.
In do_select(), make sure we call JOIN::join_free() even in case of an
error.
sql/sql_select.h
Remove JOIN::table, JOIN::all_tables has the same functionality.
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2008-07-04 10:48:08 +0000
+++ b/sql/handler.cc 2008-07-11 16:22:44 +0000
@@ -4381,6 +4381,7 @@ void DsMrr_impl::dsmrr_close()
DBUG_ENTER("DsMrr_impl::dsmrr_close");
if (h2)
{
+ h2->ha_index_or_rnd_end();
h2->ha_external_lock(current_thd, F_UNLCK);
h2->close();
delete h2;
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2008-07-04 10:48:08 +0000
+++ b/sql/handler.h 2008-07-11 16:22:44 +0000
@@ -1406,7 +1406,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 */
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2008-06-30 20:21:41 +0000
+++ b/sql/sql_select.cc 2008-07-11 16:22:44 +0000
@@ -1582,13 +1582,13 @@ JOIN::optimize()
}
if (const_tables && !thd->locked_tables_mode &&
!(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 */
@@ -4216,7 +4216,7 @@ make_join_statistics(JOIN *join, TABLE_L
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;
@@ -6944,7 +6944,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)
@@ -7223,7 +7223,7 @@ make_simple_join(JOIN *join,TABLE *tmp_t
join_tab= join->join_tab_reexec;
join->join_tab=join_tab;
- join->table=tableptr; tableptr[0]=tmp_table;
+ join->all_tables=tableptr; tableptr[0]=tmp_table;
join->tables=1;
join->const_tables=0;
join->const_table_map=0;
@@ -8650,24 +8650,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
{
@@ -8988,7 +8987,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
}
/*****************************************************************************
@@ -13393,26 +13392,7 @@ do_select(JOIN *join,List<Item> *fields,
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;
@@ -13429,6 +13409,29 @@ do_select(JOIN *join,List<Item> *fields,
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)
{
=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h 2008-06-05 16:11:22 +0000
+++ b/sql/sql_select.h 2008-07-11 16:22:44 +0000
@@ -413,7 +413,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;
+ TABLE **all_tables;
/**
The table which has an index that allows to produce the requried ordering.
A special value of 0x1 means that the ordering will be produced by
@@ -568,7 +568,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;
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (konstantin:2677) WL#3288 | Konstantin Osipov | 11 Jul |