List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:July 17 2008 9:56pm
Subject:bzr push into mysql-6.0 branch (sergefp:2723 to 2724)
View as plain text  
 2724 Sergey Petrunia	2008-07-17 [merge]
      5.1-bugteam -> 6.0-bugteam merge
modified:
  mysql-test/include/mix1.inc
  mysql-test/r/innodb_mysql.result
  mysql-test/r/query_cache.result
  sql/event_db_repository.cc
  sql/events.cc
  sql/filesort.cc
  sql/mysql_priv.h
  sql/opt_range.cc
  sql/opt_range.h
  sql/records.cc
  sql/set_var.cc
  sql/share/errmsg.txt
  sql/sql_acl.cc
  sql/sql_cache.cc
  sql/sql_cache.h
  sql/sql_delete.cc
  sql/sql_help.cc
  sql/sql_plugin.cc
  sql/sql_select.cc
  sql/sql_servers.cc
  sql/sql_table.cc
  sql/sql_udf.cc
  sql/sql_update.cc

 2723 Horst Hunger	2008-07-17
      Next attempt to push these changes for 38164.
modified:
  mysql-test/include/query_prealloc_size_basic.inc
  mysql-test/r/query_prealloc_size_basic_32.result
  mysql-test/r/query_prealloc_size_basic_64.result

=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc	2008-06-20 11:40:01 +0000
+++ b/mysql-test/include/mix1.inc	2008-07-17 19:55:18 +0000
@@ -1103,6 +1103,24 @@ set @my_innodb_commit_concurrency=@@glob
 set global innodb_commit_concurrency=0;
 set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
 
+#
+# Bug #37830: ORDER BY ASC/DESC - no difference
+#
+
+CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
+ ENGINE=InnoDB;
+
+INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
+INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
+
+# should be range access
+EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+
+# should produce '8 7 6 5 4' for a
+SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+
+DROP TABLE t1;
+
 --echo End of 5.0 tests
 
 # Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY

=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result	2008-06-20 11:40:01 +0000
+++ b/mysql-test/r/innodb_mysql.result	2008-07-17 19:55:18 +0000
@@ -1363,6 +1363,21 @@ set global innodb_autoextend_increment=@
 set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
 set global innodb_commit_concurrency=0;
 set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
+CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
+ENGINE=InnoDB;
+INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
+INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
+EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	t1_b	PRIMARY	4	NULL	8	Using where
+SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+a	b	c
+8	1	1
+7	1	1
+6	1	1
+5	1	1
+4	1	1
+DROP TABLE t1;
 End of 5.0 tests
 CREATE TABLE `t2` (
 `k` int(11) NOT NULL auto_increment,

=== modified file 'mysql-test/r/query_cache.result'
--- a/mysql-test/r/query_cache.result	2008-07-16 13:57:32 +0000
+++ b/mysql-test/r/query_cache.result	2008-07-17 19:55:18 +0000
@@ -516,7 +516,7 @@ select * from t1;
 a
 set GLOBAL query_cache_size=1024;
 Warnings:
-Warning	1282	Query cache failed to set size 1024 (minimal value: 41301); new query cache size is 0
+Warning	1282	Query cache failed to set size 1024; new query cache size is 0
 show global variables like "query_cache_size";
 Variable_name	Value
 query_cache_size	0
@@ -524,7 +524,7 @@ select * from t1;
 a
 set GLOBAL query_cache_size=10240;
 Warnings:
-Warning	1282	Query cache failed to set size 10240 (minimal value: 41301); new query cache size is 0
+Warning	1282	Query cache failed to set size 10240; new query cache size is 0
 show global variables like "query_cache_size";
 Variable_name	Value
 query_cache_size	0
@@ -532,7 +532,7 @@ select * from t1;
 a
 set GLOBAL query_cache_size=20480;
 Warnings:
-Warning	1282	Query cache failed to set size 20480 (minimal value: 41301); new query cache size is 0
+Warning	1282	Query cache failed to set size 20480; new query cache size is 0
 show global variables like "query_cache_size";
 Variable_name	Value
 query_cache_size	0
@@ -540,7 +540,7 @@ select * from t1;
 a
 set GLOBAL query_cache_size=40960;
 Warnings:
-Warning	1282	Query cache failed to set size 40960 (minimal value: 41301); new query cache size is 0
+Warning	1282	Query cache failed to set size 40960; new query cache size is 0
 show global variables like "query_cache_size";
 Variable_name	Value
 query_cache_size	0

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2008-06-12 02:23:08 +0000
+++ b/sql/event_db_repository.cc	2008-07-17 19:55:18 +0000
@@ -452,7 +452,7 @@ Event_db_repository::table_scan_all_for_
   READ_RECORD read_record_info;
   DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s");
 
-  init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
+  init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE);
 
   /*
     rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
@@ -926,7 +926,7 @@ Event_db_repository::drop_events_by_fiel
     DBUG_VOID_RETURN;
 
   /* only enabled events are in memory, so we go now and delete the rest */
-  init_read_record(&read_record_info, thd, table, NULL, 1, 0);
+  init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE);
   while (!ret && !(read_record_info.read_record(&read_record_info)) )
   {
     char *et_field= get_field(thd->mem_root, table->field[field]);

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2008-06-17 20:04:19 +0000
+++ b/sql/events.cc	2008-07-17 19:55:18 +0000
@@ -1148,7 +1148,7 @@ Events::load_events_from_db(THD *thd)
     DBUG_RETURN(TRUE);
   }
 
-  init_read_record(&read_record_info, thd, table, NULL, 0, 1);
+  init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE);
   while (!(read_record_info.read_record(&read_record_info)))
   {
     Event_queue_element *et;

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2008-05-29 15:44:11 +0000
+++ b/sql/filesort.cc	2008-07-17 19:55:18 +0000
@@ -413,6 +413,56 @@ static uchar *read_buffpek_from_file(IO_
   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.
@@ -491,13 +541,10 @@ 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);
   }
 
   /* Remember original bitmaps */
@@ -517,12 +564,13 @@ static ha_rows find_all_keys(SORTPARAM *
   {
     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 */
     {
@@ -579,15 +627,7 @@ static ha_rows find_all_keys(SORTPARAM *
     if (thd->is_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)

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2008-07-15 16:29:51 +0000
+++ b/sql/mysql_priv.h	2008-07-17 19:55:18 +0000
@@ -2257,8 +2257,8 @@ ulonglong get_datetime_value(THD *thd, I
 int test_if_number(char *str,int *res,bool allow_wildcards);
 void change_byte(uchar *,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);

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2008-06-17 20:04:19 +0000
+++ b/sql/opt_range.cc	2008-07-17 19:55:18 +0000
@@ -8040,6 +8040,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
   handler *file= head->file;
   DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
 
+  /* We're going to just read rowids. */
   file->extra(HA_EXTRA_KEYREAD);
   head->prepare_for_position();
 
@@ -8098,15 +8099,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
 
   }
 
-  DBUG_PRINT("info", ("ok"));
-  /* 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;
   /* index_merge currently doesn't support "using index" at all */
   file->extra(HA_EXTRA_NO_KEYREAD);
-  /* start table scan */
-  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
+  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
   DBUG_RETURN(result);
 }
 
@@ -8132,6 +8135,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)
     {
@@ -8704,7 +8708,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
 QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
                                      uint used_key_parts_arg,
                                      bool *create_err)
- :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
+ :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
+  used_key_parts (used_key_parts_arg)
 {
   QUICK_RANGE *r;
   /* Reverse MRR scans are currently not supported */
@@ -8750,10 +8755,11 @@ int QUICK_SELECT_DESC::get_next()
     int result;
     if (last_range)
     {						// Already read through key
-      result = ((last_range->flag & EQ_RANGE)
-		? file->index_next_same(record, last_range->min_key,
-					last_range->min_length) :
-		file->index_prev(record));
+      result = ((last_range->flag & EQ_RANGE && 
+                 used_key_parts <= head->key_info[index].key_parts) ? 
+                file->index_next_same(record, last_range->min_key,
+                                      last_range->min_length) :
+                file->index_prev(record));
       if (!result)
       {
 	if (cmp_prev(*rev_it.ref()) == 0)
@@ -8777,7 +8783,9 @@ int QUICK_SELECT_DESC::get_next()
       continue;
     }
 
-    if (last_range->flag & EQ_RANGE)
+    if (last_range->flag & EQ_RANGE &&
+        used_key_parts <= head->key_info[index].key_parts)
+
     {
       result = file->index_read_map(record, last_range->max_key,
                                     last_range->max_keypart_map,
@@ -8786,6 +8794,8 @@ int QUICK_SELECT_DESC::get_next()
     else
     {
       DBUG_ASSERT(last_range->flag & NEAR_MAX ||
+                  (last_range->flag & EQ_RANGE && 
+                   used_key_parts > head->key_info[index].key_parts) ||
                   range_reads_after_key(last_range));
       result=file->index_read_map(record, last_range->max_key,
                                   last_range->max_keypart_map,
@@ -8884,54 +8894,6 @@ bool QUICK_SELECT_DESC::range_reads_afte
 }
 
 
-/* TRUE if we are reading over a key that may have a NULL value */
-
-#ifdef NOT_USED
-bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
-					   uint used_key_parts)
-{
-  uint offset, end;
-  KEY_PART *key_part = key_parts,
-           *key_part_end= key_part+used_key_parts;
-
-  for (offset= 0,  end = min(range_arg->min_length, range_arg->max_length) ;
-       offset < end && key_part != key_part_end ;
-       offset+= key_part++->store_length)
-  {
-    if (!memcmp((char*) range_arg->min_key+offset,
-		(char*) range_arg->max_key+offset,
-		key_part->store_length))
-      continue;
-
-    if (key_part->null_bit && range_arg->min_key[offset])
-      return 1;				// min_key is null and max_key isn't
-    // Range doesn't cover NULL. This is ok if there is no more null parts
-    break;
-  }
-  /*
-    If the next min_range is > NULL, then we can use this, even if
-    it's a NULL key
-    Example:  SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
-
-  */
-  if (key_part != key_part_end && key_part->null_bit)
-  {
-    if (offset >= range_arg->min_length || range_arg->min_key[offset])
-      return 1;					// Could be null
-    key_part++;
-  }
-  /*
-    If any of the key parts used in the ORDER BY could be NULL, we can't
-    use the key to sort the data.
-  */
-  for (; key_part != key_part_end ; key_part++)
-    if (key_part->null_bit)
-      return 1;					// Covers null part
-  return 0;
-}
-#endif
-
-
 void QUICK_RANGE_SELECT::add_info_string(String *str)
 {
   KEY *key_info= head->key_info + index;

=== modified file 'sql/opt_range.h'
--- a/sql/opt_range.h	2008-05-22 18:40:15 +0000
+++ b/sql/opt_range.h	2008-07-17 19:55:18 +0000
@@ -703,12 +703,10 @@ public:
   int get_type() { return QS_TYPE_RANGE_DESC; }
 private:
   bool range_reads_after_key(QUICK_RANGE *range);
-#ifdef NOT_USED
-  bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
-#endif
   int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
   List<QUICK_RANGE> rev_ranges;
   List_iterator<QUICK_RANGE> rev_it;
+  uint used_key_parts;
 };
 
 

=== modified file 'sql/records.cc'
--- a/sql/records.cc	2008-04-09 01:07:00 +0000
+++ b/sql/records.cc	2008-07-17 19:55:18 +0000
@@ -86,6 +86,23 @@ void init_read_record_idx(READ_RECORD *i
   The temporary file is normally used when the references doesn't fit into
   a properly sized memory buffer. For most small queries the references
   are stored in the memory buffer.
+  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:
 
   The temporary file is also used when performing an update where a key is
   modified.
@@ -140,7 +157,8 @@ void init_read_record_idx(READ_RECORD *i
 */
 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");
@@ -191,7 +209,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->ha_table_flags() & HA_FAST_KEY_READ) &&

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2008-07-16 13:34:52 +0000
+++ b/sql/set_var.cc	2008-07-17 19:55:18 +0000
@@ -1056,7 +1056,19 @@ static void fix_net_retry_count(THD *thd
 static void fix_query_cache_size(THD *thd, enum_var_type type)
 {
 #ifdef HAVE_QUERY_CACHE
-  query_cache_size= query_cache.resize(query_cache_size);
+  ulong new_cache_size= query_cache.resize(query_cache_size);
+
+  /*
+     Note: query_cache_size is a global variable reflecting the 
+     requested cache size. See also query_cache_size_arg
+  */
+
+  if (query_cache_size != new_cache_size)
+    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+			ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
+			query_cache_size, new_cache_size);
+  
+  query_cache_size= new_cache_size;
 #endif
 }
 

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2008-07-16 13:34:52 +0000
+++ b/sql/share/errmsg.txt	2008-07-17 19:55:18 +0000
@@ -4990,13 +4990,13 @@ ER_WRONG_NAME_FOR_CATALOG 42000 
         spa "Nombre de catalog incorrecto '%-.100s'"
         swe "Felaktigt katalog namn '%-.100s'"
 ER_WARN_QC_RESIZE  
-	eng "Query cache failed to set size %lu (minimal value: %lu); new query cache size is %lu"
-	ger "�nderung der Query-Cache-Gr��e auf %lu (Minimale Zahl: %lu) fehlgeschlagen; neue Query-Cache-Gr��e ist %lu"
-	por "Falha em Query cache para configurar tamanho %lu (N�mero m��� �������� �� ����� ���������� ������ %lu (minimal value: %lu), ����� ������ e fallada para configurar tama�o %lu (N�mero m�nimo: %lu), nuevo tama�o de query cache es %lu"
-	swe "Storleken av "Query cache" kunde inte s�ttas till %lu (minsta v�rde: %lu); ny storlek �r %lu"
-	ukr "��� mal value: %lu), ����� ������ �cache failed to set size %lu; new query cache size is %lu"
+        ger "�nderung der Query-Cache-Gr��e auf %lu fehlgeschlagen; neue Query-Cache-Gr��e ist %lu"
+        por "Falha em Query cache para configurar tamanho %lu, novo tamanho de query cache � %lu"
+        rus "��� �������� �� ����� ���������� ������ %lu,  configurar tama�o %lu, nuevo tama�o de query cache es %lu"
+        swe "Storleken av "Query cache" kunde inte s�ttas till %lu, ny storlek �r %lu"
+        ukr " %lu, ����� ������ ���� ������� - %lu"
 ER_BAD_FT_COLUMN  
         eng "Column '%-.192s' cannot be part of FULLTEXT index"
         ger "Feld '%-.192s' kann nicht Teil eines FULLTEXT-Index sein"

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2008-06-28 11:00:59 +0000
+++ b/sql/sql_acl.cc	2008-07-17 19:55:18 +0000
@@ -324,7 +324,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);
   table->use_all_columns();
   (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50);
   while (!(read_record_info.read_record(&read_record_info)))
@@ -373,7 +374,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);
   table->use_all_columns();
   (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100);
   password_length= table->field[2]->field_length /
@@ -561,7 +562,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);
   table->use_all_columns();
   (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100);
   while (!(read_record_info.read_record(&read_record_info)))

=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc	2008-07-16 13:34:52 +0000
+++ b/sql/sql_cache.cc	2008-07-17 19:55:18 +0000
@@ -957,25 +957,18 @@ ulong Query_cache::resize(ulong query_ca
     } while (block != queries_blocks);
   }
   free_cache();
-  query_cache_size= query_cache_size_arg;
-  ::query_cache_size= init_cache();
 
-  if (::query_cache_size != query_cache_size_arg)
-  {
-    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                        ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
-                        query_cache_size_arg,
-                        get_minimal_size_limit(),
-                        ::query_cache_size);
-  }
+  query_cache_size= query_cache_size_arg;
+  new_query_cache_size= init_cache();
 
   STRUCT_LOCK(&structure_guard_mutex);
   m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS;
   pthread_cond_signal(&COND_cache_status_changed);
-  
+  if (new_query_cache_size)
+    DBUG_EXECUTE("check_querycache",check_integrity(1););
   STRUCT_UNLOCK(&structure_guard_mutex);
 
-  DBUG_RETURN(::query_cache_size);
+  DBUG_RETURN(new_query_cache_size);
 }
 
 
@@ -1838,24 +1831,6 @@ void Query_cache::init()
   DBUG_VOID_RETURN;
 }
 
-/**
-  Return the lowest possible query cache size.
-*/
-
-ulong Query_cache::get_minimal_size_limit()
-{
-  ulong approx_additional_data_size= (sizeof(Query_cache) +
-                                      sizeof(void*)*(def_query_hash_size+
-                                      def_table_hash_size));
-
-  ulong data_size= (min_allocation_unit << QUERY_CACHE_MEM_BIN_STEP_PWR2 <<
-                    QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2) +
-                    ALIGN_SIZE(1) - 1 +
-                    (1 << QUERY_CACHE_MEM_BIN_STEP_PWR2) - 1 +
-                    (1 << QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2) - 1;
-
-  return(data_size + approx_additional_data_size);
-}
 
 ulong Query_cache::init_cache()
 {

=== modified file 'sql/sql_cache.h'
--- a/sql/sql_cache.h	2008-07-16 13:34:52 +0000
+++ b/sql/sql_cache.h	2008-07-17 19:55:18 +0000
@@ -284,8 +284,6 @@ private:
   void free_query_internal(Query_cache_block *point);
   void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length);
 
-  ulong get_minimal_size_limit();
-
 protected:
   /*
     The following mutex is locked when searching or changing global

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2008-06-28 11:00:59 +0000
+++ b/sql/sql_delete.cc	2008-07-17 19:55:18 +0000
@@ -248,7 +248,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     goto err;
   }
   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);
 
@@ -851,7 +851,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

=== modified file 'sql/sql_help.cc'
--- a/sql/sql_help.cc	2008-02-19 12:58:08 +0000
+++ b/sql/sql_help.cc	2008-07-17 18:26:55 +0000
@@ -186,7 +186,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
@@ -226,7 +226,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
@@ -350,7 +350,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())
@@ -384,7 +384,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())

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2008-07-15 16:29:51 +0000
+++ b/sql/sql_plugin.cc	2008-07-17 19:55:18 +0000
@@ -1367,7 +1367,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
     goto end;
   }
   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);
   table->use_all_columns();
   /*
     there're no other threads running yet, so we don't need a mutex.

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2008-07-10 23:29:27 +0000
+++ b/sql/sql_select.cc	2008-07-17 19:55:18 +0000
@@ -14477,7 +14477,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);
 }
 
@@ -15430,6 +15430,9 @@ part_of_refkey(TABLE *table,Field *field
   @note
     used_key_parts is set to correct key parts used if return value != 0
     (On other cases, used_key_part may be changed)
+    Note that the value may actually be greater than the number of index 
+    key parts. This can happen for storage engines that have the primary 
+    key parts as a suffix for every secondary key.
 
   @retval
     1   key is ok.
@@ -15502,11 +15505,27 @@ static int test_if_order_by_key(ORDER *o
     reverse=flag;				// Remember if reverse
     key_part++;
   }
-  *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
-    (uint) (key_part - table->key_info[idx].key_part);
-  if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
-                         HA_READ_PREV))
-    reverse= 0;                                 // Index can't be used
+  if (on_primary_key)
+  {
+    uint used_key_parts_secondary= table->key_info[idx].key_parts;
+    uint used_key_parts_pk=
+      (uint) (key_part - table->key_info[table->s->primary_key].key_part);
+    *used_key_parts= used_key_parts_pk + used_key_parts_secondary;
+
+    if (reverse == -1 &&
+        (!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
+           HA_READ_PREV) ||
+         !(table->file->index_flags(table->s->primary_key,
+                                    used_key_parts_pk - 1, 1) & HA_READ_PREV)))
+      reverse= 0;                               // Index can't be used
+  }
+  else
+  {
+    *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
+    if (reverse == -1 && 
+        !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
+      reverse= 0;                               // Index can't be used
+  }
   DBUG_RETURN(reverse);
 }
 

=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc	2008-06-11 11:49:58 +0000
+++ b/sql/sql_servers.cc	2008-07-17 19:55:18 +0000
@@ -182,7 +182,8 @@ static bool servers_load(THD *thd, TABLE
   free_root(&mem, MYF(0));
   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);
   while (!(read_record_info.read_record(&read_record_info)))
   {
     /* return_val is already TRUE, so no need to set */

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-06-30 09:59:59 +0000
+++ b/sql/sql_table.cc	2008-07-17 19:55:18 +0000
@@ -7304,7 +7304,7 @@ copy_data_between_tables(TABLE *from,TAB
 
   /* Tell handler that we have values for all columns in the to table */
   to->use_all_columns();
-  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
+  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
   errpos= 4;
   if (ignore)
     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2008-05-23 13:54:03 +0000
+++ b/sql/sql_udf.cc	2008-07-17 19:55:18 +0000
@@ -153,7 +153,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);
   table->use_all_columns();
   while (!(error= read_record_info.read_record(&read_record_info)))
   {

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2008-06-28 11:00:59 +0000
+++ b/sql/sql_update.cc	2008-07-17 19:55:18 +0000
@@ -459,7 +459,7 @@ int mysql_update(THD *thd,
       */
 
       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);
 
@@ -525,7 +525,7 @@ int mysql_update(THD *thd,
   if (select && select->quick && select->quick->reset())
     goto err;
   table->file->try_semi_consistent_read(1);
-  init_read_record(&info,thd,table,select,0,1);
+  init_read_record(&info, thd, table, select, 0, 1, FALSE);
 
   updated= found= 0;
   /* Generate an error when trying to set a NOT NULL field to NULL. */

Thread
bzr push into mysql-6.0 branch (sergefp:2723 to 2724) Sergey Petrunia17 Jul