Commit 8c828e3a authored by Marko Mäkelä's avatar Marko Mäkelä

dtuple_convert_big_rec(): Store locally any fields whose maximum length

is less than 256 bytes. (Bug #52745)
Add related comments and debug assertions to the "offsets"
functions in rem0rec.c.
Approved by Sunny Bains
parent b7a6240c
2010-04-21 The InnoDB Team
* data/data0data.c:
Fix Bug#52745 Failing assertion: blob_no < page_zip->n_blobs
2010-04-20 The InnoDB Team 2010-04-20 The InnoDB Team
* dict/dict0crea.c, handler/ha_innodb.cc, include/trx0trx.h: * dict/dict0crea.c, handler/ha_innodb.cc, include/trx0trx.h:
......
...@@ -666,6 +666,21 @@ dtuple_convert_big_rec( ...@@ -666,6 +666,21 @@ dtuple_convert_big_rec(
goto skip_field; goto skip_field;
} }
/* In DYNAMIC and COMPRESSED format, store
locally any non-BLOB columns whose maximum
length does not exceed 256 bytes. This is
because there is no room for the "external
storage" flag when the maximum length is 255
bytes or less. This restriction trivially
holds in REDUNDANT and COMPACT format, because
there we always store locally columns whose
length is up to local_len == 788 bytes.
@see rec_init_offsets_comp_ordinary */
if (ifield->col->mtype != DATA_BLOB
&& ifield->col->len < 256) {
goto skip_field;
}
longest_i = i; longest_i = i;
longest = savings; longest = savings;
......
...@@ -212,6 +212,13 @@ rec_get_n_extern_new( ...@@ -212,6 +212,13 @@ rec_get_n_extern_new(
const dict_col_t* col const dict_col_t* col
= dict_field_get_col(field); = dict_field_get_col(field);
len = *lens--; len = *lens--;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
stored in one byte. If the maximum length is
more than 255 bytes, the actual length is
stored in one byte for 0..127. The length
will be encoded in two bytes when it is 128 or
more, or when the field is stored externally. */
if (UNIV_UNLIKELY(col->len > 255) if (UNIV_UNLIKELY(col->len > 255)
|| UNIV_UNLIKELY(col->mtype == DATA_BLOB)) { || UNIV_UNLIKELY(col->mtype == DATA_BLOB)) {
if (len & 0x80) { if (len & 0x80) {
...@@ -294,6 +301,13 @@ rec_init_offsets_comp_ordinary( ...@@ -294,6 +301,13 @@ rec_init_offsets_comp_ordinary(
const dict_col_t* col const dict_col_t* col
= dict_field_get_col(field); = dict_field_get_col(field);
len = *lens--; len = *lens--;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
stored in one byte. If the maximum length is
more than 255 bytes, the actual length is
stored in one byte for 0..127. The length
will be encoded in two bytes when it is 128 or
more, or when the field is stored externally. */
if (UNIV_UNLIKELY(col->len > 255) if (UNIV_UNLIKELY(col->len > 255)
|| UNIV_UNLIKELY(col->mtype || UNIV_UNLIKELY(col->mtype
== DATA_BLOB)) { == DATA_BLOB)) {
...@@ -425,6 +439,15 @@ rec_init_offsets( ...@@ -425,6 +439,15 @@ rec_init_offsets(
const dict_col_t* col const dict_col_t* col
= dict_field_get_col(field); = dict_field_get_col(field);
len = *lens--; len = *lens--;
/* If the maximum length of the field
is up to 255 bytes, the actual length
is always stored in one byte. If the
maximum length is more than 255 bytes,
the actual length is stored in one
byte for 0..127. The length will be
encoded in two bytes when it is 128 or
more, or when the field is stored
externally. */
if (UNIV_UNLIKELY(col->len > 255) if (UNIV_UNLIKELY(col->len > 255)
|| UNIV_UNLIKELY(col->mtype || UNIV_UNLIKELY(col->mtype
== DATA_BLOB)) { == DATA_BLOB)) {
...@@ -647,6 +670,13 @@ rec_get_offsets_reverse( ...@@ -647,6 +670,13 @@ rec_get_offsets_reverse(
const dict_col_t* col const dict_col_t* col
= dict_field_get_col(field); = dict_field_get_col(field);
len = *lens++; len = *lens++;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
stored in one byte. If the maximum length is
more than 255 bytes, the actual length is
stored in one byte for 0..127. The length
will be encoded in two bytes when it is 128 or
more, or when the field is stored externally. */
if (UNIV_UNLIKELY(col->len > 255) if (UNIV_UNLIKELY(col->len > 255)
|| UNIV_UNLIKELY(col->mtype == DATA_BLOB)) { || UNIV_UNLIKELY(col->mtype == DATA_BLOB)) {
if (len & 0x80) { if (len & 0x80) {
...@@ -781,12 +811,20 @@ rec_get_converted_size_comp_prefix( ...@@ -781,12 +811,20 @@ rec_get_converted_size_comp_prefix(
ut_ad(len <= col->len || col->mtype == DATA_BLOB); ut_ad(len <= col->len || col->mtype == DATA_BLOB);
/* If the maximum length of a variable-length field
is up to 255 bytes, the actual length is always stored
in one byte. If the maximum length is more than 255
bytes, the actual length is stored in one byte for
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
if (field->fixed_len) { if (field->fixed_len) {
ut_ad(len == field->fixed_len); ut_ad(len == field->fixed_len);
/* dict_index_add_col() should guarantee this */ /* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len ut_ad(!field->prefix_len
|| field->fixed_len == field->prefix_len); || field->fixed_len == field->prefix_len);
} else if (dfield_is_ext(&fields[i])) { } else if (dfield_is_ext(&fields[i])) {
ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
extra_size += 2; extra_size += 2;
} else if (len < 128 } else if (len < 128
|| (col->len < 256 && col->mtype != DATA_BLOB)) { || (col->len < 256 && col->mtype != DATA_BLOB)) {
...@@ -1086,6 +1124,8 @@ rec_convert_dtuple_to_rec_comp( ...@@ -1086,6 +1124,8 @@ rec_convert_dtuple_to_rec_comp(
/* Store the data and the offsets */ /* Store the data and the offsets */
for (i = 0, field = fields; i < n_fields; i++, field++) { for (i = 0, field = fields; i < n_fields; i++, field++) {
const dict_field_t* ifield;
type = dfield_get_type(field); type = dfield_get_type(field);
len = dfield_get_len(field); len = dfield_get_len(field);
...@@ -1120,12 +1160,20 @@ rec_convert_dtuple_to_rec_comp( ...@@ -1120,12 +1160,20 @@ rec_convert_dtuple_to_rec_comp(
/* only nullable fields can be null */ /* only nullable fields can be null */
ut_ad(!dfield_is_null(field)); ut_ad(!dfield_is_null(field));
fixed_len = dict_index_get_nth_field(index, i)->fixed_len; ifield = dict_index_get_nth_field(index, i);
fixed_len = ifield->fixed_len;
/* If the maximum length of a variable-length field
is up to 255 bytes, the actual length is always stored
in one byte. If the maximum length is more than 255
bytes, the actual length is stored in one byte for
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
if (fixed_len) { if (fixed_len) {
ut_ad(len == fixed_len); ut_ad(len == fixed_len);
ut_ad(!dfield_is_ext(field)); ut_ad(!dfield_is_ext(field));
} else if (dfield_is_ext(field)) { } else if (dfield_is_ext(field)) {
ut_ad(ifield->col->len >= 256
|| ifield->col->mtype == DATA_BLOB);
ut_ad(len <= REC_MAX_INDEX_COL_LEN ut_ad(len <= REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE); + BTR_EXTERN_FIELD_REF_SIZE);
*lens-- = (byte) (len >> 8) | 0xc0; *lens-- = (byte) (len >> 8) | 0xc0;
...@@ -1411,6 +1459,13 @@ rec_copy_prefix_to_buf( ...@@ -1411,6 +1459,13 @@ rec_copy_prefix_to_buf(
prefix_len += field->fixed_len; prefix_len += field->fixed_len;
} else { } else {
ulint len = *lens--; ulint len = *lens--;
/* If the maximum length of the column is up
to 255 bytes, the actual length is always
stored in one byte. If the maximum length is
more than 255 bytes, the actual length is
stored in one byte for 0..127. The length
will be encoded in two bytes when it is 128 or
more, or when the column is stored externally. */
if (col->len > 255 || col->mtype == DATA_BLOB) { if (col->len > 255 || col->mtype == DATA_BLOB) {
if (len & 0x80) { if (len & 0x80) {
/* 1exxxxxx */ /* 1exxxxxx */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment