summaryrefslogtreecommitdiff
path: root/innobase/row/row0sel.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row/row0sel.c')
-rw-r--r--innobase/row/row0sel.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index c0141f896ce..84a160cfc0d 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -2137,6 +2137,7 @@ row_sel_convert_mysql_key_to_innobase(
row_mysql_store_col_in_innobase_format(
dfield, buf, key_ptr + data_offset,
data_len, type,
+ index->table->comp,
dfield_get_type(dfield)->prtype
& DATA_UNSIGNED);
buf += data_len;
@@ -2232,17 +2233,15 @@ row_sel_field_store_in_mysql_format(
are not in themselves stored here: the caller must
allocate and copy the BLOB into buffer before, and pass
the pointer to the BLOB in 'data' */
- ulint col_len,/* in: MySQL column length */
+ const mysql_row_templ_t* templ, /* in: MySQL column template */
byte* data, /* in: data to store */
- ulint len, /* in: length of the data */
- ulint type, /* in: data type */
- ulint is_unsigned)/* in: != 0 if an unsigned integer type */
+ ulint len) /* in: length of the data */
{
byte* ptr;
ut_ad(len != UNIV_SQL_NULL);
- if (type == DATA_INT) {
+ if (templ->type == DATA_INT) {
/* Convert integer data from Innobase to a little-endian
format, sign bit restored to normal */
@@ -2257,31 +2256,47 @@ row_sel_field_store_in_mysql_format(
data++;
}
- if (!is_unsigned) {
+ if (!templ->is_unsigned) {
dest[len - 1] = (byte) (dest[len - 1] ^ 128);
}
- ut_ad(col_len == len);
- } else if (type == DATA_VARCHAR || type == DATA_VARMYSQL
- || type == DATA_BINARY) {
+ ut_ad(templ->mysql_col_len == len);
+ } else if (templ->type == DATA_VARCHAR || templ->type == DATA_VARMYSQL
+ || templ->type == DATA_BINARY) {
/* Store the length of the data to the first two bytes of
dest; does not do anything yet because MySQL has
no real vars! */
dest = row_mysql_store_var_len(dest, len);
ut_memcpy(dest, data, len);
-
- /* ut_ad(col_len >= len + 2); No real var implemented in
- MySQL yet! */
+#if 0
+ /* No real var implemented in MySQL yet! */
+ ut_ad(templ->mysql_col_len >= len + 2);
+#endif
- } else if (type == DATA_BLOB) {
+ } else if (templ->type == DATA_BLOB) {
/* Store a pointer to the BLOB buffer to dest: the BLOB was
already copied to the buffer in row_sel_store_mysql_rec */
- row_mysql_store_blob_ref(dest, col_len, data, len);
+ row_mysql_store_blob_ref(dest, templ->mysql_col_len,
+ data, len);
} else {
- ut_memcpy(dest, data, len);
- ut_ad(col_len == len);
+ memcpy(dest, data, len);
+
+ ut_ad(templ->mysql_col_len >= len);
+ ut_ad(templ->mbmaxlen >= templ->mbminlen);
+
+ ut_ad(templ->mbmaxlen > templ->mbminlen
+ || templ->mysql_col_len == len);
+ ut_ad(!templ->mbmaxlen
+ || !(templ->mysql_col_len % templ->mbmaxlen));
+
+ if (templ->mbminlen != templ->mbmaxlen) {
+ /* Pad with spaces. This undoes the stripping
+ done in row0mysql.ic, function
+ row_mysql_store_col_in_innobase_format(). */
+ memset(dest + len, 0x20, templ->mysql_col_len - len);
+ }
}
}
@@ -2401,8 +2416,7 @@ row_sel_store_mysql_rec(
row_sel_field_store_in_mysql_format(
mysql_rec + templ->mysql_col_offset,
- templ->mysql_col_len, data, len,
- templ->type, templ->is_unsigned);
+ templ, data, len);
if (templ->type == DATA_VARCHAR
|| templ->type == DATA_VARMYSQL
@@ -2487,7 +2501,7 @@ row_sel_store_mysql_rec(
len -= 2;
}
} else {
- ut_ad(templ->mbminlen == 1);
+ ut_ad(!pad_char || templ->mbminlen == 1);
memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len);
}
@@ -2855,9 +2869,11 @@ row_sel_push_cache_row_for_mysql(
ut_ad(prebuilt->fetch_cache_first == 0);
- ut_a(row_sel_store_mysql_rec(
+ if (!row_sel_store_mysql_rec(
prebuilt->fetch_cache[prebuilt->n_fetch_cached],
- prebuilt, rec, offsets));
+ prebuilt, rec, offsets)) {
+ ut_error;
+ }
prebuilt->n_fetch_cached++;
}