3411 Marko Mäkelä 2010-04-21
ha_innobase::add_index(): Only check for duplicate indexes
when the data dictionary is locked.
This fixes a UNIV_DEBUG assertion failure in innodb-index.test.
modified:
storage/innodb_plugin/handler/handler0alter.cc
3410 Marko Mäkelä 2010-04-21
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
modified:
storage/innodb_plugin/ChangeLog
storage/innodb_plugin/data/data0data.c
storage/innodb_plugin/rem/rem0rec.c
3409 Marko Mäkelä 2010-04-21
Adjust tests for the Bug #50495 fix.
modified:
mysql-test/suite/innodb_plugin/r/innodb-zip.result
mysql-test/suite/innodb_plugin/t/innodb-zip.test
mysql-test/suite/innodb_plugin/t/innodb_bug36169.test
=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog 2010-04-20 11:42:22 +0000
+++ b/storage/innodb_plugin/ChangeLog 2010-04-21 09:50:33 +0000
@@ -1,3 +1,8 @@
+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
* dict/dict0crea.c, handler/ha_innodb.cc, include/trx0trx.h:
=== modified file 'storage/innodb_plugin/data/data0data.c'
--- a/storage/innodb_plugin/data/data0data.c 2009-05-25 12:09:24 +0000
+++ b/storage/innodb_plugin/data/data0data.c 2010-04-21 09:50:33 +0000
@@ -666,6 +666,21 @@ dtuple_convert_big_rec(
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 = savings;
=== modified file 'storage/innodb_plugin/handler/handler0alter.cc'
--- a/storage/innodb_plugin/handler/handler0alter.cc 2010-04-06 12:11:46 +0000
+++ b/storage/innodb_plugin/handler/handler0alter.cc 2010-04-21 10:00:29 +0000
@@ -920,9 +920,8 @@ convert_error:
trx_commit_for_mysql(prebuilt->trx);
}
- ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
-
if (dict_locked) {
+ ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
row_mysql_unlock_data_dictionary(trx);
}
=== modified file 'storage/innodb_plugin/rem/rem0rec.c'
--- a/storage/innodb_plugin/rem/rem0rec.c 2010-04-21 09:16:11 +0000
+++ b/storage/innodb_plugin/rem/rem0rec.c 2010-04-21 09:50:33 +0000
@@ -212,6 +212,13 @@ rec_get_n_extern_new(
const dict_col_t* col
= dict_field_get_col(field);
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)
|| UNIV_UNLIKELY(col->mtype == DATA_BLOB)) {
if (len & 0x80) {
@@ -294,6 +301,13 @@ rec_init_offsets_comp_ordinary(
const dict_col_t* col
= dict_field_get_col(field);
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)
|| UNIV_UNLIKELY(col->mtype
== DATA_BLOB)) {
@@ -425,6 +439,15 @@ rec_init_offsets(
const dict_col_t* col
= dict_field_get_col(field);
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)
|| UNIV_UNLIKELY(col->mtype
== DATA_BLOB)) {
@@ -647,6 +670,13 @@ rec_get_offsets_reverse(
const dict_col_t* col
= dict_field_get_col(field);
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)
|| UNIV_UNLIKELY(col->mtype == DATA_BLOB)) {
if (len & 0x80) {
@@ -781,12 +811,20 @@ rec_get_converted_size_comp_prefix(
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) {
ut_ad(len == field->fixed_len);
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
|| field->fixed_len == field->prefix_len);
} else if (dfield_is_ext(&fields[i])) {
+ ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
extra_size += 2;
} else if (len < 128
|| (col->len < 256 && col->mtype != DATA_BLOB)) {
@@ -1086,6 +1124,8 @@ rec_convert_dtuple_to_rec_comp(
/* Store the data and the offsets */
for (i = 0, field = fields; i < n_fields; i++, field++) {
+ const dict_field_t* ifield;
+
type = dfield_get_type(field);
len = dfield_get_len(field);
@@ -1120,12 +1160,20 @@ rec_convert_dtuple_to_rec_comp(
/* only nullable fields can be null */
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) {
ut_ad(len == fixed_len);
ut_ad(!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
+ BTR_EXTERN_FIELD_REF_SIZE);
*lens-- = (byte) (len >> 8) | 0xc0;
@@ -1411,6 +1459,13 @@ rec_copy_prefix_to_buf(
prefix_len += field->fixed_len;
} else {
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 (len & 0x80) {
/* 1exxxxxx */
Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20100421100029-mji6lmdgvuqh96qq.bundle
| Thread |
|---|
| • bzr push into mysql-5.1-innodb branch (marko.makela:3409 to 3411) | marko.makela | 21 Apr |