diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-11-21 12:24:49 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-11-21 12:24:49 +0200 |
commit | ae2004c616e2955a7978a0e7b876836ef9d8ee33 (patch) | |
tree | 30cd188771182672137748a56b5d9227a060c21e | |
parent | ce32cae20779f19dabd3f15b9b1242ffe0ffc2fa (diff) | |
download | mariadb-git-ae2004c616e2955a7978a0e7b876836ef9d8ee33.tar.gz |
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 5aaee3746e85788475edfc0768510b937443955a.
-rw-r--r-- | mysql-test/suite/innodb/r/instant_alter.result | 20 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/instant_alter.test | 7 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 6 |
3 files changed, 30 insertions, 3 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result index a2b15e57cc6..902acf7c1ea 100644 --- a/mysql-test/suite/innodb/r/instant_alter.result +++ b/mysql-test/suite/innodb/r/instant_alter.result @@ -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 ts2 TIMESTAMP; 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 (id INT PRIMARY KEY, c2 INT UNIQUE, 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; ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST; ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP; 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 (id INT PRIMARY KEY, c2 INT UNIQUE, 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; ALTER TABLE t1 ADD COLUMN b BIT, DROP COLUMN f, ADD COLUMN t TIME FIRST; ALTER TABLE t1 ADD COLUMN ts2 TIMESTAMP; 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; SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -96 +102 SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test index b2b24b6179d..e642e3a6057 100644 --- a/mysql-test/suite/innodb/t/instant_alter.test +++ b/mysql-test/suite/innodb/t/instant_alter.test @@ -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; 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; } disconnect analyze; diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 1e70db2209d..882b9ca8013 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2153,9 +2153,11 @@ inline void dict_index_t::clear_instant_alter() dict_field_t* end = &fields[n_fields]; 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. */ - if (d->col->is_dropped()) { + if (!d->col->is_dropped()) { + d++; + } else { if (d->col->is_nullable()) { n_nullable--; } |