From b50d44768d5ee9d6ca1a7d848b46a5c335b9a0fa Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 10:37:03 +0300 Subject: Fixed unique prefix key bug for multibyte character sets (BUG #4521) for InnoDB. This fixes also a second part of the same problem with prefix keys on a multibyte string column for InnoDB. innobase/rem/rem0cmp.c: Fixed unique prefix key or prefix key using multibyte character set bugs for InnoDB (BUG #4521). The unique key with a prefix of N appears index 3*N bytes of the column not N characters. If you had two records which have the same first N characters but differ in the first 3*N bytes, then you couldn't select the records using an equality test. --- innobase/rem/rem0cmp.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'innobase/rem/rem0cmp.c') diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index 6e8f3d82ef3..f6c82102839 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -14,6 +14,9 @@ Created 7/1/1994 Heikki Tuuri #include "srv0srv.h" +#include +#include + /* ALPHABETICAL ORDER ================== @@ -453,6 +456,8 @@ cmp_dtuple_rec_with_match( in current field */ int ret = 3333; /* return value */ + CHARSET_INFO* charset; /* charset used in the field */ + ut_ad(dtuple && rec && matched_fields && matched_bytes); ut_ad(dtuple_check_typed(dtuple)); @@ -541,6 +546,32 @@ cmp_dtuple_rec_with_match( && dtype_get_charset_coll(cur_type->prtype) != data_mysql_latin1_swedish_charset_coll)) { + /* If character set is not latin1_swedish + we have to devide character length by the + maximum bytes needed for that character + set. For example if we have unique prefix + index for 1 utf8 character then we have + actually 3 bytes allocated in the index. + Therefore, we have to divide that with + maximum bytes needed for utf8 character i.e. + 3 byges.*/ + + if ( dtuple_f_len > 0) { + charset = get_charset( + dtype_get_charset_coll(cur_type->prtype), + MYF(MY_WME)); + + ut_ad(charset); + ut_ad(charset->mbmaxlen); + + dtuple_f_len = dtuple_f_len / charset->mbmaxlen; + + if ( dtuple_f_len == 0) + dtuple_f_len = 1; + + rec_f_len = dtuple_f_len; + } + ret = cmp_whole_field(cur_type, dfield_get_data(dtuple_field), dtuple_f_len, rec_b_ptr, rec_f_len); -- cgit v1.2.1