summaryrefslogtreecommitdiff
path: root/storage/innobase/handler
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/handler')
-rw-r--r--storage/innobase/handler/ha_innodb.cc20
-rw-r--r--storage/innobase/handler/ha_innodb.h4
-rw-r--r--storage/innobase/handler/handler0alter.cc26
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);