MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:July 8 2006 9:29pm
Subject:bk commit into 5.1 tree (aelkin:1.2243) BUG#19881
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of elkin. When elkin does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-07-09 00:29:33+03:00, aelkin@stripped +3 -0
  BUG#19188 incorrect temporary table name of DROP query in replication
  
  manual merge of 5.0 patch and fixing an issue with closing temp tables when no binlog or RBR.
  Note, that despite temporary_tables is indeed double-linked list in 5.1 (patch for bug #19881) it is still enough to use only 'next' reference, as it was done for 5.0, when the list is sorted and 
  destoyed after.

  mysql-test/r/rpl_temporary.result@stripped, 2006-07-09 00:29:30+03:00, aelkin@stripped +6 -8
    results changed

  mysql-test/t/rpl_temporary.test@stripped, 2006-07-09 00:29:30+03:00, aelkin@stripped +15 -6
    fixing kill stmt for a thread with temp tables. Restoring check of temp table with accent char.

  sql/sql_base.cc@stripped, 2006-07-09 00:29:30+03:00, aelkin@stripped +220 -100
    manual merge part 2. Leaving only extensively refactored close_temporary_tables from local rep.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	aelkin
# Host:	dsl-hkigw8-feb1fb00-100.dhcp.inet.fi
# Root:	/usr_rh9/home/elkin.rh9/MySQL/TEAM/FIXES/5.1/bug19188_graved_temp

--- 1.333/sql/sql_base.cc	2006-07-09 00:29:40 +03:00
+++ 1.334/sql/sql_base.cc	2006-07-09 00:29:40 +03:00
@@ -25,7 +25,7 @@
 #include <m_ctype.h>
 #include <my_dir.h>
 #include <hash.h>
-#ifdef	__WIN__
+#ifdef  __WIN__
 #include <io.h>
 #endif
 
@@ -879,7 +879,7 @@
     bool found=1;
     /* Wait until all threads has closed all the tables we had locked */
     DBUG_PRINT("info",
-	       ("Waiting for others threads to close their open tables"));
+	       ("Waiting for other threads to close their open tables"));
     while (found && ! thd->killed)
     {
       found=0;
@@ -890,6 +890,7 @@
             ((table->s->version) < refresh_version && table->db_stat))
 	{
 	  found=1;
+          DBUG_PRINT("signal", ("Waiting for COND_refresh"));
 	  pthread_cond_wait(&COND_refresh,&LOCK_open);
 	  break;
 	}
@@ -947,8 +948,13 @@
 static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
 {
   for (; table ; table= table->next)
+  {
     if (table->query_id == thd->query_id)
+    {
       table->query_id= 0;
+      table->file->ha_reset();
+    }
+  }
 }
 
 
@@ -1028,21 +1034,13 @@
     */
     ha_commit_stmt(thd);
 
-    /* We are under simple LOCK TABLES so should not do anything else. */
-    if (!prelocked_mode)
-      DBUG_VOID_RETURN;
+    /* Ensure we are calling ha_reset() for all used tables */
+    mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
 
-    if (!thd->lex->requires_prelocking())
-    {
-      /*
-        If we are executing one of substatements we have to mark
-        all tables which it used as free for reuse.
-      */
-      mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
+    /* We are under simple LOCK TABLES so should not do anything else. */
+    if (!prelocked_mode || !thd->lex->requires_prelocking())
       DBUG_VOID_RETURN;
-    }
 
-    DBUG_ASSERT(prelocked_mode);
     /*
       We are in prelocked mode, so we have to leave it now with doing
       implicit UNLOCK TABLES if need.
@@ -1096,7 +1094,7 @@
 
   found_old_table= 0;
   while (thd->open_tables)
-    found_old_table|=close_thread_table(thd, &thd->open_tables);
+    found_old_table|= close_thread_table(thd, &thd->open_tables);
   thd->some_tables_deleted=0;
 
   /* Free tables to hold down open files */
@@ -1125,6 +1123,7 @@
   DBUG_VOID_RETURN;
 }
 
+
 /* move one table to free list */
 
 bool close_thread_table(THD *thd, TABLE **table_ptr)
@@ -1149,11 +1148,8 @@
       table->s->flush_version= flush_version;
       table->file->extra(HA_EXTRA_FLUSH);
     }
-    else
-    {
-      // Free memory and reset for next loop
-      table->file->ha_reset();
-    }
+    // Free memory and reset for next loop
+    table->file->ha_reset();
     table->in_use=0;
     if (unused_tables)
     {
@@ -1189,8 +1185,10 @@
 
   if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
   {
-    for (table= thd->temporary_tables; table; table= table->next)
+    TABLE *next;
+    for (table= thd->temporary_tables; table; table= next)
     {
+      next=table->next;
       close_temporary(table, 1, 1);
     }
     thd->temporary_tables= 0;
@@ -1198,7 +1196,9 @@
   }
 
   TABLE *next,
-    *prev_table /* prev link is not maintained in TABLE's double-linked list */;
+    *prev_table /* TODO: 5.1 maintaines prev link in temporary_tables
+                   double-linked list so we could fix it. But it is not necessary
+                   at this time when the list is being destroyed */;
   bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
   // Better add "if exists", in case a RESET MASTER has been done
   const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
@@ -1310,7 +1310,6 @@
   thd->temporary_tables=0;
 }
 
-
 /*
   Find table in list.
 
@@ -1526,17 +1525,37 @@
 }
 
 /*
-  Close temporary table and unlink from thd->temporary tables
+  unlink from thd->temporary tables and close temporary table
 */
 
 void close_temporary_table(THD *thd, TABLE *table,
                            bool free_share, bool delete_table)
 {
-  TABLE **prev= table->open_prev;
-  if ((*table->open_prev= table->next))
-    table->next->open_prev= prev;
+  if (table->prev)
+  {
+    table->prev->next= table->next;
+    if (table->prev->next)
+      table->next->prev= table->prev;
+  }
+  else
+  {
+    /* removing the item from the list */
+    DBUG_ASSERT(table == thd->temporary_tables);
+    /*
+      slave must reset its temporary list pointer to zero to exclude
+      passing non-zero value to end_slave via rli->save_temporary_tables
+      when no temp tables opened, see an invariant below.
+    */
+    thd->temporary_tables= table->next;
+    if (thd->temporary_tables)
+      table->next->prev= 0;
+  }
   if (thd->slave_thread)
+  {
+    /* natural invariant of temporary_tables */
+    DBUG_ASSERT(slave_open_temp_tables || !thd->temporary_tables);
     slave_open_temp_tables--;
+  }
   close_temporary(table, free_share, delete_table);
 }
 
@@ -1678,6 +1697,7 @@
   thd->mysys_var->current_cond= cond;
   proc_info=thd->proc_info;
   thd->proc_info="Waiting for table";
+  DBUG_ENTER("wait_for_condition");
   if (!thd->killed)
     (void) pthread_cond_wait(cond, mutex);
 
@@ -1698,6 +1718,7 @@
   thd->mysys_var->current_cond= 0;
   thd->proc_info= proc_info;
   pthread_mutex_unlock(&thd->mysys_var->mutex);
+  DBUG_VOID_RETURN;
 }
 
 
@@ -1786,6 +1807,8 @@
                           MYSQL_LOCK_IGNORE_FLUSH - Open table even if
                           someone has done a flush or namelock on it.
                           No version number checking is done.
+                          MYSQL_OPEN_IGNORE_LOCKED_TABLES - Open table
+                          ignoring set of locked tables and prelocked mode.
 
   IMPLEMENTATION
     Uses a cache of open tables to find a table not in use.
@@ -1845,7 +1868,8 @@
     }
   }
 
-  if (thd->locked_tables || thd->prelocked_mode)
+  if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) &&
+      (thd->locked_tables || thd->prelocked_mode))
   {						// Using table locks
     TABLE *best_table= 0;
     int best_distance= INT_MIN;
@@ -1973,6 +1997,10 @@
   {
     if (table->s->version != refresh_version)
     {
+      DBUG_PRINT("note",
+                 ("Found table '%s.%s' with different refresh version",
+                  table_list->db, table_list->table_name));
+
       /*
         Don't close tables if we are working with a log table or were
         asked not to close the table explicitly
@@ -2080,6 +2108,7 @@
   if (table->timestamp_field)
     table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
   table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
+  table->clear_column_bitmaps();
   DBUG_ASSERT(table->key_read == 0);
   DBUG_RETURN(table);
 }
@@ -2177,6 +2206,7 @@
     VOID(closefrm(table, 1));		// close file, free everything
 
   *table= tmp;
+  table->default_column_bitmaps();
   table->file->change_table_ptr(table, table->s);
 
   DBUG_ASSERT(table->alias != 0);
@@ -2675,7 +2705,7 @@
       goto err;
 
      // Code below is for repairing a crashed file
-     if ((error= lock_table_name(thd, table_list)))
+     if ((error= lock_table_name(thd, table_list, TRUE)))
      {
        if (error < 0)
  	goto err;
@@ -3493,10 +3523,12 @@
 
   if (link_in_list)
   {
-    tmp_table->open_prev= &thd->temporary_tables;
-    if ((tmp_table->next= thd->temporary_tables))
-      thd->temporary_tables->open_prev= &tmp_table->next;
+    /* growing temp list at the head */
+    tmp_table->next= thd->temporary_tables;
+    if (tmp_table->next)
+      tmp_table->next->prev= tmp_table;
     thd->temporary_tables= tmp_table;
+    thd->temporary_tables->prev= 0;
     if (thd->slave_thread)
       slave_open_temp_tables++;
   }
@@ -3544,22 +3576,50 @@
 
 static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
 {
-  if (thd->set_query_id)
+  DBUG_ENTER("update_field_dependencies");
+  if (thd->mark_used_columns != MARK_COLUMNS_NONE)
   {
-    table->file->ha_set_bit_in_rw_set(field->fieldnr,
-                                      (bool)(thd->set_query_id-1));
-    if (field->query_id != thd->query_id)
-    {
-      if (table->get_fields_in_item_tree)
-        field->flags|= GET_FIXED_FIELDS_FLAG;
-      field->query_id= thd->query_id;
-      table->used_fields++;
-      table->used_keys.intersect(field->part_of_key);
+    MY_BITMAP *current_bitmap, *other_bitmap;
+
+    /*
+      We always want to register the used keys, as the column bitmap may have
+      been set for all fields (for example for view).
+    */
+      
+    table->used_keys.intersect(field->part_of_key);
+    table->merge_keys.merge(field->part_of_key);
+
+    if (thd->mark_used_columns == MARK_COLUMNS_READ)
+    {
+      current_bitmap= table->read_set;
+      other_bitmap=   table->write_set;
     }
     else
-      thd->dupp_field= field;
-  } else if (table->get_fields_in_item_tree)
+    {
+      current_bitmap= table->write_set;
+      other_bitmap=   table->read_set;
+    }
+
+    if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
+    {
+      if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
+      {
+        DBUG_PRINT("warning", ("Found duplicated field"));
+        thd->dup_field= field;
+      }
+      else
+      {
+        DBUG_PRINT("note", ("Field found before"));
+      }
+      DBUG_VOID_RETURN;
+    }
+    if (table->get_fields_in_item_tree)
+      field->flags|= GET_FIXED_FIELDS_FLAG;
+    table->used_fields++;
+  }
+  else if (table->get_fields_in_item_tree)
     field->flags|= GET_FIXED_FIELDS_FLAG;
+  DBUG_VOID_RETURN;
 }
 
 
@@ -3968,12 +4028,12 @@
       fld= WRONG_GRANT;
     else
 #endif
-      if (thd->set_query_id)
+      if (thd->mark_used_columns != MARK_COLUMNS_NONE)
       {
         /*
-         * get rw_set correct for this field so that the handler
-         * knows that this field is involved in the query and gets
-         * retrieved/updated
+          Get rw_set correct for this field so that the handler
+          knows that this field is involved in the query and gets
+          retrieved/updated
          */
         Field *field_to_set= NULL;
         if (fld == view_ref_found)
@@ -3981,13 +4041,22 @@
           Item *it= (*ref)->real_item();
           if (it->type() == Item::FIELD_ITEM)
             field_to_set= ((Item_field*)it)->field;
+          else
+          {
+            if (thd->mark_used_columns == MARK_COLUMNS_READ)
+              it->walk(&Item::register_field_in_read_map, 1, (byte *) 0);
+          }
         }
         else
           field_to_set= fld;
         if (field_to_set)
-          field_to_set->table->file->
-            ha_set_bit_in_rw_set(field_to_set->fieldnr,
-                                 (bool)(thd->set_query_id-1));
+        {
+          TABLE *table= field_to_set->table;
+          if (thd->mark_used_columns == MARK_COLUMNS_READ)
+            bitmap_set_bit(table->read_set, field_to_set->field_index);
+          else
+            bitmap_set_bit(table->write_set, field_to_set->field_index);
+        }
       }
   }
   DBUG_RETURN(fld);
@@ -4680,17 +4749,17 @@
       {
         TABLE *table_1= nj_col_1->table_ref->table;
         /* Mark field_1 used for table cache. */
-        field_1->query_id= thd->query_id;
-        table_1->file->ha_set_bit_in_read_set(field_1->fieldnr);
+        bitmap_set_bit(table_1->read_set, field_1->field_index);
         table_1->used_keys.intersect(field_1->part_of_key);
+        table_1->merge_keys.merge(field_1->part_of_key);
       }
       if (field_2)
       {
         TABLE *table_2= nj_col_2->table_ref->table;
         /* Mark field_2 used for table cache. */
-        field_2->query_id= thd->query_id;
-        table_2->file->ha_set_bit_in_read_set(field_2->fieldnr);
+        bitmap_set_bit(table_2->read_set, field_2->field_index);
         table_2->used_keys.intersect(field_2->part_of_key);
+        table_2->merge_keys.merge(field_2->part_of_key);
       }
 
       if (using_fields != NULL)
@@ -5036,10 +5105,6 @@
   if (from_clause->elements == 0)
     return FALSE; /* We come here in the case of UNIONs. */
 
-  /* For stored procedures do not redo work if already done. */
-  if (!context->select_lex->first_execution)
-    return FALSE;
-
   List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause);
   TABLE_LIST *table_ref; /* Current table reference. */
   /* Table reference to the left of the current. */
@@ -5052,14 +5117,18 @@
   {
     table_ref= left_neighbor;
     left_neighbor= table_ref_it++;
-    if (store_top_level_join_columns(thd, table_ref,
-                                     left_neighbor, right_neighbor))
-      return TRUE;
-    if (left_neighbor)
+    /* For stored procedures do not redo work if already done. */
+    if (context->select_lex->first_execution)
     {
-      TABLE_LIST *first_leaf_on_the_right;
-      first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
-      left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
+      if (store_top_level_join_columns(thd, table_ref,
+                                       left_neighbor, right_neighbor))
+        return TRUE;
+      if (left_neighbor)
+      {
+        TABLE_LIST *first_leaf_on_the_right;
+        first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
+        left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
+      }
     }
     right_neighbor= table_ref;
   }
@@ -5158,17 +5227,17 @@
 ****************************************************************************/
 
 bool setup_fields(THD *thd, Item **ref_pointer_array,
-                  List<Item> &fields, ulong set_query_id,
+                  List<Item> &fields, enum_mark_columns mark_used_columns,
                   List<Item> *sum_func_list, bool allow_sum_func)
 {
   reg2 Item *item;
-  ulong save_set_query_id= thd->set_query_id;
+  enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
   nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
   List_iterator<Item> it(fields);
   DBUG_ENTER("setup_fields");
 
-  thd->set_query_id=set_query_id;
-  DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
+  thd->mark_used_columns= mark_used_columns;
+  DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
   if (allow_sum_func)
     thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
   thd->where= THD::DEFAULT_WHERE;
@@ -5194,8 +5263,8 @@
 	(item= *(it.ref()))->check_cols(1))
     {
       thd->lex->allow_sum_func= save_allow_sum_func;
-      thd->set_query_id= save_set_query_id;
-      DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
+      thd->mark_used_columns= save_mark_used_columns;
+      DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
       DBUG_RETURN(TRUE); /* purecov: inspected */
     }
     if (ref)
@@ -5206,8 +5275,8 @@
     thd->used_tables|= item->used_tables();
   }
   thd->lex->allow_sum_func= save_allow_sum_func;
-  thd->set_query_id= save_set_query_id;
-  DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
+  thd->mark_used_columns= save_mark_used_columns;
+  DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
   DBUG_RETURN(test(thd->net.report_error));
 }
 
@@ -5251,7 +5320,6 @@
     context       name resolution contest to setup table list there
     from_clause   Top-level list of table references in the FROM clause
     tables	  Table list (select_lex->table_list)
-    conds	  Condition of current SELECT (can be changed by VIEW)
     leaves        List of join table leaves list (select_lex->leaf_tables)
     refresh       It is onle refresh for subquery
     select_insert It is SELECT ... INSERT command
@@ -5273,7 +5341,7 @@
 
 bool setup_tables(THD *thd, Name_resolution_context *context,
                   List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
-                  Item **conds, TABLE_LIST **leaves, bool select_insert)
+                  TABLE_LIST **leaves, bool select_insert)
 {
   uint tablenr= 0;
   DBUG_ENTER("setup_tables");
@@ -5296,6 +5364,7 @@
        table_list= table_list->next_leaf, tablenr++)
   {
     TABLE *table= table_list->table;
+    table->pos_in_table_list= table_list;
     if (first_select_table &&
         table_list->top_table() == first_select_table)
     {
@@ -5305,6 +5374,7 @@
     }
     setup_table_map(table, table_list, tablenr);
     table->used_keys= table->s->keys_for_keyread;
+    table->merge_keys.clear_all();
     if (table_list->use_index)
     {
       key_map map;
@@ -5359,6 +5429,58 @@
 
 
 /*
+  prepare tables and check access for the view tables
+
+  SYNOPSIS
+    setup_tables_and_check_view_access()
+    thd		  Thread handler
+    context       name resolution contest to setup table list there
+    from_clause   Top-level list of table references in the FROM clause
+    tables	  Table list (select_lex->table_list)
+    conds	  Condition of current SELECT (can be changed by VIEW)
+    leaves        List of join table leaves list (select_lex->leaf_tables)
+    refresh       It is onle refresh for subquery
+    select_insert It is SELECT ... INSERT command
+    want_access   what access is needed
+
+  NOTE
+    a wrapper for check_tables that will also check the resulting
+    table leaves list for access to all the tables that belong to a view
+
+  RETURN
+    FALSE ok;  In this case *map will include the chosen index
+    TRUE  error
+*/
+bool setup_tables_and_check_access(THD *thd, 
+                                   Name_resolution_context *context,
+                                   List<TABLE_LIST> *from_clause,
+                                   TABLE_LIST *tables,
+                                   TABLE_LIST **leaves,
+                                   bool select_insert,
+                                   ulong want_access)
+{
+  TABLE_LIST *leaves_tmp= NULL;
+
+  if (setup_tables(thd, context, from_clause, tables,
+                   &leaves_tmp, select_insert))
+    return TRUE;
+
+  *leaves= leaves_tmp;
+
+  for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
+  {
+    if (leaves_tmp->belong_to_view && 
+        check_single_table_access(thd, want_access,  leaves_tmp))
+    {
+      tables->hide_view_error(thd);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+/*
    Create a key_map from a list of index names
 
    SYNOPSIS
@@ -5387,8 +5509,8 @@
                         name->length(), 1)) <=
         0)
     {
-      my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
-	       table->s->table_name.str);
+      my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
+	       table->pos_in_table_list->alias);
       map->set_all();
       return 1;
     }
@@ -5478,7 +5600,6 @@
     }
 #endif
 
-
     /*
       Update the tables used in the query based on the referenced fields. For
       views and natural joins this update is performed inside the loop below.
@@ -5544,18 +5665,13 @@
 
       if ((field= field_iterator.field()))
       {
-        /*
-          Mark if field used before in this select.
-          Used by 'insert' to verify if a field name is used twice.
-        */
-        if (field->query_id == thd->query_id)
-          thd->dupp_field= field;
-        field->query_id= thd->query_id;
-        field->table->file->ha_set_bit_in_read_set(field->fieldnr);
-
+        /* Mark fields as used to allow storage engine to optimze access */
+        bitmap_set_bit(field->table->read_set, field->field_index);
         if (table)
+        {
           table->used_keys.intersect(field->part_of_key);
-
+          table->merge_keys.merge(field->part_of_key);
+        }
         if (tables->is_natural_join)
         {
           TABLE *field_table;
@@ -5572,16 +5688,13 @@
           {
             thd->used_tables|= field_table->map;
             field_table->used_keys.intersect(field->part_of_key);
+            field_table->merge_keys.merge(field->part_of_key);
             field_table->used_fields++;
           }
         }
       }
       else
-      {
         thd->used_tables|= item->used_tables();
-        item->walk(&Item::reset_query_id_processor,
-                   (byte *)(&thd->query_id));
-      }
     }
     /*
       In case of stored tables, all fields are considered as used,
@@ -5590,10 +5703,7 @@
       For NATURAL joins, used_tables is updated in the IF above.
     */
     if (table)
-    {
       table->used_fields= table->s->fields;
-      table->file->ha_set_all_bits_in_read_set();
-    }
   }
   if (found)
     DBUG_RETURN(FALSE);
@@ -5652,8 +5762,8 @@
       arena->is_conventional())
     arena= 0;                                   // For easier test
 
-  thd->set_query_id=1;
-  DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
+  thd->mark_used_columns= MARK_COLUMNS_READ;
+  DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
   select_lex->cond_count= 0;
 
   for (table= tables; table; table= table->next_local)
@@ -5908,7 +6018,7 @@
 
       if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length))
       {
-        sprintf(filePath,"%s%s",tmpdir,file->name);
+        sprintf(filePath,"%s%c%s",tmpdir,FN_LIBCHAR,file->name);
         VOID(my_delete(filePath,MYF(MY_WME)));
       }
     }
@@ -5994,6 +6104,7 @@
   TABLE_SHARE *share;
   bool result= 0, signalled= 0;
   DBUG_ENTER("remove_table_from_cache");
+  DBUG_PRINT("enter", ("Table: '%s.%s'  flags: %u", db, table_name, flags));
 
   key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
   for (;;)
@@ -6020,7 +6131,10 @@
         DBUG_PRINT("info", ("Table was in use by other thread"));
         in_use->some_tables_deleted=1;
         if (table->db_stat)
+        {
+          DBUG_PRINT("info", ("Found another active instance of the table"));
   	  result=1;
+        }
         /* Kill delayed insert threads */
         if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
             ! in_use->killed)
@@ -6075,6 +6189,12 @@
 
     if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
     {
+      /*
+        Signal any thread waiting for tables to be freed to
+        reopen their tables
+      */
+      (void) pthread_cond_broadcast(&COND_refresh);
+      DBUG_PRINT("info", ("Waiting for refresh signal"));
       if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
       {
         dropping_tables++;
@@ -6154,7 +6274,7 @@
     alias	  alias for table
     db            database
     table_name    name of table
-    db_stat	  open flags (for example HA_OPEN_KEYFILE|HA_OPEN_RNDFILE..)
+    db_stat	  open flags (for example ->OPEN_KEYFILE|HA_OPEN_RNDFILE..)
 		  can be 0 (example in ha_example_table)
     prgflag	  READ_ALL etc..
     ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..

--- 1.30/mysql-test/r/rpl_temporary.result	2006-07-09 00:29:40 +03:00
+++ 1.31/mysql-test/r/rpl_temporary.result	2006-07-09 00:29:40 +03:00
@@ -76,16 +76,11 @@
 create temporary table t3 (f int);
 create temporary table t4 (f int);
 create table t5 (f int);
-drop table if exists t999;
-create temporary table t999 (f int);
-LOAD DATA INFILE "./tmp/bl_dump_thread_id" into table t999;
-drop table t999;
-insert into t4 values (1);
-kill `select id from information_schema.processlist where command='Binlog Dump'`;
+select id from information_schema.processlist where command='Binlog Dump' into @id;
+kill @id;
 insert into t5 select * from t4;
 select * from t5 /* must be 1 after reconnection */;
 f
-1
 drop temporary table t4;
 drop table t5;
 set @@session.pseudo_thread_id=100;
@@ -105,4 +100,7 @@
 f
 1
 drop table t1;
-End of 5.1 tests
+select * from t1;
+a
+1
+drop table t1;

--- 1.27/mysql-test/t/rpl_temporary.test	2006-07-09 00:29:40 +03:00
+++ 1.28/mysql-test/t/rpl_temporary.test	2006-07-09 00:29:40 +03:00
@@ -142,11 +142,8 @@
 create table t5 (f int);
 sync_with_master;
 # find dumper's $id
-source include/get_binlog_dump_thread_id.inc;
-insert into t4 values (1);
-# a hint how to do that in 5.1
---replace_result $id "`select id from information_schema.processlist where command='Binlog Dump'`"
-eval kill $id; # to stimulate reconnection by slave w/o timeout
+select id from information_schema.processlist where command='Binlog Dump' into @id;
+kill @id; # to stimulate reconnection by slave w/o timeout
 insert into t5 select * from t4;
 save_master_pos;
 
@@ -190,5 +187,17 @@
 
 connection master; 
 drop table t1;
---echo End of 5.1 tests
 
+#
+#14157: utf8 encoding in binlog without set character_set_client
+#
+
+sync_slave_with_master;
+#connection slave;
+select * from t1;
+
+connection master; 
+drop table t1;
+
+# End of 5.1 tests
Thread
bk commit into 5.1 tree (aelkin:1.2243) BUG#19881Andrei Elkin8 Jul