mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fixed BUG#6029: Stored procedure specific handlers should have priority.
mysql-test/r/sp.result: New test case for BUG#6022. mysql-test/t/sp.test: New test case for BUG#6022. sql/sp_rcontext.cc: Find the most specific condition handler, not just the first one. (And corrected the return type for find_handler) sql/sp_rcontext.h: Corrected return type for find_handler.
This commit is contained in:
@ -1947,6 +1947,26 @@ select bug6022(5)|
|
||||
bug6022(5)
|
||||
0
|
||||
drop function bug6022|
|
||||
drop procedure if exists bug6029|
|
||||
create procedure bug6029()
|
||||
begin
|
||||
declare exit handler for 1136 select '1136';
|
||||
declare exit handler for sqlstate '23000' select 'sqlstate 23000';
|
||||
declare continue handler for sqlexception select 'sqlexception';
|
||||
insert into t3 values (1);
|
||||
insert into t3 values (1,2);
|
||||
end|
|
||||
create table t3 (s1 int, primary key (s1))|
|
||||
insert into t3 values (1)|
|
||||
call bug6029()|
|
||||
sqlstate 23000
|
||||
sqlstate 23000
|
||||
delete from t3|
|
||||
call bug6029()|
|
||||
1136
|
||||
1136
|
||||
drop procedure bug6029|
|
||||
drop table t3|
|
||||
drop table if exists fac|
|
||||
create table fac (n int unsigned not null primary key, f bigint unsigned)|
|
||||
create procedure ifac(n int unsigned)
|
||||
|
@ -2109,6 +2109,32 @@ end|
|
||||
select bug6022(5)|
|
||||
drop function bug6022|
|
||||
|
||||
#
|
||||
# BUG#6029: Stored procedure specific handlers should have priority
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug6029|
|
||||
--enable_warnings
|
||||
|
||||
create procedure bug6029()
|
||||
begin
|
||||
declare exit handler for 1136 select '1136';
|
||||
declare exit handler for sqlstate '23000' select 'sqlstate 23000';
|
||||
declare continue handler for sqlexception select 'sqlexception';
|
||||
|
||||
insert into t3 values (1);
|
||||
insert into t3 values (1,2);
|
||||
end|
|
||||
|
||||
create table t3 (s1 int, primary key (s1))|
|
||||
insert into t3 values (1)|
|
||||
call bug6029()|
|
||||
delete from t3|
|
||||
call bug6029()|
|
||||
|
||||
drop procedure bug6029|
|
||||
drop table t3|
|
||||
|
||||
|
||||
#
|
||||
# Some "real" examples
|
||||
|
@ -56,7 +56,7 @@ sp_rcontext::set_item_eval(uint idx, Item *i, enum_field_types type)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
sp_rcontext::find_handler(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level)
|
||||
{
|
||||
@ -66,9 +66,9 @@ sp_rcontext::find_handler(uint sql_errno,
|
||||
return 1; // Already got one
|
||||
|
||||
const char *sqlstate= mysql_errno_to_sqlstate(sql_errno);
|
||||
int i= m_hcount, found= 0;
|
||||
int i= m_hcount, found= -1;
|
||||
|
||||
while (!found && i--)
|
||||
while (i--)
|
||||
{
|
||||
sp_cond_type_t *cond= m_handler[i].cond;
|
||||
|
||||
@ -76,31 +76,36 @@ sp_rcontext::find_handler(uint sql_errno,
|
||||
{
|
||||
case sp_cond_type_t::number:
|
||||
if (sql_errno == cond->mysqlerr)
|
||||
found= 1;
|
||||
found= i; // Always the most specific
|
||||
break;
|
||||
case sp_cond_type_t::state:
|
||||
if (strcmp(sqlstate, cond->sqlstate) == 0)
|
||||
found= 1;
|
||||
if (strcmp(sqlstate, cond->sqlstate) == 0 &&
|
||||
(found < 0 || m_handler[found].cond->type > sp_cond_type_t::number))
|
||||
found= i;
|
||||
break;
|
||||
case sp_cond_type_t::warning:
|
||||
if (sqlstate[0] == '0' && sqlstate[1] == '1' ||
|
||||
level == MYSQL_ERROR::WARN_LEVEL_WARN)
|
||||
found= 1;
|
||||
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= i;
|
||||
break;
|
||||
case sp_cond_type_t::notfound:
|
||||
if (sqlstate[0] == '0' && sqlstate[1] == '2')
|
||||
found= 1;
|
||||
if (sqlstate[0] == '0' && sqlstate[1] == '2' &&
|
||||
(found < 0 || m_handler[found].cond->type > sp_cond_type_t::state))
|
||||
found= i;
|
||||
break;
|
||||
case sp_cond_type_t::exception:
|
||||
if (sqlstate[0] != '0' || sqlstate[1] > '2' ||
|
||||
level == MYSQL_ERROR::WARN_LEVEL_ERROR)
|
||||
found= 1;
|
||||
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))
|
||||
found= i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
m_hfound= i;
|
||||
return found;
|
||||
if (found < 0)
|
||||
return FALSE;
|
||||
m_hfound= found;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -122,7 +122,7 @@ class sp_rcontext : public Sql_alloc
|
||||
}
|
||||
|
||||
// Returns 1 if a handler was found, 0 otherwise.
|
||||
int
|
||||
bool
|
||||
find_handler(uint sql_errno,MYSQL_ERROR::enum_warning_level level);
|
||||
|
||||
// Returns handler type and sets *ip to location if one was found
|
||||
|
Reference in New Issue
Block a user