diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e8ffdc23ec5..03ed0fe4e66 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -725,7 +725,14 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (!interval) { - interval= sql_field->interval= typelib(sql_field->interval_list); + /* + Create the typelib in prepared statement memory if we're + executing one. + */ + MEM_ROOT *stmt_root= thd->current_arena->mem_root; + + interval= sql_field->interval= typelib(stmt_root, + sql_field->interval_list); List_iterator<String> it(sql_field->interval_list); String conv, *tmp; for (uint i= 0; (tmp= it++); i++) @@ -736,7 +743,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { uint cnv_errs; conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); - interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(), + interval->type_names[i]= strmake_root(stmt_root, conv.ptr(), conv.length()); interval->type_lengths[i]= conv.length(); } @@ -756,8 +763,23 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (sql_field->def && cs != sql_field->def->collation.collation) { - if (!(sql_field->def= - sql_field->def->safe_charset_converter(cs))) + Item_arena backup_arena; + bool need_to_change_arena= + !thd->current_arena->is_conventional_execution(); + if (need_to_change_arena) + { + /* Asser that we don't do that at every PS execute */ + DBUG_ASSERT(thd->current_arena->is_first_stmt_execute() || + thd->current_arena->is_first_sp_execute()); + thd->set_n_backup_item_arena(thd->current_arena, &backup_arena); + } + + sql_field->def= sql_field->def->safe_charset_converter(cs); + + if (need_to_change_arena) + thd->restore_backup_item_arena(thd->current_arena, &backup_arena); + + if (! sql_field->def) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); |