diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index f91e0b3bf60a..459ded4ae553 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -3683,3 +3683,106 @@ ERROR 22004: Invalid use of NULL value ALTER TABLE t2 MODIFY fld0 POINT NOT NULL; ERROR 22004: Invalid use of NULL value DROP TABLE t1, t2; +# +# BUG#26848813: INDEXED COLUMN CAN'T BE CHANGED FROM VARCHAR(15) +# TO VARCHAR(40) INSTANTANEOUSLY +SET @orig_sql_mode= @@sql_mode; +SET @orig_innodb_large_prefix= @@global.innodb_large_prefix; +SET GLOBAL innodb_large_prefix= ON; +Warnings: +Warning 131 Using innodb_large_prefix is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html +# Tests where an error is reported under strict mode when the index +# limit exceeds the maximum supported length by SE. +CREATE TABLE t1 (fld1 VARCHAR(768), KEY(fld1)) CHARSET latin1 ENGINE =InnoDB +ROW_FORMAT= COMPACT; +ERROR 42000: Specified key was too long; max key length is 767 bytes +CREATE TABLE t2 (fld1 VARCHAR(3073), KEY(fld1)) CHARSET latin1 ENGINE= InnoDB; +ERROR 42000: Specified key was too long; max key length is 3072 bytes +# Test with innodb prefix indexes where the index limit is 767 bytes +CREATE TABLE t1 (fld1 VARCHAR(767), KEY(fld1)) CHARSET latin1 ENGINE=INNODB +ROW_FORMAT=COMPACT; +ALTER TABLE t1 MODIFY fld1 VARCHAR(768), ALGORITHM= INPLACE; +ERROR 42000: Specified key was too long; max key length is 767 bytes +ALTER TABLE t1 MODIFY fld1 VARCHAR(768), ALGORITHM= COPY; +ERROR 42000: Specified key was too long; max key length is 767 bytes +# Test with innodb prefix indexes where the index limit is 3072 bytes +CREATE TABLE t2 (fld1 VARCHAR(3072), KEY(fld1)) CHARSET latin1 ENGINE=INNODB +ROW_FORMAT=DYNAMIC; +ALTER TABLE t2 MODIFY fld1 VARCHAR(3073), ALGORITHM= INPLACE; +ERROR 42000: Specified key was too long; max key length is 3072 bytes +ALTER TABLE t2 MODIFY fld1 VARCHAR(3073), ALGORITHM= COPY; +ERROR 42000: Specified key was too long; max key length is 3072 bytes +# Tests with innodb_large_prefix disabled and strict mode. +SET GLOBAL innodb_large_prefix= OFF; +Warnings: +Warning 131 Using innodb_large_prefix is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html +CREATE TABLE t3 (fld1 VARCHAR(3072), KEY(fld1)) CHARSET latin1 ENGINE= InnoDB; +ERROR 42000: Specified key was too long; max key length is 767 bytes +DROP TABLE t1, t2; +SET sql_mode= ''; +Warnings: +Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release. +SET GLOBAL innodb_large_prefix= ON; +Warnings: +Warning 131 Using innodb_large_prefix is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html +# Test where the indexes are truncated to fit the index limit and +# a warning is reported under non-strict mode when the index exceeds +# the SE limit. +CREATE TABLE t1 (fld1 VARCHAR(768), KEY(fld1)) ENGINE= InnoDB +ROW_FORMAT=COMPACT; +Warnings: +Warning 1071 Specified key was too long; max key length is 767 bytes +CREATE TABLE t2 (fld1 VARCHAR(3073), KEY(fld1)) ENGINE= InnoDB; +Warnings: +Warning 1071 Specified key was too long; max key length is 3072 bytes +# Test with innodb prefix indexes where the index limit is 767 bytes. +CREATE TABLE t3 (fld1 VARCHAR(767), KEY(fld1))ENGINE=INNODB ROW_FORMAT=COMPACT; +ALTER TABLE t3 MODIFY fld1 VARCHAR(768), ALGORITHM= INPLACE; +Warnings: +Warning 1071 Specified key was too long; max key length is 767 bytes +ALTER TABLE t3 MODIFY fld1 VARCHAR(800), ALGORITHM= COPY; +# Test with innodb prefix indexes where the index limit is 3072 bytes. +CREATE TABLE t4 (fld1 VARCHAR(3072), KEY(fld1))ENGINE=INNODB +ROW_FORMAT=DYNAMIC; +ALTER TABLE t4 MODIFY fld1 VARCHAR(3073), ALGORITHM= INPLACE; +Warnings: +Warning 1071 Specified key was too long; max key length is 3072 bytes +ALTER TABLE t4 MODIFY fld1 VARCHAR(3074), ALGORITHM= COPY; +# For unique and primary keys, an error is reported even in non-strict +# mode. +CREATE TABLE t5(fld1 VARCHAR(768) PRIMARY KEY) ENGINE= InnoDB +ROW_FORMAT=COMPACT; +ERROR 42000: Specified key was too long; max key length is 767 bytes +CREATE TABLE t5(fld1 VARCHAR(3073), UNIQUE KEY(fld1)) ENGINE= InnoDB; +ERROR 42000: Specified key was too long; max key length is 3072 bytes +# Tests with innodb_large_prefix disabled and strict mode. +SET GLOBAL innodb_large_prefix= OFF; +Warnings: +Warning 131 Using innodb_large_prefix is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html +CREATE TABLE t5 (fld1 VARCHAR(3072), KEY(fld1)) CHARSET latin1 ENGINE= InnoDB; +Warnings: +Warning 1071 Specified key was too long; max key length is 767 bytes +DROP TABLE t1, t2, t3, t4, t5; +SET sql_mode= @orig_sql_mode; +SET GLOBAL innodb_large_prefix= ON; +# Tests added for coverage. +CREATE TABLE t1(fld1 VARCHAR(3), KEY(fld1)) ENGINE=MYISAM; +# Conversion of unpacked keys to packed keys reports +# error for INPLACE Alter. +ALTER TABLE t1 MODIFY fld1 VARCHAR(10), ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY. +# Succeeds with index rebuild. +ALTER TABLE t1 MODIFY fld1 VARCHAR(10), ALGORITHM=COPY; +# Succeeds since the row format is dynamic. +CREATE TABLE t2(fld1 VARCHAR(768), KEY(fld1)) ENGINE= InnoDB ROW_FORMAT= DYNAMIC; +# An error is reported when the index exceeds the column size +# in both strict and non-strict mode. +ALTER TABLE t2 ADD INDEX idx1(fld1(769)); +ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys +SET sql_mode= ''; +ALTER TABLE t2 ADD INDEX idx1(fld1(769)); +ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys +# Cleanup. +DROP TABLE t1, t2; +SET sql_mode= @orig_sql_mode; +SET GLOBAL innodb_large_prefix= @orig_innodb_large_prefix; diff --git a/mysql-test/r/innodb_mysql_sync.result b/mysql-test/r/innodb_mysql_sync.result index 3a400e484f7c..960aec1a3d15 100644 --- a/mysql-test/r/innodb_mysql_sync.result +++ b/mysql-test/r/innodb_mysql_sync.result @@ -746,3 +746,22 @@ ALTER TABLE t1 MODIFY fld1 CHAR(20); #cleanup DROP TABLE t1; SET debug="-d,innodb_index_drop_count_zero"; +# +# BUG#26848813: INDEXED COLUMN CAN'T BE CHANGED FROM VARCHAR(15) +# TO VARCHAR(40) INSTANTANEOUSLY +CREATE TABLE t1(fld1 VARCHAR(5), KEY(fld1)) ENGINE= InnoDB; +SET DEBUG="+d,innodb_index_drop_count_zero"; +# Without patch, an error is reported. +ALTER TABLE t1 MODIFY fld1 VARCHAR(7), ALGORITHM= INPLACE; +# Scenario where non-packed keys is converted to packed keys +# before the patch, an error is reported. +ALTER TABLE t1 MODIFY fld1 VARCHAR(9), ALGORITHM= INPLACE; +SET DEBUG="-d,innodb_index_drop_count_zero"; +# Tests added for covering cases where rebuild is required. +# Reducing the size of the field. +ALTER TABLE t1 MODIFY fld1 VARCHAR(3), ALGORITHM= INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY. +# Increasing the size of the field to boundary condition. +ALTER TABLE t1 MODIFY fld1 VARCHAR(256), ALGORITHM= INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY. +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index e98b60a9f72d..72140352b00a 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -72,7 +72,7 @@ Table Name Tablespace Table Flags Columns Row Format Zip Size Space Type test/tab test/tab 33 5 Dynamic 0 Single SET GLOBAL innodb_default_row_format=COMPACT; ALTER TABLE tab ROW_FORMAT=COMPACT; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes DROP TABLE tab; SET GLOBAL innodb_default_row_format=Default; SELECT @@innodb_default_row_format; diff --git a/mysql-test/suite/innodb/r/innodb-large-prefix.result b/mysql-test/suite/innodb/r/innodb-large-prefix.result index f691d59f56f4..311c1742870a 100644 --- a/mysql-test/suite/innodb/r/innodb-large-prefix.result +++ b/mysql-test/suite/innodb/r/innodb-large-prefix.result @@ -5,14 +5,14 @@ CREATE TABLE t1(a int not null,key(a,a)) ENGINE=InnoDB DEFAULT CHARSET=latin1; ERROR 42S21: Duplicate column name 'a' CREATE TABLE t1(a int,b text,key(b(768))) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes CREATE TABLE t1(a int not null,b text) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; INSERT INTO t1 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,''); CREATE INDEX t1aa ON t1(a,a); ERROR 42S21: Duplicate column name 'a' CREATE INDEX t1b ON t1(b(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -35,7 +35,7 @@ INSERT INTO t2 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,''); CREATE INDEX t2aa ON t2(a,a); ERROR 42S21: Duplicate column name 'a' CREATE INDEX t2b ON t2(b(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes SELECT * FROM t2; a b 1 diff --git a/mysql-test/suite/innodb/t/default_row_format_compatibility.test b/mysql-test/suite/innodb/t/default_row_format_compatibility.test index 0fce0c4e5157..9753350fa27b 100644 --- a/mysql-test/suite/innodb/t/default_row_format_compatibility.test +++ b/mysql-test/suite/innodb/t/default_row_format_compatibility.test @@ -160,7 +160,7 @@ SELECT * FROM tab; SET GLOBAL innodb_default_row_format=COMPACT; # Check error ERROR 1709 (HY000): Index column size too large --- error ER_INDEX_COLUMN_TOO_LONG +--error ER_TOO_LONG_KEY ALTER TABLE tab ROW_FORMAT=COMPACT; # Cleanup diff --git a/mysql-test/suite/innodb/t/innodb-large-prefix.test b/mysql-test/suite/innodb/t/innodb-large-prefix.test index 57dc11002af0..b1e9b7c3cb5d 100644 --- a/mysql-test/suite/innodb/t/innodb-large-prefix.test +++ b/mysql-test/suite/innodb/t/innodb-large-prefix.test @@ -9,7 +9,7 @@ --error ER_DUP_FIELDNAME CREATE TABLE t1(a int not null,key(a,a)) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY CREATE TABLE t1(a int,b text,key(b(768))) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; CREATE TABLE t1(a int not null,b text) ENGINE=InnoDB DEFAULT CHARSET=latin1 @@ -17,7 +17,7 @@ ROW_FORMAT=COMPACT; INSERT INTO t1 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,''); --error ER_DUP_FIELDNAME CREATE INDEX t1aa ON t1(a,a); --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY CREATE INDEX t1b ON t1(b(768)); SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -28,7 +28,7 @@ ROW_FORMAT=COMPACT; INSERT INTO t2 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,''); --error ER_DUP_FIELDNAME CREATE INDEX t2aa ON t2(a,a); --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY CREATE INDEX t2b ON t2(b(768)); SELECT * FROM t2; DROP TABLE t2; diff --git a/mysql-test/suite/innodb_zip/r/index_large_prefix.result b/mysql-test/suite/innodb_zip/r/index_large_prefix.result index 7f466e957f35..f4a43c413a01 100644 --- a/mysql-test/suite/innodb_zip/r/index_large_prefix.result +++ b/mysql-test/suite/innodb_zip/r/index_large_prefix.result @@ -494,11 +494,11 @@ drop table worklog5743; ### Test 6 ### create table worklog5743(a TEXT not null, primary key (a(1000))) row_format=compact; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create table worklog5743(a TEXT) row_format=compact; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx on worklog5743(a(767)); insert into worklog5743 values(repeat("a", 20000)); begin; @@ -546,12 +546,12 @@ drop table worklog5743; SET sql_mode= default; create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx2 on worklog5743(a(767)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx2 on worklog5743(a(767)); drop table worklog5743; SET GLOBAL innodb_file_per_table=1; diff --git a/mysql-test/suite/innodb_zip/r/index_large_prefix_4k.result b/mysql-test/suite/innodb_zip/r/index_large_prefix_4k.result index 36d232f1e614..923e77892a7a 100644 --- a/mysql-test/suite/innodb_zip/r/index_large_prefix_4k.result +++ b/mysql-test/suite/innodb_zip/r/index_large_prefix_4k.result @@ -362,7 +362,7 @@ create table worklog5743(a TEXT not null, primary key (a(1000))); ERROR 42000: Specified key was too long; max key length is 768 bytes create table worklog5743(a TEXT) ROW_FORMAT=COMPACT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx on worklog5743(a(767)); insert into worklog5743 values(repeat("a", 20000)); begin; @@ -417,12 +417,12 @@ insert into worklog5743 values(repeat("a", 768)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx2 on worklog5743(a(767)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx2 on worklog5743(a(767)); drop table worklog5743; SET GLOBAL innodb_file_per_table=1; diff --git a/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result b/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result index c9ee289123ee..f7eb850524a1 100644 --- a/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result +++ b/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result @@ -404,10 +404,10 @@ drop table worklog5743; ### Test 6 ### create table worklog5743(a TEXT not null, primary key (a(1000))) row_format=compact; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create table worklog5743(a TEXT) row_format=compact; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx on worklog5743(a(767)); insert into worklog5743 values(repeat("a", 20000)); begin; @@ -455,12 +455,12 @@ worklog5743 CREATE TABLE `worklog5743` ( drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx2 on worklog5743(a(767)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; create index idx on worklog5743(a(768)); -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create index idx2 on worklog5743(a(767)); drop table worklog5743; SET GLOBAL innodb_file_per_table=1; diff --git a/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result b/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result index fd2def62c494..fd9b2ac93c5e 100644 --- a/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result +++ b/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result @@ -30,9 +30,9 @@ col_1_varchar = REPEAT("c", 4000) 0 1 ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes ALTER TABLE worklog5743 ROW_FORMAT=COMPACT; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes ALTER TABLE worklog5743 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; DROP TABLE worklog5743; CREATE TABLE worklog5743 ( diff --git a/mysql-test/suite/innodb_zip/r/wl6469.result b/mysql-test/suite/innodb_zip/r/wl6469.result index ad328188efbd..1c64e20e23a5 100644 --- a/mysql-test/suite/innodb_zip/r/wl6469.result +++ b/mysql-test/suite/innodb_zip/r/wl6469.result @@ -270,8 +270,9 @@ SET sql_mode = default; set global innodb_large_prefix = 1; Warnings: Warning 131 Using innodb_large_prefix is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html -SET sql_mode='NO_ENGINE_SUBSTITUTION'; +SET sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'; Warnings: +Warning 3135 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release. Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release. SET innodb_strict_mode=OFF; create temporary table t ( @@ -279,7 +280,7 @@ a int not null, b blob not null, index sk (b(3021)) ) row_format = compact engine=innodb; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create temporary table t ( a int not null, b blob not null, @@ -299,7 +300,7 @@ a int not null, b blob not null, index sk (b(3021)) ) row_format = compact engine=innodb; -ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +ERROR 42000: Specified key was too long; max key length is 767 bytes create temporary table t ( a int not null, b blob not null, diff --git a/mysql-test/suite/innodb_zip/t/index_large_prefix.test b/mysql-test/suite/innodb_zip/t/index_large_prefix.test index 532ffc4b60e5..694eb69bdd77 100644 --- a/mysql-test/suite/innodb_zip/t/index_large_prefix.test +++ b/mysql-test/suite/innodb_zip/t/index_large_prefix.test @@ -370,7 +370,7 @@ drop table worklog5743; -- echo ### Test 6 ### # Create a table with old format, and the limit is 768 bytes. --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create table worklog5743(a TEXT not null, primary key (a(1000))) row_format=compact; @@ -378,7 +378,7 @@ create table worklog5743(a TEXT) row_format=compact; # Excercise the column length check in ha_innobase::add_index() --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); # This should be successful @@ -426,13 +426,13 @@ SET sql_mode= default; # We have a limit of 767 bytes for Antelope tables create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; diff --git a/mysql-test/suite/innodb_zip/t/index_large_prefix_4k.test b/mysql-test/suite/innodb_zip/t/index_large_prefix_4k.test index a0229abc4f8f..0d4b86d6a4de 100644 --- a/mysql-test/suite/innodb_zip/t/index_large_prefix_4k.test +++ b/mysql-test/suite/innodb_zip/t/index_large_prefix_4k.test @@ -334,7 +334,7 @@ create table worklog5743(a TEXT not null, primary key (a(1000))); create table worklog5743(a TEXT) ROW_FORMAT=COMPACT; # Excercise the column length check in ha_innobase::add_index() --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); # This should be successful @@ -385,13 +385,13 @@ drop table worklog5743; # We have a limit of 767 bytes for Antelope tables create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; diff --git a/mysql-test/suite/innodb_zip/t/index_large_prefix_8k.test b/mysql-test/suite/innodb_zip/t/index_large_prefix_8k.test index 00a97249a957..c940915c01ca 100644 --- a/mysql-test/suite/innodb_zip/t/index_large_prefix_8k.test +++ b/mysql-test/suite/innodb_zip/t/index_large_prefix_8k.test @@ -360,14 +360,14 @@ drop table worklog5743; -- echo ### Test 6 ### # Create a table with old format, and the limit is 768 bytes. --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create table worklog5743(a TEXT not null, primary key (a(1000))) row_format=compact; create table worklog5743(a TEXT) row_format=compact; # Excercise the column length check in ha_innobase::add_index() --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); # This should be successful @@ -414,13 +414,13 @@ drop table worklog5743; # We have a limit of 767 bytes for Antelope tables create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; --- error ER_INDEX_COLUMN_TOO_LONG +-- error ER_TOO_LONG_KEY create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; diff --git a/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test b/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test index dfc3777c58a0..9c21b7982984 100644 --- a/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test +++ b/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test @@ -47,9 +47,9 @@ WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; ---error ER_INDEX_COLUMN_TOO_LONG +--error ER_TOO_LONG_KEY ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT; ---error ER_INDEX_COLUMN_TOO_LONG +--error ER_TOO_LONG_KEY ALTER TABLE worklog5743 ROW_FORMAT=COMPACT; ALTER TABLE worklog5743 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; DROP TABLE worklog5743; diff --git a/mysql-test/suite/innodb_zip/t/wl6469.test b/mysql-test/suite/innodb_zip/t/wl6469.test index ebd5f727009f..1c49d3b1e775 100644 --- a/mysql-test/suite/innodb_zip/t/wl6469.test +++ b/mysql-test/suite/innodb_zip/t/wl6469.test @@ -219,10 +219,10 @@ SET sql_mode = default; # set global innodb_large_prefix = 1; # -SET sql_mode='NO_ENGINE_SUBSTITUTION'; +SET sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'; SET innodb_strict_mode=OFF; --disable_warnings ---error ER_INDEX_COLUMN_TOO_LONG +--error ER_TOO_LONG_KEY create temporary table t ( a int not null, b blob not null, @@ -246,7 +246,7 @@ drop table t; SET GLOBAL innodb_large_prefix=default; set global innodb_file_per_table = 0; # ---error ER_INDEX_COLUMN_TOO_LONG +--error ER_TOO_LONG_KEY create temporary table t ( a int not null, b blob not null, diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 4b7a9aba0741..e5832548829c 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -3044,3 +3044,126 @@ ALTER TABLE t1 MODIFY fld0 DATETIME NOT NULL; ALTER TABLE t2 MODIFY fld0 POINT NOT NULL; DROP TABLE t1, t2; + + +--echo # +--echo # BUG#26848813: INDEXED COLUMN CAN'T BE CHANGED FROM VARCHAR(15) +--echo # TO VARCHAR(40) INSTANTANEOUSLY + +SET @orig_sql_mode= @@sql_mode; +SET @orig_innodb_large_prefix= @@global.innodb_large_prefix; + +SET GLOBAL innodb_large_prefix= ON; + +--echo # Tests where an error is reported under strict mode when the index +--echo # limit exceeds the maximum supported length by SE. + +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (fld1 VARCHAR(768), KEY(fld1)) CHARSET latin1 ENGINE =InnoDB +ROW_FORMAT= COMPACT; + +--error ER_TOO_LONG_KEY +CREATE TABLE t2 (fld1 VARCHAR(3073), KEY(fld1)) CHARSET latin1 ENGINE= InnoDB; + +--echo # Test with innodb prefix indexes where the index limit is 767 bytes +CREATE TABLE t1 (fld1 VARCHAR(767), KEY(fld1)) CHARSET latin1 ENGINE=INNODB +ROW_FORMAT=COMPACT; + +--error ER_TOO_LONG_KEY +ALTER TABLE t1 MODIFY fld1 VARCHAR(768), ALGORITHM= INPLACE; + +--error ER_TOO_LONG_KEY +ALTER TABLE t1 MODIFY fld1 VARCHAR(768), ALGORITHM= COPY; + +--echo # Test with innodb prefix indexes where the index limit is 3072 bytes +CREATE TABLE t2 (fld1 VARCHAR(3072), KEY(fld1)) CHARSET latin1 ENGINE=INNODB +ROW_FORMAT=DYNAMIC; + +--error ER_TOO_LONG_KEY +ALTER TABLE t2 MODIFY fld1 VARCHAR(3073), ALGORITHM= INPLACE; + +--error ER_TOO_LONG_KEY +ALTER TABLE t2 MODIFY fld1 VARCHAR(3073), ALGORITHM= COPY; + +--echo # Tests with innodb_large_prefix disabled and strict mode. +SET GLOBAL innodb_large_prefix= OFF; +--error ER_TOO_LONG_KEY +CREATE TABLE t3 (fld1 VARCHAR(3072), KEY(fld1)) CHARSET latin1 ENGINE= InnoDB; + +DROP TABLE t1, t2; + +SET sql_mode= ''; +SET GLOBAL innodb_large_prefix= ON; + +--enable_warnings + +--echo # Test where the indexes are truncated to fit the index limit and +--echo # a warning is reported under non-strict mode when the index exceeds +--echo # the SE limit. +CREATE TABLE t1 (fld1 VARCHAR(768), KEY(fld1)) ENGINE= InnoDB +ROW_FORMAT=COMPACT; +CREATE TABLE t2 (fld1 VARCHAR(3073), KEY(fld1)) ENGINE= InnoDB; + +--echo # Test with innodb prefix indexes where the index limit is 767 bytes. +CREATE TABLE t3 (fld1 VARCHAR(767), KEY(fld1))ENGINE=INNODB ROW_FORMAT=COMPACT; + +ALTER TABLE t3 MODIFY fld1 VARCHAR(768), ALGORITHM= INPLACE; + +ALTER TABLE t3 MODIFY fld1 VARCHAR(800), ALGORITHM= COPY; + +--echo # Test with innodb prefix indexes where the index limit is 3072 bytes. +CREATE TABLE t4 (fld1 VARCHAR(3072), KEY(fld1))ENGINE=INNODB +ROW_FORMAT=DYNAMIC; + +ALTER TABLE t4 MODIFY fld1 VARCHAR(3073), ALGORITHM= INPLACE; + +ALTER TABLE t4 MODIFY fld1 VARCHAR(3074), ALGORITHM= COPY; + +--echo # For unique and primary keys, an error is reported even in non-strict +--echo # mode. + +--error ER_TOO_LONG_KEY +CREATE TABLE t5(fld1 VARCHAR(768) PRIMARY KEY) ENGINE= InnoDB +ROW_FORMAT=COMPACT; + +--error ER_TOO_LONG_KEY +CREATE TABLE t5(fld1 VARCHAR(3073), UNIQUE KEY(fld1)) ENGINE= InnoDB; + +--echo # Tests with innodb_large_prefix disabled and strict mode. +SET GLOBAL innodb_large_prefix= OFF; +CREATE TABLE t5 (fld1 VARCHAR(3072), KEY(fld1)) CHARSET latin1 ENGINE= InnoDB; + +--disable_warnings +DROP TABLE t1, t2, t3, t4, t5; + +SET sql_mode= @orig_sql_mode; +SET GLOBAL innodb_large_prefix= ON; + +--echo # Tests added for coverage. +CREATE TABLE t1(fld1 VARCHAR(3), KEY(fld1)) ENGINE=MYISAM; + +--echo # Conversion of unpacked keys to packed keys reports +--echo # error for INPLACE Alter. +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t1 MODIFY fld1 VARCHAR(10), ALGORITHM=INPLACE; + +--echo # Succeeds with index rebuild. +ALTER TABLE t1 MODIFY fld1 VARCHAR(10), ALGORITHM=COPY; + +--echo # Succeeds since the row format is dynamic. +CREATE TABLE t2(fld1 VARCHAR(768), KEY(fld1)) ENGINE= InnoDB ROW_FORMAT= DYNAMIC; + +--echo # An error is reported when the index exceeds the column size +--echo # in both strict and non-strict mode. +--error ER_WRONG_SUB_KEY +ALTER TABLE t2 ADD INDEX idx1(fld1(769)); + +SET sql_mode= ''; + +--error ER_WRONG_SUB_KEY +ALTER TABLE t2 ADD INDEX idx1(fld1(769)); + +--echo # Cleanup. +DROP TABLE t1, t2; +SET sql_mode= @orig_sql_mode; +SET GLOBAL innodb_large_prefix= @orig_innodb_large_prefix; diff --git a/mysql-test/t/innodb_mysql_sync.test b/mysql-test/t/innodb_mysql_sync.test index 364e1ab926be..166122697cdf 100644 --- a/mysql-test/t/innodb_mysql_sync.test +++ b/mysql-test/t/innodb_mysql_sync.test @@ -1098,6 +1098,34 @@ DROP TABLE t1; SET debug="-d,innodb_index_drop_count_zero"; +--echo # +--echo # BUG#26848813: INDEXED COLUMN CAN'T BE CHANGED FROM VARCHAR(15) +--echo # TO VARCHAR(40) INSTANTANEOUSLY + +CREATE TABLE t1(fld1 VARCHAR(5), KEY(fld1)) ENGINE= InnoDB; +SET DEBUG="+d,innodb_index_drop_count_zero"; + +--echo # Without patch, an error is reported. +ALTER TABLE t1 MODIFY fld1 VARCHAR(7), ALGORITHM= INPLACE; + +--echo # Scenario where non-packed keys is converted to packed keys +--echo # before the patch, an error is reported. +ALTER TABLE t1 MODIFY fld1 VARCHAR(9), ALGORITHM= INPLACE; + +SET DEBUG="-d,innodb_index_drop_count_zero"; + +--echo # Tests added for covering cases where rebuild is required. + +--echo # Reducing the size of the field. +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 MODIFY fld1 VARCHAR(3), ALGORITHM= INPLACE; + +--echo # Increasing the size of the field to boundary condition. +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 MODIFY fld1 VARCHAR(256), ALGORITHM= INPLACE; + +DROP TABLE t1; + # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 61c345f5e75b..a438a7f340a0 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13768,7 +13768,8 @@ uint ha_ndbcluster::max_supported_key_length() const { return NDB_MAX_KEY_SIZE; } -uint ha_ndbcluster::max_supported_key_part_length() const +uint ha_ndbcluster::max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const { return NDB_MAX_KEY_SIZE; } diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 9d1c75575a1d..3f4cba5524a0 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -238,7 +238,7 @@ class ha_ndbcluster: public handler, public Partition_handler uint max_supported_keys() const; uint max_supported_key_parts() const; uint max_supported_key_length() const; - uint max_supported_key_part_length() const; + uint max_supported_key_part_length(HA_CREATE_INFO *create_info) const; virtual bool is_fk_defined_on_table_or_index(uint index); int get_child_or_parent_fk_list(THD *thd, diff --git a/sql/handler.cc b/sql/handler.cc index 78faf46c8ce4..99818b510fb9 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4845,7 +4845,8 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::ALTER_RENAME | Alter_inplace_info::RENAME_INDEX | - Alter_inplace_info::ALTER_INDEX_COMMENT; + Alter_inplace_info::ALTER_INDEX_COMMENT | + Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH; /* Is there at least one operation that requires copy algorithm? */ if (ha_alter_info->handler_flags & ~inplace_offline_operations) diff --git a/sql/handler.h b/sql/handler.h index 3cb113474d66..ca1ca5c3bc3d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1030,6 +1030,9 @@ struct handlerton #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 11) +// Engine supports packed keys. +#define HTON_SUPPORTS_PACKED_KEYS (1 << 12) + enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, ISO_REPEATABLE_READ, ISO_SERIALIZABLE}; @@ -1325,6 +1328,14 @@ class Alter_inplace_info // New/changed virtual generated column require validation static const HA_ALTER_FLAGS VALIDATE_VIRTUAL_COLUMN = 1ULL << 41; + /** + Change in index length such that it does not require index rebuild. + For example, change in index length due to column expansion like + varchar(X) changed to varchar(X + N). + */ + static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH = 1ULL << 42; + + /** Create options (like MAX_ROWS) for the new version of table. @@ -3074,16 +3085,18 @@ class handler :public Sql_alloc { return std::min(MAX_KEY_LENGTH, max_supported_key_length()); } - uint max_key_part_length() const + uint max_key_part_length(HA_CREATE_INFO *create_info) const { - return std::min(MAX_KEY_LENGTH, max_supported_key_part_length()); + return std::min(MAX_KEY_LENGTH, max_supported_key_part_length(create_info)); } virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } virtual uint max_supported_keys() const { return 0; } virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; } virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; } - virtual uint max_supported_key_part_length() const { return 255; } + virtual uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return 255; } virtual uint min_record_length(uint options) const { return 1; } virtual bool low_byte_first() const { return 1; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ec92483741b9..45f27278a0dc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4331,10 +4331,11 @@ mysql_prepare_create_table(THD *thd, const char *error_schema_name, size_t max_field_size= blob_length_by_type(sql_field->sql_type); if (key_part_length > max_field_size || key_part_length > max_key_length || - key_part_length > file->max_key_part_length()) + key_part_length > file->max_key_part_length(create_info)) { // Given prefix length is too large, adjust it. - key_part_length= min(max_key_length, file->max_key_part_length()); + key_part_length= min(max_key_length, + file->max_key_part_length(create_info)); if (max_field_size) key_part_length= min(key_part_length, max_field_size); if (key->type == KEYTYPE_MULTIPLE) @@ -4385,10 +4386,10 @@ mysql_prepare_create_table(THD *thd, const char *error_schema_name, my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); } - if (key_part_length > file->max_key_part_length() && + if (key_part_length > file->max_key_part_length(create_info) && key->type != KEYTYPE_FULLTEXT) { - key_part_length= file->max_key_part_length(); + key_part_length= file->max_key_part_length(create_info); if (key->type == KEYTYPE_MULTIPLE) { /* not a critical problem */ @@ -4412,7 +4413,8 @@ mysql_prepare_create_table(THD *thd, const char *error_schema_name, } key_part_info->length= (uint16) key_part_length; /* Use packed keys for long strings on the first column */ - if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) && + if ((create_info->db_type->flags & HTON_SUPPORTS_PACKED_KEYS) && + !((*db_options) & HA_OPTION_NO_PACK_KEYS) && !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) && (key_part_length >= KEY_DEFAULT_PACK_LENGTH && (sql_field->sql_type == MYSQL_TYPE_STRING || @@ -6297,18 +6299,30 @@ static bool has_index_def_changed(Alter_inplace_info *ha_alter_info, key_part < end; key_part++, new_part++) { + + new_field= get_field_by_index(alter_info, new_part->fieldnr); + /* - Key definition has changed if we are using a different field or - if the used key part length is different. It makes sense to - check lengths first as in case when fields differ it is likely - that lengths differ too and checking fields is more expensive - in general case. + If there is a change in index length due to column expansion + like varchar(X) changed to varchar(X + N) and has a compatible + packed data representation, we mark it for fast/INPLACE change + in index definition. Some engines like InnoDB supports INPLACE + alter for such cases. + + In other cases, key definition has changed if we are using a + different field or if the used key part length is different, or + key part direction has changed. */ - if (key_part->length != new_part->length) + if (key_part->length != new_part->length && + ha_alter_info->alter_info->flags == Alter_info::ALTER_CHANGE_COLUMN && + (key_part->field->is_equal((Create_field *)new_field) == IS_EQUAL_PACK_LENGTH)) + { + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH; + } + else if (key_part->length != new_part->length) return true; - new_field= get_field_by_index(alter_info, new_part->fieldnr); - /* For prefix keys KEY_PART_INFO::field points to cloned Field object with adjusted length. So below we have to check field diff --git a/sql/sql_tmp_table.cc b/sql/sql_tmp_table.cc index 8f5153cc8c78..39d24e852fa6 100644 --- a/sql/sql_tmp_table.cc +++ b/sql/sql_tmp_table.cc @@ -462,7 +462,7 @@ void Cache_temp_engine_properties::init(THD *thd) db_plugin= ha_lock_engine(0, heap_hton); handler= get_new_handler((TABLE_SHARE *)0, thd->mem_root, heap_hton); HEAP_MAX_KEY_LENGTH= handler->max_key_length(); - HEAP_MAX_KEY_PART_LENGTH= handler->max_key_part_length(); + HEAP_MAX_KEY_PART_LENGTH= handler->max_key_part_length(0); HEAP_MAX_KEY_PARTS= handler->max_key_parts(); delete handler; plugin_unlock(0, db_plugin); @@ -470,7 +470,7 @@ void Cache_temp_engine_properties::init(THD *thd) db_plugin= ha_lock_engine(0, myisam_hton); handler= get_new_handler((TABLE_SHARE *)0, thd->mem_root, myisam_hton); MYISAM_MAX_KEY_LENGTH= handler->max_key_length(); - MYISAM_MAX_KEY_PART_LENGTH= handler->max_key_part_length(); + MYISAM_MAX_KEY_PART_LENGTH= handler->max_key_part_length(0); MYISAM_MAX_KEY_PARTS= handler->max_key_parts(); delete handler; plugin_unlock(0, db_plugin); diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index e3b508906425..670254c58869 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -118,7 +118,9 @@ class ha_archive: public handler ulonglong *nb_reserved_values); uint max_supported_keys() const { return 1; } uint max_supported_key_length() const { return sizeof(ulonglong); } - uint max_supported_key_part_length() const { return sizeof(ulonglong); } + uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return sizeof(ulonglong); } virtual int records(ha_rows *num_rows) { *num_rows= share->rows_recorded; diff --git a/storage/blackhole/ha_blackhole.h b/storage/blackhole/ha_blackhole.h index cb8e25569478..f7a20e4ce3ed 100644 --- a/storage/blackhole/ha_blackhole.h +++ b/storage/blackhole/ha_blackhole.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -69,7 +69,9 @@ class ha_blackhole: public handler #define BLACKHOLE_MAX_KEY_LENGTH 1000 uint max_supported_keys() const { return BLACKHOLE_MAX_KEY; } uint max_supported_key_length() const { return BLACKHOLE_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return BLACKHOLE_MAX_KEY_LENGTH; } + uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return BLACKHOLE_MAX_KEY_LENGTH; } int open(const char *name, int mode, uint test_if_locked); int close(void); int truncate(); diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index f60aa79967ca..650a19df2d3a 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -168,7 +168,9 @@ class ha_federated: public handler uint max_supported_keys() const { return MAX_KEY; } uint max_supported_key_parts() const { return MAX_REF_PARTS; } uint max_supported_key_length() const { return FEDERATED_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return FEDERATED_MAX_KEY_LENGTH; } + uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return FEDERATED_MAX_KEY_LENGTH; } /* Called in test_quick_select to determine if indexes should be used. Normally, we need to know number of blocks . For federated we need to diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index cb25623b58fc..9e37047c1ae4 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -61,7 +61,9 @@ class ha_heap: public handler } const key_map *keys_to_use_for_scanning() { return &btree_keys; } uint max_supported_keys() const { return MAX_KEY; } - uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; } + uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return MAX_KEY_LENGTH; } double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } double read_time(uint index, uint ranges, ha_rows rows) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 8ce8c184ef31..f1cba471384b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6345,14 +6345,23 @@ ha_innobase::clone( uint -ha_innobase::max_supported_key_part_length() const +ha_innobase::max_supported_key_part_length(HA_CREATE_INFO *create_info) const /*==============================================*/ { /* A table format specific index column length check will be performed at ha_innobase::add_index() and row_create_index_for_mysql() */ - return(innobase_large_prefix - ? REC_VERSION_56_MAX_INDEX_COL_LEN - : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1); + switch (create_info->row_type) { + case ROW_TYPE_REDUNDANT: + case ROW_TYPE_COMPACT: + return (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1); + break; + default: + if (innobase_large_prefix) + return (REC_VERSION_56_MAX_INDEX_COL_LEN); + else + return (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1); + } + } /******************************************************************//** diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index b83b70cb4463..9d7150a2679c 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -91,7 +91,7 @@ class ha_innobase: public handler uint max_supported_key_length() const; - uint max_supported_key_part_length() const; + uint max_supported_key_part_length(HA_CREATE_INFO *create_info) const; const key_map* keys_to_use_for_scanning(); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 8d28fa567244..4683084e3047 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -110,7 +110,8 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD | Alter_inplace_info::ALTER_INDEX_COMMENT | Alter_inplace_info::ADD_VIRTUAL_COLUMN | Alter_inplace_info::DROP_VIRTUAL_COLUMN - | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER; + | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER + | Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH; /* | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE; */ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index e934a59ffec8..5f30a0c0f852 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2299,7 +2299,8 @@ static int myisam_init(void *p) myisam_hton->create= myisam_create_handler; myisam_hton->panic= myisam_panic; myisam_hton->close_connection= myisam_close_connection; - myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; + myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES | + HTON_SUPPORTS_PACKED_KEYS; myisam_hton->is_supported_system_table= myisam_is_supported_system_table; main_thread_keycache_var= st_keycache_thread_var(); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index f7794b7c85fc..11890c26032b 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -83,7 +83,9 @@ class ha_myisam: public handler } uint max_supported_keys() const { return MI_MAX_KEY; } uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; } + uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return MI_MAX_KEY_LENGTH; } uint checksum() const; int open(const char *name, int mode, uint test_if_locked); diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 2f91986d1f47..9d201ddc769c 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -99,7 +99,9 @@ class ha_myisammrg: public handler } uint max_supported_keys() const { return MI_MAX_KEY; } uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; } + uint max_supported_key_part_length(HA_CREATE_INFO + *create_info MY_ATTRIBUTE((unused))) const + { return MI_MAX_KEY_LENGTH; } double scan_time() { return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; } diff --git a/storage/partition/ha_partition.cc b/storage/partition/ha_partition.cc index de8348ff988d..f3258dc375d0 100644 --- a/storage/partition/ha_partition.cc +++ b/storage/partition/ha_partition.cc @@ -5551,6 +5551,21 @@ uint ha_partition::min_of_the_max_uint( } +uint ha_partition::min_of_the_max_uint(HA_CREATE_INFO *create_info, + uint (handler::*operator_func)(HA_CREATE_INFO *) const) const +{ + handler **file; + uint min_of_the_max= ((*m_file)->*operator_func)(create_info); + + for (file= m_file+1; *file; file++) + { + uint tmp= ((*file)->*operator_func)(create_info); + set_if_smaller(min_of_the_max, tmp); + } + return min_of_the_max; +} + + uint ha_partition::max_supported_key_parts() const { return min_of_the_max_uint(&handler::max_supported_key_parts); @@ -5563,9 +5578,11 @@ uint ha_partition::max_supported_key_length() const } -uint ha_partition::max_supported_key_part_length() const +uint ha_partition::max_supported_key_part_length(HA_CREATE_INFO + *create_info) const { - return min_of_the_max_uint(&handler::max_supported_key_part_length); + return + min_of_the_max_uint(create_info, &handler::max_supported_key_part_length); } diff --git a/storage/partition/ha_partition.h b/storage/partition/ha_partition.h index 2f7311e10c6e..f5be20d95004 100644 --- a/storage/partition/ha_partition.h +++ b/storage/partition/ha_partition.h @@ -2,7 +2,7 @@ #define HA_PARTITION_INCLUDED /* - Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -902,11 +902,13 @@ class ha_partition : The maximum supported values is the minimum of all handlers in the table */ uint min_of_the_max_uint(uint (handler::*operator_func)(void) const) const; + uint min_of_the_max_uint(HA_CREATE_INFO *create_info, + uint (handler::*operator_func)(HA_CREATE_INFO *) const) const; virtual uint max_supported_record_length() const; virtual uint max_supported_keys() const; virtual uint max_supported_key_parts() const; virtual uint max_supported_key_length() const; - virtual uint max_supported_key_part_length() const; + virtual uint max_supported_key_part_length(HA_CREATE_INFO *create_info) const; /* All handlers in a partitioned table must have the same low_byte_first