List:Commits« Previous MessageNext Message »
From:Ingo Struewing Date:November 7 2007 9:30am
Subject:bk commit into 5.1 tree (istruewing:1.2598) BUG#22351
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of istruewing. When istruewing 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-11-07 09:30:41+01:00, istruewing@stripped +1 -0
  Bug#22351 - handler::index_next_same() call to key_cmp_if_same() uses
              the wrong buffer
  
  handler::index_next_same() did not take into account that the
  internally called function key_cmp_if_same() uses the fixed
  buffer table->record[0] for key comparison instead of the
  buffer provided by the caller of handler::index_next_same().
  
  Added code to temporarily redirect table->record[0] and the fields
  used for the key to the record buffer provided by the caller of
  handler::index_next_same().
  
  The test case is in partition.test already.

  sql/handler.cc@stripped, 2007-11-07 09:30:38+01:00, istruewing@stripped +42 -1
    Bug#22351 - handler::index_next_same() call to key_cmp_if_same() uses
                the wrong buffer
    Added code to temporarily redirect table->record[0] and the fields
    used for the key to the record buffer provided by the caller of
    handler::index_next_same().

diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-08-31 08:57:57 +02:00
+++ b/sql/handler.cc	2007-11-07 09:30:38 +01:00
@@ -2522,15 +2522,56 @@ int ha_enable_transaction(THD *thd, bool
 int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
 {
   int error;
+  DBUG_ENTER("index_next_same");
   if (!(error=index_next(buf)))
   {
+    my_ptrdiff_t ptrdiff= buf - table->record[0];
+    uchar *save_record_0;
+    KEY *key_info;
+    KEY_PART_INFO *key_part;
+    KEY_PART_INFO *key_part_end;
+    LINT_INIT(save_record_0);
+    LINT_INIT(key_info);
+    LINT_INIT(key_part);
+    LINT_INIT(key_part_end);
+
+    /*
+      key_cmp_if_same() compares table->record[0] against 'key'.
+      In parts it uses table->record[0] directly, in parts it uses
+      field objects with their local pointers into table->record[0].
+      If 'buf' is distinct from table->record[0], we need to move
+      all record references. This is table->record[0] itself and
+      the field pointers of the fields used in this key.
+    */
+    if (ptrdiff)
+    {
+      save_record_0= table->record[0];
+      table->record[0]= buf;
+      key_info= table->key_info + active_index;
+      key_part= key_info->key_part;
+      key_part_end= key_part + key_info->key_parts;
+      for (; key_part < key_part_end; key_part++)
+      {
+        DBUG_ASSERT(key_part->field);
+        key_part->field->move_field_offset(ptrdiff);
+      }
+    }
+
     if (key_cmp_if_same(table, key, active_index, keylen))
     {
       table->status=STATUS_NOT_FOUND;
       error=HA_ERR_END_OF_FILE;
     }
+
+    /* Move back if necessary. */
+    if (ptrdiff)
+    {
+      table->record[0]= save_record_0;
+      for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
+        key_part->field->move_field_offset(-ptrdiff);
+    }
   }
-  return error;
+  DBUG_RETURN(error);
 }
 
 
Thread
bk commit into 5.1 tree (istruewing:1.2598) BUG#22351Ingo Struewing7 Nov