summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_bugs.result7
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_bugs.test9
-rw-r--r--storage/innobase/handler/handler0alter.cc13
3 files changed, 22 insertions, 7 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result
index 0c82ee8f070..2d667737a99 100644
--- a/mysql-test/suite/innodb/r/instant_alter_bugs.result
+++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result
@@ -458,3 +458,10 @@ f4 INT NOT NULL, f5 INT NOT NULL),
CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL;
DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
+#
+# MDEV-26420 Buffer overflow on instant ADD/DROP of generated column
+#
+CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
+ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
+DROP TABLE t1;
+# End of 10.4 tests
diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test
index b22d4bbbae1..74e5949818b 100644
--- a/mysql-test/suite/innodb/t/instant_alter_bugs.test
+++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test
@@ -476,3 +476,12 @@ ALTER TABLE t1 ADD COLUMN(f2 INT NOT NULL, f3 INT NOT NULL,
CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL;
DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
+
+--echo #
+--echo # MDEV-26420 Buffer overflow on instant ADD/DROP of generated column
+--echo #
+CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
+ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
+DROP TABLE t1;
+
+--echo # End of 10.4 tests
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 8c51f80f1d3..82d945e6414 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -5016,20 +5016,18 @@ prepare_inplace_add_virtual(
{
ha_innobase_inplace_ctx* ctx;
ulint i = 0;
- ulint j = 0;
ctx = static_cast<ha_innobase_inplace_ctx*>
(ha_alter_info->handler_ctx);
- ctx->num_to_add_vcol = altered_table->s->virtual_fields
- + ctx->num_to_drop_vcol - table->s->virtual_fields;
+ ulint j = altered_table->s->virtual_fields + ctx->num_to_drop_vcol;
ctx->add_vcol = static_cast<dict_v_col_t*>(
- mem_heap_zalloc(ctx->heap, ctx->num_to_add_vcol
- * sizeof *ctx->add_vcol));
+ mem_heap_zalloc(ctx->heap, j * sizeof *ctx->add_vcol));
ctx->add_vcol_name = static_cast<const char**>(
- mem_heap_alloc(ctx->heap, ctx->num_to_add_vcol
- * sizeof *ctx->add_vcol_name));
+ mem_heap_alloc(ctx->heap, j * sizeof *ctx->add_vcol_name));
+
+ j = 0;
for (const Create_field& new_field :
ha_alter_info->alter_info->create_list) {
@@ -5110,6 +5108,7 @@ prepare_inplace_add_virtual(
j++;
}
+ ctx->num_to_add_vcol = j;
return(false);
}