diff --git a/mysql-test/suite/innodb/r/create_select.result b/mysql-test/suite/innodb/r/create_select.result index f5db880816e..183705680bd 100644 --- a/mysql-test/suite/innodb/r/create_select.result +++ b/mysql-test/suite/innodb/r/create_select.result @@ -8,3 +8,13 @@ connection default; ERROR 70100: Query execution was interrupted CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; DROP TABLE t1; +# End of 10.2 tests +# +# MDEV-35236 Assertion `(mem_root->flags & 4) == 0' failed in safe_lexcstrdup_root +# +prepare stmt from 'create or replace table t engine=innodb select 1 as f'; +set innodb_compression_default=on; +execute stmt; +execute stmt; +drop table t; +# End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/create_select.test b/mysql-test/suite/innodb/t/create_select.test index 8103902e5f6..053db79b8f4 100644 --- a/mysql-test/suite/innodb/t/create_select.test +++ b/mysql-test/suite/innodb/t/create_select.test @@ -26,3 +26,16 @@ reap; CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; DROP TABLE t1; --source include/wait_until_count_sessions.inc + +--echo # End of 10.2 tests + +--echo # +--echo # MDEV-35236 Assertion `(mem_root->flags & 4) == 0' failed in safe_lexcstrdup_root +--echo # +prepare stmt from 'create or replace table t engine=innodb select 1 as f'; +set innodb_compression_default=on; +execute stmt; +execute stmt; +drop table t; + +--echo # End of 10.5 tests diff --git a/sql/create_options.cc b/sql/create_options.cc index 6e1217dcdfd..c4d320f7843 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -247,9 +247,11 @@ static const size_t ha_option_type_sizeof[]= bool extend_option_list(THD* thd, handlerton *hton, bool create, engine_option_value **option_list, - ha_create_table_option *rules, MEM_ROOT *root) + ha_create_table_option *rules) { DBUG_ENTER("extend_option_list"); + MEM_ROOT *root= thd->mem_root; + bool extended= false; for (ha_create_table_option *opt= rules; rules && opt->name; opt++) { @@ -280,8 +282,16 @@ bool extend_option_list(THD* thd, handlerton *hton, bool create, if (found) found->value= value; else + { + if (!extended) + { + void *pos= *option_list ? &(last->next) : option_list; + thd->register_item_tree_change((Item**)pos); + extended= true; + } new (root) engine_option_value(name, value, opt->type != HA_OPTION_TYPE_ULL, option_list, &last); + } } } } @@ -803,4 +813,3 @@ bool is_engine_option_known(engine_option_value *opt, } return false; } - diff --git a/sql/create_options.h b/sql/create_options.h index fc208d933a0..a8eece58a22 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -89,7 +89,7 @@ bool parse_option_list(THD* thd, void *option_struct, bool suppress_warning, MEM_ROOT *root); bool extend_option_list(THD* thd, handlerton *hton, bool create, engine_option_value **option_list, - ha_create_table_option *rules, MEM_ROOT *root); + ha_create_table_option *rules); bool engine_table_options_frm_read(const uchar *buff, size_t length, TABLE_SHARE *share); diff --git a/sql/sql_class.h b/sql/sql_class.h index e1c6b83c448..07b225c7d06 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4301,14 +4301,19 @@ public: return !stmt_arena->is_conventional(); } + void register_item_tree_change(Item **place) + { + /* TODO: check for OOM condition here */ + if (is_item_tree_change_register_required()) + nocheck_register_item_tree_change(place, *place, mem_root); + } + void change_item_tree(Item **place, Item *new_value) { DBUG_ENTER("THD::change_item_tree"); DBUG_PRINT("enter", ("Register: %p (%p) <- %p", *place, place, new_value)); - /* TODO: check for OOM condition here */ - if (is_item_tree_change_register_required()) - nocheck_register_item_tree_change(place, *place, mem_root); + register_item_tree_change(place); *place= new_value; DBUG_VOID_RETURN; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3f035defbd3..15b2cac14e9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3769,8 +3769,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, auto_increment++; extend_option_list(thd, create_info->db_type, !sql_field->field, &sql_field->option_list, - create_info->db_type->field_options, - thd->stmt_arena->mem_root); + create_info->db_type->field_options); if (parse_option_list(thd, &sql_field->option_struct, &sql_field->option_list, create_info->db_type->field_options, FALSE, @@ -4039,8 +4038,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->algorithm= key->key_create_info.algorithm; key_info->option_list= key->option_list; extend_option_list(thd, create_info->db_type, !key->old, - &key_info->option_list, create_info->db_type->index_options, - thd->stmt_arena->mem_root); + &key_info->option_list, create_info->db_type->index_options); if (parse_option_list(thd, &key_info->option_struct, &key_info->option_list, create_info->db_type->index_options, FALSE, @@ -4633,8 +4631,7 @@ without_overlaps_err: extend_option_list(thd, file->partition_ht(), !thd->lex->create_like() && create_table_mode > C_ALTER_TABLE, - &create_info->option_list, file->partition_ht()->table_options, - thd->stmt_arena->mem_root); + &create_info->option_list, file->partition_ht()->table_options); if (parse_option_list(thd, &create_info->option_struct, &create_info->option_list, file->partition_ht()->table_options, FALSE, thd->mem_root))