summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-02-04 16:31:52 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-02-04 16:36:58 +0200
commita56f78243ee06167b5baf8255d3866099f3a3936 (patch)
treef5ad6c5a29321aee2a8c1f0d40682457f734262a
parent46386661a2311cabd7bac914c44b1af0b4746e07 (diff)
downloadmariadb-git-a56f78243ee06167b5baf8255d3866099f3a3936.tar.gz
MDEV-21645 SIGSEGV in innobase_get_computed_value
ha_innobase::commit_inplace_alter_table(): After ALTER_STORED_COLUMN_ORDER, ensure that the virtual column metadata will be reloaded also when the table is not being rebuilt.
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_bugs.result9
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_bugs.test10
-rw-r--r--storage/innobase/handler/handler0alter.cc5
3 files changed, 23 insertions, 1 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result
index 4512542f612..53f2d4f1c60 100644
--- a/mysql-test/suite/innodb/r/instant_alter_bugs.result
+++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result
@@ -358,4 +358,13 @@ t1 CREATE TABLE `t1` (
`a` char(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin2 ROW_FORMAT=REDUNDANT
DROP TABLE t1;
+#
+# MDEV-21645 SIGSEGV in innobase_get_computed_value
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, va INTEGER GENERATED ALWAYS AS (a))
+ENGINE=InnoDB;
+INSERT INTO t1 SET a=1, b=NULL;
+ALTER TABLE t1 MODIFY COLUMN b INT FIRST;
+ALTER TABLE t1 ADD UNIQUE INDEX (va);
+DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test
index 0a1de256b6a..d76a586cfa1 100644
--- a/mysql-test/suite/innodb/t/instant_alter_bugs.test
+++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test
@@ -374,4 +374,14 @@ ALTER TABLE t1 MODIFY a CHAR, ALGORITHM=INSTANT;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-21645 SIGSEGV in innobase_get_computed_value
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, va INTEGER GENERATED ALWAYS AS (a))
+ENGINE=InnoDB;
+INSERT INTO t1 SET a=1, b=NULL;
+ALTER TABLE t1 MODIFY COLUMN b INT FIRST;
+ALTER TABLE t1 ADD UNIQUE INDEX (va);
+DROP TABLE t1;
+
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 741a94ae42b..4200e87fa7f 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -11172,7 +11172,10 @@ foreign_fail:
/* MDEV-17468: Avoid this at least when ctx->is_instant().
Currently dict_load_column_low() is the only place where
num_base for virtual columns is assigned to nonzero. */
- if (ctx0->num_to_drop_vcol || ctx0->num_to_add_vcol) {
+ if (ctx0->num_to_drop_vcol || ctx0->num_to_add_vcol
+ || (ctx0->is_instant()
+ && m_prebuilt->table->n_v_cols
+ && ha_alter_info->handler_flags & ALTER_STORED_COLUMN_ORDER)) {
DBUG_ASSERT(ctx0->old_table->get_ref_count() == 1);
trx_commit_for_mysql(m_prebuilt->trx);