Skip to content

Commit d956709

Browse files
committed
MDEV-17833 ALTER TABLE is not enforcing prefix index size limit
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.
1 parent 4886d14 commit d956709

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

mysql-test/suite/innodb/r/innodb-index.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,3 +1180,36 @@ t2c CREATE TABLE `t2c` (
11801180
KEY `t2a` (`a`)
11811181
) ENGINE=InnoDB DEFAULT CHARSET=latin1
11821182
DROP TABLE t1,t2,t2c,t2i;
1183+
SET @save_format = @@GLOBAL.innodb_file_format;
1184+
SET @save_prefix = @@GLOBAL.innodb_large_prefix;
1185+
SET GLOBAL innodb_file_format=barracuda;
1186+
SET GLOBAL innodb_large_prefix=ON;
1187+
CREATE TABLE t1 (c VARCHAR(1024),
1188+
c1 CHAR(255) NOT NULL,c2 CHAR(255) NOT NULL,c3 CHAR(255) NOT NULL,
1189+
c4 CHAR(255) NOT NULL,c5 CHAR(255) NOT NULL,c6 CHAR(255) NOT NULL,
1190+
c7 CHAR(255) NOT NULL,c8 CHAR(255) NOT NULL,c9 CHAR(255) NOT NULL,
1191+
ca CHAR(255) NOT NULL,cb CHAR(255) NOT NULL,cc CHAR(255) NOT NULL,
1192+
cd CHAR(255) NOT NULL,ce CHAR(255) NOT NULL,cf CHAR(255) NOT NULL,
1193+
d0 CHAR(255) NOT NULL,d1 CHAR(255) NOT NULL,d2 CHAR(255) NOT NULL,
1194+
d3 CHAR(255) NOT NULL,d4 CHAR(255) NOT NULL,d5 CHAR(255) NOT NULL,
1195+
d6 CHAR(255) NOT NULL,d7 CHAR(255) NOT NULL,d8 CHAR(255) NOT NULL,
1196+
d9 CHAR(255) NOT NULL,da CHAR(255) NOT NULL,db CHAR(255) NOT NULL,
1197+
dc CHAR(255) NOT NULL,dd CHAR(255) NOT NULL,de CHAR(255) NOT NULL,
1198+
UNIQUE KEY(c))
1199+
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
1200+
INSERT INTO t1 VALUES
1201+
(repeat('a',999),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
1202+
(CONCAT(repeat('a',999),'b'),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
1203+
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=inplace;
1204+
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
1205+
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=copy;
1206+
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
1207+
SELECT COUNT(*) FROM t1;
1208+
COUNT(*)
1209+
2
1210+
CHECK TABLE t1;
1211+
Table Op Msg_type Msg_text
1212+
test.t1 check status OK
1213+
DROP TABLE t1;
1214+
SET GLOBAL innodb_file_format=@save_format;
1215+
SET GLOBAL innodb_large_prefix=@save_prefix;

mysql-test/suite/innodb/t/innodb-index.test

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,33 @@ DROP TABLE t1,t2,t2c,t2i;
563563
eval SET GLOBAL innodb_file_format=$innodb_file_format_orig;
564564
eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig;
565565
--enable_query_log
566+
567+
SET @save_format = @@GLOBAL.innodb_file_format;
568+
SET @save_prefix = @@GLOBAL.innodb_large_prefix;
569+
SET GLOBAL innodb_file_format=barracuda;
570+
SET GLOBAL innodb_large_prefix=ON;
571+
CREATE TABLE t1 (c VARCHAR(1024),
572+
c1 CHAR(255) NOT NULL,c2 CHAR(255) NOT NULL,c3 CHAR(255) NOT NULL,
573+
c4 CHAR(255) NOT NULL,c5 CHAR(255) NOT NULL,c6 CHAR(255) NOT NULL,
574+
c7 CHAR(255) NOT NULL,c8 CHAR(255) NOT NULL,c9 CHAR(255) NOT NULL,
575+
ca CHAR(255) NOT NULL,cb CHAR(255) NOT NULL,cc CHAR(255) NOT NULL,
576+
cd CHAR(255) NOT NULL,ce CHAR(255) NOT NULL,cf CHAR(255) NOT NULL,
577+
d0 CHAR(255) NOT NULL,d1 CHAR(255) NOT NULL,d2 CHAR(255) NOT NULL,
578+
d3 CHAR(255) NOT NULL,d4 CHAR(255) NOT NULL,d5 CHAR(255) NOT NULL,
579+
d6 CHAR(255) NOT NULL,d7 CHAR(255) NOT NULL,d8 CHAR(255) NOT NULL,
580+
d9 CHAR(255) NOT NULL,da CHAR(255) NOT NULL,db CHAR(255) NOT NULL,
581+
dc CHAR(255) NOT NULL,dd CHAR(255) NOT NULL,de CHAR(255) NOT NULL,
582+
UNIQUE KEY(c))
583+
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
584+
INSERT INTO t1 VALUES
585+
(repeat('a',999),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
586+
(CONCAT(repeat('a',999),'b'),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
587+
--error ER_INDEX_COLUMN_TOO_LONG
588+
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=inplace;
589+
--error ER_INDEX_COLUMN_TOO_LONG
590+
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=copy;
591+
SELECT COUNT(*) FROM t1;
592+
CHECK TABLE t1;
593+
DROP TABLE t1;
594+
SET GLOBAL innodb_file_format=@save_format;
595+
SET GLOBAL innodb_large_prefix=@save_prefix;

storage/innobase/handler/handler0alter.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3582,9 +3582,8 @@ ha_innobase::prepare_inplace_alter_table(
35823582

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

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

storage/xtradb/handler/handler0alter.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,9 +3596,8 @@ ha_innobase::prepare_inplace_alter_table(
35963596

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

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

0 commit comments

Comments
 (0)