List:Commits« Previous MessageNext Message »
From:holyfoot Date:April 19 2007 4:43pm
Subject:bk commit into 5.1 tree (holyfoot:1.2590) BUG#27123
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of hf. When hf 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-04-19 21:43:42+05:00, holyfoot@stripped +6 -0
  Bug #27123 (partition + on duplicate key update + varchar = Can't find
  record in table)
  
  key_restore function didn't work as intended in the case of
  VARCHAR or BLOB fields, stored the restored key in field->ptr instead
  of to_record.
  That produced the wrong key so search returned wrong result

  mysql-test/r/partition.result@stripped, 2007-04-19 21:43:40+05:00, holyfoot@stripped +8 -0
    result added

  mysql-test/t/partition.test@stripped, 2007-04-19 21:43:40+05:00, holyfoot@stripped +11 -0
    testcase

  sql/field.cc@stripped, 2007-04-19 21:43:40+05:00, holyfoot@stripped +1 -1
    Field_blob::store_length made static

  sql/field.h@stripped, 2007-04-19 21:43:40+05:00, holyfoot@stripped +14 -3
    Field_blob::store_length and set_ptr functions implemented in slightly
    different way

  sql/ha_ndbcluster.cc@stripped, 2007-04-19 21:43:40+05:00, holyfoot@stripped +2 -6
    set_ptr_offset used

  sql/key.cc@stripped, 2007-04-19 21:43:40+05:00, holyfoot@stripped +17 -6
    set key_part->field->ptr to the proper place inside the to_record
    so the restored key will be placed there as key_restore
    is supposed to behave

# 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:	holyfoot
# Host:	hfmain.(none)
# Root:	/home/hf/work/27123/my51-27123

--- 1.388/sql/field.cc	2007-04-19 21:43:47 +05:00
+++ 1.389/sql/field.cc	2007-04-19 21:43:47 +05:00
@@ -6969,7 +6969,7 @@ Field_blob::Field_blob(char *ptr_arg, uc
 }
 
 
-void Field_blob::store_length(uint32 number)
+void Field_blob::store_length(char *ptr, uint packlength, uint32 number)
 {
   switch (packlength) {
   case 1:

--- 1.220/sql/field.h	2007-04-19 21:43:47 +05:00
+++ 1.221/sql/field.h	2007-04-19 21:43:47 +05:00
@@ -1274,7 +1274,12 @@ public:
   }
   int reset(void) { bzero(ptr, packlength+sizeof(char*)); return 0; }
   void reset_fields() { bzero((char*) &value,sizeof(value)); }
-  void store_length(uint32 number);
+  static void store_length(char *ptr, uint packlength, uint32 number);
+  inline void store_length(uint32 number)
+  {
+    store_length(ptr, packlength, number);
+  }
+
   inline uint32 get_length(uint row_offset=0)
   { return get_length(ptr+row_offset); }
   uint32 get_length(const char *ptr);
@@ -1292,11 +1297,17 @@ public:
       memcpy(ptr,length,packlength);
       memcpy_fixed(ptr+packlength,&data,sizeof(char*));
     }
+  void set_ptr_offset(my_ptrdiff_t ptr_diff, uint32 length,char *data)
+    {
+      char *ptr_ofs= ADD_TO_PTR(ptr,ptr_diff,char*);
+      store_length(ptr_ofs, packlength, length);
+      memcpy_fixed(ptr_ofs+packlength,&data,sizeof(char*));
+    }
   inline void set_ptr(uint32 length,char *data)
     {
-      store_length(length);
-      memcpy_fixed(ptr+packlength,&data,sizeof(char*));
+      set_ptr_offset(0, length, data);
     }
+
   void get_key_image(char *buff,uint length, imagetype type);
   void set_key_image(char *buff,uint length);
   void sql_type(String &str) const;

--- 1.49/sql/key.cc	2007-04-19 21:43:47 +05:00
+++ 1.50/sql/key.cc	2007-04-19 21:43:47 +05:00
@@ -221,23 +221,34 @@ void key_restore(byte *to_record, byte *
     }
     if (key_part->key_part_flag & HA_BLOB_PART)
     {
+      /*
+        This in fact never happens, as we have only partial BLOB
+        keys yet anyway, so it's difficult to find any sence to
+        restore the part of a record.
+        Maybe this branch is to be removed, but now we
+        have to ignore GCov compaining.
+      */
       uint blob_length= uint2korr(from_key);
+      Field_blob *field= (Field_blob*) key_part->field;
       from_key+= HA_KEY_BLOB_LENGTH;
       key_length-= HA_KEY_BLOB_LENGTH;
-      ((Field_blob*) key_part->field)->set_ptr((ulong) blob_length,
-					       (char*) from_key);
+      field->set_ptr_offset(to_record - field->table->record[0],
+                            (ulong) blob_length, (char*) from_key);
       length= key_part->length;
     }
     else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
     {
+      Field *field= key_part->field;
       my_bitmap_map *old_map;
+      my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+      field->move_field_offset(ptrdiff);
       key_length-= HA_KEY_BLOB_LENGTH;
       length= min(key_length, key_part->length);
-      old_map= dbug_tmp_use_all_columns(key_part->field->table,
-                                        key_part->field->table->write_set);
-      key_part->field->set_key_image((char *) from_key, length);
-      dbug_tmp_restore_column_map(key_part->field->table->write_set, old_map);
+      old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+      field->set_key_image((char *) from_key, length);
+      dbug_tmp_restore_column_map(field->table->write_set, old_map);
       from_key+= HA_KEY_BLOB_LENGTH;
+      field->move_field_offset(-ptrdiff);
     }
     else
     {

--- 1.444/sql/ha_ndbcluster.cc	2007-04-19 21:43:47 +05:00
+++ 1.445/sql/ha_ndbcluster.cc	2007-04-19 21:43:47 +05:00
@@ -853,9 +853,7 @@ int get_ndb_blobs_value(TABLE* table, Nd
                               i, offset, (long) buf, len, (int)ptrdiff));
           DBUG_ASSERT(len == len64);
           // Ugly hack assumes only ptr needs to be changed
-          field_blob->ptr+= ptrdiff;
-          field_blob->set_ptr(len, buf);
-          field_blob->ptr-= ptrdiff;
+          field_blob->set_ptr_offset(ptrdiff, len, buf);
         }
         offset+= size;
       }
@@ -864,9 +862,7 @@ int get_ndb_blobs_value(TABLE* table, Nd
         // have to set length even in this case
         char *buf= buffer + offset; // or maybe NULL
         uint32 len= 0;
-        field_blob->ptr+= ptrdiff;
-        field_blob->set_ptr(len, buf);
-        field_blob->ptr-= ptrdiff;
+        field_blob->set_ptr_offset(ptrdiff, len, buf);
         DBUG_PRINT("info", ("[%u] isNull=%d", i, isNull));
       }
     }

--- 1.60/mysql-test/r/partition.result	2007-04-19 21:43:47 +05:00
+++ 1.61/mysql-test/r/partition.result	2007-04-19 21:43:47 +05:00
@@ -1238,4 +1238,12 @@ t2	CREATE TABLE `t2` (
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (i) (PARTITION p01 VALUES LESS THAN (1000) ENGINE = MyISAM) */
 DROP TABLE t1, t2;
 set @@sql_mode=@org_mode;
+create table t1 (c1 varchar(255),c2 tinyint,primary key(c1))
+partition by key (c1) partitions 10 ;
+insert into t1 values ('aaa','1') on duplicate key update c2 = c2 + 1;
+insert into t1 values ('aaa','1') on duplicate key update c2 = c2 + 1;
+select * from t1;
+c1	c2
+aaa	2
+drop table t1;
 End of 5.1 tests

--- 1.54/mysql-test/t/partition.test	2007-04-19 21:43:47 +05:00
+++ 1.55/mysql-test/t/partition.test	2007-04-19 21:43:47 +05:00
@@ -1492,4 +1492,15 @@ show create table t2;
 DROP TABLE t1, t2;
 set @@sql_mode=@org_mode;
 
+#
+# Bug #27123 partition + on duplicate key update + varchar = Can't find record in <table> 
+#
+create table t1 (c1 varchar(255),c2 tinyint,primary key(c1))
+   partition by key (c1) partitions 10 ;
+insert into t1 values ('aaa','1') on duplicate key update c2 = c2 + 1;
+insert into t1 values ('aaa','1') on duplicate key update c2 = c2 + 1;
+select * from t1;
+drop table t1;
+
+
 --echo End of 5.1 tests
Thread
bk commit into 5.1 tree (holyfoot:1.2590) BUG#27123holyfoot19 Apr