|
|
|
@ -2468,6 +2468,8 @@ row_sel_field_store_in_mysql_format( |
|
|
|
|
|
|
|
ut_ad(len != UNIV_SQL_NULL); |
|
|
|
UNIV_MEM_ASSERT_RW(data, len); |
|
|
|
UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len); |
|
|
|
UNIV_MEM_INVALID(dest, templ->mysql_col_len); |
|
|
|
|
|
|
|
if (templ->type == DATA_INT) { |
|
|
|
/* Convert integer data from Innobase to a little-endian |
|
|
|
@ -2502,14 +2504,16 @@ row_sel_field_store_in_mysql_format( |
|
|
|
|
|
|
|
dest = row_mysql_store_true_var_len( |
|
|
|
dest, len, templ->mysql_length_bytes); |
|
|
|
/* Copy the actual data. Leave the rest of the |
|
|
|
buffer uninitialized. */ |
|
|
|
ut_memcpy(dest, data, len); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* Copy the actual data */ |
|
|
|
ut_memcpy(dest, data, len); |
|
|
|
|
|
|
|
/* Pad with trailing spaces. We pad with spaces also the |
|
|
|
unused end of a >= 5.0.3 true VARCHAR column, just in case |
|
|
|
MySQL expects its contents to be deterministic. */ |
|
|
|
/* Pad with trailing spaces. */ |
|
|
|
|
|
|
|
pad_ptr = dest + len; |
|
|
|
|
|
|
|
@ -3012,6 +3016,39 @@ sel_restore_position_for_mysql( |
|
|
|
return(TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
/************************************************************************ |
|
|
|
Copies a cached field for MySQL from the fetch cache. */ |
|
|
|
static |
|
|
|
void |
|
|
|
row_sel_copy_cached_field_for_mysql( |
|
|
|
/*================================*/ |
|
|
|
byte* buf, /* in/out: row buffer */ |
|
|
|
byte* cache, /* in: cached row */ |
|
|
|
const mysql_row_templ_t*templ) /* in: column template */ |
|
|
|
{ |
|
|
|
ulint len; |
|
|
|
|
|
|
|
buf += templ->mysql_col_offset; |
|
|
|
cache += templ->mysql_col_offset; |
|
|
|
|
|
|
|
UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len); |
|
|
|
|
|
|
|
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR |
|
|
|
&& templ->type != DATA_INT) { |
|
|
|
/* Check for != DATA_INT to make sure we do |
|
|
|
not treat MySQL ENUM or SET as a true VARCHAR! |
|
|
|
Find the actual length of the true VARCHAR field. */ |
|
|
|
row_mysql_read_true_varchar( |
|
|
|
&len, cache, templ->mysql_length_bytes); |
|
|
|
len += templ->mysql_length_bytes; |
|
|
|
UNIV_MEM_INVALID(buf, templ->mysql_col_len); |
|
|
|
} else { |
|
|
|
len = templ->mysql_col_len; |
|
|
|
} |
|
|
|
|
|
|
|
ut_memcpy(buf, cache, len); |
|
|
|
} |
|
|
|
|
|
|
|
/************************************************************************ |
|
|
|
Pops a cached row for MySQL from the fetch cache. */ |
|
|
|
UNIV_INLINE |
|
|
|
@ -3028,22 +3065,18 @@ row_sel_pop_cached_row_for_mysql( |
|
|
|
ut_ad(prebuilt->n_fetch_cached > 0); |
|
|
|
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); |
|
|
|
|
|
|
|
UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len); |
|
|
|
|
|
|
|
cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first]; |
|
|
|
|
|
|
|
if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread)) { |
|
|
|
/* Copy cache record field by field, don't touch fields that |
|
|
|
are not covered by current key */ |
|
|
|
cached_rec = prebuilt->fetch_cache[ |
|
|
|
prebuilt->fetch_cache_first]; |
|
|
|
|
|
|
|
for (i = 0; i < prebuilt->n_template; i++) { |
|
|
|
templ = prebuilt->mysql_template + i; |
|
|
|
#if 0 /* Some of the cached_rec may legitimately be uninitialized. */ |
|
|
|
UNIV_MEM_ASSERT_RW(cached_rec |
|
|
|
+ templ->mysql_col_offset, |
|
|
|
templ->mysql_col_len); |
|
|
|
#endif |
|
|
|
ut_memcpy(buf + templ->mysql_col_offset, |
|
|
|
cached_rec + templ->mysql_col_offset, |
|
|
|
templ->mysql_col_len); |
|
|
|
row_sel_copy_cached_field_for_mysql( |
|
|
|
buf, cached_rec, templ); |
|
|
|
/* Copy NULL bit of the current field from cached_rec |
|
|
|
to buf */ |
|
|
|
if (templ->mysql_null_bit_mask) { |
|
|
|
@ -3053,17 +3086,24 @@ row_sel_pop_cached_row_for_mysql( |
|
|
|
& (byte)templ->mysql_null_bit_mask; |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (prebuilt->mysql_prefix_len > 63) { |
|
|
|
/* The record is long. Copy it field by field, in case |
|
|
|
there are some long VARCHAR column of which only a |
|
|
|
small length is being used. */ |
|
|
|
UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len); |
|
|
|
|
|
|
|
/* First copy the NULL bits. */ |
|
|
|
ut_memcpy(buf, cached_rec, prebuilt->null_bitmap_len); |
|
|
|
/* Then copy the requested fields. */ |
|
|
|
|
|
|
|
for (i = 0; i < prebuilt->n_template; i++) { |
|
|
|
row_sel_copy_cached_field_for_mysql( |
|
|
|
buf, cached_rec, prebuilt->mysql_template + i); |
|
|
|
} |
|
|
|
} else { |
|
|
|
ut_memcpy(buf, cached_rec, prebuilt->mysql_prefix_len); |
|
|
|
} |
|
|
|
else { |
|
|
|
#if 0 /* Some of the cached_rec may legitimately be uninitialized. */ |
|
|
|
UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache |
|
|
|
[prebuilt->fetch_cache_first], |
|
|
|
prebuilt->mysql_prefix_len); |
|
|
|
#endif |
|
|
|
ut_memcpy(buf, |
|
|
|
prebuilt->fetch_cache[prebuilt->fetch_cache_first], |
|
|
|
prebuilt->mysql_prefix_len); |
|
|
|
} |
|
|
|
|
|
|
|
prebuilt->n_fetch_cached--; |
|
|
|
prebuilt->fetch_cache_first++; |
|
|
|
|
|
|
|
|