From 98c0da4ed5dd8cbfc8450675e2c008b829367318 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Apr 2007 04:16:17 +0500 Subject: Fixed bug #13191. INSERT...ON DUPLICATE KEY UPDATE may cause error 1032: "Can't find record in ..." if we are inserting into InnoDB table unique index of partial key with underlying UTF-8 string field. This error occurs because INSERT...ON DUPLICATE uses a wrong procedure to copy string fields of multi-byte character sets for index search. mysql-test/t/innodb_mysql.test: Added test case for bug #13191. mysql-test/r/innodb_mysql.result: Added test case for bug #13191. sql/field.h: Fixed bug #13191. Field_string::get_key_image() virtual function was overloaded to implement copying of variable length character (UTF-8) fields. Field::get_key_image() function prototype has been changed to return byte size of copied data. sql/field.cc: Fixed bug #13191. Field_string::get_key_image() virtual function was overloaded to implement copying of variable length character (UTF-8) fields. Field::get_key_image() function prototype has been changed to return byte size of copied data. sql/key.cc: Fixed bug #13191. INSERT...ON DUPLICATE KEY UPDATE may cause error 1032: "Can't find record in ...". This error occurs because INSERT...ON DUPLICATE uses a wrong procedure to copy field parts for index search. key_copy() function has been fixed. --- sql/key.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'sql/key.cc') diff --git a/sql/key.cc b/sql/key.cc index 7ddd40de2c9..d57d1570da7 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -89,20 +89,21 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length) } if (key_part->key_part_flag & HA_BLOB_PART) { - char *pos; - ulong blob_length=((Field_blob*) key_part->field)->get_length(); - key_length-=2; - ((Field_blob*) key_part->field)->get_ptr(&pos); - length=min(key_length,key_part->length); - set_if_smaller(blob_length,length); - int2store(key,(uint) blob_length); - key+=2; // Skip length info - memcpy(key,pos,blob_length); + key_length-= HA_KEY_BLOB_LENGTH; + length= min(key_length, key_part->length); + key_part->field->get_key_image((char *) key, length, + key_part->field->charset(), + Field::itRAW); + key+= HA_KEY_BLOB_LENGTH; } else { - length=min(key_length,key_part->length); - memcpy(key,table->record[0]+key_part->offset,(size_t) length); + length= min(key_length, key_part->length); + Field *field= key_part->field; + CHARSET_INFO *cs= field->charset(); + uint bytes= field->get_key_image(key, length, cs, Field::itRAW); + if (bytes < length) + cs->cset->fill(cs, key + bytes, length - bytes, ' '); } key+=length; key_length-=length; -- cgit v1.2.1 From e8225073649844a43bc4ea6362a5df5e6210933b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Apr 2007 11:56:23 +0500 Subject: Patch to eliminate compilation errors under VC after bug #13191 fix. --- sql/key.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/key.cc') diff --git a/sql/key.cc b/sql/key.cc index d57d1570da7..5bb389fcb45 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -101,9 +101,9 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length) length= min(key_length, key_part->length); Field *field= key_part->field; CHARSET_INFO *cs= field->charset(); - uint bytes= field->get_key_image(key, length, cs, Field::itRAW); + uint bytes= field->get_key_image((char *) key, length, cs, Field::itRAW); if (bytes < length) - cs->cset->fill(cs, key + bytes, length - bytes, ' '); + cs->cset->fill(cs, (char *) key + bytes, length - bytes, ' '); } key+=length; key_length-=length; -- cgit v1.2.1 From 7eb77da33a7da7c56053164793012f1091048350 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Apr 2007 12:56:46 +0500 Subject: Patch to eliminate compilation errors under VC after bug #13191 fix. --- sql/key.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/key.cc') diff --git a/sql/key.cc b/sql/key.cc index 1816e924c2b..2bdde46b6b3 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -124,7 +124,7 @@ void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length) { key_length-= HA_KEY_BLOB_LENGTH; length= min(key_length, key_part->length); - key_part->field->get_key_image(to_key, length, Field::itRAW); + key_part->field->get_key_image((char*) to_key, length, Field::itRAW); to_key+= HA_KEY_BLOB_LENGTH; } else -- cgit v1.2.1