summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-01-21 15:25:37 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-01-21 15:25:37 +0200
commit71261e31887a48a081051e8a880e8c4fb259ce44 (patch)
tree4834f6e58e22186376af057ff965ab88ebe539ec
parent8aae31cf494678b6253031c627566e50bc666920 (diff)
downloadmariadb-git-71261e31887a48a081051e8a880e8c4fb259ce44.tar.gz
MDEV-18315/MDEV-18316: Assertion failures on instant DROP COLUMN
dict_table_t::prepare_instant(): Correctly assign instantly dropped columns to instant->dropped[].
-rw-r--r--mysql-test/suite/innodb/r/instant_alter.result32
-rw-r--r--mysql-test/suite/innodb/t/instant_alter.test15
-rw-r--r--storage/innobase/handler/handler0alter.cc13
3 files changed, 52 insertions, 8 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result
index 0c0b81da6e3..f864221def5 100644
--- a/mysql-test/suite/innodb/r/instant_alter.result
+++ b/mysql-test/suite/innodb/r/instant_alter.result
@@ -724,6 +724,16 @@ INSERT INTO t1 VALUES (2,20);
ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
ALTER TABLE t1 DROP COLUMN i;
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD f DATE AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD COLUMN f INT AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
@@ -1394,6 +1404,16 @@ INSERT INTO t1 VALUES (2,20);
ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
ALTER TABLE t1 DROP COLUMN i;
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD f DATE AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD COLUMN f INT AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
@@ -2064,10 +2084,20 @@ INSERT INTO t1 VALUES (2,20);
ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
ALTER TABLE t1 DROP COLUMN i;
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD f DATE AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD COLUMN f INT AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
disconnect analyze;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
-158
+170
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 65dde13808c..b1679023e11 100644
--- a/mysql-test/suite/innodb/t/instant_alter.test
+++ b/mysql-test/suite/innodb/t/instant_alter.test
@@ -618,6 +618,21 @@ ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
ALTER TABLE t1 DROP COLUMN i;
DROP TABLE t1;
+# MDEV-18315 Assertion instant.fields[i].col->same_format(*fields[i].col)
+# failed in dict_index_t::instant_add_field
+eval CREATE TABLE t1 (a INT, b INT) $engine;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD f DATE AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
+
+# MDEV-18316 Assertion is_added() failed in dict_col_t::instant_value
+eval CREATE TABLE t1 (a INT, b INT) $engine;
+INSERT INTO t1 VALUES (1,1);
+ALTER TABLE t1 ADD COLUMN f INT AFTER a;
+ALTER TABLE t1 DROP b, DROP f;
+DROP TABLE t1;
+
dec $format;
}
disconnect analyze;
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 1edbd337e35..108703142d6 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -302,9 +302,7 @@ add_metadata:
instant->dropped = NULL;
}
- unsigned d = n_old_drop;
-
- for (unsigned i = 0; i < old.n_cols; i++) {
+ for (unsigned i = 0, d = n_old_drop; i < old.n_cols; i++) {
if (col_map[i] == ULINT_UNDEFINED) {
(new (&instant->dropped[d++])
dict_col_t(old.cols[i]))->set_dropped();
@@ -315,13 +313,11 @@ add_metadata:
DBUG_ASSERT(instant->dropped[i].is_dropped());
}
#endif
- DBUG_ASSERT(d == n_drop);
const uint n_fields = index.n_fields + n_dropped();
DBUG_ASSERT(n_fields >= oindex.n_fields);
dict_field_t* fields = static_cast<dict_field_t*>(
mem_heap_zalloc(heap, n_fields * sizeof *fields));
- d = n_old_drop;
uint i = 0, j = 0, n_nullable = 0;
ut_d(uint core_null = 0);
for (; i < oindex.n_fields; i++) {
@@ -383,8 +379,12 @@ found_j:
}
/* This column is being dropped. */
+ unsigned d = n_old_drop;
+ for (unsigned c = 0; c < f.col->ind; c++) {
+ d += col_map[c] == ULINT_UNDEFINED;
+ }
DBUG_ASSERT(d < n_drop);
- f.col = &instant->dropped[d++];
+ f.col = &instant->dropped[d];
f.name = NULL;
if (f.col->is_nullable()) {
goto found_nullable;
@@ -400,7 +400,6 @@ found_j:
std::sort(index.fields + j, index.fields + index.n_fields,
[](const dict_field_t& a, const dict_field_t& b)
{ return a.col->ind < b.col->ind; });
- DBUG_ASSERT(d == n_drop);
for (; i < n_fields; i++) {
fields[i] = index.fields[j++];
n_nullable += fields[i].col->is_nullable();