Manual merge

parent ec6c4fad
...@@ -1579,3 +1579,51 @@ drop function f2; ...@@ -1579,3 +1579,51 @@ drop function f2;
drop table t2; drop table t2;
ERROR 42S02: Unknown table 't2' ERROR 42S02: Unknown table 't2'
End of 5.1 tests End of 5.1 tests
drop procedure if exists proc_33983_a;
drop procedure if exists proc_33983_b;
drop procedure if exists proc_33983_c;
drop procedure if exists proc_33983_d;
create procedure proc_33983_a()
begin
label1:
begin
label2:
begin
select 1;
end label1;
end;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_b()
begin
label1:
repeat
label2:
repeat
select 1;
until FALSE end repeat label1;
until FALSE end repeat;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_c()
begin
label1:
while TRUE do
label2:
while TRUE do
select 1;
end while label1;
end while;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_d()
begin
label1:
loop
label2:
loop
select 1;
end loop label1;
end loop;
end|
ERROR 42000: End-label label1 without match
...@@ -6827,6 +6827,41 @@ SELECT @state, @exception; ...@@ -6827,6 +6827,41 @@ SELECT @state, @exception;
run NULL run NULL
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE bug29770; DROP PROCEDURE bug29770;
use test;
drop table if exists t_33618;
drop procedure if exists proc_33618;
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
create procedure proc_33618(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
call proc_33618(20);
drop table t_33618;
drop procedure proc_33618;
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# -- End of 5.0 tests # -- End of 5.0 tests
# ------------------------------------------------------------------ # ------------------------------------------------------------------
......
...@@ -2305,6 +2305,69 @@ drop table t2; ...@@ -2305,6 +2305,69 @@ drop table t2;
--echo End of 5.1 tests --echo End of 5.1 tests
#
# Bug#33983 (Stored Procedures: wrong end <label> syntax is accepted)
#
--disable_warnings
drop procedure if exists proc_33983_a;
drop procedure if exists proc_33983_b;
drop procedure if exists proc_33983_c;
drop procedure if exists proc_33983_d;
--enable_warnings
delimiter |;
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_a()
begin
label1:
begin
label2:
begin
select 1;
end label1;
end;
end|
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_b()
begin
label1:
repeat
label2:
repeat
select 1;
until FALSE end repeat label1;
until FALSE end repeat;
end|
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_c()
begin
label1:
while TRUE do
label2:
while TRUE do
select 1;
end while label1;
end while;
end|
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_d()
begin
label1:
loop
label2:
loop
select 1;
end loop label1;
end loop;
end|
delimiter ;|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
...@@ -7925,6 +7925,58 @@ SELECT @state, @exception; ...@@ -7925,6 +7925,58 @@ SELECT @state, @exception;
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE bug29770; DROP PROCEDURE bug29770;
#
# Bug#33618 Crash in sp_rcontext
#
use test;
--disable_warnings
drop table if exists t_33618;
drop procedure if exists proc_33618;
--enable_warnings
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
delimiter //;
create procedure proc_33618(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
delimiter ;//
call proc_33618(20);
drop table t_33618;
drop procedure proc_33618;
########################################################################### ###########################################################################
--echo # ------------------------------------------------------------------ --echo # ------------------------------------------------------------------
......
...@@ -1284,7 +1284,9 @@ END_OF_INPUT ...@@ -1284,7 +1284,9 @@ END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
%type <NONE> sp_proc_stmt_if %type <NONE> sp_proc_stmt_if
%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave %type <NONE> sp_labeled_control sp_proc_stmt_unlabeled
%type <NONE> sp_labeled_block sp_unlabeled_block
%type <NONE> sp_proc_stmt_leave
%type <NONE> sp_proc_stmt_iterate %type <NONE> sp_proc_stmt_iterate
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
%type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt %type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt
...@@ -1945,6 +1947,8 @@ ev_sql_stmt_inner: ...@@ -1945,6 +1947,8 @@ ev_sql_stmt_inner:
| sp_proc_stmt_return | sp_proc_stmt_return
| sp_proc_stmt_if | sp_proc_stmt_if
| case_stmt_specification | case_stmt_specification
| sp_labeled_block
| sp_unlabeled_block
| sp_labeled_control | sp_labeled_control
| sp_proc_stmt_unlabeled | sp_proc_stmt_unlabeled
| sp_proc_stmt_leave | sp_proc_stmt_leave
...@@ -2519,6 +2523,8 @@ sp_proc_stmt: ...@@ -2519,6 +2523,8 @@ sp_proc_stmt:
| sp_proc_stmt_return | sp_proc_stmt_return
| sp_proc_stmt_if | sp_proc_stmt_if
| case_stmt_specification | case_stmt_specification
| sp_labeled_block
| sp_unlabeled_block
| sp_labeled_control | sp_labeled_control
| sp_proc_stmt_unlabeled | sp_proc_stmt_unlabeled
| sp_proc_stmt_leave | sp_proc_stmt_leave
...@@ -2645,14 +2651,35 @@ sp_proc_stmt_leave: ...@@ -2645,14 +2651,35 @@ sp_proc_stmt_leave:
sp_instr_jump *i; sp_instr_jump *i;
uint ip= sp->instructions(); uint ip= sp->instructions();
uint n; uint n;
/*
When jumping to a BEGIN-END block end, the target jump
points to the block hpop/cpop cleanup instructions,
so we should exclude the block context here.
When jumping to something else (i.e., SP_LAB_ITER),
there are no hpop/cpop at the jump destination,
so we should include the block context here for cleanup.
*/
bool exclusive= (lab->type == SP_LAB_BEGIN);
n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */ n= ctx->diff_handlers(lab->ctx, exclusive);
if (n) if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); {
n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */ sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
if (hpop == NULL)
MYSQL_YYABORT;
sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, exclusive);
if (n) if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); {
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
if (cpop == NULL)
MYSQL_YYABORT;
sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx); i= new sp_instr_jump(ip, ctx);
if (i == NULL)
MYSQL_YYABORT;
sp->push_backpatch(i, lab); /* Jumping forward */ sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i); sp->add_instr(i);
} }
...@@ -2680,10 +2707,20 @@ sp_proc_stmt_iterate: ...@@ -2680,10 +2707,20 @@ sp_proc_stmt_iterate:
n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); {
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
if (hpop == NULL)
MYSQL_YYABORT;
sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */ n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); {
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
if (cpop == NULL)
MYSQL_YYABORT;
sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
sp->add_instr(i); sp->add_instr(i);
} }
...@@ -2967,19 +3004,17 @@ sp_labeled_control: ...@@ -2967,19 +3004,17 @@ sp_labeled_control:
sp_unlabeled_control sp_opt_label sp_unlabeled_control sp_opt_label
{ {
LEX *lex= Lex; LEX *lex= Lex;
sp_label_t *lab= lex->spcont->pop_label();
if ($5.str) if ($5.str)
{ {
sp_label_t *lab= lex->spcont->find_label($5.str); if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
if (!lab ||
my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
{ {
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
MYSQL_YYABORT; MYSQL_YYABORT;
} }
} }
lex->sphead->backpatch(lex->spcont->pop_label()); lex->sphead->backpatch(lab);
} }
; ;
...@@ -2988,15 +3023,59 @@ sp_opt_label: ...@@ -2988,15 +3023,59 @@ sp_opt_label:
| label_ident { $$= $1; } | label_ident { $$= $1; }
; ;
sp_unlabeled_control: sp_labeled_block:
label_ident ':'
{
LEX *lex= Lex;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($1.str);
if (lab)
{
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
MYSQL_YYABORT;
}
lab= lex->spcont->push_label($1.str,
lex->sphead->instructions());
lab->type= SP_LAB_BEGIN;
}
sp_block_content sp_opt_label
{
LEX *lex= Lex;
sp_label_t *lab= lex->spcont->pop_label();
if ($5.str)
{
if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
{
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
MYSQL_YYABORT;
}
}
}
;
sp_unlabeled_block:
{ /* Unlabeled blocks get a secret label. */
LEX *lex= Lex;
uint ip= lex->sphead->instructions();
sp_label_t *lab= lex->spcont->push_label((char *)"", ip);
lab->type= SP_LAB_BEGIN;
}
sp_block_content
{
LEX *lex= Lex;
lex->spcont->pop_label();
}
;
sp_block_content:
BEGIN_SYM BEGIN_SYM
{ /* QQ This is just a dummy for grouping declarations and statements { /* QQ This is just a dummy for grouping declarations and statements
together. No [[NOT] ATOMIC] yet, and we need to figure out how together. No [[NOT] ATOMIC] yet, and we need to figure out how
make it coexist with the existing BEGIN COMMIT/ROLLBACK. */ make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
LEX *lex= Lex; LEX *lex= Lex;
sp_label_t *lab= lex->spcont->last_label();
lab->type= SP_LAB_BEGIN;
lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE); lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE);
} }
sp_decls sp_decls
...@@ -3016,7 +3095,10 @@ sp_unlabeled_control: ...@@ -3016,7 +3095,10 @@ sp_unlabeled_control:
$3.curs)); $3.curs));
lex->spcont= ctx->pop_context(); lex->spcont= ctx->pop_context();
} }
| LOOP_SYM ;
sp_unlabeled_control:
LOOP_SYM
sp_proc_stmts1 END LOOP_SYM sp_proc_stmts1 END LOOP_SYM
{ {
LEX *lex= Lex; LEX *lex= Lex;
......
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