Commit ae2004c6 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-17721: Corrupted data dictionary after instant DROP COLUMN

dict_index_t::clear_instant_alter(): Correctly move all fields
corresponding to instantly dropped columns to the end of the array.
This fixes a regression that was introduced in
commit 5aaee374.
parent ce32cae2
...@@ -547,6 +547,12 @@ ALTER TABLE t1 ADD COLUMN f VARCHAR(8), ADD COLUMN dt DATETIME; ...@@ -547,6 +547,12 @@ ALTER TABLE t1 ADD COLUMN f VARCHAR(8), ADD COLUMN dt DATETIME;
ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST; ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST;
ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP; ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 VALUES (4,4,4);
ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1040,6 +1046,12 @@ ALTER TABLE t1 ADD COLUMN f VARCHAR(8), ADD COLUMN dt DATETIME; ...@@ -1040,6 +1046,12 @@ ALTER TABLE t1 ADD COLUMN f VARCHAR(8), ADD COLUMN dt DATETIME;
ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST; ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST;
ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP; ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1 VALUES (4,4,4);
ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1533,10 +1545,16 @@ ALTER TABLE t1 ADD COLUMN f VARCHAR(8), ADD COLUMN dt DATETIME; ...@@ -1533,10 +1545,16 @@ ALTER TABLE t1 ADD COLUMN f VARCHAR(8), ADD COLUMN dt DATETIME;
ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST; ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST;
ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP; ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES (4,4,4);
ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1;
disconnect analyze; disconnect analyze;
SELECT variable_value-@old_instant instants SELECT variable_value-@old_instant instants
FROM information_schema.global_status FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column'; WHERE variable_name = 'innodb_instant_alter_column';
instants instants
96 102
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
...@@ -424,6 +424,13 @@ ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST; ...@@ -424,6 +424,13 @@ ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST;
ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP; ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP;
DROP TABLE t1; DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) $engine;
INSERT INTO t1 VALUES (4,4,4);
ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1;
dec $format; dec $format;
} }
disconnect analyze; disconnect analyze;
......
...@@ -2153,9 +2153,11 @@ inline void dict_index_t::clear_instant_alter() ...@@ -2153,9 +2153,11 @@ inline void dict_index_t::clear_instant_alter()
dict_field_t* end = &fields[n_fields]; dict_field_t* end = &fields[n_fields];
while (end[-1].col->is_dropped()) end--; while (end[-1].col->is_dropped()) end--;
for (dict_field_t* d = begin; d < end; d++) { for (dict_field_t* d = begin; d < end; ) {
/* Move fields for dropped columns to the end. */ /* Move fields for dropped columns to the end. */
if (d->col->is_dropped()) { if (!d->col->is_dropped()) {
d++;
} else {
if (d->col->is_nullable()) { if (d->col->is_nullable()) {
n_nullable--; n_nullable--;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment