mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
A fix and a test case for Bug#14410 "Crash in Enum or Set type in
CREATE TABLE and PS/SP": make sure that 'typelib' object for ENUM values and 'Item_string' object for DEFAULT clause are created in the statement memory root.
This commit is contained in:
@ -699,3 +699,22 @@ execute stmt;
|
|||||||
@@tx_isolation
|
@@tx_isolation
|
||||||
REPEATABLE-READ
|
REPEATABLE-READ
|
||||||
deallocate prepare stmt;
|
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;
|
||||||
|
@ -718,4 +718,33 @@ set @@tx_isolation=default;
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
deallocate prepare 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
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
@ -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);
|
uint calc_week(TIME *l_time, uint week_behaviour, uint *year);
|
||||||
void find_date(char *pos,uint *vek,uint flag);
|
void find_date(char *pos,uint *vek,uint flag);
|
||||||
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
|
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 get_form_pos(File file, uchar *head, TYPELIB *save_names);
|
||||||
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
|
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
|
||||||
const char *newname);
|
const char *newname);
|
||||||
|
@ -524,7 +524,14 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
*/
|
*/
|
||||||
if (!interval)
|
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);
|
List_iterator<String> it(sql_field->interval_list);
|
||||||
String conv, *tmp;
|
String conv, *tmp;
|
||||||
for (uint i= 0; (tmp= it++); i++)
|
for (uint i= 0; (tmp= it++); i++)
|
||||||
@ -534,7 +541,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
{
|
{
|
||||||
uint cnv_errs;
|
uint cnv_errs;
|
||||||
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &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());
|
memcpy(buf, conv.ptr(), conv.length());
|
||||||
buf[conv.length()]= '\0';
|
buf[conv.length()]= '\0';
|
||||||
interval->type_names[i]= buf;
|
interval->type_names[i]= buf;
|
||||||
@ -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 && cs != sql_field->def->collation.collation)
|
||||||
{
|
{
|
||||||
if (!(sql_field->def=
|
Item_arena backup_arena;
|
||||||
sql_field->def->safe_charset_converter(cs)))
|
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 */
|
/* Could not convert */
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
||||||
|
@ -1099,15 +1099,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
|
|||||||
} /* fix_type_pointers */
|
} /* 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)
|
if (!result)
|
||||||
return 0;
|
return 0;
|
||||||
result->count=strings.elements;
|
result->count=strings.elements;
|
||||||
result->name="";
|
result->name="";
|
||||||
uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
|
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;
|
return 0;
|
||||||
result->type_lengths= (uint*) (result->type_names + result->count + 1);
|
result->type_lengths= (uint*) (result->type_names + result->count + 1);
|
||||||
List_iterator<String> it(strings);
|
List_iterator<String> it(strings);
|
||||||
|
Reference in New Issue
Block a user