summaryrefslogtreecommitdiff
path: root/innobase/row
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2004-12-17 18:35:11 +0200
committerunknown <marko@hundin.mysql.fi>2004-12-17 18:35:11 +0200
commit7b063137855ed2dd72f661260e9d157c8779b360 (patch)
treec409114526e80bf5c0378ea758cd06c7cc3ba8c4 /innobase/row
parent7b592c9e2416792fd17997a8f44eadb939c2629a (diff)
downloadmariadb-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.c68
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);
+ }
}
}