List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:July 11 2008 4:22pm
Subject:bzr commit into mysql-6.0 branch (konstantin:2677) WL#3288
View as plain text  
#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#3288Konstantin Osipov11 Jul