Commit 71261e31 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18315/MDEV-18316: Assertion failures on instant DROP COLUMN

dict_table_t::prepare_instant(): Correctly assign instantly
dropped columns to instant->dropped[].
parent 8aae31cf
......@@ -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;
......@@ -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;
......
......@@ -302,9 +302,7 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
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 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
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 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
}
/* 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 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
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();
......
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