summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp-error.result41
-rw-r--r--mysql-test/t/sp-error.test50
-rw-r--r--sql/share/errmsg.txt3
-rw-r--r--sql/sp_pcontext.cc37
-rw-r--r--sql/sp_pcontext.h10
-rw-r--r--sql/sql_yacc.yy36
6 files changed, 170 insertions, 7 deletions
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 42e45f67d33..b9d33bbe606 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -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|
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 90c776a8b88..a02d2ff6733 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -743,6 +743,56 @@ 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
#
#--disable_warnings
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 2ef2555753d..95fb1736741 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -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"
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 15d3f87ff29..26f576233f3 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -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)
{
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 42d8140b78c..dbce191975a 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -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
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 9266ab69790..9ff7f4449b2 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1774,19 +1774,43 @@ 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;
- i->add_condition($1);
- $$= 1;
+ 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;
- i->add_condition($3);
- $$= $1 + 1;
+ 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;
+ }
}
;