# Testcase for worklog #5743: Lift the limit of index key prefixes let $innodb_file_format_orig=`select @@innodb_file_format`; let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; let $innodb_large_prefix_orig=`select @@innodb_large_prefix`; set global innodb_file_format="Barracuda"; set global innodb_file_per_table=1; set global innodb_large_prefix=1; # Create a table of DYNAMIC format, with a primary index of 1000 bytes in # size create table worklog5743(a TEXT not null, primary key (a(1000))) ROW_FORMAT=DYNAMIC, engine = innodb; # Do some insertion and update to excercise the external cache # code path insert into worklog5743 values(repeat("a", 20000)); # default session, update the table update worklog5743 set a = (repeat("b", 16000)); # Create a secondary index create index idx on worklog5743(a(2000)); # Start a few sessions to do selections on table being updated in default # session, so it would rebuild the previous version from undo log. # 1) Default session: Initiate an update on the externally stored column # 2) Session con1: Select from table with repeated read # 3) Session con2: Select from table with read uncommitted # 4) Default session: rollback updates begin; update worklog5743 set a = (repeat("x", 17000)); # Start a new session to select the column to force it build # an earlier version of the clustered index through undo log. So it should # just see the result of repeat("b", 16000) select @@session.tx_isolation; --connect (con1,localhost,root,,) select a = repeat("x", 17000) from worklog5743; select a = repeat("b", 16000) from worklog5743; # Start another session doing "read uncommitted" query, it # should see the uncommitted update --connect (con2,localhost,root,,) SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; select @@session.tx_isolation; select a = repeat("x", 17000) from worklog5743; # Roll back the transaction --connection default rollback; drop table worklog5743; # Create a table with only a secondary index has large prefix column create table worklog5743(a1 int, a2 TEXT not null) ROW_FORMAT=DYNAMIC, engine = innodb; create index idx on worklog5743(a1, a2(2000)); insert into worklog5743 values(9, repeat("a", 10000)); begin; update worklog5743 set a1 = 1000; # Do a select from another connection that would use the secondary index --connection con1 select @@session.tx_isolation; explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; # Do read uncommitted in another session, it would show there is no # row with a1 = 9 --connection con2 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; select @@session.tx_isolation; select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; --connection default rollback; drop table worklog5743; # Create a table with a secondary index has small (50 bytes) prefix column create table worklog5743(a1 int, a2 TEXT not null) ROW_FORMAT=DYNAMIC, engine = innodb; create index idx on worklog5743(a1, a2(50)); insert into worklog5743 values(9, repeat("a", 10000)); begin; update worklog5743 set a1 = 1000; # Do a select from another connection that would use the secondary index --connection con1 select @@session.tx_isolation; explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; # Do read uncommitted in another session, it would show there is no # row with a1 = 9 --connection con2 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; select @@session.tx_isolation; select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; --connection default rollback; drop table worklog5743; # Create a table of ROW_FORMAT=COMPRESSED format create table worklog5743_2(a1 int, a2 TEXT not null) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; create table worklog5743_4(a1 int, a2 TEXT not null) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; # The maximum overall index record (not prefix) length for this table # is page_zip_empty_size() / 2, which is 960. "Too big row" error ( # HA_ERR_TO_BIG_ROW) will be printed if this limit is exceeded. # Considering other fields and their overhead, the maximum length # for column a2 is 940 or 941 depending on the zlib version used and # compressBound() value used in page_zip_empty_size() (please refer # to Bug #47495 for more detail). -- error 139 create index idx1 on worklog5743_2(a1, a2(942)); create index idx1 on worklog5743_2(a1, a2(940)); # similarly, the maximum index record length for the table is # 1984. Considering other fields and their overhead, the # maximum length for column a2 is 1964 or 1965 (please refer # to Bug #47495 for more detail). -- error 139 create index idx1 on worklog5743_4(a1, a2(1966)); create index idx1 on worklog5743_4(a1, a2(1964)); insert into worklog5743_2 values(9, repeat("a", 10000)); insert into worklog5743_4 values(9, repeat("a", 10000)); begin; update worklog5743_2 set a1 = 1000; update worklog5743_4 set a1 = 1000; # Do a select from another connection that would use the secondary index --connection con1 select @@session.tx_isolation; explain select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; select a1, a2 = repeat("a", 10000) from worklog5743_4 where a1 = 9; # Do read uncommitted in another session, it would show there is no # row with a1 = 9 --connection con2 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; select @@session.tx_isolation; select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; select a1, a2 = repeat("a", 10000) from worklog5743_4 where a1 = 9; --connection default rollback; drop table worklog5743_2; drop table worklog5743_4; # Create a table with varchar column, and create index directly on this # large column (without prefix) create table worklog5743(a1 int, a2 varchar(3000)) ROW_FORMAT=DYNAMIC, engine = innodb; # Create an index with large column without prefix create index idx on worklog5743(a1, a2); insert into worklog5743 values(9, repeat("a", 3000)); begin; update worklog5743 set a1 = 1000; # Do a select from another connection that would use the secondary index --connection con1 select @@session.tx_isolation; explain select a1 from worklog5743 where a1 = 9; select a1 from worklog5743 where a1 = 9; # Do read uncommitted, it would show there is no row with a1 = 9 --connection con2 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; select @@session.tx_isolation; select a1 from worklog5743 where a1 = 9; --connection default rollback; drop table worklog5743; # Create a table with old format, and the limit is 768 bytes. -- error ER_INDEX_COLUMN_TOO_LONG create table worklog5743(a TEXT not null, primary key (a(1000))) engine = innodb; create table worklog5743(a TEXT) engine = innodb; # Excercise the column length check in ha_innobase::add_index() -- error ER_INDEX_COLUMN_TOO_LONG create index idx on worklog5743(a(1000)); # This should be successful create index idx on worklog5743(a(725)); # Perform some DMLs insert into worklog5743 values(repeat("a", 20000)); begin; insert into worklog5743 values(repeat("b", 20000)); update worklog5743 set a = (repeat("x", 25000)); # Start a new session to select the table to force it build # an earlier version of the cluster index through undo log select @@session.tx_isolation; --connection con1 select a = repeat("a", 20000) from worklog5743; --connection con2 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; select @@session.tx_isolation; select a = repeat("x", 25000) from worklog5743; --connection default rollback; drop table worklog5743; # Some border line test on the column length. # We have a limit of 3072 bytes for Barracuda table create table worklog5743(a TEXT not null) ROW_FORMAT=DYNAMIC, engine = innodb; # Length exceeds maximum supported key length, will auto-truncated to 3072 create index idx on worklog5743(a(3073)); create index idx2 on worklog5743(a(3072)); show create table worklog5743; drop table worklog5743; # We have a limit of 767 bytes for Antelope table create table worklog5743(a TEXT not null) engine = innodb; -- error ER_INDEX_COLUMN_TOO_LONG create index idx on worklog5743(a(768)); create index idx2 on worklog5743(a(767)); drop table worklog5743; eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig;