Bug #76096 Incorrect return value from ha_innobase::max_supported_key_part_length()
Submitted: 2 Mar 2015 14:06 Modified: 29 Oct 2018 17:55
Reporter: Marko Mäkelä Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Storage Engines Severity:S3 (Non-critical)
Version:5.5.14 OS:Any
Assigned to: CPU Architecture:Any

[2 Mar 2015 14:06] Marko Mäkelä
Description:
The storage engine API method handler::max_supported_key_part_length() needs some cleanup.

In InnoDB, the maximum supported column prefix length in indexes depends on a number of things:

* The actual ROW_FORMAT of the table that is part of the DDL operation
* The page size of the tablespace (innodb_page_size)
* The setting of innodb_large_prefix.

Currently, depending on the innodb_large_prefix setting, InnoDB is returning 3072 or 767.
The SQL layer will treat the return value as a hard limit.

In MySQL 5.7, SQL_MODE=STRICT_TRANS_TABLES by default. So, by default, the SQL layer would return an error if an attempt is made to create a too long column prefix index. In a non-strict SQL_MODE, this would result in a warning, or an error if the too-long prefix is part of a UNIQUE index or the PRIMARY KEY.

If InnoDB leads the SQL layer to believe that it can support prefixes up to 3072 bytes, and the SQL layer tries to create a table that has a longer prefix that InnoDB actually supports for the chosen ROW_FORMAT and page size, then InnoDB will flag a hard error.

How to repeat:
Look at tests that depend on innodb_large_prefix=OFF
such as the test in main.alter_table for

--echo # BUG#16886196 - ALTER TABLE FAILS TO CONVERT TO PREFIX INDEX IN
--echo #                ALTER_COLUMN_EQUAL_PACK_LENGTH

Try to run such tests with innodb_large_prefix=ON.

Suggested fix:
Change the handler::max_supported_key_part_length() API in such a way that InnoDB can return the actual maximum length. This would seem to require at least the ROW_FORMAT as a parameter. We might as well pass all the information that would be passed to create() or prepare_inplace_alter_table().

The method could also require extra information about the tablespace where the table is (going to be) located, in case InnoDB starts to support different page sizes within a single instance. With innodb_page_size=4k, the limit is somewhere between 767 and 3072 bytes.
[21 Mar 2016 6:50] Marko Mäkelä
Posted by developer:
 
Note: the setting innodb_large_prefix was removed in WL#7704 (MySQL 5.8.), and its default was changed to innodb_large_prefix=ON in WL#7703 (MySQL 5.7.7).
[29 Oct 2018 17:55] Paul DuBois
Posted by developer:
 
Fixed in 5.7.24.

For InnoDB tables, the storage engine API could return incorrect
values for the maximum supported key-part length.