diff options
author | unknown <jan@hundin.mysql.fi> | 2004-09-03 15:26:29 +0300 |
---|---|---|
committer | unknown <jan@hundin.mysql.fi> | 2004-09-03 15:26:29 +0300 |
commit | bbd402dc4f45947ff282775eea7b921c66667058 (patch) | |
tree | bb1dba9818e4bb46971804c5f7b810602a9a6d25 /innobase | |
parent | 3e3981b558befa08a3278f86e5fd0a12417abba1 (diff) | |
download | mariadb-git-bbd402dc4f45947ff282775eea7b921c66667058.tar.gz |
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/btr/btr0btr.c:
Multibyte character set prefix indexes are not any more fixed size. Therefore,
we have to chect that length of the index field in not greater than
prefix length.
innobase/rem/rem0cmp.c:
Remove unnecessary changes.
innobase/row/row0ins.c:
Fixed unique prefix key or prefix key using multibyte character set bugs for
InnoDB (BUG #4521). For prefix keys we have to get the storage length
for the prefix length of characters in the key.
innobase/row/row0row.c:
Fixed unique prefix key or prefix key using multibyte character set bugs for
InnoDB (BUG #4521). For prefix keys we have to get the storage length
for the prefix length of characters in the key.
innobase/row/row0sel.c:
Fixed unique prefix key or prefix key using multibyte character set bugs for
InnoDB (BUG #4521). For prefix keys we have to get the storage length
for the prefix length of characters in the key.
innobase/row/row0upd.c:
Fixed unique prefix key or prefix key using multibyte character set bugs for
InnoDB (BUG #4521). For prefix keys we have to get the storage length
for the prefix length of characters in the key.
mysql-test/r/ctype_utf8.result:
Added utf8 character test cases for InnoDB.
mysql-test/t/ctype_utf8.test:
Added utf8 character expected test results for InnoDB.
sql/ha_innodb.cc:
Added function innobase_get_at_most_n_mbchars to return position of
the nth character in the multibyte character string.
sql/ha_innodb.h:
Remove unnecessary changes.
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/btr/btr0btr.c | 9 | ||||
-rw-r--r-- | innobase/rem/rem0cmp.c | 34 | ||||
-rw-r--r-- | innobase/row/row0ins.c | 17 | ||||
-rw-r--r-- | innobase/row/row0row.c | 33 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 15 | ||||
-rw-r--r-- | innobase/row/row0upd.c | 32 |
6 files changed, 86 insertions, 54 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 27d798f925a..e31aadbbfff 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -2400,14 +2400,17 @@ btr_index_rec_validate( dtype_t* type = dict_index_get_nth_type(index, i); rec_get_nth_field(rec, i, &len); - + + /* Note that prefix indexes are not fixed size even when + their type is CHAR. */ + if ((dict_index_get_nth_field(index, i)->prefix_len == 0 && len != UNIV_SQL_NULL && dtype_is_fixed_size(type) && len != dtype_get_fixed_size(type)) || (dict_index_get_nth_field(index, i)->prefix_len > 0 - && len != UNIV_SQL_NULL && dtype_is_fixed_size(type) - && len != + && len != UNIV_SQL_NULL + && len > dict_index_get_nth_field(index, i)->prefix_len)) { btr_index_rec_validate_report(page, rec, index); diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index f6c82102839..041fb7914e2 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -14,9 +14,6 @@ Created 7/1/1994 Heikki Tuuri #include "srv0srv.h" -#include <m_ctype.h> -#include <my_sys.h> - /* ALPHABETICAL ORDER ================== @@ -455,8 +452,6 @@ cmp_dtuple_rec_with_match( ulint cur_bytes; /* number of already matched bytes 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)); @@ -546,33 +541,8 @@ 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, + ret = cmp_whole_field( + cur_type, dfield_get_data(dtuple_field), dtuple_f_len, rec_b_ptr, rec_f_len); diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index edd3099b5f3..2429b8f2bf3 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -1999,6 +1999,7 @@ row_ins_index_entry_set_vals( dfield_t* row_field; ulint n_fields; ulint i; + dtype_t* cur_type; ut_ad(entry && row); @@ -2012,10 +2013,18 @@ row_ins_index_entry_set_vals( /* Check column prefix indexes */ if (ind_field->prefix_len > 0 - && dfield_get_len(row_field) != UNIV_SQL_NULL - && dfield_get_len(row_field) > ind_field->prefix_len) { - - field->len = ind_field->prefix_len; + && dfield_get_len(row_field) != UNIV_SQL_NULL) { + + /* For prefix keys get the storage length + for the prefix_len characters. */ + + cur_type = dict_col_get_type( + dict_field_get_col(ind_field)); + + field->len = innobase_get_at_most_n_mbchars( + dtype_get_charset_coll(cur_type->prtype), + ind_field->prefix_len, + dfield_get_len(field),row_field->data); } else { field->len = row_field->len; } diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 680539764fd..ed6462b7377 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -113,6 +113,8 @@ row_build_index_entry( dfield_t* dfield2; dict_col_t* col; ulint i; + ulint storage_len; + dtype_t* cur_type; ut_ad(row && index && heap); ut_ad(dtuple_check_typed(row)); @@ -139,10 +141,20 @@ row_build_index_entry( /* If a column prefix index, take only the prefix */ if (ind_field->prefix_len > 0 - && dfield_get_len(dfield2) != UNIV_SQL_NULL - && dfield_get_len(dfield2) > ind_field->prefix_len) { + && dfield_get_len(dfield2) != UNIV_SQL_NULL) { - dfield_set_len(dfield, ind_field->prefix_len); + /* For prefix keys get the storage length + for the prefix_len characters. */ + + cur_type = dict_col_get_type( + dict_field_get_col(ind_field)); + + storage_len = innobase_get_at_most_n_mbchars( + dtype_get_charset_coll(cur_type->prtype), + ind_field->prefix_len, + dfield_get_len(dfield2),dfield2->data); + + dfield_set_len(dfield,storage_len); } } @@ -460,6 +472,7 @@ row_build_row_ref_from_row( dict_col_t* col; ulint ref_len; ulint i; + dtype_t* cur_type; ut_ad(ref && table && row); @@ -481,10 +494,18 @@ row_build_row_ref_from_row( dfield_copy(dfield, dfield2); if (field->prefix_len > 0 - && dfield->len != UNIV_SQL_NULL - && dfield->len > field->prefix_len) { + && dfield->len != UNIV_SQL_NULL) { + + /* For prefix keys get the storage length + for the prefix_len characters. */ + + cur_type = dict_col_get_type( + dict_field_get_col(field)); - dfield->len = field->prefix_len; + dfield->len = innobase_get_at_most_n_mbchars( + dtype_get_charset_coll(cur_type->prtype), + field->prefix_len, + dfield->len,dfield->data); } } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 2c0092adc6e..d87cc857651 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -76,6 +76,7 @@ row_sel_sec_rec_is_for_clust_rec( ulint clust_len; ulint n; ulint i; + dtype_t* cur_type; UT_NOT_USED(clust_index); @@ -91,10 +92,18 @@ row_sel_sec_rec_is_for_clust_rec( sec_field = rec_get_nth_field(sec_rec, i, &sec_len); if (ifield->prefix_len > 0 - && clust_len != UNIV_SQL_NULL - && clust_len > ifield->prefix_len) { + && clust_len != UNIV_SQL_NULL) { - clust_len = ifield->prefix_len; + /* For prefix keys get the storage length + for the prefix_len characters. */ + + cur_type = dict_col_get_type( + dict_field_get_col(ifield)); + + clust_len = innobase_get_at_most_n_mbchars( + dtype_get_charset_coll(cur_type->prtype), + ifield->prefix_len, + clust_len,clust_field); } if (0 != cmp_data_data(dict_col_get_type(col), diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index d35ae0a3e38..75400e06059 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -842,6 +842,7 @@ row_upd_index_replace_new_col_vals_index_pos( dfield_t* new_val; ulint j; ulint i; + dtype_t* cur_type; ut_ad(index); @@ -871,10 +872,19 @@ row_upd_index_replace_new_col_vals_index_pos( } if (field->prefix_len > 0 - && new_val->len != UNIV_SQL_NULL - && new_val->len > field->prefix_len) { + && new_val->len != UNIV_SQL_NULL) { - dfield->len = field->prefix_len; + /* For prefix keys get the storage length + for the prefix_len characters. */ + + cur_type = dict_col_get_type( + dict_field_get_col(field)); + + dfield->len = + innobase_get_at_most_n_mbchars( + dtype_get_charset_coll(cur_type->prtype), + field->prefix_len, + new_val->len,new_val->data); } } } @@ -904,6 +914,7 @@ row_upd_index_replace_new_col_vals( dfield_t* new_val; ulint j; ulint i; + dtype_t* cur_type; ut_ad(index); @@ -933,10 +944,19 @@ row_upd_index_replace_new_col_vals( } if (field->prefix_len > 0 - && new_val->len != UNIV_SQL_NULL - && new_val->len > field->prefix_len) { + && new_val->len != UNIV_SQL_NULL) { + + /* For prefix keys get the storage length + for the prefix_len characters. */ + + cur_type = dict_col_get_type( + dict_field_get_col(field)); - dfield->len = field->prefix_len; + dfield->len = + innobase_get_at_most_n_mbchars( + dtype_get_charset_coll(cur_type->prtype), + field->prefix_len, + new_val->len,new_val->data); } } } |