Commit 16847025 authored by sunny's avatar sunny

Fix for bug# 21101 - returns wrong error message when table column

defs exceed the max row size.

The fix returns a more appropriate error message. Add a test case to
innodb.test and expected output to innodb.result.
parent f90f55b0
......@@ -31,6 +31,7 @@ have disables the InnoDB inlining in this file. */
#endif
#include <mysql_priv.h>
#include <mysqld_error.h>
#ifdef WITH_INNOBASE_STORAGE_ENGINE
......@@ -4507,6 +4508,24 @@ ha_innobase::position(
}
}
/*********************************************************************
If it's a DB_TOO_BIG_RECORD error then set a suitable message to
return to the client.*/
static
void
innodb_check_for_record_too_big_error(
dict_table_t* table,
int error)
{
if (error == (int)DB_TOO_BIG_RECORD) {
ulint max_row_size;
max_row_size = page_get_free_space_of_empty_noninline(table);
my_error(ER_TOO_BIG_ROWSIZE, MYF(0), max_row_size);
}
}
/*********************************************************************
Creates a table definition to an InnoDB database. */
static
......@@ -4615,6 +4634,10 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
/* We need access to the table and so we do the error checking
and set the error message here, before the error translation.*/
innodb_check_for_record_too_big_error(table, error);
error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
......@@ -4737,6 +4760,10 @@ create_index(
sure we don't create too long indexes. */
error = row_create_index_for_mysql(index, trx, field_lengths);
/* We need access to the table and so we do the error checking
and set the error message here, before the error translation.*/
innodb_check_for_record_too_big_error(index->table, error);
error = convert_error_code_to_mysql(error, NULL);
my_free((gptr) field_lengths, MYF(0));
......@@ -4764,6 +4791,10 @@ create_clustered_index_when_no_primary(
(char*) "GEN_CLUST_INDEX", 0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
/* We need access to the table and so we do the error checking
and set the error message here, before the error translation.*/
innodb_check_for_record_too_big_error(index->table, error);
error = convert_error_code_to_mysql(error, NULL);
return(error);
......
......@@ -460,6 +460,19 @@ row_check_table_for_mysql(
/* out: DB_ERROR or DB_SUCCESS */
row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
handle */
/*************************************************************************
Get the min of the maximum possible row sizes. */
ulint
page_get_free_space_of_empty_noninline(
/*===================================*/
/* out: The (approx) maximum size
of a row, this is a conservative
estimate, since the size can be
slightly larger depending upon
the ROW_FORMAT setting.*/
dict_table_t* table); /* in: table for which max record
size required.*/
/* A struct describing a place for an individual column in the MySQL
row format which is presented to the table handler in ha_innobase.
......
......@@ -3202,3 +3202,14 @@ t1 CREATE TABLE `t1` (
CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
DROP TABLE t1,t2;
CREATE TABLE t1 (
c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255),
c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255),
c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255),
c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
) ENGINE = InnoDB;
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
......@@ -2340,6 +2340,21 @@ SHOW CREATE TABLE t1;
DROP TABLE t1,t2;
#
# Bug #21101 (Prints wrong error message if max row size is too large)
#
--error 1118
CREATE TABLE t1 (
c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255),
c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255),
c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255),
c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
) ENGINE = InnoDB;
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
......
......@@ -4058,3 +4058,25 @@ row_check_table_for_mysql(
return(ret);
}
/*************************************************************************
Get the maximum row size. */
ulint
page_get_free_space_of_empty_noninline(
/*===================================*/
/* out: The (approx) maximum size
of a row, this is a conservative
estimate, since the size can be
slightly larger depending upon
the ROW_FORMAT setting.*/
dict_table_t* table) /* in: table for which max record
size is required.*/
{
ibool compact;
compact = dict_table_is_comp(table);
return(page_get_free_space_of_empty(compact) / 2);
}
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