diff options
Diffstat (limited to 'storage/innobase/handler')
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 20 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.h | 4 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 26 |
3 files changed, 34 insertions, 16 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c2b085b2c04..79d0c7543b0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2167,15 +2167,21 @@ convert_error_code_to_mysql( locally for BLOB fields. Refer to dict_table_get_format(). We limit max record size to 16k for 64k page size. */ bool prefix = (dict_tf_get_format(flags) == UNIV_FORMAT_A); + bool comp = !!(flags & DICT_TF_COMPACT); + ulint free_space = page_get_free_space_of_empty(comp) / 2; + + if (free_space >= (comp ? COMPRESSED_REC_MAX_DATA_SIZE : + REDUNDANT_REC_MAX_DATA_SIZE)) { + free_space = (comp ? COMPRESSED_REC_MAX_DATA_SIZE : + REDUNDANT_REC_MAX_DATA_SIZE) - 1; + } + my_printf_error(ER_TOO_BIG_ROWSIZE, - "Row size too large (> %lu). Changing some columns" - " to TEXT or BLOB %smay help. In current row" - " format, BLOB prefix of %d bytes is stored inline.", + "Row size too large (> " ULINTPF "). Changing some columns " + "to TEXT or BLOB %smay help. In current row " + "format, BLOB prefix of %d bytes is stored inline.", MYF(0), - srv_page_size == UNIV_PAGE_SIZE_MAX - ? REC_MAX_DATA_SIZE - 1 - : page_get_free_space_of_empty(flags & - DICT_TF_COMPACT) / 2, + free_space, prefix ? "or using ROW_FORMAT=DYNAMIC or" " ROW_FORMAT=COMPRESSED " diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 8a781963cec..6f87e0cf2f0 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -170,6 +170,10 @@ public: int index_last(uchar * buf); + /* Copy a cached MySQL row. If requested, also avoids + overwriting non-read columns. */ + void copy_cached_row(uchar *to_rec, const uchar *from_rec, + uint rec_length); int rnd_init(bool scan); int rnd_end(); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 22db204faa2..ba4a4a2154f 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -320,14 +320,22 @@ my_error_innodb( case DB_CORRUPTION: my_error(ER_NOT_KEYFILE, MYF(0), table); break; - case DB_TOO_BIG_RECORD: - /* We limit max record size to 16k for 64k page size. */ - my_error(ER_TOO_BIG_ROWSIZE, MYF(0), - srv_page_size == UNIV_PAGE_SIZE_MAX - ? REC_MAX_DATA_SIZE - 1 - : page_get_free_space_of_empty( - flags & DICT_TF_COMPACT) / 2); + case DB_TOO_BIG_RECORD: { + /* Note that in page0zip.ic page_zip_rec_needs_ext() rec_size + is limited to COMPRESSED_REC_MAX_DATA_SIZE (16K) or + REDUNDANT_REC_MAX_DATA_SIZE (16K-1). */ + bool comp = !!(flags & DICT_TF_COMPACT); + ulint free_space = page_get_free_space_of_empty(comp) / 2; + + if (free_space >= (comp ? COMPRESSED_REC_MAX_DATA_SIZE : + REDUNDANT_REC_MAX_DATA_SIZE)) { + free_space = (comp ? COMPRESSED_REC_MAX_DATA_SIZE : + REDUNDANT_REC_MAX_DATA_SIZE) - 1; + } + + my_error(ER_TOO_BIG_ROWSIZE, MYF(0), free_space); break; + } case DB_INVALID_NULL: /* TODO: report the row, as we do for DB_DUPLICATE_KEY */ my_error(ER_INVALID_USE_OF_NULL, MYF(0)); @@ -3293,8 +3301,8 @@ innobase_pk_col_prefix_compare( ulint new_prefix_len, ulint old_prefix_len) { - ut_ad(new_prefix_len < REC_MAX_DATA_SIZE); - ut_ad(old_prefix_len < REC_MAX_DATA_SIZE); + ut_ad(new_prefix_len < COMPRESSED_REC_MAX_DATA_SIZE); + ut_ad(old_prefix_len < COMPRESSED_REC_MAX_DATA_SIZE); if (new_prefix_len == old_prefix_len) { return(0); |