List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:April 21 2008 6:14am
Subject:bk commit into 5.0 tree (sergefp:1.2602) BUG#35478
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of sergefp.  When sergefp 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, 2008-04-21 08:14:30+04:00, sergefp@stripped +11 -0
  BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
  - In QUICK_INDEX_MERGE_SELECT::read_keys_and_merge: when we got table->sort from
Unique,
    tell init_read_record() not to use rr_from_cache() because a) rowids are already
sorted
    and b) it might be that the the data is used by filesort(), which will need record
rowids
    (which rr_from_cache() cannot provide).
  - Fully de-initialize the table->sort read in QUICK_INDEX_MERGE_SELECT::get_next().
This fixes BUG#35477.
  (bk trigger: file as fix for BUG#35478).

  sql/filesort.cc@stripped, 2008-04-21 08:14:21+04:00, sergefp@stripped +53 -13
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - make find_all_keys() use quick->get_next() instead of
init_read_record(r)/r.read_record() calls
    - added dbug printout

  sql/mysql_priv.h@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +2 -2
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/opt_range.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +10 -5
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - In QUICK_INDEX_MERGE_SELECT::read_keys_and_merge: when we got table->sort from
Unique,
      tell init_read_record() not to use rr_from_cache() because a) rowids are already
sorted
      and b) it might be that the the data is used by filesort(), which will need record
rowids
      (which rr_from_cache() cannot provide).
    - Fully de-initialize the table->sort read in QUICK_INDEX_MERGE_SELECT::get_next().

  sql/records.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +40 -3
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added disable_rr_cache parameter to init_read_record
    - Added comment

  sql/sql_acl.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +4 -3
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/sql_delete.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +2 -2
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/sql_help.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +4 -4
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/sql_select.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +1 -1
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/sql_table.cc@stripped, 2008-04-21 08:14:22+04:00, sergefp@stripped +1 -1
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/sql_udf.cc@stripped, 2008-04-21 08:14:23+04:00, sergefp@stripped +1 -1
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

  sql/sql_update.cc@stripped, 2008-04-21 08:14:23+04:00, sergefp@stripped +2 -2
    BUG#35478: sort_union() returns bad data when sort_buffer_size is hit
    - Added parameter to init_read_record

diff -Nrup a/sql/filesort.cc b/sql/filesort.cc
--- a/sql/filesort.cc	2008-03-12 10:54:53 +03:00
+++ b/sql/filesort.cc	2008-04-21 08:14:21 +04:00
@@ -402,6 +402,56 @@ static byte *read_buffpek_from_file(IO_C
   DBUG_RETURN(tmp);
 }
 
+#ifndef DBUG_OFF
+/*
+  Print a text, SQL-like record representation into dbug trace.
+
+  Note: this function is a work in progress: at the moment
+   - column read bitmap is ignored (can print garbage for unused columns)
+   - there is no quoting
+*/
+static void dbug_print_record(TABLE *table, bool print_rowid)
+{
+  char buff[1024];
+  Field **pfield;
+  String tmp(buff,sizeof(buff),&my_charset_bin);
+  DBUG_LOCK_FILE;
+  
+  fprintf(DBUG_FILE, "record (");
+  for (pfield= table->field; *pfield ; pfield++)
+    fprintf(DBUG_FILE, "%s%s", (*pfield)->field_name, (pfield[1])? ", ":"");
+  fprintf(DBUG_FILE, ") = ");
+
+  fprintf(DBUG_FILE, "(");
+  for (pfield= table->field; *pfield ; pfield++)
+  {
+    Field *field=  *pfield;
+
+    if (field->is_null())
+      fwrite("NULL", sizeof(char), 4, DBUG_FILE);
+   
+    if (field->type() == MYSQL_TYPE_BIT)
+      (void) field->val_int_as_str(&tmp, 1);
+    else
+      field->val_str(&tmp);
+
+    fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
+    if (pfield[1])
+      fwrite(", ", sizeof(char), 2, DBUG_FILE);
+  }
+  fprintf(DBUG_FILE, ")");
+  if (print_rowid)
+  {
+    fprintf(DBUG_FILE, " rowid ");
+    for (uint i=0; i < table->file->ref_length; i++)
+    {
+      fprintf(DBUG_FILE, "%x", (uchar)table->file->ref[i]);
+    }
+  }
+  fprintf(DBUG_FILE, "\n");
+  DBUG_UNLOCK_FILE;
+}
+#endif 
 
 /* 
   Search after sort_keys and write them into tempfile.
@@ -475,25 +525,23 @@ static ha_rows find_all_keys(SORTPARAM *
 		    current_thd->variables.read_buff_size);
   }
 
-  READ_RECORD read_record_info;
   if (quick_select)
   {
     if (select->quick->reset())
       DBUG_RETURN(HA_POS_ERROR);
-    init_read_record(&read_record_info, current_thd, select->quick->head,
-                     select, 1, 1);
   }
 
   for (;;)
   {
     if (quick_select)
     {
-      if ((error= read_record_info.read_record(&read_record_info)))
+      if ((error= select->quick->get_next()))
       {
         error= HA_ERR_END_OF_FILE;
         break;
       }
       file->position(sort_form->record[0]);
+      DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
     }
     else					/* Not quick-select */
     {
@@ -550,15 +598,7 @@ static ha_rows find_all_keys(SORTPARAM *
     if (thd->net.report_error)
       break;
   }
-  if (quick_select)
-  {
-    /*
-      index_merge quick select uses table->sort when retrieving rows, so free
-      resoures it has allocated.
-    */
-    end_read_record(&read_record_info);
-  }
-  else
+  if (!quick_select)
   {
     (void) file->extra(HA_EXTRA_NO_CACHE);	/* End cacheing of records */
     if (!next_pos)
diff -Nrup a/sql/mysql_priv.h b/sql/mysql_priv.h
--- a/sql/mysql_priv.h	2008-03-21 18:23:13 +03:00
+++ b/sql/mysql_priv.h	2008-04-21 08:14:22 +04:00
@@ -1550,8 +1550,8 @@ ulonglong get_datetime_value(THD *thd, I
 int test_if_number(char *str,int *res,bool allow_wildcards);
 void change_byte(byte *,uint,char,char);
 void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
-		      SQL_SELECT *select,
-		      int use_record_cache, bool print_errors);
+		      SQL_SELECT *select, int use_record_cache, 
+                      bool print_errors, bool disable_rr_cache);
 void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, 
                           bool print_error, uint idx);
 void end_read_record(READ_RECORD *info);
diff -Nrup a/sql/opt_range.cc b/sql/opt_range.cc
--- a/sql/opt_range.cc	2008-01-23 18:01:28 +03:00
+++ b/sql/opt_range.cc	2008-04-21 08:14:22 +04:00
@@ -6476,7 +6476,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
   QUICK_RANGE_SELECT* cur_quick;
   int result;
   Unique *unique;
-  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::prepare_unique");
+  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
 
   /* We're going to just read rowids. */
   if (head->file->extra(HA_EXTRA_KEYREAD))
@@ -6547,13 +6547,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
 
   }
 
-  /* ok, all row ids are in Unique */
+  /*
+    Ok all rowids are in the Unique now. The next call will initialize
+    head->sort structure so it can be used to iterate through the rowids
+    sequence.
+  */
   result= unique->get(head);
   delete unique;
   doing_pk_scan= FALSE;
-  /* start table scan */
-  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
-  /* index_merge currently doesn't support "using index" at all */
+
+  /* Start the rnd_pos() scan. */
+  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
   head->file->extra(HA_EXTRA_NO_KEYREAD);
 
   DBUG_RETURN(result);
@@ -6583,6 +6587,7 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
   {
     result= HA_ERR_END_OF_FILE;
     end_read_record(&read_record);
+    free_io_cache(head);
     /* All rows from Unique have been retrieved, do a clustered PK scan */
     if (pk_quick_select)
     {
diff -Nrup a/sql/records.cc b/sql/records.cc
--- a/sql/records.cc	2007-10-17 20:08:53 +04:00
+++ b/sql/records.cc	2008-04-21 08:14:22 +04:00
@@ -72,11 +72,47 @@ void init_read_record_idx(READ_RECORD *i
 }
 
 
-/* init struct for read with info->read_record */
+/*
+  init struct for read with info->read_record 
+
+  SYNOPSIS
+    init_read_record()
+      info              OUT read structure
+      thd               Thread handle
+      table             Table the data [originally] comes from.
+      select            SQL_SELECT structure. We may select->quick or 
+                        select->file as data source
+      use_record_cache  Call file->extra_opt(HA_EXTRA_CACHE,...)
+                        if we're going to do sequential read and some
+                        additional conditions are satisfied.
+      print_error       Copy this to info->print_error
+      disable_rr_cache  Don't use rr_from_cache (used by sort-union
+                        index-merge which produces rowid sequences that 
+                        are already ordered)
+
+  DESCRIPTION
+    This function sets up reading data via one of the methods:
+
+    rr_unpack_from_tempfile  Unpack full records from sequential file
+    rr_unpack_from_buffer    ... or from buffer
+    
+    rr_from_tempfile         Read rowids from tempfile and get full records
+                             with handler->rnd_pos() calls.
+    rr_from_pointers         ... or get rowids from buffer
+    
+    rr_from_cache            Read a bunch of rowids from file, sort them, 
+                             get records in rowid order, return, repeat.
+
+    rr_quick                 Get data from QUICK_*_SELECT
+    
+    rr_sequential            Sequentially scan the table using
+                             handler->rnd_next() calls
+*/
 
 void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
 		      SQL_SELECT *select,
-		      int use_record_cache, bool print_error)
+		      int use_record_cache, bool print_error, 
+                      bool disable_rr_cache)
 {
   IO_CACHE *tempfile;
   DBUG_ENTER("init_read_record");
@@ -121,7 +157,8 @@ void init_read_record(READ_RECORD *info,
       it doesn't make sense to use cache - we don't read from the table
       and table->sort.io_cache is read sequentially
     */
-    if (!table->sort.addon_field &&
+    if (!disable_rr_cache &&
+        !table->sort.addon_field &&
         ! (specialflag & SPECIAL_SAFE_MODE) &&
 	thd->variables.read_rnd_buff_size &&
 	!(table->file->table_flags() & HA_FAST_KEY_READ) &&
diff -Nrup a/sql/sql_acl.cc b/sql/sql_acl.cc
--- a/sql/sql_acl.cc	2008-03-21 18:23:14 +03:00
+++ b/sql/sql_acl.cc	2008-04-21 08:14:22 +04:00
@@ -205,7 +205,8 @@ static my_bool acl_load(THD *thd, TABLE_
   acl_cache->clear(1);				// Clear locked hostname cache
 
   init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
-  init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, 
+                   FALSE);
   VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50));
   while (!(read_record_info.read_record(&read_record_info)))
   {
@@ -253,7 +254,7 @@ static my_bool acl_load(THD *thd, TABLE_
   end_read_record(&read_record_info);
   freeze_size(&acl_hosts);
 
-  init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE);
   VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100));
   password_length= table->field[2]->field_length /
     table->field[2]->charset()->mbmaxlen;
@@ -426,7 +427,7 @@ static my_bool acl_load(THD *thd, TABLE_
   end_read_record(&read_record_info);
   freeze_size(&acl_users);
 
-  init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE);
   VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100));
   while (!(read_record_info.read_record(&read_record_info)))
   {
diff -Nrup a/sql/sql_delete.cc b/sql/sql_delete.cc
--- a/sql/sql_delete.cc	2008-03-27 14:52:54 +03:00
+++ b/sql/sql_delete.cc	2008-04-21 08:14:22 +04:00
@@ -214,7 +214,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     DBUG_RETURN(TRUE);
   }
   if (usable_index==MAX_KEY)
-    init_read_record(&info,thd,table,select,1,1);
+    init_read_record(&info, thd, table, select, 1, 1, FALSE);
   else
     init_read_record_idx(&info, thd, table, 1, usable_index);
 
@@ -772,7 +772,7 @@ int multi_delete::do_deletes()
     }
 
     READ_RECORD	info;
-    init_read_record(&info,thd,table,NULL,0,1);
+    init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
     /*
       Ignore any rows not found in reference tables as they may already have
       been deleted by foreign key handling
diff -Nrup a/sql/sql_help.cc b/sql/sql_help.cc
--- a/sql/sql_help.cc	2007-10-17 20:08:53 +04:00
+++ b/sql/sql_help.cc	2008-04-21 08:14:22 +04:00
@@ -181,7 +181,7 @@ int search_topics(THD *thd, TABLE *topic
   int count= 0;
 
   READ_RECORD read_record_info;
-  init_read_record(&read_record_info, thd, topics, select,1,0);
+  init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE);
   while (!read_record_info.read_record(&read_record_info))
   {
     if (!select->cond->val_int())		// Doesn't match like
@@ -221,7 +221,7 @@ int search_keyword(THD *thd, TABLE *keyw
   int count= 0;
 
   READ_RECORD read_record_info;
-  init_read_record(&read_record_info, thd, keywords, select,1,0);
+  init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE);
   while (!read_record_info.read_record(&read_record_info) && count<2)
   {
     if (!select->cond->val_int())		// Dosn't match like
@@ -346,7 +346,7 @@ int search_categories(THD *thd, TABLE *c
 
   DBUG_ENTER("search_categories");
 
-  init_read_record(&read_record_info, thd, categories, select,1,0);
+  init_read_record(&read_record_info, thd, categories, select,1,0,FALSE);
   while (!read_record_info.read_record(&read_record_info))
   {
     if (select && !select->cond->val_int())
@@ -380,7 +380,7 @@ void get_all_items_for_category(THD *thd
   DBUG_ENTER("get_all_items_for_category");
 
   READ_RECORD read_record_info;
-  init_read_record(&read_record_info, thd, items, select,1,0);
+  init_read_record(&read_record_info, thd, items, select,1,0,FALSE);
   while (!read_record_info.read_record(&read_record_info))
   {
     if (!select->cond->val_int())
diff -Nrup a/sql/sql_select.cc b/sql/sql_select.cc
--- a/sql/sql_select.cc	2008-03-26 21:10:00 +03:00
+++ b/sql/sql_select.cc	2008-04-21 08:14:22 +04:00
@@ -11331,7 +11331,7 @@ join_init_read_record(JOIN_TAB *tab)
   if (tab->select && tab->select->quick &&
tab->select->quick->reset())
     return 1;
   init_read_record(&tab->read_record, tab->join->thd, tab->table,
-		   tab->select,1,1);
+		   tab->select,1,1, FALSE);
   return (*tab->read_record.read_record)(&tab->read_record);
 }
 
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc	2008-01-23 18:01:29 +03:00
+++ b/sql/sql_table.cc	2008-04-21 08:14:22 +04:00
@@ -4170,7 +4170,7 @@ copy_data_between_tables(TABLE *from,TAB
     current query id
   */
   from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
-  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
+  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
   if (ignore)
     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
   thd->row_count= 0;
diff -Nrup a/sql/sql_udf.cc b/sql/sql_udf.cc
--- a/sql/sql_udf.cc	2007-11-09 13:41:46 +03:00
+++ b/sql/sql_udf.cc	2008-04-21 08:14:23 +04:00
@@ -176,7 +176,7 @@ void udf_init()
   }
 
   table= tables.table;
-  init_read_record(&read_record_info, new_thd, table, NULL,1,0);
+  init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE);
   while (!(error = read_record_info.read_record(&read_record_info)))
   {
     DBUG_PRINT("info",("init udf record"));
diff -Nrup a/sql/sql_update.cc b/sql/sql_update.cc
--- a/sql/sql_update.cc	2008-03-27 14:52:54 +03:00
+++ b/sql/sql_update.cc	2008-04-21 08:14:23 +04:00
@@ -358,7 +358,7 @@ int mysql_update(THD *thd,
                Full index scan must be started with init_read_record_idx
       */
       if (used_index == MAX_KEY || (select && select->quick))
-        init_read_record(&info,thd,table,select,0,1);
+        init_read_record(&info, thd, table, select, 0, 1, FALSE);
       else
         init_read_record_idx(&info, thd, table, 1, used_index);
 
@@ -422,7 +422,7 @@ int mysql_update(THD *thd,
   
   if (select && select->quick && select->quick->reset())
         goto err;
-  init_read_record(&info,thd,table,select,0,1);
+  init_read_record(&info, thd, table, select, 0, 1, FALSE);
 
   updated= found= 0;
   thd->count_cuted_fields= CHECK_FIELD_WARN;		/* calc cuted fields */
Thread
bk commit into 5.0 tree (sergefp:1.2602) BUG#35478Sergey Petrunia21 Apr