diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ff7d71b3384aafb65e40e4aa6962778db4380bf1..42e45f67d339266a345b28eb13133bc042caa094 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -513,4 +513,17 @@ call bug9566()| ERROR HY000: Table 'proc' was not locked with LOCK TABLES unlock tables| drop procedure bug9566| +drop procedure if exists bug7299| +create procedure bug7299() +begin +declare v int; +declare c cursor for select val from t1; +declare exit handler for sqlexception select 'Error!'; +open c; +fetch c into v; +end| +delete from t1| +call bug7299()| +ERROR 02000: No data to FETCH +drop procedure bug7299| drop table t1| diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index daad032b854b6be4f9b072e5526e09e233f8859c..36a4331c9bed4980e5f8c6472a4f88f568986af5 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2779,4 +2779,69 @@ a 3.2000 drop procedure bug8937| delete from t1| +drop procedure if exists bug6900| +drop procedure if exists bug9074| +drop procedure if exists bug6900_9074| +drop table if exists t3| +create table t3 (w char unique, x char)| +insert into t3 values ('a', 'b')| +create procedure bug6900() +begin +declare exit handler for sqlexception select '1'; +begin +declare exit handler for sqlexception select '2'; +insert into t3 values ('x', 'y', 'z'); +end; +end| +create procedure bug9074() +begin +declare x1, x2, x3, x4, x5, x6 int default 0; +begin +declare continue handler for sqlstate '23000' set x5 = 1; +insert into t3 values ('a', 'b'); +set x6 = 1; +end; +begin1_label: +begin +declare continue handler for sqlstate '23000' set x1 = 1; +insert into t3 values ('a', 'b'); +set x2 = 1; +begin2_label: +begin +declare exit handler for sqlstate '23000' set x3 = 1; +set x4= 1; +insert into t3 values ('a','b'); +set x4= 0; +end begin2_label; +end begin1_label; +select x1, x2, x3, x4, x5, x6; +end| +create procedure bug6900_9074(z int) +begin +declare exit handler for sqlstate '23000' select '23000'; +begin +declare exit handler for sqlexception select 'sqlexception'; +if z = 1 then +insert into t3 values ('a', 'b'); +else +insert into t3 values ('x', 'y', 'z'); +end if; +end; +end| +call bug6900()| +2 +2 +call bug9074()| +x1 x2 x3 x4 x5 x6 +1 1 1 1 1 1 +call bug6900_9074(0)| +sqlexception +sqlexception +call bug6900_9074(1)| +23000 +23000 +drop procedure bug6900| +drop procedure bug9074| +drop procedure bug6900_9074| +drop table t3| drop table t1,t2; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 51776453730df655d3aba682edae5362f939da12..90c776a8b887061600de933158bc0f33e64c9fdb 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -720,6 +720,28 @@ unlock tables| drop procedure bug9566| +# +# BUG#7299: Stored procedures: exception handler catches not-found conditions +# +--disable_warnings +drop procedure if exists bug7299| +--enable_warnings +create procedure bug7299() +begin + declare v int; + declare c cursor for select val from t1; + declare exit handler for sqlexception select 'Error!'; + + open c; + fetch c into v; +end| + +delete from t1| +--error ER_SP_FETCH_NO_DATA +call bug7299()| +drop procedure bug7299| + + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index a741a4af7d84908466adfaad998b039e07811354..69c7544ee7c1b252e48b5c8a92c0f93fa56d4ffe 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3398,6 +3398,89 @@ drop procedure bug8937| delete from t1| +# +# BUG#6900: Stored procedure inner handler ignored +# BUG#9074: STORED PROC: The scope of every handler declared is not +# properly applied +# +--disable_warnings +drop procedure if exists bug6900| +drop procedure if exists bug9074| +drop procedure if exists bug6900_9074| +drop table if exists t3| +--enable_warnings + +create table t3 (w char unique, x char)| +insert into t3 values ('a', 'b')| + +create procedure bug6900() +begin + declare exit handler for sqlexception select '1'; + + begin + declare exit handler for sqlexception select '2'; + + insert into t3 values ('x', 'y', 'z'); + end; +end| + +create procedure bug9074() +begin + declare x1, x2, x3, x4, x5, x6 int default 0; + + begin + declare continue handler for sqlstate '23000' set x5 = 1; + + insert into t3 values ('a', 'b'); + set x6 = 1; + end; + + begin1_label: + begin + declare continue handler for sqlstate '23000' set x1 = 1; + + insert into t3 values ('a', 'b'); + set x2 = 1; + + begin2_label: + begin + declare exit handler for sqlstate '23000' set x3 = 1; + + set x4= 1; + insert into t3 values ('a','b'); + set x4= 0; + end begin2_label; + end begin1_label; + + select x1, x2, x3, x4, x5, x6; +end| + +create procedure bug6900_9074(z int) +begin + declare exit handler for sqlstate '23000' select '23000'; + + begin + declare exit handler for sqlexception select 'sqlexception'; + + if z = 1 then + insert into t3 values ('a', 'b'); + else + insert into t3 values ('x', 'y', 'z'); + end if; + end; +end| + +call bug6900()| +call bug9074()| +call bug6900_9074(0)| +call bug6900_9074(1)| + +drop procedure bug6900| +drop procedure bug9074| +drop procedure bug6900_9074| +drop table t3| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 9b29c17385646aedc74b038a60f07918e4060e8d..d98cdfdd2265f4dc032fb05f96ac8b7b6190f282 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -80,24 +80,24 @@ sp_rcontext::find_handler(uint sql_errno, break; case sp_cond_type_t::state: if (strcmp(sqlstate, cond->sqlstate) == 0 && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::number)) + (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) found= i; break; case sp_cond_type_t::warning: if ((sqlstate[0] == '0' && sqlstate[1] == '1' || level == MYSQL_ERROR::WARN_LEVEL_WARN) && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) + found < 0) found= i; break; case sp_cond_type_t::notfound: if (sqlstate[0] == '0' && sqlstate[1] == '2' && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) + found < 0) found= i; break; case sp_cond_type_t::exception: - if ((sqlstate[0] != '0' || sqlstate[1] > '2' || - level == MYSQL_ERROR::WARN_LEVEL_ERROR) && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) + if ((sqlstate[0] != '0' || sqlstate[1] > '2') && + level == MYSQL_ERROR::WARN_LEVEL_ERROR && + found < 0) found= i; break; }