diff options
author | unknown <marko@hundin.mysql.fi> | 2004-12-17 18:35:11 +0200 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-12-17 18:35:11 +0200 |
commit | 7b063137855ed2dd72f661260e9d157c8779b360 (patch) | |
tree | c409114526e80bf5c0378ea758cd06c7cc3ba8c4 /innobase/row | |
parent | 7b592c9e2416792fd17997a8f44eadb939c2629a (diff) | |
download | mariadb-git-7b063137855ed2dd72f661260e9d157c8779b360.tar.gz |
InnoDB: Fixed bugs in the padding and trimming of trailing spaces
that affected the UCS2 character set. (Bug #7350)
innobase/data/data0type.c:
Added dtype_get_charset_coll_noninline()
innobase/include/data0type.h:
Added dtype_get_charset_coll_noninline()
innobase/include/row0mysql.h:
Added charset field to mysql_row_templ_struct.
innobase/include/row0mysql.ic:
row_mysql_store_col_in_innobase_format():
When removing trailing spaces, treat the UCS2 character set properly.
innobase/rem/rem0cmp.c:
cmp_whole_field(): Do not remove trailing 0x20 bytes, as
innobase_mysql_cmp() implicitly pads the strings with trailing
spaces as necessary.
innobase/row/row0sel.c:
row_sel_field_store_in_mysql_format(): Do not pad with 0x20 bytes.
row_sel_store_mysql_rec(): Pad VARCHARs with trailing spaces
(0x20, or 0x0020 in UCS2).
sql/ha_innodb.cc:
build_template(): Initialize templ->charset
Diffstat (limited to 'innobase/row')
-rw-r--r-- | innobase/row/row0sel.c | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index ce76f48e7a7..61ba0b53172 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2204,9 +2204,6 @@ row_sel_field_store_in_mysql_format( dest = row_mysql_store_var_len(dest, len); ut_memcpy(dest, data, len); - /* Pad with trailing spaces */ - memset(dest + len, ' ', col_len - len); - /* ut_ad(col_len >= len + 2); No real var implemented in MySQL yet! */ @@ -2334,7 +2331,45 @@ row_sel_store_mysql_rec( mysql_rec + templ->mysql_col_offset, templ->mysql_col_len, data, len, templ->type, templ->is_unsigned); - + + if (templ->type == DATA_VARCHAR + || templ->type == DATA_VARMYSQL + || templ->type == DATA_BINARY) { + /* Pad with trailing spaces */ + data = mysql_rec + templ->mysql_col_offset; + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we + hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* space=0x0020 */ + ulint col_len = templ->mysql_col_len; + + ut_a(!(col_len & 1)); + if (len & 1) { + /* A 0x20 has been stripped + from the column. + Pad it back. */ + goto pad_0x20; + } + /* Pad the rest of the string + with 0x0020 */ + while (len < col_len) { + data[len++] = 0x00; + pad_0x20: + data[len++] = 0x20; + } + } else { + /* space=0x20 */ + memset(data + len, 0x20, + templ->mysql_col_len - len); + } + } + /* Cleanup */ if (extern_field_heap) { mem_heap_free(extern_field_heap); @@ -2368,8 +2403,29 @@ row_sel_store_mysql_rec( pad_char = '\0'; } - memset(mysql_rec + templ->mysql_col_offset, pad_char, - templ->mysql_col_len); + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, + we hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* There are two bytes per char, so the length + has to be an even number. */ + ut_a(!(templ->mysql_col_len & 1)); + data = mysql_rec + templ->mysql_col_offset; + len = templ->mysql_col_len; + /* Pad with 0x0020. */ + while (len >= 2) { + *data++ = 0x00; + *data++ = 0x20; + len -= 2; + } + } else { + memset(mysql_rec + templ->mysql_col_offset, + pad_char, templ->mysql_col_len); + } } } |