From 9381c8a0896bcb67ce9be44463456313d485ad00 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Apr 2006 12:17:57 +0200 Subject: [PATCH 1/2] Fixed BUG#18787: Server crashed when calling a stored procedure containing a misnamed function ... in the presence of a continue handler. The problem was that with a handler, it continued to execute as if function existed and had set a useful return value (which it hadn't). The fix is to set a null return value and do an error return when a function wasn't found. mysql-test/r/sp.result: Updated results for a new test case (BUG#18787). mysql-test/t/sp.test: New testcase for BUG#18787. sql/item_func.cc: Don't set "out of resources" error in Item_func_sp::execute() if no result field is returned, it's simply wrong, it can be sometthing else, like a function not found. Instead set null_value and return error. Also, set "out of resources" when field creation fails in Item_func_sp::sp_result_field() and Item_func_sp::tmp_table_field(). --- mysql-test/r/sp.result | 10 ++++++++++ mysql-test/t/sp.test | 18 ++++++++++++++++++ sql/item_func.cc | 12 +++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 3e139f8cce5..df68bd13c9f 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -4837,4 +4837,14 @@ c 2 b 3 a 1 delete from t1| +drop procedure if exists bug18787| +create procedure bug18787() +begin +declare continue handler for sqlexception begin end; +select no_such_function(); +end| +call bug18787()| +no_such_function() +NULL +drop procedure bug18787| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 9e1afa53149..a5eeccfb8bd 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -5683,6 +5683,24 @@ select * from t1 order by @x| delete from t1| +# +# BUG#18787: Server crashed when calling a stored procedure containing +# a misnamed function +# +--disable_warnings +drop procedure if exists bug18787| +--enable_warnings +create procedure bug18787() +begin + declare continue handler for sqlexception begin end; + + select no_such_function(); +end| + +call bug18787()| +drop procedure bug18787| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/item_func.cc b/sql/item_func.cc index f40f868f75f..8d30fafbe63 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4722,7 +4722,9 @@ Item_func_sp::sp_result_field(void) const share->table_cache_key = empty_name; share->table_name = empty_name; } - field= m_sp->create_result_field(max_length, name, dummy_table); + if (!(field= m_sp->create_result_field(max_length, name, dummy_table))) + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + DBUG_RETURN(field); } @@ -4750,8 +4752,9 @@ Item_func_sp::execute(Field **flp) { if (!(*flp= f= sp_result_field())) { - my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); - return 0; + /* Error set by sp_result_field() */ + null_value= 1; + return TRUE; } f->move_field((f->pack_length() > sizeof(result_buf)) ? @@ -4915,6 +4918,9 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) if (!res) res= Item_func::tmp_table_field(t_arg); + if (!res) + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + DBUG_RETURN(res); } From d9142f992ee5c60a487cb631594ff27352df7f64 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Apr 2006 11:16:39 +0200 Subject: [PATCH 2/2] Post-review fix for BUG#18787. Renamed a local variable in Item_func_sp::tmp_table_field() to something more descriptive. sql/item_func.cc: Renamed local variable 'res' to 'field' in Item_func_sp::tmp_table_field(), because it is. --- sql/item_func.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index 8d30fafbe63..32b1075c99a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4909,19 +4909,19 @@ longlong Item_func_found_rows::val_int() Field * Item_func_sp::tmp_table_field(TABLE *t_arg) { - Field *res= 0; + Field *field= 0; DBUG_ENTER("Item_func_sp::tmp_table_field"); if (m_sp) - res= m_sp->create_result_field(max_length, (const char*) name, t_arg); + field= m_sp->create_result_field(max_length, (const char*) name, t_arg); - if (!res) - res= Item_func::tmp_table_field(t_arg); + if (!field) + field= Item_func::tmp_table_field(t_arg); - if (!res) + if (!field) my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); - DBUG_RETURN(res); + DBUG_RETURN(field); }