• Nikita Malyavin's avatar
    MDEV-20154 Assertion `len <= col->len | ...` failed in row_merge_buf_add · 22709897
    Nikita Malyavin authored
    len was containing garbage, since vctempl->mysql_col_offset was
    containing old value while calling row_mysql_store_col_in_innobase_format
    from innobase_get_computed_value().
    
    It was not updated after the first ALTER TABLE call, because it's INPLACE
    logic considered there's nothing to update, and exited immediately from
    ha_innobase::inplace_alter_table().
    
    However, vcol metadata needs an update, since vcols structure is changed
    in mysql record.
    
    The regression was introduced by 12614af1. There, refcount==1 condition
    was removed, which turned out to be crucial, though racy. The idea was to
    update vc_templ after each (sequencing) ALTER TABLE.
    
    We should do the same another way, and there may be a plenty of solutions,
    but the simplest one is to add a following condition:
      if vcol structure is changed, drop vc_templ; it will be recreated on next
      ha_innobase::open() call.
    
    in prepare_inplace_alter_table. It is safe, since innodb inplace changes
    require at least HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE, which
    guarantee MDL_EXCLUSIVE on this stage.
    
    alter_templ_needs_rebuild() also has to track the columns not indexed, to
    keep vc_templ correct.
    
    Note that vc_templ is always kept constructed and available after
    ha_innobase::open() call, even on INSERT, though no virtual columns are
    evaluated during that statement
    inside innodb.
    
    In the test case suplied, it will be recreated on the second ALTER TABLE.
    22709897
innodb_virtual_index.test 10.4 KB