mirror of
https://github.com/MariaDB/server.git
synced 2025-11-12 10:22:39 +03:00
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().
97 lines
2.9 KiB
Plaintext
97 lines
2.9 KiB
Plaintext
set default_storage_engine=innodb;
|
|
CREATE TABLE `t` (
|
|
`a` VARCHAR(100),
|
|
`b` VARCHAR(100),
|
|
`c` VARCHAR(200) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL,
|
|
`h` VARCHAR(10) DEFAULT NULL,
|
|
`i` int
|
|
) ENGINE=InnoDB;
|
|
INSERT INTO t VALUES (REPEAT('g', 100), REPEAT('x', 10), DEFAULT, "kk", 1);
|
|
INSERT INTO t VALUES (REPEAT('a', 100), REPEAT('b', 100), DEFAULT, "mm", 2);
|
|
CREATE INDEX idx ON t(c(100));
|
|
SET session debug_dbug="+d,ib_alter_add_virtual_fail";
|
|
ALTER TABLE t ADD COLUMN x VARCHAR(200) GENERATED ALWAYS AS (a) VIRTUAL,
|
|
ALGORITHM = INPLACE;
|
|
ERROR 42000: The storage engine InnoDB can't index column `x`
|
|
ALTER TABLE t DROP COLUMN c, ALGORITHM = INPLACE;
|
|
ERROR 42000: The storage engine InnoDB can't index column `c`
|
|
SET session debug_dbug="";
|
|
DROP TABLE t;
|
|
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10));
|
|
INSERT INTO t VALUES (11, 3, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (null, null, DEFAULT, "mx");
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
|
|
CREATE INDEX idx ON t(c);
|
|
connect con1,localhost,root,,;
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_create';
|
|
update t set a=0 where a = 11;
|
|
start transaction;
|
|
update t set a=1 where a = 0;
|
|
ROLLBACK;
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
connection default;
|
|
SELECT c FROM t;
|
|
c
|
|
NULL
|
|
3
|
|
19
|
|
29
|
|
SHOW CREATE TABLE t;
|
|
Table Create Table
|
|
t CREATE TABLE `t` (
|
|
`a` int(11) DEFAULT NULL,
|
|
`b` int(11) DEFAULT NULL,
|
|
`c` int(11) GENERATED ALWAYS AS (`a` + `b`) VIRTUAL,
|
|
`h` varchar(10) DEFAULT NULL,
|
|
KEY `idx` (`c`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
|
SELECT * FROM t;
|
|
a b c h
|
|
0 3 3 mm
|
|
18 1 19 mm
|
|
28 1 29 mm
|
|
NULL NULL NULL mx
|
|
ALTER TABLE t FORCE, LOCK=NONE;
|
|
ERROR 0A000: LOCK=NONE is not supported. Reason: online rebuild with indexed virtual columns. Try LOCK=SHARED
|
|
disconnect con1;
|
|
DROP TABLE t;
|
|
SET DEBUG_SYNC = 'RESET';
|
|
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10));
|
|
INSERT INTO t VALUES (11, 3, DEFAULT, 'mm');
|
|
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 @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*'
|
|
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` (
|
|
`a` int(11) DEFAULT NULL,
|
|
`b` int(11) DEFAULT NULL,
|
|
`c` int(11) GENERATED ALWAYS AS (`a` + `b`) VIRTUAL,
|
|
`h` varchar(10) DEFAULT NULL,
|
|
KEY `idx_1` (`c`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
|
SELECT c FROM t;
|
|
c
|
|
NULL
|
|
14
|
|
19
|
|
29
|
|
DROP TABLE t;
|
|
SET DEBUG_SYNC = 'RESET';
|