Commit 5aaee374 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 sort the index fields
to correspond to the columns of the table.
parent 21a58840
......@@ -542,6 +542,11 @@ SELECT * FROM t1;
b i v
NULL 1 1
DROP TABLE t1;
CREATE TABLE t1 (ts TIMESTAMP) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
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
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1030,6 +1035,11 @@ SELECT * FROM t1;
b i v
NULL 1 1
DROP TABLE t1;
CREATE TABLE t1 (ts TIMESTAMP) ENGINE=InnoDB ROW_FORMAT=COMPACT;
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
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1518,10 +1528,15 @@ SELECT * FROM t1;
b i v
NULL 1 1
DROP TABLE t1;
CREATE TABLE t1 (ts TIMESTAMP) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
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;
disconnect analyze;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
87
96
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
......@@ -417,6 +417,13 @@ ALTER TABLE t1 ADD COLUMN v INT AS (i) VIRTUAL;
SELECT * FROM t1;
DROP TABLE t1;
# MDEV-17721 Corrupted data dictionary after instant DROP COLUMN
eval CREATE TABLE t1 (ts TIMESTAMP) $engine;
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;
dec $format;
}
disconnect analyze;
......
......@@ -2149,39 +2149,26 @@ inline void dict_index_t::clear_instant_alter()
DBUG_ASSERT(!fields[i].col->is_nullable());
}
#endif
dict_field_t* const begin = &fields[first_user_field()];
dict_field_t* end = &fields[n_fields];
while (end[-1].col->is_dropped()) end--;
for (dict_field_t* d = &fields[first_user_field()]; d < end; d++) {
for (dict_field_t* d = begin; d < end; d++) {
/* Move fields for dropped columns to the end. */
while (d->col->is_dropped()) {
if (d->col->is_dropped()) {
if (d->col->is_nullable()) {
n_nullable--;
}
std::swap(*d, *--end);
if (d == end) {
goto done;
}
}
/* Ensure that the surviving fields are sorted by
ascending order of columns. */
const unsigned c = d->col->ind;
for (dict_field_t* s = d + 1; s < end; s++) {
if (s->col->ind < c) {
std::swap(*d, *s);
break;
}
}
}
done:
DBUG_ASSERT(&fields[n_fields - table->n_dropped()] == end);
n_core_fields = n_fields = n_def = end - fields;
n_core_null_bytes = UT_BITS_IN_BYTES(n_nullable);
std::sort(begin, end, [](const dict_field_t& a, const dict_field_t& b)
{ return a.col->ind < b.col->ind; });
table->instant = NULL;
}
......
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