Skip to content

Commit c55a234

Browse files
author
Shaohua Wang
committed
BUG#22082762 RE-ENABLE SUPPORT FOR ADDING VIRTUAL INDEX WHILE
DROPPING VIRTUAL COLUMN 1. Enable adding virtual index on existing virtual column while dropping virtual column; 2. Enable online adding virtual column with adding index; 3. Skip uncommitted virtual index in purge when adding a virtual index on newly added virtual column. Reviewed-by: Marko Mäkelä <[email protected]> RB: 11357
1 parent af689d3 commit c55a234

File tree

11 files changed

+531
-43
lines changed

11 files changed

+531
-43
lines changed

mysql-test/suite/gcol/r/gcol_rollback.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,29 @@ SELECT * FROM t;
4747
a b c
4848
9 9 10
4949
DROP TABLE t;
50+
CREATE TABLE t (
51+
a INT,
52+
b INT,
53+
c INT GENERATED ALWAYS AS(a+b),
54+
d INT GENERATED ALWAYS AS(a+b+b),
55+
KEY(c, d)
56+
)ENGINE=INNODB;
57+
INSERT INTO t (a,b) VALUES (9, 10);
58+
SELECT * FROM t;
59+
a b c d
60+
9 10 19 29
61+
SET DEBUG_SYNC = 'row_log_apply_after SIGNAL created WAIT_FOR dml_done';
62+
ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE;
63+
SET DEBUG_SYNC = 'now WAIT_FOR created';
64+
BEGIN;
65+
INSERT INTO t (a,b) VALUES (10, 12);
66+
SELECT * FROM t;
67+
a b c d
68+
9 10 19 29
69+
10 12 22 34
70+
ROLLBACK;
71+
SET DEBUG_SYNC = 'now SIGNAL dml_done';
72+
SELECT * FROM t;
73+
a b d
74+
9 10 29
75+
DROP TABLE t;

mysql-test/suite/gcol/t/gcol_rollback.test

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,44 @@ connection default;
6565
SELECT * FROM t;
6666
DROP TABLE t;
6767

68+
# drop virtual column and alter index
69+
CREATE TABLE t (
70+
a INT,
71+
b INT,
72+
c INT GENERATED ALWAYS AS(a+b),
73+
d INT GENERATED ALWAYS AS(a+b+b),
74+
KEY(c, d)
75+
)ENGINE=INNODB;
76+
77+
INSERT INTO t (a,b) VALUES (9, 10);
78+
SELECT * FROM t;
79+
80+
connect (con1,localhost,root,,);
81+
connection con1;
82+
83+
# This DEBUG_SYNC should not kick in yet, because the duplicate key will be
84+
# detected before we get a chance to apply the online log.
85+
86+
SET DEBUG_SYNC = 'row_log_apply_after SIGNAL created WAIT_FOR dml_done';
87+
--send
88+
ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE;
89+
90+
connection default;
91+
SET DEBUG_SYNC = 'now WAIT_FOR created';
92+
BEGIN;
93+
INSERT INTO t (a,b) VALUES (10, 12);
94+
SELECT * FROM t;
95+
ROLLBACK;
96+
SET DEBUG_SYNC = 'now SIGNAL dml_done';
97+
98+
connection con1;
99+
reap;
100+
disconnect con1;
101+
connection default;
102+
103+
SELECT * FROM t;
104+
105+
DROP TABLE t;
106+
68107
# Wait till all disconnects are completed
69108
--source include/wait_until_count_sessions.inc

mysql-test/suite/innodb/r/virtual_basic.result

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,12 +1420,103 @@ OR(c9 BETWEEN 'hwstqua' AND 'wstquadcji' OR (c9k=0))
14201420
AND(c3 IS NULL OR c3 IN (0,0,0));
14211421
c1 c2 c3 c3k c4 c5 c5k c5time_gckey c6 c5time c7 c5timek c7k c8 c9 c9k
14221422
drop table t;
1423-
#
1424-
# Bug#22374827 ALTER TABLE..LOCK NONE INVOLVING VIRTUAL COL IS REFUSED
1425-
# WITHOUT STATING A REASON
1426-
#
1427-
CREATE TABLE t1(a int NOT NULL) ENGINE=innodb;
1428-
ALTER TABLE t1 ADD INDEX idx1(a), ADD COLUMN (c int as (1) VIRTUAL), LOCK=NONE;
1429-
ERROR 0A000: LOCK=NONE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try LOCK=SHARED.
1430-
ALTER TABLE t1 ADD INDEX idx1(a), ADD COLUMN (c int as (1) VIRTUAL);
1431-
DROP TABLE t1;
1423+
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), d INT
1424+
GENERATED ALWAYS AS(a+b+b), e INT GENERATED ALWAYS AS(a), h VARCHAR(10));
1425+
INSERT INTO t VALUES (11, 3, DEFAULT, DEFAULT, DEFAULT, 'mm');
1426+
INSERT INTO t VALUES (18, 1, DEFAULT, DEFAULT, DEFAULT, 'mm');
1427+
INSERT INTO t VALUES (28, 1, DEFAULT, DEFAULT, DEFAULT, 'mm');
1428+
INSERT INTO t VALUES (null, null, DEFAULT, DEFAULT, DEFAULT, 'mm');
1429+
CREATE INDEX idx ON t(c, d);
1430+
CREATE INDEX idx1 ON t(c);
1431+
CREATE INDEX idx2 ON t(e, c, d);
1432+
ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE;
1433+
SELECT d FROM t;
1434+
d
1435+
NULL
1436+
11
1437+
18
1438+
28
1439+
SHOW CREATE TABLE t;
1440+
Table Create Table
1441+
t CREATE TABLE `t` (
1442+
`a` int(11) DEFAULT NULL,
1443+
`b` int(11) DEFAULT NULL,
1444+
`d` int(11) GENERATED ALWAYS AS (((`a` + `b`) + `b`)) VIRTUAL,
1445+
`e` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
1446+
`h` varchar(10) DEFAULT NULL,
1447+
KEY `idx` (`d`),
1448+
KEY `idx2` (`e`,`d`)
1449+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1450+
ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE;
1451+
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY.
1452+
ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (e), ALGORITHM=INPLACE, LOCK=NONE;
1453+
Warnings:
1454+
Warning 1831 Duplicate index 'idx2' defined on the table 'test.t'. This is deprecated and will be disallowed in a future release.
1455+
Warning 1831 Duplicate index 'idx' defined on the table 'test.t'. This is deprecated and will be disallowed in a future release.
1456+
SHOW CREATE TABLE t;
1457+
Table Create Table
1458+
t CREATE TABLE `t` (
1459+
`a` int(11) DEFAULT NULL,
1460+
`b` int(11) DEFAULT NULL,
1461+
`e` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
1462+
`h` varchar(10) DEFAULT NULL,
1463+
`c` int(11) GENERATED ALWAYS AS ((`a` + `b`)) VIRTUAL,
1464+
KEY `idx2` (`e`),
1465+
KEY `idx` (`e`)
1466+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1467+
ALTER TABLE t ADD INDEX idx4(c, e), ADD COLUMN x VARCHAR(10) GENERATED ALWAYS AS(h), DROP INDEX idx, ALGORITHM=INPLACE, LOCK=NONE;
1468+
SHOW CREATE TABLE t;
1469+
Table Create Table
1470+
t CREATE TABLE `t` (
1471+
`a` int(11) DEFAULT NULL,
1472+
`b` int(11) DEFAULT NULL,
1473+
`e` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
1474+
`h` varchar(10) DEFAULT NULL,
1475+
`c` int(11) GENERATED ALWAYS AS ((`a` + `b`)) VIRTUAL,
1476+
`x` varchar(10) GENERATED ALWAYS AS (`h`) VIRTUAL,
1477+
KEY `idx2` (`e`),
1478+
KEY `idx4` (`c`,`e`)
1479+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1480+
ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD COLUMN j INT, ALGORITHM=INPLACE;
1481+
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY.
1482+
ALTER TABLE t ADD INDEX (x), ADD COLUMN j INT, ALGORITHM=INPLACE, LOCK=NONE;
1483+
SHOW CREATE TABLE t;
1484+
Table Create Table
1485+
t CREATE TABLE `t` (
1486+
`a` int(11) DEFAULT NULL,
1487+
`b` int(11) DEFAULT NULL,
1488+
`e` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
1489+
`h` varchar(10) DEFAULT NULL,
1490+
`c` int(11) GENERATED ALWAYS AS ((`a` + `b`)) VIRTUAL,
1491+
`x` varchar(10) GENERATED ALWAYS AS (`h`) VIRTUAL,
1492+
`j` int(11) DEFAULT NULL,
1493+
KEY `idx2` (`e`),
1494+
KEY `idx4` (`c`,`e`),
1495+
KEY `x` (`x`)
1496+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1497+
ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=NONE;
1498+
ERROR 0A000: LOCK=NONE is not supported. Reason: ADD COLUMN col...VIRTUAL, ADD INDEX(col). Try LOCK=SHARED.
1499+
ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=SHARED;
1500+
SHOW CREATE TABLE t;
1501+
Table Create Table
1502+
t CREATE TABLE `t` (
1503+
`a` int(11) DEFAULT NULL,
1504+
`b` int(11) DEFAULT NULL,
1505+
`e` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
1506+
`h` varchar(10) DEFAULT NULL,
1507+
`c` int(11) GENERATED ALWAYS AS ((`a` + `b`)) VIRTUAL,
1508+
`x` varchar(10) GENERATED ALWAYS AS (`h`) VIRTUAL,
1509+
`j` int(11) DEFAULT NULL,
1510+
`i` int(11) GENERATED ALWAYS AS (((`a` + `a`) + `b`)) VIRTUAL,
1511+
KEY `idx2` (`e`),
1512+
KEY `idx4` (`c`,`e`),
1513+
KEY `x` (`x`),
1514+
KEY `i` (`i`)
1515+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1516+
SELECT * FROM t;
1517+
a b e h c x j i
1518+
11 3 11 mm 14 mm NULL 25
1519+
18 1 18 mm 19 mm NULL 37
1520+
28 1 28 mm 29 mm NULL 57
1521+
NULL NULL NULL mm NULL mm NULL NULL
1522+
DROP TABLE t;

mysql-test/suite/innodb/r/virtual_debug_purge.result

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,72 @@ sleep(3)
5555
0
5656
SET global debug="-d,ib_purge_virtual_index_callback";
5757
DROP TABLE t1;
58+
CREATE TABLE t1 (a INT, b INT);
59+
INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3);
60+
# disable purge
61+
CREATE TABLE t0 (a INT) ENGINE=InnoDB;
62+
BEGIN;
63+
SELECT * FROM t0;
64+
a
65+
DELETE FROM t1 WHERE a = 1;
66+
UPDATE t1 SET a = 4, b = 4 WHERE a = 3;
67+
INSERT INTO t1(a, b) VALUES (5, 5);
68+
SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged';
69+
ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE;
70+
ERROR 0A000: LOCK=NONE is not supported. Reason: ADD COLUMN col...VIRTUAL, ADD INDEX(col). Try LOCK=SHARED.
71+
ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED;
72+
SET DEBUG_SYNC= 'now WAIT_FOR uncommitted';
73+
# enable purge
74+
COMMIT;
75+
# wait for purge to process the deleted records.
76+
SET DEBUG_SYNC= 'now SIGNAL purged';
77+
/* connection default */ ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED;
78+
SHOW CREATE TABLE t1;
79+
Table Create Table
80+
t1 CREATE TABLE `t1` (
81+
`a` int(11) DEFAULT NULL,
82+
`b` int(11) DEFAULT NULL,
83+
`c` int(11) GENERATED ALWAYS AS ((`a` + `b`)) VIRTUAL,
84+
KEY `idx` (`c`)
85+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
86+
SELECT * FROM t1;
87+
a b c
88+
2 2 4
89+
4 4 8
90+
5 5 10
91+
DROP TABLE t1;
92+
CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b));
93+
INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4);
94+
# disable purge
95+
BEGIN;
96+
SELECT * FROM t0;
97+
a
98+
DELETE FROM t1 WHERE a = 1;
99+
UPDATE t1 SET a = 2, b = 2 WHERE a = 5;
100+
INSERT INTO t1(a, b) VALUES (6, 6);
101+
SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged';
102+
ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE;
103+
SET DEBUG_SYNC= 'now WAIT_FOR uncommitted';
104+
DELETE FROM t1 WHERE a = 3;
105+
UPDATE t1 SET a = 7, b = 7 WHERE a = 4;
106+
INSERT INTO t1(a, b) VALUES (8, 8);
107+
# enable purge
108+
COMMIT;
109+
# wait for purge to process the deleted/updated records.
110+
SET DEBUG_SYNC= 'now SIGNAL purged';
111+
/* connection default */ ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE;
112+
SHOW CREATE TABLE t1;
113+
Table Create Table
114+
t1 CREATE TABLE `t1` (
115+
`a` int(11) DEFAULT NULL,
116+
`b` int(11) DEFAULT NULL,
117+
`c` int(11) GENERATED ALWAYS AS ((`a` + `b`)) VIRTUAL,
118+
KEY `idx` (`c`)
119+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
120+
SELECT * FROM t1;
121+
a b c
122+
2 2 4
123+
7 7 14
124+
6 6 12
125+
8 8 16
126+
DROP TABLE t0, t1;

mysql-test/suite/innodb/t/virtual_basic.test

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,14 +1381,58 @@ AND(c3 IS NULL OR c3 IN (0,0,0));
13811381

13821382
drop table t;
13831383

1384-
--source include/wait_until_count_sessions.inc
1384+
#
1385+
# BUG#22082762 RE-ENABLE SUPPORT FOR ADDING VIRTUAL INDEX WHILE DROPPING VIRTUAL COLUMN
1386+
#
13851387

1386-
--echo #
1387-
--echo # Bug#22374827 ALTER TABLE..LOCK NONE INVOLVING VIRTUAL COL IS REFUSED
1388-
--echo # WITHOUT STATING A REASON
1389-
--echo #
1390-
CREATE TABLE t1(a int NOT NULL) ENGINE=innodb;
1388+
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), d INT
1389+
GENERATED ALWAYS AS(a+b+b), e INT GENERATED ALWAYS AS(a), h VARCHAR(10));
1390+
1391+
INSERT INTO t VALUES (11, 3, DEFAULT, DEFAULT, DEFAULT, 'mm');
1392+
INSERT INTO t VALUES (18, 1, DEFAULT, DEFAULT, DEFAULT, 'mm');
1393+
INSERT INTO t VALUES (28, 1, DEFAULT, DEFAULT, DEFAULT, 'mm');
1394+
INSERT INTO t VALUES (null, null, DEFAULT, DEFAULT, DEFAULT, 'mm');
1395+
CREATE INDEX idx ON t(c, d);
1396+
CREATE INDEX idx1 ON t(c);
1397+
CREATE INDEX idx2 ON t(e, c, d);
1398+
1399+
# This will drop column c, drop index idx1 on column c, and build index
1400+
# idx and idx2, so they become idx(d) and idx2(e, d) respectively.
1401+
ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE;
1402+
1403+
SELECT d FROM t;
1404+
1405+
SHOW CREATE TABLE t;
1406+
1407+
# Drop a column, adding a new column and also adding a index on this new column
1408+
# is not allowed for INPLACE algorithm
13911409
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
1392-
ALTER TABLE t1 ADD INDEX idx1(a), ADD COLUMN (c int as (1) VIRTUAL), LOCK=NONE;
1393-
ALTER TABLE t1 ADD INDEX idx1(a), ADD COLUMN (c int as (1) VIRTUAL);
1394-
DROP TABLE t1;
1410+
ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE;
1411+
1412+
# Add an index on existing column along with dropping a column is allowed
1413+
ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (e), ALGORITHM=INPLACE, LOCK=NONE;
1414+
SHOW CREATE TABLE t;
1415+
1416+
# Add an index on existing column along with adding a virtual column and droping a virtual index
1417+
ALTER TABLE t ADD INDEX idx4(c, e), ADD COLUMN x VARCHAR(10) GENERATED ALWAYS AS(h), DROP INDEX idx, ALGORITHM=INPLACE, LOCK=NONE;
1418+
SHOW CREATE TABLE t;
1419+
1420+
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
1421+
ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD COLUMN j INT, ALGORITHM=INPLACE;
1422+
1423+
# Add an index along with adding a regular column is allowed.
1424+
ALTER TABLE t ADD INDEX (x), ADD COLUMN j INT, ALGORITHM=INPLACE, LOCK=NONE;
1425+
SHOW CREATE TABLE t;
1426+
1427+
# Online add an index on newly added virtual column is not allowed.
1428+
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
1429+
ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=NONE;
1430+
1431+
ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=SHARED;
1432+
SHOW CREATE TABLE t;
1433+
1434+
SELECT * FROM t;
1435+
1436+
DROP TABLE t;
1437+
1438+
--source include/wait_until_count_sessions.inc

0 commit comments

Comments
 (0)