Skip to content
  • Nisha Gopalakrishnan's avatar
    09ebb775
    BUG#26848813: INDEXED COLUMN CAN'T BE CHANGED FROM VARCHAR(15) · 09ebb775
    Nisha Gopalakrishnan authored
                  TO VARCHAR(40) INSTANTANEOUSLY
    
    Analysis
    ========
    
    Indexed VARCHAR columns are not expanded instantaneously (without index rebuild)for
    InnoDB tables using INPLACE algorithm. The other problems uncovered as part of this
    bug are:
    a) Indexed VARCHAR columns when converted from unpacked
       keys to packed keys(key size > 8 bytes) by expanding
       the VARCHAR column was not instantaneous for InnoDB
       tables using INPLACE algorithm even though pack keys
       is a no-op for InnoDB tables.
    b) CREATE/ALTER of InnoDB tables where the index size
       exceeds the SE limit of 767 bytes for COMPACT or
       REDUNDANT row_format did not report error in STRICT
       mode and warning in non-strict mode.
    
    SQL layer determines if there has been a change in index definition and sets the
    appropriate handler flags which helps the SE to determine whether a index rebuild
    needs to be performed. The 'has_index_def_changed()' did not check if the change
    in length had a compatible packed data representation and marked it as a change in
    index by setting the handler flags DROP_INDEX and ADD_INDEX triggering a recreation
    of indexes in InnoDB.
    
    When 'PACK_KEYS' option is not specified, indexes on columns with string types are
    marked for packing through HA_PACK_KEY. Currently only MyISAM engine supports it.
    Indexes on columns with length greater than 8 bytes were marked for packing
    irrespective of the storage engine. Converting the indexes from non-packed to packed
    i.e expanding the varchar column from lesser than 8 chars to more than 8 chars using
    ALTER was marked as a change in index definition during the check in
    'has_index_def_changed()' even though InnoDB does not support packed keys.
    
    The handler API ha_innobase::max_supported_key_part_length() returned an incorrect
    maximum support key part length since the row format of the table was not taken into
    account. Hence creation of tables using REDUNDANT/COMPACT row format with index size
    exceeding the SE limit were allowed.
    
    Fix:
    ===
    a) A new handler flag 'Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH"
       is introduced. This is set in 'has_index_def_changed()' when the
       index length differs due to column modification and has compatible
       packed data representation while determining if the index definition
       has changed.
    
    b) Introduced a handlerton flag 'HTON_SUPPORTS_PACKED_KEYS' to check for
       'PACK_KEYS' support which is currently set for MyISAM engine since it
       is the only engine which supports packed keys. The 'HTON_SUPPORTS_PACKED_KEYS'
       is checked prior to setting the index flag 'HA_BINARY_PACK_KEY' for packed keys.
       Hence for InnoDB the packed key flag for indexes is not set.
    
    c) The handler API max_supported_key_part_length() has been modified to take 'create_info'
       as a parameter from which the row_format can be fetched and appropriate index limit can
       be computed and returned by the InnoDB implementation of the handler API. More details
       on the behavior is mentioned in the table below.
    
       - Since the index limit is computed correctly and checked at the SQL layer,
         the error message 'ER_TOO_LONG_KEY' is reported at the SQL layer instead of
         'ER_INDEX_COLUMN_TOO_LONG' (which was reported by the handler interface
         after mapping the error returned by SE).
       - For COMPACT and REDUNDANT row format, when the index size exceeds 767 bytes,
         a warning is reported in non-STRICT mode and the index is truncated to fit
         767 bytes. In a STRICT mode, an error is reported.
    
    This table describes the behavior of INDEX limit, Type of INDEX and
    behavior under STRICT and NON_STRICT mode.
    IL===> Index Limit.
    -------------------------------------------------------------------------------|
      Row Format          |INDEX LIMIT | STRICT MODE(>IL) | NON-STRICT MODE(>IL)   |
    ----------------------|--------------------------------------------------------|
    Compact/Redundant     |  767 bytes |    Error         | Index truncation(767)  |
    (Non Unique Index)    |            |                  | and warning.           |
    --------------------------------------------------------------------------------
    Compact/Redundant     |  767 bytes |    Error         | Error                  |
    (Unique/Primary Index)|            |                  |                        |
    --------------------------------------------------------------------------------
    Dynamic/Compressed    |  3072 byes |    Error         | Index truncation(3072) |
    (Non Unique Index)    |            |                  | and warning            |
    --------------------------------------------------------------------------------
    Dynamic/Compressed    |  3072 bytes|    Error         | Error                  |
    (Unique/Primary Index)|            |                  |                        |
    --------------------------------------------------------------------------------
    
    (cherry picked from commit bdc97b75674ade0251bdbc3ea2dc7d36871f73cd)
    
    "Resolved the copyright year fix"
    09ebb775
    BUG#26848813: INDEXED COLUMN CAN'T BE CHANGED FROM VARCHAR(15)
    Nisha Gopalakrishnan authored
                  TO VARCHAR(40) INSTANTANEOUSLY
    
    Analysis
    ========
    
    Indexed VARCHAR columns are not expanded instantaneously (without index rebuild)for
    InnoDB tables using INPLACE algorithm. The other problems uncovered as part of this
    bug are:
    a) Indexed VARCHAR columns when converted from unpacked
       keys to packed keys(key size > 8 bytes) by expanding
       the VARCHAR column was not instantaneous for InnoDB
       tables using INPLACE algorithm even though pack keys
       is a no-op for InnoDB tables.
    b) CREATE/ALTER of InnoDB tables where the index size
       exceeds the SE limit of 767 bytes for COMPACT or
       REDUNDANT row_format did not report error in STRICT
       mode and warning in non-strict mode.
    
    SQL layer determines if there has been a change in index definition and sets the
    appropriate handler flags which helps the SE to determine whether a index rebuild
    needs to be performed. The 'has_index_def_changed()' did not check if the change
    in length had a compatible packed data representation and marked it as a change in
    index by setting the handler flags DROP_INDEX and ADD_INDEX triggering a recreation
    of indexes in InnoDB.
    
    When 'PACK_KEYS' option is not specified, indexes on columns with string types are
    marked for packing through HA_PACK_KEY. Currently only MyISAM engine supports it.
    Indexes on columns with length greater than 8 bytes were marked for packing
    irrespective of the storage engine. Converting the indexes from non-packed to packed
    i.e expanding the varchar column from lesser than 8 chars to more than 8 chars using
    ALTER was marked as a change in index definition during the check in
    'has_index_def_changed()' even though InnoDB does not support packed keys.
    
    The handler API ha_innobase::max_supported_key_part_length() returned an incorrect
    maximum support key part length since the row format of the table was not taken into
    account. Hence creation of tables using REDUNDANT/COMPACT row format with index size
    exceeding the SE limit were allowed.
    
    Fix:
    ===
    a) A new handler flag 'Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH"
       is introduced. This is set in 'has_index_def_changed()' when the
       index length differs due to column modification and has compatible
       packed data representation while determining if the index definition
       has changed.
    
    b) Introduced a handlerton flag 'HTON_SUPPORTS_PACKED_KEYS' to check for
       'PACK_KEYS' support which is currently set for MyISAM engine since it
       is the only engine which supports packed keys. The 'HTON_SUPPORTS_PACKED_KEYS'
       is checked prior to setting the index flag 'HA_BINARY_PACK_KEY' for packed keys.
       Hence for InnoDB the packed key flag for indexes is not set.
    
    c) The handler API max_supported_key_part_length() has been modified to take 'create_info'
       as a parameter from which the row_format can be fetched and appropriate index limit can
       be computed and returned by the InnoDB implementation of the handler API. More details
       on the behavior is mentioned in the table below.
    
       - Since the index limit is computed correctly and checked at the SQL layer,
         the error message 'ER_TOO_LONG_KEY' is reported at the SQL layer instead of
         'ER_INDEX_COLUMN_TOO_LONG' (which was reported by the handler interface
         after mapping the error returned by SE).
       - For COMPACT and REDUNDANT row format, when the index size exceeds 767 bytes,
         a warning is reported in non-STRICT mode and the index is truncated to fit
         767 bytes. In a STRICT mode, an error is reported.
    
    This table describes the behavior of INDEX limit, Type of INDEX and
    behavior under STRICT and NON_STRICT mode.
    IL===> Index Limit.
    -------------------------------------------------------------------------------|
      Row Format          |INDEX LIMIT | STRICT MODE(>IL) | NON-STRICT MODE(>IL)   |
    ----------------------|--------------------------------------------------------|
    Compact/Redundant     |  767 bytes |    Error         | Index truncation(767)  |
    (Non Unique Index)    |            |                  | and warning.           |
    --------------------------------------------------------------------------------
    Compact/Redundant     |  767 bytes |    Error         | Error                  |
    (Unique/Primary Index)|            |                  |                        |
    --------------------------------------------------------------------------------
    Dynamic/Compressed    |  3072 byes |    Error         | Index truncation(3072) |
    (Non Unique Index)    |            |                  | and warning            |
    --------------------------------------------------------------------------------
    Dynamic/Compressed    |  3072 bytes|    Error         | Error                  |
    (Unique/Primary Index)|            |                  |                        |
    --------------------------------------------------------------------------------
    
    (cherry picked from commit bdc97b75674ade0251bdbc3ea2dc7d36871f73cd)
    
    "Resolved the copyright year fix"
Loading