Skip to content

Commit 71261e3

Browse files
committed
MDEV-18315/MDEV-18316: Assertion failures on instant DROP COLUMN
dict_table_t::prepare_instant(): Correctly assign instantly dropped columns to instant->dropped[].
1 parent 8aae31c commit 71261e3

File tree

3 files changed

+52
-8
lines changed

3 files changed

+52
-8
lines changed

mysql-test/suite/innodb/r/instant_alter.result

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,16 @@ INSERT INTO t1 VALUES (2,20);
724724
ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
725725
ALTER TABLE t1 DROP COLUMN i;
726726
DROP TABLE t1;
727+
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
728+
INSERT INTO t1 VALUES (1,1);
729+
ALTER TABLE t1 ADD f DATE AFTER a;
730+
ALTER TABLE t1 DROP b, DROP f;
731+
DROP TABLE t1;
732+
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
733+
INSERT INTO t1 VALUES (1,1);
734+
ALTER TABLE t1 ADD COLUMN f INT AFTER a;
735+
ALTER TABLE t1 DROP b, DROP f;
736+
DROP TABLE t1;
727737
CREATE TABLE t1
728738
(id INT PRIMARY KEY, c2 INT UNIQUE,
729739
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
@@ -1394,6 +1404,16 @@ INSERT INTO t1 VALUES (2,20);
13941404
ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
13951405
ALTER TABLE t1 DROP COLUMN i;
13961406
DROP TABLE t1;
1407+
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
1408+
INSERT INTO t1 VALUES (1,1);
1409+
ALTER TABLE t1 ADD f DATE AFTER a;
1410+
ALTER TABLE t1 DROP b, DROP f;
1411+
DROP TABLE t1;
1412+
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
1413+
INSERT INTO t1 VALUES (1,1);
1414+
ALTER TABLE t1 ADD COLUMN f INT AFTER a;
1415+
ALTER TABLE t1 DROP b, DROP f;
1416+
DROP TABLE t1;
13971417
CREATE TABLE t1
13981418
(id INT PRIMARY KEY, c2 INT UNIQUE,
13991419
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
@@ -2064,10 +2084,20 @@ INSERT INTO t1 VALUES (2,20);
20642084
ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
20652085
ALTER TABLE t1 DROP COLUMN i;
20662086
DROP TABLE t1;
2087+
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
2088+
INSERT INTO t1 VALUES (1,1);
2089+
ALTER TABLE t1 ADD f DATE AFTER a;
2090+
ALTER TABLE t1 DROP b, DROP f;
2091+
DROP TABLE t1;
2092+
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
2093+
INSERT INTO t1 VALUES (1,1);
2094+
ALTER TABLE t1 ADD COLUMN f INT AFTER a;
2095+
ALTER TABLE t1 DROP b, DROP f;
2096+
DROP TABLE t1;
20672097
disconnect analyze;
20682098
SELECT variable_value-@old_instant instants
20692099
FROM information_schema.global_status
20702100
WHERE variable_name = 'innodb_instant_alter_column';
20712101
instants
2072-
158
2102+
170
20732103
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;

mysql-test/suite/innodb/t/instant_alter.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,21 @@ ALTER TABLE t1 ADD COLUMN vpk INT AS (pk);
618618
ALTER TABLE t1 DROP COLUMN i;
619619
DROP TABLE t1;
620620

621+
# MDEV-18315 Assertion instant.fields[i].col->same_format(*fields[i].col)
622+
# failed in dict_index_t::instant_add_field
623+
eval CREATE TABLE t1 (a INT, b INT) $engine;
624+
INSERT INTO t1 VALUES (1,1);
625+
ALTER TABLE t1 ADD f DATE AFTER a;
626+
ALTER TABLE t1 DROP b, DROP f;
627+
DROP TABLE t1;
628+
629+
# MDEV-18316 Assertion is_added() failed in dict_col_t::instant_value
630+
eval CREATE TABLE t1 (a INT, b INT) $engine;
631+
INSERT INTO t1 VALUES (1,1);
632+
ALTER TABLE t1 ADD COLUMN f INT AFTER a;
633+
ALTER TABLE t1 DROP b, DROP f;
634+
DROP TABLE t1;
635+
621636
dec $format;
622637
}
623638
disconnect analyze;

storage/innobase/handler/handler0alter.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,7 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
302302
instant->dropped = NULL;
303303
}
304304

305-
unsigned d = n_old_drop;
306-
307-
for (unsigned i = 0; i < old.n_cols; i++) {
305+
for (unsigned i = 0, d = n_old_drop; i < old.n_cols; i++) {
308306
if (col_map[i] == ULINT_UNDEFINED) {
309307
(new (&instant->dropped[d++])
310308
dict_col_t(old.cols[i]))->set_dropped();
@@ -315,13 +313,11 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
315313
DBUG_ASSERT(instant->dropped[i].is_dropped());
316314
}
317315
#endif
318-
DBUG_ASSERT(d == n_drop);
319316
const uint n_fields = index.n_fields + n_dropped();
320317

321318
DBUG_ASSERT(n_fields >= oindex.n_fields);
322319
dict_field_t* fields = static_cast<dict_field_t*>(
323320
mem_heap_zalloc(heap, n_fields * sizeof *fields));
324-
d = n_old_drop;
325321
uint i = 0, j = 0, n_nullable = 0;
326322
ut_d(uint core_null = 0);
327323
for (; i < oindex.n_fields; i++) {
@@ -383,8 +379,12 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
383379
}
384380

385381
/* This column is being dropped. */
382+
unsigned d = n_old_drop;
383+
for (unsigned c = 0; c < f.col->ind; c++) {
384+
d += col_map[c] == ULINT_UNDEFINED;
385+
}
386386
DBUG_ASSERT(d < n_drop);
387-
f.col = &instant->dropped[d++];
387+
f.col = &instant->dropped[d];
388388
f.name = NULL;
389389
if (f.col->is_nullable()) {
390390
goto found_nullable;
@@ -400,7 +400,6 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
400400
std::sort(index.fields + j, index.fields + index.n_fields,
401401
[](const dict_field_t& a, const dict_field_t& b)
402402
{ return a.col->ind < b.col->ind; });
403-
DBUG_ASSERT(d == n_drop);
404403
for (; i < n_fields; i++) {
405404
fields[i] = index.fields[j++];
406405
n_nullable += fields[i].col->is_nullable();

0 commit comments

Comments
 (0)