Backport of Bug#15192 to mysql-next-mr

------------------------------------------------------------
revno: 2597.4.17
revision-id: sp1r-davi@mysql.com/endora.local-20080328174753-24337
parent: sp1r-anozdrin/alik@quad.opbmk-20080328140038-16479
committer: davi@mysql.com/endora.local
timestamp: Fri 2008-03-28 14:47:53 -0300
message:
  Bug#15192 "fatal errors" are caught by handlers in stored procedures

  The problem is that fatal errors (e.g.: out of memory) were being
  caught by stored procedure exception handlers which could cause
  the execution to not be stopped due to a continue handler.

  The solution is to not call any exception handler if the error is
  fatal and send the fatal error to the client.

mysql-test/r/sp-error.result:
  Add test case result for Bug#15192
mysql-test/t/sp-error.test:
  Add test case for Bug#15192
mysys/my_alloc.c:
  Pass flag to signal fatal error in memory root allocations.
sql/event_data_objects.cc:
  Use init_sql_alloc to initialize memory roots, which uses
  the sql error handler to push errors.
sql/ha_partition.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/item_func.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/item_subselect.cc:
  Remove redundant fatal error, memory root already pushes error.
sql/opt_sum.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sp_head.cc:
  Allocator already sets fatal error.
sql/sql_class.h:
  A error must exist for it to be fatal. Pass flag to signal fatal
  error instead of calling fatal_error.
sql/sql_insert.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sql_list.h:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sql_parse.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sql_partition.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sql_select.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sql_servers.cc:
  Use init_sql_alloc to initialize memory roots, which uses
  the sql error handler to push errors.
sql/sql_show.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/sql_trigger.cc:
  Use init_sql_alloc to initialize memory roots, which uses
  the sql error handler to push errors.
sql/sql_update.cc:
  Pass flag to signal fatal error instead of calling fatal_error.
sql/tztime.cc:
  Use init_sql_alloc to initialize memory roots, which uses
  the sql error handler to push errors.
This commit is contained in:
Davi Arnaut 2009-11-10 18:31:28 -02:00
parent 17871ade9a
commit e879919a9f
20 changed files with 80 additions and 70 deletions

View File

@ -1659,6 +1659,17 @@ begin
declare continue handler for sqlstate '00000' set @x=0; declare continue handler for sqlstate '00000' set @x=0;
end$$ end$$
ERROR 42000: Bad SQLSTATE: '00000' ERROR 42000: Bad SQLSTATE: '00000'
drop procedure if exists p1;
set @old_recursion_depth = @@max_sp_recursion_depth;
set @@max_sp_recursion_depth = 255;
create procedure p1(a int)
begin
declare continue handler for sqlexception select 'exception';
call p1(a+1);
end|
call p1(1);
set @@max_sp_recursion_depth = @old_recursion_depth;
drop procedure p1;
LOAD DATA INFILE '../../tmp/proc.txt' INTO TABLE mysql.proc; LOAD DATA INFILE '../../tmp/proc.txt' INTO TABLE mysql.proc;
CREATE TABLE t1 (a INT, b INT); CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);

View File

@ -2420,6 +2420,27 @@ end$$
delimiter ;$$ delimiter ;$$
#
# Bug#15192: "fatal errors" are caught by handlers in stored procedures
#
--disable_warnings
drop procedure if exists p1;
--enable_warnings
set @old_recursion_depth = @@max_sp_recursion_depth;
set @@max_sp_recursion_depth = 255;
delimiter |;
create procedure p1(a int)
begin
declare continue handler for sqlexception select 'exception';
call p1(a+1);
end|
delimiter ;|
--error 0,ER_STACK_OVERRUN_NEED_MORE
call p1(1);
set @@max_sp_recursion_depth = @old_recursion_depth;
drop procedure p1;
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #

View File

@ -155,7 +155,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
DBUG_ASSERT(alloc_root_inited(mem_root)); DBUG_ASSERT(alloc_root_inited(mem_root));
length+=ALIGN_SIZE(sizeof(USED_MEM)); length+=ALIGN_SIZE(sizeof(USED_MEM));
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME)))) if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
{ {
if (mem_root->error_handler) if (mem_root->error_handler)
(*mem_root->error_handler)(); (*mem_root->error_handler)();
@ -198,7 +198,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
get_size= length+ALIGN_SIZE(sizeof(USED_MEM)); get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
get_size= max(get_size, block_size); get_size= max(get_size, block_size);
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME)))) if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR))))
{ {
if (mem_root->error_handler) if (mem_root->error_handler)
(*mem_root->error_handler)(); (*mem_root->error_handler)();

View File

@ -196,7 +196,7 @@ Event_basic::Event_basic()
{ {
DBUG_ENTER("Event_basic::Event_basic"); DBUG_ENTER("Event_basic::Event_basic");
/* init memory root */ /* init memory root */
init_alloc_root(&mem_root, 256, 512); init_sql_alloc(&mem_root, 256, 512);
dbname.str= name.str= NULL; dbname.str= name.str= NULL;
dbname.length= name.length= 0; dbname.length= name.length= 0;
time_zone= NULL; time_zone= NULL;

View File

@ -1980,8 +1980,7 @@ partition_element *ha_partition::find_partition_element(uint part_id)
return part_elem; return part_elem;
} }
DBUG_ASSERT(0); DBUG_ASSERT(0);
my_error(ER_OUT_OF_RESOURCES, MYF(0)); my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
current_thd->fatal_error(); // Abort
return NULL; return NULL;
} }

View File

@ -3818,7 +3818,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size; uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
if (!my_hash_inited(hash)) if (!my_hash_inited(hash))
return 0; return 0;
if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME)))) if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
return 0; return 0;
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+ entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
extra_size; extra_size;
@ -3956,6 +3956,8 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
@param dv derivation for new value @param dv derivation for new value
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned @param unsigned_arg indiates if a value of type INT_RESULT is unsigned
@note Sets error and fatal error if allocation fails.
@retval @retval
false success false success
@retval @retval
@ -3999,7 +4001,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
if (entry->value == pos) if (entry->value == pos)
entry->value=0; entry->value=0;
entry->value= (char*) my_realloc(entry->value, length, entry->value= (char*) my_realloc(entry->value, length,
MYF(MY_ALLOW_ZERO_PTR | MY_WME)); MYF(MY_ALLOW_ZERO_PTR | MY_WME |
ME_FATALERROR));
if (!entry->value) if (!entry->value)
return 1; return 1;
} }
@ -4036,7 +4039,6 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
if (::update_hash(entry, (null_value= args[0]->null_value), if (::update_hash(entry, (null_value= args[0]->null_value),
ptr, length, res_type, cs, dv, unsigned_arg)) ptr, length, res_type, cs, dv, unsigned_arg))
{ {
current_thd->fatal_error(); // Probably end of memory
null_value= 1; null_value= 1;
return 1; return 1;
} }
@ -4769,11 +4771,6 @@ void Item_func_get_user_var::fix_length_and_dec()
m_cached_result_type= STRING_RESULT; m_cached_result_type= STRING_RESULT;
max_length= MAX_BLOB_WIDTH; max_length= MAX_BLOB_WIDTH;
} }
if (error)
thd->fatal_error();
return;
} }
@ -4857,18 +4854,16 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs) void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
{ {
if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, ::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
current_thd->fatal_error(); // Probably end of memory
} }
void Item_user_var_as_out_param::set_value(const char *str, uint length, void Item_user_var_as_out_param::set_value(const char *str, uint length,
CHARSET_INFO* cs) CHARSET_INFO* cs)
{ {
if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs, ::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
current_thd->fatal_error(); // Probably end of memory
} }

View File

@ -1735,8 +1735,6 @@ subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
:subselect_engine(item_arg, result_arg) :subselect_engine(item_arg, result_arg)
{ {
unit= u; unit= u;
if (!result_arg) //out of memory
current_thd->fatal_error();
unit->item= item_arg; unit->item= item_arg;
} }
@ -1748,10 +1746,7 @@ int subselect_single_select_engine::prepare()
join= new JOIN(thd, select_lex->item_list, join= new JOIN(thd, select_lex->item_list,
select_lex->options | SELECT_NO_UNLOCK, result); select_lex->options | SELECT_NO_UNLOCK, result);
if (!join || !result) if (!join || !result)
{ return 1; /* Fatal error is set already. */
thd->fatal_error(); //out of memory
return 1;
}
prepared= 1; prepared= 1;
SELECT_LEX *save_select= thd->lex->current_select; SELECT_LEX *save_select= thd->lex->current_select;
thd->lex->current_select= select_lex; thd->lex->current_select= select_lex;

View File

@ -175,8 +175,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
if(error) if(error)
{ {
tl->table->file->print_error(error, MYF(0)); tl->table->file->print_error(error, MYF(ME_FATALERROR));
tl->table->in_use->fatal_error();
return error; return error;
} }
count*= tl->table->file->stats.records; count*= tl->table->file->stats.records;
@ -427,8 +426,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
/* HA_ERR_LOCK_DEADLOCK or some other error */ /* HA_ERR_LOCK_DEADLOCK or some other error */
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(ME_FATALERROR));
table->in_use->fatal_error();
return(error); return(error);
} }
removed_tables|= table->map; removed_tables|= table->map;

View File

@ -4012,10 +4012,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
TABLE_LIST *table; TABLE_LIST *table;
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST)))) if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
{
thd->fatal_error();
return NULL; return NULL;
}
table->db_length= strlen(db); table->db_length= strlen(db);
table->db= thd->strmake(db, table->db_length); table->db= thd->strmake(db, table->db_length);
table->table_name_length= strlen(name); table->table_name_length= strlen(name);

View File

@ -1978,6 +1978,7 @@ public:
*/ */
inline void fatal_error() inline void fatal_error()
{ {
DBUG_ASSERT(main_da.is_error());
is_fatal_error= 1; is_fatal_error= 1;
DBUG_PRINT("error",("Fatal error set")); DBUG_PRINT("error",("Fatal error set"));
} }
@ -2139,7 +2140,10 @@ public:
else else
{ {
x_free(db); x_free(db);
db= new_db ? my_strndup(new_db, new_db_len, MYF(MY_WME)) : NULL; if (new_db)
db= my_strndup(new_db, new_db_len, MYF(MY_WME | ME_FATALERROR));
else
db= NULL;
} }
db_length= db ? new_db_len : 0; db_length= db ? new_db_len : 0;
return new_db && !db; return new_db && !db;

View File

@ -1922,20 +1922,17 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
if (! (di= find_handler(thd, table_list))) if (! (di= find_handler(thd, table_list)))
{ {
if (!(di= new Delayed_insert())) if (!(di= new Delayed_insert()))
{
thd->fatal_error();
goto end_create; goto end_create;
}
pthread_mutex_lock(&LOCK_thread_count); pthread_mutex_lock(&LOCK_thread_count);
thread_count++; thread_count++;
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
di->thd.set_db(table_list->db, (uint) strlen(table_list->db)); di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0); di->thd.set_query(my_strdup(table_list->table_name,
MYF(MY_WME | ME_FATALERROR)), 0);
if (di->thd.db == NULL || di->thd.query == NULL) if (di->thd.db == NULL || di->thd.query == NULL)
{ {
/* The error is reported */ /* The error is reported */
delete di; delete di;
thd->fatal_error();
goto end_create; goto end_create;
} }
di->table_list= *table_list; // Needed to open table di->table_list= *table_list; // Needed to open table
@ -1953,8 +1950,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_unlock(&di->mutex); pthread_mutex_unlock(&di->mutex);
di->unlock(); di->unlock();
delete di; delete di;
my_error(ER_CANT_CREATE_THREAD, MYF(0), error); my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error);
thd->fatal_error();
goto end_create; goto end_create;
} }
@ -2331,8 +2327,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
} }
if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED)) if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
{ {
thd->fatal_error(); my_error(ER_DELAYED_NOT_SUPPORTED, MYF(ME_FATALERROR),
my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), di->table_list.table_name); di->table_list.table_name);
goto err; goto err;
} }
if (di->table->triggers) if (di->table->triggers)

View File

@ -458,7 +458,7 @@ struct ilink
struct ilink **prev,*next; struct ilink **prev,*next;
static void *operator new(size_t size) throw () static void *operator new(size_t size) throw ()
{ {
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR));
} }
static void operator delete(void* ptr_arg, size_t size) static void operator delete(void* ptr_arg, size_t size)
{ {

View File

@ -5823,7 +5823,6 @@ bool check_stack_overrun(THD *thd, long margin,
my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE), my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
stack_used, my_thread_stack_size, margin); stack_used, my_thread_stack_size, margin);
my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
thd->fatal_error();
return 1; return 1;
} }
#ifndef DBUG_OFF #ifndef DBUG_OFF

View File

@ -2084,8 +2084,7 @@ char *generate_partition_syntax(partition_info *part_info,
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
/* We really shouldn't get here, no use in continuing from here */ /* We really shouldn't get here, no use in continuing from here */
my_error(ER_OUT_OF_RESOURCES, MYF(0)); my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
current_thd->fatal_error();
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (part_info->part_expr) if (part_info->part_expr)
@ -5150,10 +5149,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
&lpt->deleted, lpt->pack_frm_data, &lpt->deleted, lpt->pack_frm_data,
lpt->pack_frm_len))) lpt->pack_frm_len)))
{ {
if (error != ER_OUTOFMEMORY) file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR));
file->print_error(error, MYF(0));
else
lpt->thd->fatal_error();
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);

View File

@ -9628,7 +9628,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item_sum *item_sum=(Item_sum*) item; Item_sum *item_sum=(Item_sum*) item;
result= item_sum->create_tmp_field(group, table, convert_blob_length); result= item_sum->create_tmp_field(group, table, convert_blob_length);
if (!result) if (!result)
thd->fatal_error(); my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
return result; return result;
} }
case Item::FIELD_ITEM: case Item::FIELD_ITEM:
@ -10771,8 +10771,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
We don't want this error to be converted to a warning, e.g. in case of We don't want this error to be converted to a warning, e.g. in case of
INSERT IGNORE ... SELECT. INSERT IGNORE ... SELECT.
*/ */
thd->fatal_error(); table->file->print_error(error, MYF(ME_FATALERROR));
table->file->print_error(error,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -14930,8 +14929,7 @@ calc_group_buffer(JOIN *join,ORDER *group)
default: default:
/* This case should never be choosen */ /* This case should never be choosen */
DBUG_ASSERT(0); DBUG_ASSERT(0);
my_error(ER_OUT_OF_RESOURCES, MYF(0)); my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
join->thd->fatal_error();
} }
} }
parts++; parts++;

View File

@ -128,7 +128,7 @@ bool servers_init(bool dont_read_servers_table)
} }
/* Initialize the mem root for data */ /* Initialize the mem root for data */
init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
if (dont_read_servers_table) if (dont_read_servers_table)
goto end; goto end;
@ -180,7 +180,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
my_hash_reset(&servers_cache); my_hash_reset(&servers_cache);
free_root(&mem, MYF(0)); free_root(&mem, MYF(0));
init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0,
FALSE); FALSE);

View File

@ -4960,8 +4960,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
break; break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
my_error(ER_OUT_OF_RESOURCES, MYF(0)); my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
current_thd->fatal_error();
DBUG_RETURN(1); DBUG_RETURN(1);
} }
table->field[7]->set_notnull(); table->field[7]->set_notnull();

View File

@ -1660,7 +1660,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
DBUG_ENTER("drop_all_triggers"); DBUG_ENTER("drop_all_triggers");
bzero(&table, sizeof(table)); bzero(&table, sizeof(table));
init_alloc_root(&table.mem_root, 8192, 0); init_sql_alloc(&table.mem_root, 8192, 0);
if (Table_triggers_list::check_n_load(thd, db, name, &table, 1)) if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
{ {
@ -1871,7 +1871,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
DBUG_ENTER("change_table_name"); DBUG_ENTER("change_table_name");
bzero(&table, sizeof(table)); bzero(&table, sizeof(table));
init_alloc_root(&table.mem_root, 8192, 0); init_sql_alloc(&table.mem_root, 8192, 0);
/* /*
This method interfaces the mysql server code protected by This method interfaces the mysql server code protected by

View File

@ -662,11 +662,13 @@ int mysql_update(THD *thd,
If (ignore && error is ignorable) we don't have to If (ignore && error is ignorable) we don't have to
do anything; otherwise... do anything; otherwise...
*/ */
myf flags= 0;
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
thd->fatal_error(); /* Other handler errors are fatal */ flags|= ME_FATALERROR; /* Other handler errors are fatal */
prepare_record_for_error_message(error, table); prepare_record_for_error_message(error, table);
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(flags));
error= 1; error= 1;
break; break;
} }
@ -763,9 +765,8 @@ int mysql_update(THD *thd,
*/ */
{ {
/* purecov: begin inspected */ /* purecov: begin inspected */
thd->fatal_error();
prepare_record_for_error_message(loc_error, table); prepare_record_for_error_message(loc_error, table);
table->file->print_error(loc_error,MYF(0)); table->file->print_error(loc_error,MYF(ME_FATALERROR));
error= 1; error= 1;
/* purecov: end */ /* purecov: end */
} }
@ -1737,11 +1738,13 @@ bool multi_update::send_data(List<Item> &not_used_values)
If (ignore && error == is ignorable) we don't have to If (ignore && error == is ignorable) we don't have to
do anything; otherwise... do anything; otherwise...
*/ */
myf flags= 0;
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
thd->fatal_error(); /* Other handler errors are fatal */ flags|= ME_FATALERROR; /* Other handler errors are fatal */
prepare_record_for_error_message(error, table); prepare_record_for_error_message(error, table);
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(flags));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
@ -2024,9 +2027,8 @@ int multi_update::do_updates()
err: err:
{ {
thd->fatal_error();
prepare_record_for_error_message(local_error, table); prepare_record_for_error_message(local_error, table);
table->file->print_error(local_error,MYF(0)); table->file->print_error(local_error,MYF(ME_FATALERROR));
} }
err2: err2:

View File

@ -1594,7 +1594,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
my_hash_free(&tz_names); my_hash_free(&tz_names);
goto end; goto end;
} }
init_alloc_root(&tz_storage, 32 * 1024, 0); init_sql_alloc(&tz_storage, 32 * 1024, 0);
VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST)); VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST));
tz_inited= 1; tz_inited= 1;