Commit 918a3fb9 authored by unknown's avatar unknown

row0sel.c, row0row.c:

  Fix bug #5975 about UTF-8 chars and prefix indexes; do not print warnings if a column prefix is > 255 bytes


innobase/row/row0row.c:
  Fix bug #5975 about UTF-8 chars and prefix indexes; do not print warnings if a column prefix is > 255 bytes
innobase/row/row0sel.c:
  Fix bug #5975 about UTF-8 chars and prefix indexes; do not print warnings if a column prefix is > 255 bytes
parent 451636cd
...@@ -386,10 +386,12 @@ row_build_row_ref( ...@@ -386,10 +386,12 @@ row_build_row_ref(
dict_index_get_nth_field(clust_index, i)->prefix_len; dict_index_get_nth_field(clust_index, i)->prefix_len;
if (clust_col_prefix_len > 0) { if (clust_col_prefix_len > 0) {
if (len != UNIV_SQL_NULL if (len != UNIV_SQL_NULL) {
&& len > clust_col_prefix_len) {
dfield_set_len(dfield, clust_col_prefix_len); dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dfield_get_type(dfield),
clust_col_prefix_len, len, field));
} }
} }
} }
...@@ -471,10 +473,12 @@ row_build_row_ref_in_tuple( ...@@ -471,10 +473,12 @@ row_build_row_ref_in_tuple(
dict_index_get_nth_field(clust_index, i)->prefix_len; dict_index_get_nth_field(clust_index, i)->prefix_len;
if (clust_col_prefix_len > 0) { if (clust_col_prefix_len > 0) {
if (len != UNIV_SQL_NULL if (len != UNIV_SQL_NULL) {
&& len > clust_col_prefix_len) {
dfield_set_len(dfield, clust_col_prefix_len); dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dfield_get_type(dfield),
clust_col_prefix_len, len, field));
} }
} }
} }
......
...@@ -2024,19 +2024,15 @@ row_sel_convert_mysql_key_to_innobase( ...@@ -2024,19 +2024,15 @@ row_sel_convert_mysql_key_to_innobase(
/* MySQL stores the actual data length to the first 2 /* MySQL stores the actual data length to the first 2
bytes after the optional SQL NULL marker byte. The bytes after the optional SQL NULL marker byte. The
storage format is little-endian. */ storage format is little-endian, that is, the most
significant byte at a higher address. In UTF-8, MySQL
/* There are no key fields > 255 bytes currently in seems to reserve field->prefix_len bytes for
MySQL */ storing this field in the key value buffer, even
if (key_ptr[data_offset + 1] != 0) { though the actual value only takes data_len bytes
ut_print_timestamp(stderr); from the start. */
fputs(
" InnoDB: Error: BLOB or TEXT prefix > 255 bytes in query to table ", stderr); data_len = key_ptr[data_offset]
ut_print_name(stderr, trx, index->table_name); + 256 * key_ptr[data_offset + 1];
putc('\n', stderr);
}
data_len = key_ptr[data_offset];
data_field_len = data_offset + 2 + field->prefix_len; data_field_len = data_offset + 2 + field->prefix_len;
data_offset += 2; data_offset += 2;
...@@ -2044,6 +2040,17 @@ row_sel_convert_mysql_key_to_innobase( ...@@ -2044,6 +2040,17 @@ row_sel_convert_mysql_key_to_innobase(
store the column value like it would store the column value like it would
be a fixed char field */ be a fixed char field */
} else if (field->prefix_len > 0) { } else if (field->prefix_len > 0) {
/* Looks like MySQL pads unused end bytes in the
prefix with space. Therefore, also in UTF-8, it is ok
to compare with a prefix containing full prefix_len
bytes, and no need to take at most prefix_len / 3
UTF-8 characters from the start.
If the prefix is used as the upper end of a LIKE
'abc%' query, then MySQL pads the end with chars
0xff. TODO: in that case does it any harm to compare
with the full prefix_len bytes. How do characters
0xff in UTF-8 behave? */
data_len = field->prefix_len; data_len = field->prefix_len;
data_field_len = data_offset + data_len; data_field_len = data_offset + data_len;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment