List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:February 21 2007 11:36am
Subject:bk commit into 5.1 tree (serg:1.2440)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of serg. When serg 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, 2007-02-21 11:36:23+01:00, serg@stripped +33 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-5.1
  into  janus.mylan:/usr/home/serg/Abk/mysql-5.1
  MERGE: 1.2411.1.6

  dbug/dbug.c@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.33.1.1

  include/my_base.h@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.95.1.1

  include/my_global.h@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.155.1.1

  sql/event_db_repository.cc@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.20.1.1

  sql/ha_ndbcluster.cc@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.397.1.1

  sql/ha_ndbcluster.h@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.165.1.4

  sql/ha_partition.cc@stripped, 2007-02-21 11:20:31+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.82.1.1

  sql/handler.cc@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.291.1.1

  sql/item_subselect.cc@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.141.1.2

  sql/log.cc@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.253.1.1

  sql/log_event.cc@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.263.1.1

  sql/mysql_priv.h@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.473.1.1

  sql/opt_range.cc@stripped, 2007-02-21 11:36:19+01:00, serg@stripped +12 -19
    manual merge
    MERGE: 1.258.1.1

  sql/opt_range.h@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.74.1.1

  sql/opt_sum.cc@stripped, 2007-02-21 11:20:32+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.59.1.1

  sql/slave.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.302.1.1

  sql/slave.h@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.103.1.1

  sql/sp.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.136.1.1

  sql/sql_insert.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.243.1.1

  sql/sql_plugin.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.42.2.1

  sql/sql_select.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.485.1.1

  sql/sql_servers.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.4.1.1

  sql/sql_servers.h@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.3.1.1

  sql/table.cc@stripped, 2007-02-21 11:20:33+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.270.1.1

  sql/table.h@stripped, 2007-02-21 11:20:34+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.158.1.3

  sql/tztime.cc@stripped, 2007-02-21 11:20:34+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.46.1.1

  storage/example/ha_example.cc@stripped, 2007-02-21 11:36:19+01:00, serg@stripped +0 -1
    manual merge
    MERGE: 1.51.1.1

  storage/federated/ha_federated.cc@stripped, 2007-02-21 11:36:19+01:00, serg@stripped +0
-2
    manual merge
    MERGE: 1.96.1.1

  storage/heap/ha_heap.cc@stripped, 2007-02-21 11:20:34+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.106.1.1

  storage/myisam/ha_myisam.cc@stripped, 2007-02-21 11:36:19+01:00, serg@stripped +0 -1
    manual merge
    MERGE: 1.206.1.1

  storage/myisam/mi_rkey.c@stripped, 2007-02-21 11:36:19+01:00, serg@stripped +2 -2
    manual merge
    MERGE: 1.29.1.1

  storage/myisammrg/ha_myisammrg.cc@stripped, 2007-02-21 11:20:34+01:00, serg@stripped +0
-0
    Auto merged
    MERGE: 1.111.1.1

  support-files/Makefile.am@stripped, 2007-02-21 11:20:34+01:00, serg@stripped +0 -0
    Auto merged
    MERGE: 1.33.1.1

# 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:	serg
# Host:	janus.mylan
# Root:	/usr/home/serg/Abk/mysql-5.1/RESYNC

--- 1.34/dbug/dbug.c	2007-02-21 11:36:31 +01:00
+++ 1.35/dbug/dbug.c	2007-02-21 11:36:31 +01:00
@@ -1995,12 +1995,14 @@
 
 
 /*
- *     strtok lookalike - splits on ':', magically handles :\ and :/
+ *     strtok lookalike - splits on ':', magically handles ::, :\ and :/
  */
 
 static const char *DbugStrTok(const char *s)
 {
-  while (s[0] && (s[0] != ':' || (s[1] == '\\' || s[1] == '/')))
+  const char *start=s;
+  while (s[0] && (s[0] != ':' ||
+                  (s[1] == '\\' || s[1] == '/' || (s[1] == ':' && s++))))
     s++;
   return s;
 }

--- 1.96/include/my_base.h	2007-02-21 11:36:31 +01:00
+++ 1.97/include/my_base.h	2007-02-21 11:36:31 +01:00
@@ -47,6 +47,7 @@
 #define HA_OPEN_ABORT_IF_CRASHED	16
 #define HA_OPEN_FOR_REPAIR		32	/* open even if crashed */
 #define HA_OPEN_FROM_SQL_LAYER          64
+#define HA_OPEN_MMAP                    128     /* open memory mapped */
 
 	/* The following is parameter to ha_rkey() how to use key */
 

--- 1.30/storage/myisam/mi_rkey.c	2007-02-21 11:36:31 +01:00
+++ 1.31/storage/myisam/mi_rkey.c	2007-02-21 11:36:31 +01:00
@@ -21,8 +21,8 @@
 	/* Read a record using key */
 	/* Ordinary search_flag is 0 ; Give error if no record with key */
 
-int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
-	    enum ha_rkey_function search_flag)
+int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key,
+            ulonglong keypart_map, enum ha_rkey_function search_flag)
 {
   uchar *key_buff;
   MYISAM_SHARE *share=info->s;
@@ -47,18 +47,17 @@
       key is already packed!;  This happens when we are using a MERGE TABLE
     */
     key_buff=info->lastkey+info->s->base.max_key_length;
-    pack_key_length= key_len;
-    bmove(key_buff,key,key_len);
+    pack_key_length= keypart_map;
+    bmove(key_buff, key, pack_key_length);
     last_used_keyseg= 0;
   }
   else
   {
-    if (key_len == 0)
-      key_len=USE_WHOLE_KEY;
+    DBUG_ASSERT(keypart_map);
     /* Save the packed key for later use in the second buffer of lastkey. */
     key_buff=info->lastkey+info->s->base.max_key_length;
     pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
-				 key_len, &last_used_keyseg);
+				 keypart_map, &last_used_keyseg);
     /* Save packed_key_length for use by the MERGE engine. */
     info->pack_key_length= pack_key_length;
     DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,

--- 1.107/storage/heap/ha_heap.cc	2007-02-21 11:36:31 +01:00
+++ 1.108/storage/heap/ha_heap.cc	2007-02-21 11:36:31 +01:00
@@ -238,34 +238,35 @@
   return res;
 }
 
-int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
+int ha_heap::index_read(byte * buf, const byte * key, ulonglong keypart_map,
 			enum ha_rkey_function find_flag)
 {
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error = heap_rkey(file,buf,active_index, key, key_len, find_flag);
+  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
   table->status = error ? STATUS_NOT_FOUND : 0;
   return error;
 }
 
-int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len)
+int ha_heap::index_read_last(byte *buf, const byte *key, ulonglong keypart_map)
 {
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error= heap_rkey(file, buf, active_index, key, key_len,
+  int error= heap_rkey(file, buf, active_index, key, keypart_map,
 		       HA_READ_PREFIX_LAST);
   table->status= error ? STATUS_NOT_FOUND : 0;
   return error;
 }
 
 int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
-			    uint key_len, enum ha_rkey_function find_flag)
+			    ulonglong keypart_map,
+                            enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error = heap_rkey(file, buf, index, key, key_len, find_flag);
+  int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
   table->status = error ? STATUS_NOT_FOUND : 0;
   return error;
 }

--- 1.209/storage/myisam/ha_myisam.cc	2007-02-21 11:36:31 +01:00
+++ 1.210/storage/myisam/ha_myisam.cc	2007-02-21 11:36:31 +01:00
@@ -1521,34 +1521,37 @@
   return mi_delete(file,buf);
 }
 
-int ha_myisam::index_read(byte * buf, const byte * key,
-			  uint key_len, enum ha_rkey_function find_flag)
+int ha_myisam::index_read(byte *buf, const byte *key, ulonglong keypart_map,
+                          enum ha_rkey_function find_flag)
 {
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
+  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
-int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key,
-			      uint key_len, enum ha_rkey_function find_flag)
+int ha_myisam::index_read_idx(byte *buf, uint index, const byte *key,
+                              ulonglong keypart_map,
+                              enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=mi_rkey(file,buf,index, key, key_len, find_flag);
+  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
-int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
+int ha_myisam::index_read_last(byte *buf, const byte *key,
+                               ulonglong keypart_map)
 {
   DBUG_ENTER("ha_myisam::index_read_last");
   DBUG_ASSERT(inited==INDEX);
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
+  int error=mi_rkey(file, buf, active_index, key, keypart_map,
+                    HA_READ_PREFIX_LAST);
   table->status=error ? STATUS_NOT_FOUND: 0;
   DBUG_RETURN(error);
 }
@@ -1857,8 +1860,9 @@
   key_copy(key, table->record[0],
            table->key_info + table->s->next_number_index,
            table->s->next_number_key_offset);
-  error= mi_rkey(file,table->record[1],(int) table->s->next_number_index,
-                 key,table->s->next_number_key_offset,HA_READ_PREFIX_LAST);
+  error= mi_rkey(file, table->record[1], (int) table->s->next_number_index,
+                 key, make_prev_keypart_map(table->s->next_number_keypart),
+                 HA_READ_PREFIX_LAST);
   if (error)
     nr= 1;
   else

--- 1.114/storage/myisammrg/ha_myisammrg.cc	2007-02-21 11:36:31 +01:00
+++ 1.115/storage/myisammrg/ha_myisammrg.cc	2007-02-21 11:36:31 +01:00
@@ -179,30 +179,33 @@
 }
 
 int ha_myisammrg::index_read(byte * buf, const byte * key,
-			  uint key_len, enum ha_rkey_function find_flag)
+                             ulonglong keypart_map,
+                             enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=myrg_rkey(file,buf,active_index, key, key_len, find_flag);
+  int error=myrg_rkey(file,buf,active_index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
 int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key,
-				 uint key_len, enum ha_rkey_function find_flag)
+				 ulonglong keypart_map,
+                                 enum ha_rkey_function find_flag)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=myrg_rkey(file,buf,index, key, key_len, find_flag);
+  int error=myrg_rkey(file,buf,index, key, keypart_map, find_flag);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;
 }
 
-int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len)
+int ha_myisammrg::index_read_last(byte * buf, const byte * key,
+                                  ulonglong keypart_map)
 {
   statistic_increment(table->in_use->status_var.ha_read_key_count,
 		      &LOCK_status);
-  int error=myrg_rkey(file,buf,active_index, key, key_len,
+  int error=myrg_rkey(file,buf,active_index, key, keypart_map,
 		      HA_READ_PREFIX_LAST);
   table->status=error ? STATUS_NOT_FOUND: 0;
   return error;

--- 1.295/sql/handler.cc	2007-02-21 11:36:31 +01:00
+++ 1.296/sql/handler.cc	2007-02-21 11:36:31 +01:00
@@ -1843,7 +1843,7 @@
       nr= compute_next_insert_id(nr-1, variables);
     }
     
-    if (table->s->next_number_key_offset == 0)
+    if (table->s->next_number_keypart == 0)
     {
       /* We must defer the appending until "nr" has been possibly truncated */
       append= TRUE;
@@ -1963,7 +1963,7 @@
                                         table->read_set);
   column_bitmaps_signal();
   index_init(table->s->next_number_index, 1);
-  if (!table->s->next_number_key_offset)
+  if (table->s->next_number_keypart == 0)
   {						// Autoincrement at key-start
     error=index_last(table->record[1]);
     /*
@@ -1979,7 +1979,8 @@
     key_copy(key, table->record[0],
              table->key_info + table->s->next_number_index,
              table->s->next_number_key_offset);
-    error= index_read(table->record[1], key, table->s->next_number_key_offset,
+    error= index_read(table->record[1], key,
+                      make_prev_keypart_map(table->s->next_number_keypart),
                       HA_READ_PREFIX_LAST);
     /*
       MySQL needs to call us for next row: assume we are inserting ("a",null)
@@ -3084,9 +3085,9 @@
        multi_range_curr < multi_range_end;
        multi_range_curr++)
   {
-    result= read_range_first(multi_range_curr->start_key.length ?
+    result= read_range_first(multi_range_curr->start_key.keypart_map ?
                              &multi_range_curr->start_key : 0,
-                             multi_range_curr->end_key.length ?
+                             multi_range_curr->end_key.keypart_map ?
                              &multi_range_curr->end_key : 0,
                              test(multi_range_curr->range_flag & EQ_RANGE),
                              multi_range_sorted);
@@ -3151,9 +3152,9 @@
          multi_range_curr < multi_range_end;
          multi_range_curr++)
     {
-      result= read_range_first(multi_range_curr->start_key.length ?
+      result= read_range_first(multi_range_curr->start_key.keypart_map ?
                                &multi_range_curr->start_key : 0,
-                               multi_range_curr->end_key.length ?
+                               multi_range_curr->end_key.keypart_map ?
                                &multi_range_curr->end_key : 0,
                                test(multi_range_curr->range_flag & EQ_RANGE),
                                multi_range_sorted);
@@ -3212,7 +3213,7 @@
   else
     result= index_read(table->record[0],
 		       start_key->key,
-		       start_key->length,
+                       start_key->keypart_map,
 		       start_key->flag);
   if (result)
     DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND) 
@@ -3284,15 +3285,19 @@
   return cmp;
 }
 
+
 int handler::index_read_idx(byte * buf, uint index, const byte * key,
-			     uint key_len, enum ha_rkey_function find_flag)
+                             ulonglong keypart_map,
+                             enum ha_rkey_function find_flag)
 {
-  int error= ha_index_init(index, 0);
-  if (!error)
-    error= index_read(buf, key, key_len, find_flag);
+  int error, error1;
+  error= index_init(index, 0);
   if (!error)
-    error= ha_index_end();
-  return error;
+  {
+    error= index_read(buf, key, keypart_map, find_flag);
+    error1= index_end();
+  }
+  return error ?  error : error1;
 }
 
 

--- 1.255/sql/log.cc	2007-02-21 11:36:31 +01:00
+++ 1.256/sql/log.cc	2007-02-21 11:36:31 +01:00
@@ -3780,7 +3780,7 @@
                              nb_elements()));
           /*
             If the auto_increment was second in a table's index (possible with
-            MyISAM or BDB) (table->next_number_key_offset != 0), such event is
+            MyISAM or BDB) (table->next_number_keypart != 0), such event is
             in fact not necessary. We could avoid logging it.
           */
           Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,

--- 1.266/sql/log_event.cc	2007-02-21 11:36:31 +01:00
+++ 1.267/sql/log_event.cc	2007-02-21 11:36:31 +01:00
@@ -6722,9 +6722,8 @@
       }
 
       key_copy((byte*)key.get(), table->record[0], table->key_info + keynum, 0);
-      error= table->file->index_read_idx(table->record[1], keynum, 
-                                         (const byte*)key.get(),
-                                         table->key_info[keynum].key_length,
+      error= table->file->index_read_idx(table->record[1], keynum,
+                                         (const byte*)key.get(), ~ULL(0),
                                          HA_READ_KEY_EXACT);
       if (error)
         DBUG_RETURN(error);
@@ -6909,8 +6908,7 @@
       table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
     table->record[1][pos]= 0xFF;
     if ((error= table->file->index_read(table->record[1], key,
-                                        table->key_info->key_length,
-                                        HA_READ_KEY_EXACT)))
+                                        ~(ulonglong)0, HA_READ_KEY_EXACT)))
     {
       table->file->print_error(error, MYF(0));
       table->file->ha_index_end();

--- 1.482/sql/mysql_priv.h	2007-02-21 11:36:31 +01:00
+++ 1.483/sql/mysql_priv.h	2007-02-21 11:36:31 +01:00
@@ -1452,7 +1452,7 @@
 void mysql_print_status();
 /* key.cc */
 int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
-                 uint *key_length);
+                 uint *key_length, uint *keypart);
 void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length);
 void key_restore(byte *to_record, byte *from_key, KEY *key_info,
                  uint key_length);

--- 1.262/sql/opt_range.cc	2007-02-21 11:36:31 +01:00
+++ 1.263/sql/opt_range.cc	2007-02-21 11:36:31 +01:00
@@ -312,7 +312,7 @@
     min_value=arg->max_value;
     min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
   }
-  void store_min(uint length,char **min_key,uint min_key_flag)
+  int store_min(uint length,char **min_key,uint min_key_flag)
   {
     if ((min_flag & GEOM_FLAG) ||
         (!(min_flag & NO_MIN_RANGE) &&
@@ -326,12 +326,12 @@
       else
 	memcpy(*min_key,min_value,length);
       (*min_key)+= length;
+      return 1;
     }
+    return 0;
   }
-  void store(uint length,char **min_key,uint min_key_flag,
-	     char **max_key, uint max_key_flag)
+  int store_max(uint length,char **max_key, uint max_key_flag)
   {
-    store_min(length, min_key, min_key_flag);
     if (!(max_flag & NO_MAX_RANGE) &&
 	!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
     {
@@ -343,33 +343,45 @@
       else
 	memcpy(*max_key,max_value,length);
       (*max_key)+= length;
+      return 1;
     }
+    return 0;
   }
+  /*void store(uint length,char **min_key,uint min_key_flag,
+	     char **max_key, uint max_key_flag)
+  {
+    store_min(length, min_key, min_key_flag);
+    store_max(length, max_key, max_key_flag);
+  }*/
 
-  void store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
+  int store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
   {
     SEL_ARG *key_tree= first();
-    key_tree->store(key[key_tree->part].store_length,
-		    range_key,*range_key_flag,range_key,NO_MAX_RANGE);
+    uint res= key_tree->store_min(key[key_tree->part].store_length,
+                                  range_key, *range_key_flag);
     *range_key_flag|= key_tree->min_flag;
     if (key_tree->next_key_part &&
 	key_tree->next_key_part->part == key_tree->part+1 &&
 	!(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
 	key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
-      key_tree->next_key_part->store_min_key(key,range_key, range_key_flag);
+      res+= key_tree->next_key_part->store_min_key(key, range_key,
+                                                   range_key_flag);
+    return res;
   }
 
-  void store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
+  int store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
   {
     SEL_ARG *key_tree= last();
-    key_tree->store(key[key_tree->part].store_length,
-		    range_key, NO_MIN_RANGE, range_key,*range_key_flag);
+    uint res=key_tree->store_max(key[key_tree->part].store_length,
+                                 range_key, *range_key_flag);
     (*range_key_flag)|= key_tree->max_flag;
     if (key_tree->next_key_part &&
 	key_tree->next_key_part->part == key_tree->part+1 &&
 	!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
 	key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
-      key_tree->next_key_part->store_max_key(key,range_key, range_key_flag);
+      res+= key_tree->next_key_part->store_max_key(key, range_key,
+                                                   range_key_flag);
+    return res;
   }
 
   SEL_ARG *insert(SEL_ARG *key);
@@ -586,8 +598,8 @@
 static ha_rows check_quick_select(PARAM *param,uint index,SEL_ARG *key_tree, 
                                   bool update_tbl_stats);
 static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
-				char *min_key,uint min_key_flag,
-				char *max_key, uint max_key_flag);
+                                char *min_key, uint min_key_flag, int,
+                                char *max_key, uint max_key_flag, int);
 
 QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
                                      SEL_ARG *key_tree,
@@ -1453,6 +1465,7 @@
 
 QUICK_RANGE::QUICK_RANGE()
   :min_key(0),max_key(0),min_length(0),max_length(0),
+  min_keypart_map(0), max_keypart_map(0),
    flag(NO_MIN_RANGE | NO_MAX_RANGE)
 {}
 
@@ -4031,9 +4044,9 @@
     The calculation is conducted as follows:
     Lets denote #records(keypart1, ... keypartK) as n_k. We need to calculate
 
-     n_{k1}      n_{k_2}
+     n_{k1}      n_{k2}
     --------- * ---------  * .... (3)
-     n_{k1-1}    n_{k2_1}
+     n_{k1-1}    n_{k2-1}
 
     where k1,k2,... are key parts which fields were not yet marked as fixed
     ( this is result of application of option b) of the recursion step for
@@ -4041,9 +4054,9 @@
     Since it is reasonable to expect that most of the fields are not marked
     as fixed, we calculate (3) as
 
-                                  n_{i1}      n_{i_2}
+                                  n_{i1}      n_{i2}
     (3) = n_{max_key_part}  / (   --------- * ---------  * ....  )
-                                  n_{i1-1}    n_{i2_1}
+                                  n_{i1-1}    n_{i2-1}
 
     where i1,i2, .. are key parts that were already marked as fixed.
 
@@ -4052,7 +4065,6 @@
 
   RETURN
     Selectivity of given ROR scan.
-    
 */
 
 static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, 
@@ -4063,6 +4075,7 @@
   byte key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
   char *key_ptr= (char*) key_val;
   SEL_ARG *sel_arg, *tuple_arg= NULL;
+  ulonglong keypart_map= 0;
   bool cur_covered;
   bool prev_covered= test(bitmap_is_set(&info->covered_fields,
                                         key_part->fieldnr-1));
@@ -4073,7 +4086,7 @@
   max_range.key= (byte*) key_val;
   max_range.flag= HA_READ_AFTER_KEY;
   ha_rows prev_records= info->param->table->file->stats.records;
-  DBUG_ENTER("ror_intersect_selectivity");
+  DBUG_ENTER("ror_scan_selectivity");
 
   for (sel_arg= scan->sel_arg; sel_arg;
        sel_arg= sel_arg->next_key_part)
@@ -4090,13 +4103,17 @@
         tuple_arg= scan->sel_arg;
         /* Here we use the length of the first key part */
         tuple_arg->store_min(key_part->store_length, &key_ptr, 0);
+        keypart_map= 1;
       }
       while (tuple_arg->next_key_part != sel_arg)
       {
         tuple_arg= tuple_arg->next_key_part;
-        tuple_arg->store_min(key_part[tuple_arg->part].store_length, &key_ptr,
0);
+        tuple_arg->store_min(key_part[tuple_arg->part].store_length,
+                             &key_ptr, 0);
+        keypart_map= (keypart_map << 1) | 1;
       }
       min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val);
+      min_range.keypart_map= max_range.keypart_map= keypart_map;
       records= (info->param->table->file->
                 records_in_range(scan->keynr, &min_range, &max_range));
       if (cur_covered)
@@ -5305,12 +5322,11 @@
     */
     for (uint i= 1 ; i < cond_func->arg_count ; i++)
     {
-     
       if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
       {
         field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
         SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, 
-                                    field_item, (Item*) i, inv);
+                                    field_item, (Item*)(intptr)i, inv);
         if (inv)
           tree= !tree ? tmp : tree_or(param, tree, tmp);
         else 
@@ -7057,7 +7073,9 @@
   }
   param->n_ranges= 0;
 
-  records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0);
+  records= check_quick_keys(param, idx, tree,
+                            param->min_key, 0, -1,
+                            param->max_key, 0, -1);
   if (records != HA_POS_ERROR)
   {
     if (update_tbl_stats)
@@ -7120,12 +7138,13 @@
 */
 
 static ha_rows
-check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
-		 char *min_key,uint min_key_flag, char *max_key,
-		 uint max_key_flag)
+check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
+		 char *min_key, uint min_key_flag, int min_keypart,
+                 char *max_key, uint max_key_flag, int max_keypart)
 {
   ha_rows records=0, tmp;
   uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length;
+  uint tmp_min_keypart= min_keypart, tmp_max_keypart= max_keypart;
   char *tmp_min_key, *tmp_max_key;
   uint8 save_first_null_comp= param->first_null_comp;
 
@@ -7139,18 +7158,21 @@
       This is not a ROR scan if the key is not Clustered Primary Key.
     */
     param->is_ror_scan= FALSE;
-    records=check_quick_keys(param,idx,key_tree->left,min_key,min_key_flag,
-			     max_key,max_key_flag);
+    records=check_quick_keys(param, idx, key_tree->left,
+                             min_key, min_key_flag, min_keypart,
+			     max_key, max_key_flag, max_keypart);
     if (records == HA_POS_ERROR)			// Impossible
       return records;
   }
 
   tmp_min_key= min_key;
   tmp_max_key= max_key;
-  key_tree->store(param->key[idx][key_tree->part].store_length,
-		  &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
-  min_key_length= (uint) (tmp_min_key- param->min_key);
-  max_key_length= (uint) (tmp_max_key- param->max_key);
+  tmp_min_keypart+=
key_tree->store_min(param->key[idx][key_tree->part].store_length,
+                                        &tmp_min_key, min_key_flag);
+  tmp_max_keypart+=
key_tree->store_max(param->key[idx][key_tree->part].store_length,
+                                        &tmp_max_key, max_key_flag);
+  min_key_length= (uint) (tmp_min_key - param->min_key);
+  max_key_length= (uint) (tmp_max_key - param->max_key);
 
   if (param->is_ror_scan)
   {
@@ -7173,12 +7195,13 @@
       key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
   {						// const key as prefix
     if (min_key_length == max_key_length &&
-	!memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) &&
+	!memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
 	!key_tree->min_flag && !key_tree->max_flag)
     {
-      tmp=check_quick_keys(param,idx,key_tree->next_key_part,
-			   tmp_min_key, min_key_flag | key_tree->min_flag,
-			   tmp_max_key, max_key_flag | key_tree->max_flag);
+      tmp=check_quick_keys(param,idx,key_tree->next_key_part, tmp_min_key,
+                           min_key_flag | key_tree->min_flag, tmp_min_keypart,
+                           tmp_max_key, max_key_flag | key_tree->max_flag,
+                           tmp_max_keypart);
       goto end;					// Ugly, but efficient
     }
     else
@@ -7190,18 +7213,20 @@
     tmp_min_flag=key_tree->min_flag;
     tmp_max_flag=key_tree->max_flag;
     if (!tmp_min_flag)
+      tmp_min_keypart+=
       key_tree->next_key_part->store_min_key(param->key[idx], &tmp_min_key,
 					     &tmp_min_flag);
     if (!tmp_max_flag)
+      tmp_max_keypart+=
       key_tree->next_key_part->store_max_key(param->key[idx], &tmp_max_key,
 					     &tmp_max_flag);
-    min_key_length= (uint) (tmp_min_key- param->min_key);
-    max_key_length= (uint) (tmp_max_key- param->max_key);
+    min_key_length= (uint) (tmp_min_key - param->min_key);
+    max_key_length= (uint) (tmp_max_key - param->max_key);
   }
   else
   {
-    tmp_min_flag=min_key_flag | key_tree->min_flag;
-    tmp_max_flag=max_key_flag | key_tree->max_flag;
+    tmp_min_flag= min_key_flag | key_tree->min_flag;
+    tmp_max_flag= max_key_flag | key_tree->max_flag;
   }
 
   keynr=param->real_keynr[idx];
@@ -7209,9 +7234,8 @@
   if (!tmp_min_flag && ! tmp_max_flag &&
       (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts
&&
       (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
-      HA_NOSAME &&
-      min_key_length == max_key_length &&
-      !memcmp(param->min_key,param->max_key,min_key_length) &&
+      HA_NOSAME && min_key_length == max_key_length &&
+      !memcmp(param->min_key, param->max_key, min_key_length) &&
       !param->first_null_comp)
   {
     tmp=1;					// Max one record
@@ -7231,7 +7255,7 @@
           first members of clustered primary key.
       */
       if (!(min_key_length == max_key_length &&
-            !memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) &&
+            !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
             !key_tree->min_flag && !key_tree->max_flag &&
             is_key_scan_ror(param, keynr, key_tree->part + 1)))
         param->is_ror_scan= FALSE;
@@ -7243,11 +7267,12 @@
       key_range min_range;
       min_range.key=    (byte*) param->min_key;
       min_range.length= min_key_length;
+      min_range.keypart_map= make_keypart_map(tmp_min_keypart);
       /* In this case tmp_min_flag contains the handler-read-function */
       min_range.flag=   (ha_rkey_function) (tmp_min_flag ^ GEOM_FLAG);
 
-      tmp= param->table->file->records_in_range(keynr, &min_range,
-                                                (key_range*) 0);
+      tmp= param->table->file->records_in_range(keynr,
+                                                &min_range, (key_range*) 0);
     }
     else
     {
@@ -7257,10 +7282,12 @@
       min_range.length= min_key_length;
       min_range.flag=   (tmp_min_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
                          HA_READ_KEY_EXACT);
+      min_range.keypart_map= make_keypart_map(tmp_min_keypart);
       max_range.key=    (byte*) param->max_key;
       max_range.length= max_key_length;
       max_range.flag=   (tmp_max_flag & NEAR_MAX ?
                          HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
+      max_range.keypart_map= make_keypart_map(tmp_max_keypart);
       tmp=param->table->file->records_in_range(keynr,
                                                (min_key_length ? &min_range :
                                                 (key_range*) 0),
@@ -7281,8 +7308,9 @@
       This is not a ROR scan if the key is not Clustered Primary Key.
     */
     param->is_ror_scan= FALSE;
-    tmp=check_quick_keys(param,idx,key_tree->right,min_key,min_key_flag,
-			 max_key,max_key_flag);
+    tmp=check_quick_keys(param, idx, key_tree->right,
+                         min_key, min_key_flag, min_keypart,
+                         max_key, max_key_flag, max_keypart);
     if (tmp == HA_POS_ERROR)
       return tmp;
     records+=tmp;
@@ -7429,6 +7457,7 @@
 {
   QUICK_RANGE *range;
   uint flag;
+  int min_part= key_tree->part-1, max_part=key_tree->part-1;
 
   if (key_tree->left != &null_element)
   {
@@ -7437,16 +7466,18 @@
       return 1;
   }
   char *tmp_min_key=min_key,*tmp_max_key=max_key;
-  key_tree->store(key[key_tree->part].store_length,
-		  &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
+  min_part+= key_tree->store_min(key[key_tree->part].store_length,
+                                 &tmp_min_key,min_key_flag);
+  max_part+= key_tree->store_max(key[key_tree->part].store_length,
+                                 &tmp_max_key,max_key_flag);
 
   if (key_tree->next_key_part &&
       key_tree->next_key_part->part == key_tree->part+1 &&
       key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
   {						  // const key as prefix
-    if (!((tmp_min_key - min_key) != (tmp_max_key - max_key) ||
-	  memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) ||
-	  key_tree->min_flag || key_tree->max_flag))
+    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
+         memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
+	 key_tree->min_flag==0 && key_tree->max_flag==0)
     {
       if (get_quick_keys(param,quick,key,key_tree->next_key_part,
 			 tmp_min_key, min_key_flag | key_tree->min_flag,
@@ -7457,11 +7488,15 @@
     {
       uint tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
       if (!tmp_min_flag)
-	key_tree->next_key_part->store_min_key(key, &tmp_min_key,
+      {
+        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
 					       &tmp_min_flag);
+      }
       if (!tmp_max_flag)
-	key_tree->next_key_part->store_max_key(key, &tmp_max_key,
+      {
+        max_part+= key_tree->next_key_part->store_max_key(key, &tmp_max_key,
 					       &tmp_max_flag);
+      }
       flag=tmp_min_flag | tmp_max_flag;
     }
   }
@@ -7511,13 +7546,15 @@
   /* Get range for retrieving rows in QUICK_SELECT::get_next */
   if (!(range= new QUICK_RANGE((const char *) param->min_key,
 			       (uint) (tmp_min_key - param->min_key),
+                               min_part >=0 ? make_keypart_map(min_part) : 0,
 			       (const char *) param->max_key,
 			       (uint) (tmp_max_key - param->max_key),
+                               max_part >=0 ? make_keypart_map(max_part) : 0,
 			       flag)))
     return 1;			// out of memory
 
-  set_if_bigger(quick->max_used_key_length,range->min_length);
-  set_if_bigger(quick->max_used_key_length,range->max_length);
+  set_if_bigger(quick->max_used_key_length, range->min_length);
+  set_if_bigger(quick->max_used_key_length, range->max_length);
   set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
   if (insert_dynamic(&quick->ranges, (gptr)&range))
     return 1;
@@ -7659,6 +7696,7 @@
 
   range->min_key=range->max_key=(char*) ref->key_buff;
   range->min_length=range->max_length=ref->key_length;
+  range->min_keypart_map= range->max_keypart_map= (1 << ref->key_parts) -
1;
   range->flag= ((ref->key_length == key_info->key_length &&
 		 (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
 		 HA_NOSAME) ? EQ_RANGE : 0);
@@ -7692,8 +7730,10 @@
     *ref->null_ref_key= 1;		// Set null byte then create a range
     if (!(null_range= new (alloc) QUICK_RANGE((char*)ref->key_buff,
                                               ref->key_length,
+                                              (1 << ref->key_parts) - 1,
                                               (char*)ref->key_buff,
                                               ref->key_length,
+                                              (1 << ref->key_parts) - 1,
                                               EQ_RANGE)))
       goto err;
     *ref->null_ref_key= 0;		// Clear null byte
@@ -8146,6 +8186,7 @@
       start_key->flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
                           (last_range->flag & EQ_RANGE) ?
                           HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
+      start_key->keypart_map= last_range->min_keypart_map;
       end_key->key=      (const byte*) last_range->max_key;
       end_key->length=   last_range->max_length;
       /*
@@ -8154,6 +8195,7 @@
       */
       end_key->flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
                           HA_READ_AFTER_KEY);
+      end_key->keypart_map= range->max_keypart_map;
 
       mrange_slot->range_flag= last_range->flag;
     }
@@ -8203,7 +8245,9 @@
     other              if some error occurred
 */
 
-int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length, byte *cur_prefix)
+int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
+                                        ulonglong keypart_map,
+                                        byte *cur_prefix)
 {
   DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
 
@@ -8215,8 +8259,7 @@
     {
       /* Read the next record in the same range with prefix after cur_prefix. */
       DBUG_ASSERT(cur_prefix != 0);
-      result= file->index_read(record, cur_prefix, prefix_length,
-                               HA_READ_AFTER_KEY);
+      result= file->index_read(record, cur_prefix, keypart_map, HA_READ_AFTER_KEY);
       if (result || (file->compare_key(file->end_range) <= 0))
         DBUG_RETURN(result);
     }
@@ -8232,11 +8275,13 @@
 
     start_key.key=    (const byte*) last_range->min_key;
     start_key.length= min(last_range->min_length, prefix_length);
+    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
     start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 		       (last_range->flag & EQ_RANGE) ?
 		       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
     end_key.key=      (const byte*) last_range->max_key;
     end_key.length=   min(last_range->max_length, prefix_length);
+    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
     /*
       We use READ_AFTER_KEY here because if we are reading on a key
       prefix we want to find all keys with this prefix
@@ -8244,8 +8289,8 @@
     end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 		       HA_READ_AFTER_KEY);
 
-    result= file->read_range_first(last_range->min_length ? &start_key : 0,
-				   last_range->max_length ? &end_key : 0,
+    result= file->read_range_first(last_range->min_keypart_map ? &start_key :
0,
+				   last_range->max_keypart_map ? &end_key : 0,
                                    test(last_range->flag & EQ_RANGE),
 				   sorted);
     if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
@@ -8285,9 +8330,8 @@
     }
     last_range= *(cur_range++);
 
-    result= file->index_read(record,
-			     (byte*) last_range->min_key,
-			     last_range->min_length,
+    result= file->index_read(record, (byte*) last_range->min_key,
+			     last_range->min_keypart_map,
 			     (ha_rkey_function)(last_range->flag ^ GEOM_FLAG));
     if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
       DBUG_RETURN(result);
@@ -8419,15 +8463,15 @@
 
     if (last_range->flag & EQ_RANGE)
     {
-      result= file->index_read(record, (byte*) last_range->max_key,
-                               last_range->max_length, HA_READ_KEY_EXACT);
+      result = file->index_read(record, (byte*) last_range->max_key,
+				last_range->max_keypart_map, HA_READ_KEY_EXACT);
     }
     else
     {
       DBUG_ASSERT(last_range->flag & NEAR_MAX ||
                   range_reads_after_key(last_range));
       result=file->index_read(record, (byte*) last_range->max_key,
-			      last_range->max_length,
+			      last_range->max_keypart_map,
 			      ((last_range->flag & NEAR_MAX) ?
 			       HA_READ_BEFORE_KEY :
                                HA_READ_PREFIX_LAST_OR_PREV));
@@ -8747,8 +8791,7 @@
 static inline uint get_field_keypart(KEY *index, Field *field);
 static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
                                              PARAM *param, uint *param_idx);
-static bool
-get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
+static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
                        KEY_PART_INFO *first_non_group_part,
                        KEY_PART_INFO *min_max_arg_part,
                        KEY_PART_INFO *last_part, THD *thd,
@@ -9146,7 +9189,7 @@
                           NULL;
     first_non_infix_part= min_max_arg_part ?
                           (min_max_arg_part < last_part) ?
-                             min_max_arg_part + 1 :
+                             min_max_arg_part :
                              NULL :
                            NULL;
     if (first_non_group_part &&
@@ -9203,7 +9246,9 @@
     */
     if (first_non_infix_part)
     {
-      for (cur_part= first_non_infix_part; cur_part != last_part; cur_part++)
+      cur_part= first_non_infix_part +
+                (min_max_arg_part && (min_max_arg_part < last_part));
+      for (; cur_part != last_part; cur_part++)
       {
         if (bitmap_is_set(table->read_set, cur_part->field->field_index))
           goto next_index;
@@ -9749,7 +9794,7 @@
 
   RETURN
     New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
-    NULL o/w.
+    NULL otherwise.
 */
 
 QUICK_SELECT_I *
@@ -9762,10 +9807,10 @@
   quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
                                        
param->thd->lex->current_select->join,
                                         have_min, have_max, min_max_arg_part,
-                                        group_prefix_len, used_key_parts,
-                                        index_info, index, read_cost, records,
-                                        key_infix_len, key_infix,
-                                        parent_alloc);
+                                        group_prefix_len, group_key_parts,
+                                        used_key_parts, index_info, index,
+                                        read_cost, records, key_infix_len,
+                                        key_infix, parent_alloc);
   if (!quick)
     DBUG_RETURN(NULL);
 
@@ -9854,7 +9899,7 @@
 QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
                            bool have_max_arg,
                            KEY_PART_INFO *min_max_arg_part_arg,
-                           uint group_prefix_len_arg,
+                           uint group_prefix_len_arg, uint group_key_parts_arg,
                            uint used_key_parts_arg, KEY *index_info_arg,
                            uint use_index, double read_cost_arg,
                            ha_rows records_arg, uint key_infix_len_arg,
@@ -9864,7 +9909,7 @@
    have_max(have_max_arg), seen_first_key(FALSE),
    min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg),
    key_infix_len(key_infix_len_arg), min_functions_it(NULL),
-   max_functions_it(NULL)
+   max_functions_it(NULL), group_key_parts(group_key_parts_arg)
 {
   head=       table;
   file=       head->file;
@@ -9874,6 +9919,7 @@
   read_time= read_cost_arg;
   records= records_arg;
   used_key_parts= used_key_parts_arg;
+  real_key_parts= used_key_parts_arg;
   real_prefix_len= group_prefix_len + key_infix_len;
   group_prefix= NULL;
   min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0;
@@ -10040,7 +10086,9 @@
       range_flag|= EQ_RANGE;  /* equality condition */
   }
   range= new QUICK_RANGE(sel_range->min_value, min_max_arg_len,
+                         make_keypart_map(sel_range->part),
                          sel_range->max_value, min_max_arg_len,
+                         make_keypart_map(sel_range->part),
                          range_flag);
   if (!range)
     return TRUE;
@@ -10279,7 +10327,8 @@
       first sub-group with the extended prefix.
     */
     if (!have_min && !have_max && key_infix_len > 0)
-      result= file->index_read(record, group_prefix, real_prefix_len,
+      result= file->index_read(record, group_prefix,
+                               make_prev_keypart_map(real_key_parts),
                                HA_READ_KEY_EXACT);
 
     result= have_min ? min_res : have_max ? max_res : result;
@@ -10342,7 +10391,8 @@
     /* Apply the constant equality conditions to the non-group select fields */
     if (key_infix_len > 0)
     {
-      if ((result= file->index_read(record, group_prefix, real_prefix_len,
+      if ((result= file->index_read(record, group_prefix,
+                                    make_prev_keypart_map(real_key_parts),
                                     HA_READ_KEY_EXACT)))
         DBUG_RETURN(result);
     }
@@ -10359,7 +10409,7 @@
       /* Find the first subsequent record without NULL in the MIN/MAX field. */
       key_copy(tmp_record, record, index_info, 0);
       result= file->index_read(record, tmp_record,
-                               real_prefix_len + min_max_arg_len,
+                               make_keypart_map(real_key_parts),
                                HA_READ_AFTER_KEY);
       /*
         Check if the new record belongs to the current group by comparing its
@@ -10415,7 +10465,8 @@
   if (min_max_ranges.elements > 0)
     result= next_max_in_range();
   else
-    result= file->index_read(record, group_prefix, real_prefix_len,
+    result= file->index_read(record, group_prefix,
+                             make_prev_keypart_map(real_key_parts),
                              HA_READ_PREFIX_LAST);
   DBUG_RETURN(result);
 }
@@ -10451,7 +10502,7 @@
   {
     byte *cur_prefix= seen_first_key ? group_prefix : NULL;
     if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
-                                                      cur_prefix)))
+                         (ULL(1) << group_key_parts) - 1, cur_prefix)))
       DBUG_RETURN(result);
     seen_first_key= TRUE;
   }
@@ -10467,7 +10518,8 @@
     else
     {
       /* Load the first key in this group into record. */
-      result= file->index_read(record, group_prefix, group_prefix_len,
+      result= file->index_read(record, group_prefix,
+                               make_prev_keypart_map(group_key_parts),
                                HA_READ_AFTER_KEY);
       if (result)
         DBUG_RETURN(result);
@@ -10510,6 +10562,7 @@
 {
   ha_rkey_function find_flag;
   uint search_prefix_len;
+  ulonglong keypart_map;
   QUICK_RANGE *cur_range;
   bool found_null= FALSE;
   int result= HA_ERR_KEY_NOT_FOUND;
@@ -10531,8 +10584,9 @@
 
     if (cur_range->flag & NO_MIN_RANGE)
     {
-      find_flag= HA_READ_KEY_EXACT;
       search_prefix_len= real_prefix_len;
+      keypart_map= (ULL(1) << real_key_parts) - 1;
+      find_flag= HA_READ_KEY_EXACT;
     }
     else
     {
@@ -10540,13 +10594,13 @@
       memcpy(group_prefix + real_prefix_len, cur_range->min_key,
              cur_range->min_length);
       search_prefix_len= real_prefix_len + min_max_arg_len;
+      keypart_map= (ULL(2) << real_key_parts) - 1;
       find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
                  HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MIN) ?
                  HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
     }
 
-    result= file->index_read(record, group_prefix, search_prefix_len,
-                             find_flag);
+    result= file->index_read(record, group_prefix, keypart_map, find_flag);
     if (result)
     {
       if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
@@ -10644,6 +10698,7 @@
 {
   ha_rkey_function find_flag;
   uint search_prefix_len;
+  ulonglong keypart_map;
   QUICK_RANGE *cur_range;
   int result;
 
@@ -10665,8 +10720,9 @@
 
     if (cur_range->flag & NO_MAX_RANGE)
     {
-      find_flag= HA_READ_PREFIX_LAST;
       search_prefix_len= real_prefix_len;
+      keypart_map= (ULL(1) << real_key_parts) - 1;
+      find_flag= HA_READ_PREFIX_LAST;
     }
     else
     {
@@ -10674,13 +10730,13 @@
       memcpy(group_prefix + real_prefix_len, cur_range->max_key,
              cur_range->max_length);
       search_prefix_len= real_prefix_len + min_max_arg_len;
+      keypart_map= (ULL(2) << real_key_parts) - 1;
       find_flag= (cur_range->flag & EQ_RANGE) ?
                  HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MAX) ?
                  HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
     }
 
-    result= file->index_read(record, group_prefix, search_prefix_len,
-                             find_flag);
+    result= file->index_read(record, group_prefix, keypart_map, find_flag);
 
     if (result)
     {

--- 1.75/sql/opt_range.h	2007-02-21 11:36:31 +01:00
+++ 1.76/sql/opt_range.h	2007-02-21 11:36:31 +01:00
@@ -37,17 +37,22 @@
  public:
   char *min_key,*max_key;
   uint16 min_length,max_length,flag;
+  ulonglong min_keypart_map, max_keypart_map;
 #ifdef HAVE_purify
   uint16 dummy;					/* Avoid warnings on 'flag' */
 #endif
   QUICK_RANGE();				/* Full range */
-  QUICK_RANGE(const char *min_key_arg,uint min_length_arg,
-	      const char *max_key_arg,uint max_length_arg,
+  QUICK_RANGE(const char *min_key_arg, uint min_length_arg,
+              ulonglong min_keypart_map_arg,
+	      const char *max_key_arg, uint max_length_arg,
+              ulonglong max_keypart_map_arg,
 	      uint flag_arg)
     : min_key((char*) sql_memdup(min_key_arg,min_length_arg+1)),
       max_key((char*) sql_memdup(max_key_arg,max_length_arg+1)),
       min_length((uint16) min_length_arg),
       max_length((uint16) max_length_arg),
+      min_keypart_map(min_keypart_map_arg),
+      max_keypart_map(max_keypart_map_arg),
       flag((uint16) flag_arg)
     {
 #ifdef HAVE_purify
@@ -318,7 +323,8 @@
   int reset(void);
   int get_next();
   void range_end();
-  int get_next_prefix(uint prefix_length, byte *cur_prefix);
+  int get_next_prefix(uint prefix_length, ulonglong keypart_map,
+                      byte *cur_prefix);
   bool reverse_sorted() { return 0; }
   bool unique_key_range();
   int init_ror_merged_scan(bool reuse_handler);
@@ -605,6 +611,7 @@
   byte *tmp_record;      /* Temporary storage for next_min(), next_max(). */
   byte *group_prefix;    /* Key prefix consisting of the GROUP fields. */
   uint group_prefix_len; /* Length of the group prefix. */
+  uint group_key_parts;
   byte *last_prefix;     /* Prefix of the last group for detecting EOF. */
   bool have_min;         /* Specify whether we are computing */
   bool have_max;         /*   a MIN, a MAX, or both.         */
@@ -616,6 +623,7 @@
   uint key_infix_len;
   DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
   uint real_prefix_len; /* Length of key prefix extended with key_infix. */
+  uint real_key_parts;
   List<Item_sum> *min_functions;
   List<Item_sum> *max_functions;
   List_iterator<Item_sum> *min_functions_it;
@@ -638,10 +646,11 @@
 public:
   QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join, bool have_min,
                              bool have_max, KEY_PART_INFO *min_max_arg_part,
-                             uint group_prefix_len, uint used_key_parts,
-                             KEY *index_info, uint use_index, double read_cost,
-                             ha_rows records, uint key_infix_len,
-                             byte *key_infix, MEM_ROOT *parent_alloc);
+                             uint group_prefix_len, uint group_key_parts,
+                             uint used_key_parts, KEY *index_info, uint
+                             use_index, double read_cost, ha_rows records, uint
+                             key_infix_len, byte *key_infix, MEM_ROOT
+                             *parent_alloc);
   ~QUICK_GROUP_MIN_MAX_SELECT();
   bool add_range(SEL_ARG *sel_range);
   void update_key_stat();

--- 1.60/sql/opt_sum.cc	2007-02-21 11:36:31 +01:00
+++ 1.61/sql/opt_sum.cc	2007-02-21 11:36:31 +01:00
@@ -97,9 +97,9 @@
     GROUP BY part.
 
   RETURN VALUES
-    0 No errors
-    1 if all items were resolved
-   -1 on impossible conditions
+    0                    no errors
+    1                    if all items were resolved
+    HA_ERR_KEY_NOT_FOUND on impossible conditions
     OR an error number from my_base.h HA_ERR_... if a deadlock or a lock
        wait timeout happens, for example
 */
@@ -267,7 +267,7 @@
           if (error)
 	  {
 	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
-	      return -1;		       // No rows matching WHERE
+	      return HA_ERR_KEY_NOT_FOUND;	      // No rows matching WHERE
 	    /* HA_ERR_LOCK_DEADLOCK or some other error */
  	    table->file->print_error(error, MYF(0));
             return(error);
@@ -354,7 +354,7 @@
           if (error)
           {
 	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
-	      return -1;		       // No rows matching WHERE
+	      return HA_ERR_KEY_NOT_FOUND;	     // No rows matching WHERE
 	    /* HA_ERR_LOCK_DEADLOCK or some other error */
  	    table->file->print_error(error, MYF(0));
             return(error);

--- 1.306/sql/slave.cc	2007-02-21 11:36:31 +01:00
+++ 1.307/sql/slave.cc	2007-02-21 11:36:31 +01:00
@@ -31,6 +31,8 @@
 #include "rpl_tblmap.h"
 
 int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
+static Log_event* next_event(RELAY_LOG_INFO* rli);
+
 
 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 

--- 1.246/sql/sql_insert.cc	2007-02-21 11:36:31 +01:00
+++ 1.247/sql/sql_insert.cc	2007-02-21 11:36:31 +01:00
@@ -1163,9 +1163,7 @@
 	}
 	key_copy((byte*) key,table->record[0],table->key_info+key_nr,0);
 	if ((error=(table->file->index_read_idx(table->record[1],key_nr,
-						(byte*) key,
-						table->key_info[key_nr].
-						key_length,
+						(byte*) key, ~ULL(0),
 						HA_READ_KEY_EXACT))))
 	  goto err;
       }

--- 1.492/sql/sql_select.cc	2007-02-21 11:36:31 +01:00
+++ 1.493/sql/sql_select.cc	2007-02-21 11:36:31 +01:00
@@ -10889,7 +10889,8 @@
   TABLE *table= tab->table;
   if ((error=table->file->index_read(table->record[0],
 				     tab->ref.key_buff,
-				     tab->ref.key_length, HA_READ_KEY_EXACT)))
+                                     tab_to_keypart_map(tab),
+                                     HA_READ_KEY_EXACT)))
     return report_error(table, error);
   return 0;
 }
@@ -11027,7 +11028,8 @@
     {
       error=table->file->index_read_idx(table->record[0],tab->ref.key,
 					(byte*) tab->ref.key_buff,
-					tab->ref.key_length,HA_READ_KEY_EXACT);
+					tab_to_keypart_map(tab),
+                                        HA_READ_KEY_EXACT);
     }
     if (error)
     {
@@ -11070,7 +11072,8 @@
     }
     error=table->file->index_read(table->record[0],
 				  tab->ref.key_buff,
-				  tab->ref.key_length,HA_READ_KEY_EXACT);
+                                  tab_to_keypart_map(tab),
+                                  HA_READ_KEY_EXACT);
     if (error && error != HA_ERR_KEY_NOT_FOUND && error !=
HA_ERR_END_OF_FILE)
       return report_error(table, error);
   }
@@ -11098,7 +11101,8 @@
     return -1;
   if ((error=table->file->index_read(table->record[0],
 				     tab->ref.key_buff,
-				     tab->ref.key_length,HA_READ_KEY_EXACT)))
+				     tab_to_keypart_map(tab),
+                                     HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
       return report_error(table, error);
@@ -11125,7 +11129,7 @@
     return -1;
   if ((error=table->file->index_read_last(table->record[0],
 					  tab->ref.key_buff,
-					  tab->ref.key_length)))
+					  tab_to_keypart_map(tab))))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
       return report_error(table, error);
@@ -11666,7 +11670,7 @@
       group->buff[-1]= (char) group->field->is_null();
   }
   if (!table->file->index_read(table->record[1],
-			       join->tmp_table_param.group_buff,0,
+			       join->tmp_table_param.group_buff, ~(ulonglong)0,
 			       HA_READ_KEY_EXACT))
   {						/* Update old record */
     restore_record(table,record[1]);

--- 1.275/sql/table.cc	2007-02-21 11:36:31 +01:00
+++ 1.276/sql/table.cc	2007-02-21 11:36:31 +01:00
@@ -1223,12 +1223,12 @@
     if ((int) (share->next_number_index= (uint)
 	       find_ref_key(share->key_info, share->keys,
                             share->default_values, reg_field,
-			    &share->next_number_key_offset)) < 0)
+			    &share->next_number_key_offset,
+                            &share->next_number_keypart)) < 0)
     {
       /* Wrong field definition */
-      DBUG_ASSERT(0);
-      reg_field->unireg_check= Field::NONE;	/* purecov: inspected */
-      share->found_next_number_field= 0;
+      error= 4;
+      goto err;
     }
     else
       reg_field->flags |= AUTO_INCREMENT_FLAG;
@@ -2245,6 +2245,30 @@
   return to;
 }
 
+/*
+  DESCRIPTION
+    given a buffer with a key value, and a map of keyparts
+    that are present in this value, returns the length of the value
+*/
+uint calculate_key_len(TABLE *table, uint key, const byte *buf,
+                       ulonglong keypart_map)
+{
+  /* works only with key prefixes */
+  DBUG_ASSERT(((keypart_map + 1) & keypart_map) == 0);
+
+  KEY *key_info= table->s->key_info+key;
+  KEY_PART_INFO *key_part= key_info->key_part;
+  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
+  uint length= 0;
+
+  while (key_part < end_key_part && keypart_map)
+  {
+    length+= key_part->store_length;
+    keypart_map >>= 1;
+    key_part++;
+  }
+  return length;
+}
 
 /*
   Check if database name is valid
@@ -3937,7 +3961,7 @@
   */
   bitmap_set_bit(read_set, found_next_number_field->field_index);
   bitmap_set_bit(write_set, found_next_number_field->field_index);
-  if (s->next_number_key_offset)
+  if (s->next_number_keypart)
     mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
   file->column_bitmaps_signal();
 }

--- 1.159/sql/table.h	2007-02-21 11:36:31 +01:00
+++ 1.160/sql/table.h	2007-02-21 11:36:31 +01:00
@@ -158,7 +158,12 @@
   LEX_STRING path;                	/* Path to .frm file (from datadir) */
   LEX_STRING normalized_path;		/* unpack_filename(path) */
   LEX_STRING connect_string;
-  key_map keys_in_use;                  /* Keys in use for table */
+
+  /* 
+     Set of keys in use, implemented as a Bitmap.
+     Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.
+  */
+  key_map keys_in_use;
   key_map keys_for_keyread;
   ha_rows min_rows, max_rows;		/* create information */
   ulong   avg_row_length;		/* create information */
@@ -314,7 +319,21 @@
   byte *write_row_record;		/* Used as optimisation in
 					   THD::write_row */
   byte *insert_values;                  /* used by INSERT ... UPDATE */
-  key_map quick_keys, used_keys, keys_in_use_for_query, merge_keys;
+  key_map quick_keys, used_keys;
+
+  /*
+    A set of keys that can be used in the query that references this
+    table.
+
+    All indexes disabled on the table's TABLE_SHARE (see TABLE::s) will be 
+    subtracted from this set upon instantiation. Thus for any TABLE t it holds
+    that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we 
+    must not introduce any new keys here (see setup_tables).
+
+    The set is implemented as a bitmap.
+  */
+  key_map keys_in_use_for_query;
+  key_map merge_keys;
   KEY  *key_info;			/* data of keys in database */
 
   Field *next_number_field;		/* Set if next_number is activated */
@@ -453,6 +472,12 @@
 
 };
 
+enum enum_schema_table_state
+{ 
+  NOT_PROCESSED= 0,
+  PROCESSED_BY_CREATE_SORT_INDEX,
+  PROCESSED_BY_JOIN_EXEC
+};
 
 typedef struct st_foreign_key_info
 {
@@ -712,7 +737,6 @@
   st_select_lex_unit *derived;		/* SELECT_LEX_UNIT of derived table */
   ST_SCHEMA_TABLE *schema_table;        /* Information_schema table */
   st_select_lex	*schema_select_lex;
-  bool is_schema_table_processed;
   /*
     True when the view field translation table is used to convert
     schema table fields for backwards compatibility with SHOW command.
@@ -822,6 +846,7 @@
   */
   bool          prelocking_placeholder;
 
+  enum enum_schema_table_state schema_table_state;
   void calc_md5(char *buffer);
   void set_underlying_merge();
   int view_check_option(THD *thd, bool ignore_failure);

--- 1.34/support-files/Makefile.am	2007-02-21 11:36:31 +01:00
+++ 1.35/support-files/Makefile.am	2007-02-21 11:36:31 +01:00
@@ -43,6 +43,9 @@
 
 pkgdata_SCRIPTS =	mysql.server
 
+aclocaldir =		$(datadir)/aclocal
+aclocal_DATA =		mysql.m4
+
 noinst_DATA = mysql-@VERSION@.spec \
 			MySQL-shared-compat.spec
 

--- 1.21/sql/event_db_repository.cc	2007-02-21 11:36:31 +01:00
+++ 1.22/sql/event_db_repository.cc	2007-02-21 11:36:31 +01:00
@@ -288,7 +288,7 @@
   {
     key_copy(key_buf, event_table->record[0], key_info, key_len);
     if (!(ret= event_table->file->index_read(event_table->record[0], key_buf,
-                                             key_len, HA_READ_PREFIX)))
+                                             (ulonglong)1, HA_READ_PREFIX)))
     {
       DBUG_PRINT("info",("Found rows. Let's retrieve them. ret=%d", ret));
       do
@@ -843,8 +843,7 @@
 
   key_copy(key, table->record[0], table->key_info,
table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0], 0, key,
-                                  table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0], 0, key, ~ULL(0),
                                   HA_READ_KEY_EXACT))
   {
     DBUG_PRINT("info", ("Row not found"));

--- 1.145/sql/item_subselect.cc	2007-02-21 11:36:31 +01:00
+++ 1.146/sql/item_subselect.cc	2007-02-21 11:36:31 +01:00
@@ -2015,7 +2015,8 @@
     table->file->ha_index_init(tab->ref.key, 0);
   error= table->file->index_read(table->record[0],
                                  tab->ref.key_buff,
-                                 tab->ref.key_length,HA_READ_KEY_EXACT);
+                                 tab_to_keypart_map(tab),
+                                 HA_READ_KEY_EXACT);
   if (error &&
       error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
     error= report_error(table, error);
@@ -2124,7 +2125,8 @@
     table->file->ha_index_init(tab->ref.key, 1);
   error= table->file->index_read(table->record[0],
                                  tab->ref.key_buff,
-                                 tab->ref.key_length,HA_READ_KEY_EXACT);
+                                 tab_to_keypart_map(tab),
+                                 HA_READ_KEY_EXACT);
   if (error &&
       error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
     error= report_error(table, error);

--- 1.52/storage/example/ha_example.cc	2007-02-21 11:36:31 +01:00
+++ 1.53/storage/example/ha_example.cc	2007-02-21 11:36:31 +01:00
@@ -415,7 +415,7 @@
 */
 
 int ha_example::index_read(byte * buf, const byte * key,
-                           uint key_len __attribute__((unused)),
+                           ulonglong keypart_map __attribute__((unused)),
                            enum ha_rkey_function find_flag
                            __attribute__((unused)))
 {

--- 1.47/sql/tztime.cc	2007-02-21 11:36:31 +01:00
+++ 1.48/sql/tztime.cc	2007-02-21 11:36:31 +01:00
@@ -1900,9 +1900,9 @@
   (void)table->file->ha_index_init(0, 1);
 
   if (table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                              0, HA_READ_KEY_EXACT))
+                              ~(ulonglong)0, HA_READ_KEY_EXACT))
   {
-#ifdef EXTRA_DEBUG    
+#ifdef EXTRA_DEBUG
     /*
       Most probably user has mistyped time zone name, so no need to bark here
       unless we need it for debugging.
@@ -1928,7 +1928,7 @@
   (void)table->file->ha_index_init(0, 1);
 
   if (table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                              0, HA_READ_KEY_EXACT))
+                              ~(ulonglong)0, HA_READ_KEY_EXACT))
   {
     sql_print_error("Can't find description of time zone '%u'", tzid);
     goto end;
@@ -1955,9 +1955,8 @@
   table->field[0]->store((longlong) tzid, TRUE);
   (void)table->file->ha_index_init(0, 1);
 
-  // FIXME Is there any better approach than explicitly specifying 4 ???
   res= table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                               4, HA_READ_KEY_EXACT);
+                               (ulonglong)1, HA_READ_KEY_EXACT);
   while (!res)
   {
     ttid= (uint)table->field[1]->val_int();
@@ -2028,9 +2027,8 @@
   table->field[0]->store((longlong) tzid, TRUE);
   (void)table->file->ha_index_init(0, 1);
 
-  // FIXME Is there any better approach than explicitly specifying 4 ???
   res= table->file->index_read(table->record[0],
(byte*)table->field[0]->ptr,
-                               4, HA_READ_KEY_EXACT);
+                               (ulonglong)1, HA_READ_KEY_EXACT);
   while (!res)
   {
     ttime= (my_time_t)table->field[1]->val_int();

--- 1.406/sql/ha_ndbcluster.cc	2007-02-21 11:36:31 +01:00
+++ 1.407/sql/ha_ndbcluster.cc	2007-02-21 11:36:31 +01:00
@@ -1105,7 +1105,7 @@
   KEY* key_info= tab->key_info;
   const char **key_name= tab->s->keynames.type_names;
   DBUG_ENTER("ha_ndbcluster::create_indexes");
-  
+
   for (i= 0; i < tab->s->keys; i++, key_info++, key_name++)
   {
     index_name= *key_name;
@@ -3369,19 +3369,6 @@
 }
 
 
-int ha_ndbcluster::index_read_idx(byte *buf, uint index_no, 
-                              const byte *key, uint key_len, 
-                              enum ha_rkey_function find_flag)
-{
-  statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status);
-  DBUG_ENTER("ha_ndbcluster::index_read_idx");
-  DBUG_PRINT("enter", ("index_no: %u, key_len: %u", index_no, key_len));  
-  close_scan();
-  index_init(index_no, 0);  
-  DBUG_RETURN(index_read(buf, key, key_len, find_flag));
-}
-
-
 int ha_ndbcluster::index_next(byte *buf)
 {
   DBUG_ENTER("ha_ndbcluster::index_next");
@@ -3548,10 +3535,10 @@
 
   m_multi_cursor= 0;
   if (!m_active_cursor && !m_multi_cursor)
-    DBUG_RETURN(1);
+    DBUG_RETURN(0);
 
   NdbScanOperation *cursor= m_active_cursor ? m_active_cursor : m_multi_cursor;
-  
+
   if (m_lock_tuple)
   {
     /*

--- 1.166/sql/ha_ndbcluster.h	2007-02-21 11:36:31 +01:00
+++ 1.167/sql/ha_ndbcluster.h	2007-02-21 11:36:31 +01:00
@@ -108,6 +108,7 @@
   char *table_name;
   Ndb::TupleIdRange tuple_id_range;
 #ifdef HAVE_NDB_BINLOG
+  uint32 connect_count;
   uint32 flags;
   NdbEventOperation *op;
   NdbEventOperation *op_old; // for rename table

--- 1.157/include/my_global.h	2007-02-21 11:36:31 +01:00
+++ 1.158/include/my_global.h	2007-02-21 11:36:31 +01:00
@@ -987,7 +987,7 @@
 typedef unsigned long uint32;
 #endif
 #else
-#error "Neither int or long is of 4 bytes width"
+#error Neither int or long is of 4 bytes width
 #endif
 
 #if !defined(HAVE_ULONG) && !defined(__USE_MISC)
@@ -1015,6 +1015,14 @@
 typedef unsigned __int64 my_ulonglong;
 #else
 typedef unsigned long long my_ulonglong;
+#endif
+
+#if SIZEOF_CHARP == SIZEOF_INT
+typedef int intptr;
+#elif SIZEOF_CHARP == SIZEOF_LONG
+typedef long intptr;
+#else
+#error sizeof(void *) is neither sizeof(int) nor sizeof(long)
 #endif
 
 #ifdef USE_RAID

--- 1.44/sql/sql_plugin.cc	2007-02-21 11:36:31 +01:00
+++ 1.45/sql/sql_plugin.cc	2007-02-21 11:36:31 +01:00
@@ -943,8 +943,7 @@
   table->use_all_columns();
   table->field[0]->store(name->str, name->length, system_charset_info);
   if (! table->file->index_read_idx(table->record[0], 0,
-                                    (byte *)table->field[0]->ptr,
-                                    table->key_info[0].key_length,
+                                    (byte *)table->field[0]->ptr, ~ULL(0),
                                     HA_READ_KEY_EXACT))
   {
     int error;

--- 1.83/sql/ha_partition.cc	2007-02-21 11:36:31 +01:00
+++ 1.84/sql/ha_partition.cc	2007-02-21 11:36:31 +01:00
@@ -3320,13 +3320,14 @@
 */
 
 int ha_partition::index_read(byte * buf, const byte * key,
-			     uint key_len, enum ha_rkey_function find_flag)
+			     ulonglong keypart_map,
+                             enum ha_rkey_function find_flag)
 {
   DBUG_ENTER("ha_partition::index_read");
 
   end_range= 0;
   m_index_scan_type= partition_index_read;
-  DBUG_RETURN(common_index_read(buf, key, key_len, find_flag));
+  DBUG_RETURN(common_index_read(buf, key, keypart_map, find_flag));
 }
 
 
@@ -3339,14 +3340,17 @@
   see index_read for rest
 */
 
-int ha_partition::common_index_read(byte *buf, const byte *key, uint key_len,
+int ha_partition::common_index_read(byte *buf, const byte *key,
+                                    ulonglong keypart_map,
 				    enum ha_rkey_function find_flag)
 {
   int error;
   bool reverse_order= FALSE;
+  uint key_len= calculate_key_len(table, active_index, key, keypart_map);
   DBUG_ENTER("ha_partition::common_index_read");
 
   memcpy((void*)m_start_key.key, key, key_len);
+  m_start_key.keypart_map= keypart_map;
   m_start_key.length= key_len;
   m_start_key.flag= find_flag;
 
@@ -3475,33 +3479,6 @@
 
 
 /*
-  Perform index read using index where always only one row is returned
-
-  SYNOPSIS
-    index_read_idx()
-    see index_read for rest of parameters and return values
-
-  DESCRIPTION
-    Positions an index cursor to the index specified in key. Fetches the
-    row if any.  This is only used to read whole keys.
-    TODO: Optimise this code to avoid index_init and index_end
-*/
-
-int ha_partition::index_read_idx(byte * buf, uint index, const byte * key,
-				 uint key_len,
-                                 enum ha_rkey_function find_flag)
-{
-  int res;
-  DBUG_ENTER("ha_partition::index_read_idx");
-
-  index_init(index, 0);
-  res= index_read(buf, key, key_len, find_flag);
-  index_end();
-  DBUG_RETURN(res);
-}
-
-
-/*
   Read last using key
 
   SYNOPSIS
@@ -3519,14 +3496,15 @@
     Can only be used on indexes supporting HA_READ_ORDER
 */
 
-int ha_partition::index_read_last(byte *buf, const byte *key, uint keylen)
+int ha_partition::index_read_last(byte *buf, const byte *key,
+                                      ulonglong keypart_map)
 {
   DBUG_ENTER("ha_partition::index_read_last");
 
   m_ordered= TRUE;				// Safety measure
   end_range= 0;
   m_index_scan_type= partition_index_read_last;
-  DBUG_RETURN(common_index_read(buf, key, keylen, HA_READ_PREFIX_LAST));
+  DBUG_RETURN(common_index_read(buf, key, keypart_map, HA_READ_PREFIX_LAST));
 }
 
 
@@ -3672,7 +3650,7 @@
     m_index_scan_type= partition_index_read;
     error= common_index_read(m_rec0,
 			     start_key->key,
-			     start_key->length, start_key->flag);
+                             start_key->keypart_map, start_key->flag);
   }
   DBUG_RETURN(error);
 }
@@ -3871,7 +3849,7 @@
     case partition_index_read:
       DBUG_PRINT("info", ("index_read on partition %d", i));
       error= file->index_read(buf, m_start_key.key,
-                              m_start_key.length,
+                              m_start_key.keypart_map,
                               m_start_key.flag);
       break;
     case partition_index_first:
@@ -3963,7 +3941,7 @@
     case partition_index_read:
       error= file->index_read(rec_buf_ptr,
                               m_start_key.key,
-                              m_start_key.length,
+                              m_start_key.keypart_map,
                               m_start_key.flag);
       break;
     case partition_index_first:
@@ -3977,7 +3955,7 @@
     case partition_index_read_last:
       error= file->index_read_last(rec_buf_ptr,
                                    m_start_key.key,
-                                   m_start_key.length);
+                                   m_start_key.keypart_map);
       reverse_order= TRUE;
       break;
     default:

--- 1.97/storage/federated/ha_federated.cc	2007-02-21 11:36:31 +01:00
+++ 1.98/storage/federated/ha_federated.cc	2007-02-21 11:36:31 +01:00
@@ -363,7 +363,6 @@
 static int federated_commit(handlerton *hton, THD *thd, bool all);
 static int federated_rollback(handlerton *hton, THD *thd, bool all);
 
-
 /* Federated storage engine handlerton */
 
 static handler *federated_create_handler(handlerton *hton, 

--- 1.5/sql/sql_servers.cc	2007-02-21 11:36:31 +01:00
+++ 1.6/sql/sql_servers.cc	2007-02-21 11:36:31 +01:00
@@ -25,6 +25,7 @@
 #include "sp_head.h"
 #include "sp.h"
 
+static my_bool servers_load(THD *thd, TABLE_LIST *tables);
 HASH servers_cache;
 pthread_mutex_t servers_cache_mutex;                // To init the hash
 uint servers_cache_initialised=FALSE;
@@ -353,8 +354,7 @@
                          system_charset_info);
 
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(ulonglong)0,
                                    HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -552,8 +552,7 @@
 
   /* read index until record is that specified in server_name */
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(longlong)0,
                                    HA_READ_KEY_EXACT)))
   {
     /* if not found, err */
@@ -871,8 +870,7 @@
                          system_charset_info);
 
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(longlong)0,
                                    HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -926,8 +924,7 @@
   table->field[0]->store(server_name, server_name_length, system_charset_info);
 
   if ((error= table->file->index_read_idx(table->record[0], 0,
-                                   (byte *)table->field[0]->ptr,
-                                   table->key_info[0].key_length,
+                                   (byte *)table->field[0]->ptr, ~(ulonglong)0,
                                    HA_READ_KEY_EXACT)))
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)

--- 1.138/sql/sp.cc	2007-02-21 11:36:31 +01:00
+++ 1.139/sql/sp.cc	2007-02-21 11:36:31 +01:00
@@ -218,8 +218,7 @@
   key_copy(key, table->record[0], table->key_info,
            table->key_info->key_length);
 
-  if (table->file->index_read_idx(table->record[0], 0,
-				  key, table->key_info->key_length,
+  if (table->file->index_read_idx(table->record[0], 0, key, ~ULL(0),
 				  HA_READ_KEY_EXACT))
     DBUG_RETURN(SP_KEY_NOT_FOUND);
 
@@ -904,7 +903,7 @@
   table->file->ha_index_init(0, 1);
   if (! table->file->index_read(table->record[0],
                                 (byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
-				key_len, HA_READ_KEY_EXACT))
+                                (ulonglong)1, HA_READ_KEY_EXACT))
   {
     int nxtres;
     bool deleted= FALSE;
Thread
bk commit into 5.1 tree (serg:1.2440)Sergei Golubchik21 Feb