summaryrefslogtreecommitdiff
path: root/sql/key.cc
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gshchepa.loc>2007-04-29 04:16:17 +0500
committerunknown <gshchepa/uchum@gshchepa.loc>2007-04-29 04:16:17 +0500
commit98c0da4ed5dd8cbfc8450675e2c008b829367318 (patch)
treea64b8db2706959f7c4cfb27333e1de68f84a8e9e /sql/key.cc
parent78c734b0132fbd53ff033eada5a9664919370739 (diff)
downloadmariadb-git-98c0da4ed5dd8cbfc8450675e2c008b829367318.tar.gz
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.
Diffstat (limited to 'sql/key.cc')
-rw-r--r--sql/key.cc23
1 files changed, 12 insertions, 11 deletions
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;