Commit fc5db935 authored by unknown's avatar unknown

Fixed BUG#9073: Able to declare two handlers for same condition in same scope


mysql-test/r/sp-error.result:
  Added test case for BUG#9073.
mysql-test/t/sp-error.test:
  Added test case for BUG#9073.
sql/share/errmsg.txt:
  New error message for duplicate condition handlers in stored procedures.
sql/sp_pcontext.cc:
  Keep track on condition handlers in the same block for error checking.
sql/sp_pcontext.h:
  Keep track on condition handlers in the same block for error checking.
sql/sql_yacc.yy:
  Keep track on condition handlers in the same block for error checking.
parent 45279423
......@@ -526,4 +526,45 @@ delete from t1|
call bug7299()|
ERROR 02000: No data to FETCH
drop procedure bug7299|
create procedure bug9073()
begin
declare continue handler for sqlexception select 1;
declare continue handler for sqlexception select 2;
end|
ERROR 42000: Duplicate handler declared in the same block
create procedure bug9073()
begin
declare condname1 condition for 1234;
declare continue handler for condname1 select 1;
declare exit handler for condname1 select 2;
end|
ERROR 42000: Duplicate handler declared in the same block
create procedure bug9073()
begin
declare condname1 condition for sqlstate '42000';
declare condname2 condition for sqlstate '42000';
declare exit handler for condname1 select 1;
declare continue handler for condname2 select 2;
end|
ERROR 42000: Duplicate handler declared in the same block
create procedure bug9073()
begin
declare condname1 condition for sqlstate '42000';
declare exit handler for condname1 select 1;
declare exit handler for sqlstate '42000' select 2;
end|
ERROR 42000: Duplicate handler declared in the same block
drop procedure if exists bug9073|
create procedure bug9073()
begin
declare condname1 condition for sqlstate '42000';
declare continue handler for condname1 select 1;
begin
declare exit handler for sqlstate '42000' select 2;
begin
declare continue handler for sqlstate '42000' select 3;
end;
end;
end|
drop procedure bug9073|
drop table t1|
......@@ -742,6 +742,56 @@ call bug7299()|
drop procedure bug7299|
#
# BUG#9073: Able to declare two handlers for same condition in same scope
#
--error ER_SP_DUP_HANDLER
create procedure bug9073()
begin
declare continue handler for sqlexception select 1;
declare continue handler for sqlexception select 2;
end|
--error ER_SP_DUP_HANDLER
create procedure bug9073()
begin
declare condname1 condition for 1234;
declare continue handler for condname1 select 1;
declare exit handler for condname1 select 2;
end|
--error ER_SP_DUP_HANDLER
create procedure bug9073()
begin
declare condname1 condition for sqlstate '42000';
declare condname2 condition for sqlstate '42000';
declare exit handler for condname1 select 1;
declare continue handler for condname2 select 2;
end|
--error ER_SP_DUP_HANDLER
create procedure bug9073()
begin
declare condname1 condition for sqlstate '42000';
declare exit handler for condname1 select 1;
declare exit handler for sqlstate '42000' select 2;
end|
# This should still work.
--disable_warnings
drop procedure if exists bug9073|
--enable_warnings
create procedure bug9073()
begin
declare condname1 condition for sqlstate '42000';
declare continue handler for condname1 select 1;
begin
declare exit handler for sqlstate '42000' select 2;
begin
declare continue handler for sqlstate '42000' select 3;
end;
end;
end|
drop procedure bug9073|
#
# BUG#NNNN: New bug synopsis
#
......
......@@ -5338,4 +5338,5 @@ ER_WRONG_VALUE_FOR_TYPE
eng "Incorrect %-.32s value: '%-.128s' for function %-.32s"
ER_TABLE_DEF_CHANGED
eng "Table definition has changed, please retry transaction"
ER_SP_DUP_HANDLER 42000
eng "Duplicate handler declared in the same block"
......@@ -57,6 +57,7 @@ sp_pcontext::sp_pcontext(sp_pcontext *prev)
VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8));
VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8));
VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8));
VOID(my_init_dynamic_array(&m_handler, sizeof(sp_cond_type_t *), 16, 8));
m_label.empty();
m_children.empty();
if (!prev)
......@@ -82,6 +83,7 @@ sp_pcontext::destroy()
delete_dynamic(&m_pvar);
delete_dynamic(&m_cond);
delete_dynamic(&m_cursor);
delete_dynamic(&m_handler);
}
sp_pcontext *
......@@ -258,6 +260,41 @@ sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped)
return NULL;
}
/*
* This only searches the current context, for error checking of
* duplicates.
* Returns TRUE if found.
*/
bool
sp_pcontext::find_handler(sp_cond_type_t *cond)
{
uint i= m_handler.elements;
while (i--)
{
sp_cond_type_t *p;
get_dynamic(&m_handler, (gptr)&p, i);
if (cond->type == p->type)
{
switch (p->type)
{
case sp_cond_type_t::number:
if (cond->mysqlerr == p->mysqlerr)
return TRUE;
break;
case sp_cond_type_t::state:
if (strcmp(cond->sqlstate, p->sqlstate) == 0)
return TRUE;
break;
default:
return TRUE;
}
}
}
return FALSE;
}
void
sp_pcontext::push_cursor(LEX_STRING *name)
{
......
......@@ -241,6 +241,15 @@ class sp_pcontext : public Sql_alloc
m_handlers+= 1;
}
inline void
push_handler(sp_cond_type_t *cond)
{
insert_dynamic(&m_handler, (gptr)&cond);
}
bool
find_handler(sp_cond_type *cond);
inline uint
max_handlers()
{
......@@ -293,6 +302,7 @@ private:
DYNAMIC_ARRAY m_pvar; // Parameters/variables
DYNAMIC_ARRAY m_cond; // Conditions
DYNAMIC_ARRAY m_cursor; // Cursors
DYNAMIC_ARRAY m_handler; // Handlers, for checking of duplicates
List<sp_label_t> m_label; // The label list
......
......@@ -1774,20 +1774,44 @@ sp_hcond_list:
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction();
sp_pcontext *ctx= lex->spcont;
if (ctx->find_handler($1))
{
my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0));
YYABORT;
}
else
{
sp_instr_hpush_jump *i=
(sp_instr_hpush_jump *)sp->last_instruction();
i->add_condition($1);
ctx->push_handler($1);
$$= 1;
}
}
| sp_hcond_list ',' sp_hcond
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction();
sp_pcontext *ctx= lex->spcont;
if (ctx->find_handler($3))
{
my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0));
YYABORT;
}
else
{
sp_instr_hpush_jump *i=
(sp_instr_hpush_jump *)sp->last_instruction();
i->add_condition($3);
ctx->push_handler($3);
$$= $1 + 1;
}
}
;
sp_cond:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment