mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-16376 ASAN: heap-use-after-free in gcol.innodb_virtual_debug
After a failed ADD INDEX, dict_index_remove_from_cache_low() could iterate the index fields and dereference a freed virtual column object when trying to remove the index from the v_indexes of the virtual column. This regression was caused by a merge of MDEV-16119 InnoDB lock->index refers to a freed object. ha_innobase_inplace_ctx::clear_added_indexes(): Detach the indexes of uncommitted indexes from virtual columns, so that the iteration in dict_index_remove_from_cache_low() can be avoided. ha_innobase::prepare_inplace_alter_table(): Ignore uncommitted corrupted indexes when rejecting ALTER TABLE. (This minor bug was revealed by the extension of the test case.) dict_index_t::detach_columns(): Detach an index from virtual columns. Invoked by both dict_index_remove_from_cache_low() and ha_innobase_inplace_ctx::clear_added_indexes(). dict_col_t::detach(const dict_index_t& index): Detach an index from a column. dict_col_t::is_virtual(): Replaces dict_col_is_virtual(). dict_index_t::has_virtual(): Replaces dict_index_has_virtual().
This commit is contained in:
@@ -64,11 +64,19 @@ INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
|
||||
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
||||
INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
|
||||
CREATE INDEX idx_1 on t(c);
|
||||
SET SESSION debug_dbug="+d,create_index_fail";
|
||||
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x);
|
||||
SET @saved_dbug = @@SESSION.debug_dbug;
|
||||
SET debug_dbug = '+d,create_index_fail';
|
||||
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x),
|
||||
ADD INDEX idcx (c,x);
|
||||
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
||||
SET SESSION debug_dbug="";
|
||||
UPDATE t SET a=a+1;
|
||||
affected rows: 3
|
||||
info: Rows matched: 4 Changed: 3 Warnings: 0
|
||||
ALTER TABLE t ADD INDEX idc(c);
|
||||
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
||||
SET debug_dbug = @saved_dbug;
|
||||
affected rows: 0
|
||||
UPDATE t SET b=b-1;
|
||||
SHOW CREATE TABLE t;
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
|
Reference in New Issue
Block a user