Skip to content

Commit

Permalink
MDEV-17833 ALTER TABLE is not enforcing prefix index size limit
Browse files Browse the repository at this point in the history
ha_innobase::prepare_inplace_alter_table(): check max column length for every
index in a table, not just added in this particular ALTER TABLE with ADD INDEX ones.
  • Loading branch information
kevgs committed Dec 11, 2018
1 parent 4886d14 commit d956709
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 6 deletions.
33 changes: 33 additions & 0 deletions mysql-test/suite/innodb/r/innodb-index.result
Expand Up @@ -1180,3 +1180,36 @@ t2c CREATE TABLE `t2c` (
KEY `t2a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1,t2,t2c,t2i;
SET @save_format = @@GLOBAL.innodb_file_format;
SET @save_prefix = @@GLOBAL.innodb_large_prefix;
SET GLOBAL innodb_file_format=barracuda;
SET GLOBAL innodb_large_prefix=ON;
CREATE TABLE t1 (c VARCHAR(1024),
c1 CHAR(255) NOT NULL,c2 CHAR(255) NOT NULL,c3 CHAR(255) NOT NULL,
c4 CHAR(255) NOT NULL,c5 CHAR(255) NOT NULL,c6 CHAR(255) NOT NULL,
c7 CHAR(255) NOT NULL,c8 CHAR(255) NOT NULL,c9 CHAR(255) NOT NULL,
ca CHAR(255) NOT NULL,cb CHAR(255) NOT NULL,cc CHAR(255) NOT NULL,
cd CHAR(255) NOT NULL,ce CHAR(255) NOT NULL,cf CHAR(255) NOT NULL,
d0 CHAR(255) NOT NULL,d1 CHAR(255) NOT NULL,d2 CHAR(255) NOT NULL,
d3 CHAR(255) NOT NULL,d4 CHAR(255) NOT NULL,d5 CHAR(255) NOT NULL,
d6 CHAR(255) NOT NULL,d7 CHAR(255) NOT NULL,d8 CHAR(255) NOT NULL,
d9 CHAR(255) NOT NULL,da CHAR(255) NOT NULL,db CHAR(255) NOT NULL,
dc CHAR(255) NOT NULL,dd CHAR(255) NOT NULL,de CHAR(255) NOT NULL,
UNIQUE KEY(c))
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES
(repeat('a',999),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
(CONCAT(repeat('a',999),'b'),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=inplace;
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=copy;
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
SELECT COUNT(*) FROM t1;
COUNT(*)
2
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
SET GLOBAL innodb_file_format=@save_format;
SET GLOBAL innodb_large_prefix=@save_prefix;
30 changes: 30 additions & 0 deletions mysql-test/suite/innodb/t/innodb-index.test
Expand Up @@ -563,3 +563,33 @@ DROP TABLE t1,t2,t2c,t2i;
eval SET GLOBAL innodb_file_format=$innodb_file_format_orig;
eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig;
--enable_query_log

SET @save_format = @@GLOBAL.innodb_file_format;
SET @save_prefix = @@GLOBAL.innodb_large_prefix;
SET GLOBAL innodb_file_format=barracuda;
SET GLOBAL innodb_large_prefix=ON;
CREATE TABLE t1 (c VARCHAR(1024),
c1 CHAR(255) NOT NULL,c2 CHAR(255) NOT NULL,c3 CHAR(255) NOT NULL,
c4 CHAR(255) NOT NULL,c5 CHAR(255) NOT NULL,c6 CHAR(255) NOT NULL,
c7 CHAR(255) NOT NULL,c8 CHAR(255) NOT NULL,c9 CHAR(255) NOT NULL,
ca CHAR(255) NOT NULL,cb CHAR(255) NOT NULL,cc CHAR(255) NOT NULL,
cd CHAR(255) NOT NULL,ce CHAR(255) NOT NULL,cf CHAR(255) NOT NULL,
d0 CHAR(255) NOT NULL,d1 CHAR(255) NOT NULL,d2 CHAR(255) NOT NULL,
d3 CHAR(255) NOT NULL,d4 CHAR(255) NOT NULL,d5 CHAR(255) NOT NULL,
d6 CHAR(255) NOT NULL,d7 CHAR(255) NOT NULL,d8 CHAR(255) NOT NULL,
d9 CHAR(255) NOT NULL,da CHAR(255) NOT NULL,db CHAR(255) NOT NULL,
dc CHAR(255) NOT NULL,dd CHAR(255) NOT NULL,de CHAR(255) NOT NULL,
UNIQUE KEY(c))
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES
(repeat('a',999),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
(CONCAT(repeat('a',999),'b'),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
--error ER_INDEX_COLUMN_TOO_LONG
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=inplace;
--error ER_INDEX_COLUMN_TOO_LONG
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=copy;
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
DROP TABLE t1;
SET GLOBAL innodb_file_format=@save_format;
SET GLOBAL innodb_large_prefix=@save_prefix;
5 changes: 2 additions & 3 deletions storage/innobase/handler/handler0alter.cc
Expand Up @@ -3582,9 +3582,8 @@ ha_innobase::prepare_inplace_alter_table(

/* Check each index's column length to make sure they do not
exceed limit */
for (ulint i = 0; i < ha_alter_info->index_add_count; i++) {
const KEY* key = &ha_alter_info->key_info_buffer[
ha_alter_info->index_add_buffer[i]];
for (ulint i = 0; i < ha_alter_info->key_count; i++) {
const KEY* key = &ha_alter_info->key_info_buffer[i];

if (key->flags & HA_FULLTEXT) {
/* The column length does not matter for
Expand Down
5 changes: 2 additions & 3 deletions storage/xtradb/handler/handler0alter.cc
Expand Up @@ -3596,9 +3596,8 @@ ha_innobase::prepare_inplace_alter_table(

/* Check each index's column length to make sure they do not
exceed limit */
for (ulint i = 0; i < ha_alter_info->index_add_count; i++) {
const KEY* key = &ha_alter_info->key_info_buffer[
ha_alter_info->index_add_buffer[i]];
for (ulint i = 0; i < ha_alter_info->key_count; i++) {
const KEY* key = &ha_alter_info->key_info_buffer[i];

if (key->flags & HA_FULLTEXT) {
/* The column length does not matter for
Expand Down

0 comments on commit d956709

Please sign in to comment.