Commit 9a897335 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-26420 Buffer overflow on instant ADD/DROP of generated column

prepare_inplace_add_virtual(): Over-estimate the size of the arrays
by not subtracting table->s->virtual_fields (which may refer to
stored, not virtual generated columns). InnoDB only distinguishes
virtual columns.
parent 8911823f
...@@ -458,3 +458,10 @@ f4 INT NOT NULL, f5 INT NOT NULL), ...@@ -458,3 +458,10 @@ f4 INT NOT NULL, f5 INT NOT NULL),
CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL; CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL;
DROP TABLE t1; DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; 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
...@@ -476,3 +476,12 @@ ALTER TABLE t1 ADD COLUMN(f2 INT NOT NULL, f3 INT NOT NULL, ...@@ -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; CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL;
DROP TABLE t1; DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; 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
...@@ -5016,20 +5016,18 @@ prepare_inplace_add_virtual( ...@@ -5016,20 +5016,18 @@ prepare_inplace_add_virtual(
{ {
ha_innobase_inplace_ctx* ctx; ha_innobase_inplace_ctx* ctx;
ulint i = 0; ulint i = 0;
ulint j = 0;
ctx = static_cast<ha_innobase_inplace_ctx*> ctx = static_cast<ha_innobase_inplace_ctx*>
(ha_alter_info->handler_ctx); (ha_alter_info->handler_ctx);
ctx->num_to_add_vcol = altered_table->s->virtual_fields ulint j = altered_table->s->virtual_fields + ctx->num_to_drop_vcol;
+ ctx->num_to_drop_vcol - table->s->virtual_fields;
ctx->add_vcol = static_cast<dict_v_col_t*>( ctx->add_vcol = static_cast<dict_v_col_t*>(
mem_heap_zalloc(ctx->heap, ctx->num_to_add_vcol mem_heap_zalloc(ctx->heap, j * sizeof *ctx->add_vcol));
* sizeof *ctx->add_vcol));
ctx->add_vcol_name = static_cast<const char**>( ctx->add_vcol_name = static_cast<const char**>(
mem_heap_alloc(ctx->heap, ctx->num_to_add_vcol mem_heap_alloc(ctx->heap, j * sizeof *ctx->add_vcol_name));
* sizeof *ctx->add_vcol_name));
j = 0;
for (const Create_field& new_field : for (const Create_field& new_field :
ha_alter_info->alter_info->create_list) { ha_alter_info->alter_info->create_list) {
...@@ -5110,6 +5108,7 @@ prepare_inplace_add_virtual( ...@@ -5110,6 +5108,7 @@ prepare_inplace_add_virtual(
j++; j++;
} }
ctx->num_to_add_vcol = j;
return(false); return(false);
} }
......
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