Loading mysql-test/r/ps.result +19 −0 Original line number Diff line number Diff line Loading @@ -699,3 +699,22 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; prepare stmt from "create temporary table t1 (letter enum('','a','b','c') not null)"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; set names latin1; prepare stmt from "create table t1 (a enum('test') default 'test') character set utf8"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; set names default; deallocate prepare stmt; mysql-test/t/ps.test +29 −0 Original line number Diff line number Diff line Loading @@ -718,4 +718,33 @@ set @@tx_isolation=default; execute stmt; deallocate prepare stmt; # # Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP" # # Part I. Make sure the typelib for ENUM is created in the statement memory # root. prepare stmt from "create temporary table t1 (letter enum('','a','b','c') not null)"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; # Part II. Make sure that when the default value is converted to UTF-8, # the new item is # created in the statement memory root. set names latin1; prepare stmt from "create table t1 (a enum('test') default 'test') character set utf8"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; # Cleanup set names default; deallocate prepare stmt; # End of 4.1 tests sql/mysql_priv.h +1 −1 Original line number Diff line number Diff line Loading @@ -1119,7 +1119,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week); uint calc_week(TIME *l_time, uint week_behaviour, uint *year); void find_date(char *pos,uint *vek,uint flag); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); TYPELIB *typelib(List<String> &strings); TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); Loading sql/sql_table.cc +25 −4 Original line number Diff line number Diff line Loading @@ -524,7 +524,14 @@ 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++) Loading @@ -534,7 +541,7 @@ 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); char *buf= (char*) sql_alloc(conv.length()+1); char *buf= (char*) alloc_root(stmt_root, conv.length()+1); memcpy(buf, conv.ptr(), conv.length()); buf[conv.length()]= '\0'; interval->type_names[i]= buf; Loading @@ -556,8 +563,22 @@ 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->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); Loading sql/table.cc +3 −3 Original line number Diff line number Diff line Loading @@ -1099,15 +1099,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, } /* fix_type_pointers */ TYPELIB *typelib(List<String> &strings) TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings) { TYPELIB *result=(TYPELIB*) sql_alloc(sizeof(TYPELIB)); TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); if (!result) return 0; result->count=strings.elements; result->name=""; uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1); if (!(result->type_names= (const char**) sql_alloc(nbytes))) if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes))) return 0; result->type_lengths= (uint*) (result->type_names + result->count + 1); List_iterator<String> it(strings); Loading Loading
mysql-test/r/ps.result +19 −0 Original line number Diff line number Diff line Loading @@ -699,3 +699,22 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; prepare stmt from "create temporary table t1 (letter enum('','a','b','c') not null)"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; set names latin1; prepare stmt from "create table t1 (a enum('test') default 'test') character set utf8"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; set names default; deallocate prepare stmt;
mysql-test/t/ps.test +29 −0 Original line number Diff line number Diff line Loading @@ -718,4 +718,33 @@ set @@tx_isolation=default; execute stmt; deallocate prepare stmt; # # Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP" # # Part I. Make sure the typelib for ENUM is created in the statement memory # root. prepare stmt from "create temporary table t1 (letter enum('','a','b','c') not null)"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; # Part II. Make sure that when the default value is converted to UTF-8, # the new item is # created in the statement memory root. set names latin1; prepare stmt from "create table t1 (a enum('test') default 'test') character set utf8"; execute stmt; drop table t1; execute stmt; drop table t1; execute stmt; drop table t1; # Cleanup set names default; deallocate prepare stmt; # End of 4.1 tests
sql/mysql_priv.h +1 −1 Original line number Diff line number Diff line Loading @@ -1119,7 +1119,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week); uint calc_week(TIME *l_time, uint week_behaviour, uint *year); void find_date(char *pos,uint *vek,uint flag); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); TYPELIB *typelib(List<String> &strings); TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); Loading
sql/sql_table.cc +25 −4 Original line number Diff line number Diff line Loading @@ -524,7 +524,14 @@ 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++) Loading @@ -534,7 +541,7 @@ 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); char *buf= (char*) sql_alloc(conv.length()+1); char *buf= (char*) alloc_root(stmt_root, conv.length()+1); memcpy(buf, conv.ptr(), conv.length()); buf[conv.length()]= '\0'; interval->type_names[i]= buf; Loading @@ -556,8 +563,22 @@ 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->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); Loading
sql/table.cc +3 −3 Original line number Diff line number Diff line Loading @@ -1099,15 +1099,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, } /* fix_type_pointers */ TYPELIB *typelib(List<String> &strings) TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings) { TYPELIB *result=(TYPELIB*) sql_alloc(sizeof(TYPELIB)); TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); if (!result) return 0; result->count=strings.elements; result->name=""; uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1); if (!(result->type_names= (const char**) sql_alloc(nbytes))) if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes))) return 0; result->type_lengths= (uint*) (result->type_names + result->count + 1); List_iterator<String> it(strings); Loading