From 85f19d5da53b842d4e68a7b2a5eac64aa7b655d2 Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Wed, 1 Jun 2005 12:18:41 +0200 Subject: [PATCH 1/2] Fixed BUG#10961: Stored procedures: crash if select * from dual Have to catch errors from SELECT when opening a cursor. --- mysql-test/r/sp.result | 29 +++++++++++++++++++++++++++++ mysql-test/t/sp.test | 29 +++++++++++++++++++++++++++++ sql/protocol.h | 4 ++-- sql/sp_head.cc | 14 +++++++++++++- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index da54c100178..3c6fa84882f 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3109,4 +3109,33 @@ select bug9559()| bug9559() -3 drop function bug9559| +drop procedure if exists bug10961| +create procedure bug10961() +begin +declare v char; +declare x int; +declare c cursor for select * from dual; +declare continue handler for sqlexception select x; +set x = 1; +open c; +set x = 2; +fetch c into v; +set x = 3; +close c; +end| +call bug10961()| +x +1 +x +2 +x +3 +call bug10961()| +x +1 +x +2 +x +3 +drop procedure bug10961| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 18389f4d80a..7acd4d81081 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3801,6 +3801,7 @@ call bug5963_2(1)| drop procedure bug5963_2| drop table t3| + # # BUG#9559: Functions: Numeric Operations using -ve value gives incorrect # results. @@ -3820,6 +3821,34 @@ select bug9559()| drop function bug9559| +# +# BUG#10961: Stored procedures: crash if select * from dual +# +--disable_warnings +drop procedure if exists bug10961| +--enable_warnings +# "select * from dual" results in an error, so the cursor will not open +create procedure bug10961() +begin + declare v char; + declare x int; + declare c cursor for select * from dual; + declare continue handler for sqlexception select x; + + set x = 1; + open c; + set x = 2; + fetch c into v; + set x = 3; + close c; +end| + +call bug10961()| +call bug10961()| + +drop procedure bug10961| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/protocol.h b/sql/protocol.h index 01331ef64ba..5b402cb2669 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -159,8 +159,8 @@ public: MYSQL_ROWS **prev_record; ulong row_count; - Protocol_cursor() {} - Protocol_cursor(THD *thd_arg, MEM_ROOT *ini_alloc) :Protocol_simple(thd_arg), alloc(ini_alloc) {} + Protocol_cursor() :data(NULL) {} + Protocol_cursor(THD *thd_arg, MEM_ROOT *ini_alloc) :Protocol_simple(thd_arg), alloc(ini_alloc), data(NULL) {} bool prepare_for_send(List *item_list) { row_count= 0; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fcca1b51d1c..c17c8b81cb2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1913,7 +1913,19 @@ sp_instr_copen::execute(THD *thd, uint *nextp) else res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this); - c->post_open(thd, (lex_keeper ? TRUE : FALSE)); + /* + Work around the fact that errors in selects are not returned properly + (but instead converted into a warning), so if a condition handler + caught, we have lost the result code. + */ + if (!res) + { + uint dummy1, dummy2; + + if (thd->spcont->found_handler(&dummy1, &dummy2)) + res= -1; + } + c->post_open(thd, (lex_keeper && !res ? TRUE : FALSE)); } DBUG_RETURN(res); From 5afef58364d444f0b222c6e01d785335c7301815 Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Wed, 1 Jun 2005 15:42:40 +0200 Subject: [PATCH 2/2] Fixed BUG#10969: Stored procedures: crash if default() function Return an error if default() is used on a local variable. This is actaully a side-effect of BUG#5967: Stored procedure declared variable used instead of column (to be fixed later), so this is really a workaround until that is fixed. --- mysql-test/r/sp-error.result | 13 +++++++++++++ mysql-test/t/sp-error.test | 23 +++++++++++++++++++++++ sql/item.h | 7 +++++++ sql/sql_yacc.yy | 13 ++++++++++++- 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ccdb46f10d0..1dc97124a07 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -658,4 +658,17 @@ create procedure bug9529_9012345678901234567890123456789012345678901234567890123 begin end| ERROR 42000: Identifier name 'bug9529_90123456789012345678901234567890123456789012345678901234567890' is too long +drop procedure if exists bug10969| +create procedure bug10969() +begin +declare s1 int default 0; +select default(s1) from t30; +end| +ERROR 42000: Incorrect column name 's1' +create procedure bug10969() +begin +declare s1 int default 0; +select default(t30.s1) from t30; +end| +drop procedure bug10969| drop table t1| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index a2a43110b54..891e282e335 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -930,6 +930,29 @@ begin end| +# +# BUG#10969: Stored procedures: crash if default() function +# +--disable_warnings +drop procedure if exists bug10969| +--enable_warnings +--error ER_WRONG_COLUMN_NAME +create procedure bug10969() +begin + declare s1 int default 0; + select default(s1) from t30; +end| + +# This should work +create procedure bug10969() +begin + declare s1 int default 0; + select default(t30.s1) from t30; +end| + +drop procedure bug10969| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/item.h b/sql/item.h index 18b419dd6d5..f2e8e582780 100644 --- a/sql/item.h +++ b/sql/item.h @@ -584,6 +584,13 @@ public: Item::maybe_null= TRUE; } + /* For error printing */ + inline void my_name(char **strp, uint *lengthp) + { + *strp= m_name.str; + *lengthp= m_name.length; + } + bool is_splocal() { return 1; } /* Needed for error checking */ Item *this_item(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 708dcb7a0d9..861216ebc96 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4343,7 +4343,18 @@ simple_expr: | CONVERT_SYM '(' expr USING charset_name ')' { $$= new Item_func_conv_charset($3,$5); } | DEFAULT '(' simple_ident ')' - { $$= new Item_default_value($3); } + { + if ($3->is_splocal()) + { + LEX_STRING name; + Item_splocal *il= static_cast($3); + + il->my_name(&name.str, &name.length); + my_error(ER_WRONG_COLUMN_NAME, MYF(0), name.str); + YYABORT; + } + $$= new Item_default_value($3); + } | VALUES '(' simple_ident ')' { $$= new Item_insert_value($3); } | FUNC_ARG0 '(' ')'