From 695bcb9e7b39c50bbc4bdba8e12aaa4375be3bee Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Sep 2006 16:15:57 +0500 Subject: Bug#19960 Inconsistent results when joining InnoDB tables using partial UTF8 indexes Adding a multibyte-aware VARCHAR copying function, to put correct column prefix, taking in account number of characters (instead just limiting on number of bytes). For example, for a KEY(col(3)) on a UTF8 column when copying the string 'foo bar foo', we should put only 3 leftmost characters: 'foo'. 9 characters were incorrectly put before this fix. mysql-test/r/ctype_utf8.result: Adding test case mysql-test/t/ctype_utf8.test: Adding test case sql/field_conv.cc: Adding multibyte aware copy function for VARCHAR --- sql/field_conv.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'sql/field_conv.cc') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 3200f2ca9b2..95ff985376d 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -428,6 +428,21 @@ static void do_varstring2(Copy_field *copy) length); } + +static void do_varstring2_mb(Copy_field *copy) +{ + int well_formed_error; + CHARSET_INFO *cs= copy->from_field->charset(); + uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen; + uint from_length= uint2korr(copy->from_ptr); + const char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH; + uint length= cs->cset->well_formed_len(cs, from_beg, from_beg + from_length, + char_length, &well_formed_error); + int2store(copy->to_ptr, length); + memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length); +} + + /*************************************************************************** ** The different functions that fills in a Copy_field class ***************************************************************************/ @@ -587,7 +602,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) return do_field_string; if (to_length != from_length) return (((Field_varstring*) to)->length_bytes == 1 ? - do_varstring1 : do_varstring2); + do_varstring1 : (from->charset()->mbmaxlen == 1 ? + do_varstring2 : do_varstring2_mb)); } else if (to_length < from_length) return (from->charset()->mbmaxlen == 1 ? -- cgit v1.2.1