summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-11-21 12:24:49 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-11-21 12:24:49 +0200
commitae2004c616e2955a7978a0e7b876836ef9d8ee33 (patch)
tree30cd188771182672137748a56b5d9227a060c21e
parentce32cae20779f19dabd3f15b9b1242ffe0ffc2fa (diff)
downloadmariadb-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.result20
-rw-r--r--mysql-test/suite/innodb/t/instant_alter.test7
-rw-r--r--storage/innobase/include/dict0mem.h6
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--;
}