diff options
author | unknown <elliot@mysql.com> | 2005-10-19 12:06:29 -0400 |
---|---|---|
committer | unknown <elliot@mysql.com> | 2005-10-19 12:06:29 -0400 |
commit | 33b4154cecea8e346413ce661897e109f87832e0 (patch) | |
tree | 8945c70768e431709b907690953c7e032ebe44dd /sql/ha_innodb.cc | |
parent | 723b28a25cfe81846ef88a87bbffc3144f14b1d6 (diff) | |
download | mariadb-git-33b4154cecea8e346413ce661897e109f87832e0.tar.gz |
BUG#14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..'
Applying InnoDB patch from Jan Lindstrom
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r-- | sql/ha_innodb.cc | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 455b54361f0..a7957ee3cbf 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2872,6 +2872,9 @@ ha_innobase::store_key_val_for_row( ulint lenlen; ulint len; byte* data; + ulint key_len; + CHARSET_INFO* cs; + int error=0; if (is_null) { buff += key_part->length + 2; @@ -2890,8 +2893,20 @@ ha_innobase::store_key_val_for_row( /* In a column prefix index, we may need to truncate the stored value: */ - if (len > key_part->length) { - len = key_part->length; + cs = key_part->field->charset(); + + if (cs->mbmaxlen > 1 && key_part->length > 0) { + key_len = (ulint) cs->cset->well_formed_len(cs, + (const char *) data, + (const char *) data + key_part->length, + key_part->length / cs->mbmaxlen, + &error); + } else { + key_len = key_part->length; + } + + if (len > key_len) { + len = key_len; } /* The length in a key value is always stored in 2 @@ -2915,6 +2930,11 @@ ha_innobase::store_key_val_for_row( || mysql_type == FIELD_TYPE_BLOB || mysql_type == FIELD_TYPE_LONG_BLOB) { + CHARSET_INFO* cs; + ulint key_len; + ulint len; + int error=0; + ut_a(key_part->key_part_flag & HA_PART_KEY_SEG); if (is_null) { @@ -2935,8 +2955,21 @@ ha_innobase::store_key_val_for_row( indexes, and we may need to truncate the data to be stored in the key value: */ - if (blob_len > key_part->length) { - blob_len = key_part->length; + cs = key_part->field->charset(); + + if (cs->mbmaxlen > 1 && key_part->length > 0) { + key_len = (ulint) cs->cset->well_formed_len(cs, + (const char *) blob_data, + (const char *) blob_data + + key_part->length, + key_part->length / cs->mbmaxlen, + &error); + } else { + key_len = key_part->length; + } + + if (blob_len > key_len) { + blob_len = key_len; } /* MySQL reserves 2 bytes for the length and the @@ -2958,15 +2991,40 @@ ha_innobase::store_key_val_for_row( value we store may be also in a column prefix index. */ + CHARSET_INFO* cs; + ulint len; + const mysql_byte* src_start; + int error=0; + if (is_null) { buff += key_part->length; continue; } - memcpy(buff, record + key_part->offset, - key_part->length); - buff += key_part->length; + cs = key_part->field->charset(); + src_start = record + key_part->offset; + + if (key_part->length > 0 && cs->mbmaxlen > 1) { + len = (ulint) cs->cset->well_formed_len(cs, + src_start, + src_start + key_part->length, + key_part->length / cs->mbmaxlen, + &error); + } else { + len = key_part->length; + } + + memcpy(buff, src_start, len); + buff+=len; + + /* Pad the unused space with spaces */ + + if (len < key_part->length) { + len = key_part->length - len; + memset(buff, ' ', len); + buff+=len; + } } } |