Below is the list of changes that have just been committed into a local
5.1 repository of malff. When malff does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-01-23 16:21:09-07:00, malff@stripped. +5 -0
Manual merge
mysql-test/r/sp-error.result@stripped, 2008-01-23 16:21:04-07:00,
malff@stripped. +48 -0
Manual merge
mysql-test/r/sp.result@stripped, 2008-01-23 16:21:04-07:00,
malff@stripped. +35 -0
Manual merge
mysql-test/t/sp-error.test@stripped, 2008-01-23 16:21:04-07:00,
malff@stripped. +63 -0
Manual merge
mysql-test/t/sp.test@stripped, 2008-01-23 16:21:04-07:00, malff@stripped.
+52 -0
Manual merge
sql/sql_yacc.yy@stripped, 2008-01-23 16:21:04-07:00, malff@stripped. +99
-17
Manual merge
diff -Nrup a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
--- a/mysql-test/r/sp-error.result 2008-01-23 15:36:43 -07:00
+++ b/mysql-test/r/sp-error.result 2008-01-23 16:21:04 -07:00
@@ -1579,3 +1579,51 @@ drop function f2;
drop table t2;
ERROR 42S02: Unknown table 't2'
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
diff -Nrup a/mysql-test/r/sp.result b/mysql-test/r/sp.result
--- a/mysql-test/r/sp.result 2008-01-23 15:36:45 -07:00
+++ b/mysql-test/r/sp.result 2008-01-23 16:21:04 -07:00
@@ -6827,6 +6827,41 @@ SELECT @state, @exception;
run NULL
DROP TABLE t1;
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
# ------------------------------------------------------------------
diff -Nrup a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
--- a/mysql-test/t/sp-error.test 2008-01-23 15:36:47 -07:00
+++ b/mysql-test/t/sp-error.test 2008-01-23 16:21:04 -07:00
@@ -2306,6 +2306,69 @@ drop table t2;
--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
#
#--disable_warnings
diff -Nrup a/mysql-test/t/sp.test b/mysql-test/t/sp.test
--- a/mysql-test/t/sp.test 2008-01-23 15:36:50 -07:00
+++ b/mysql-test/t/sp.test 2008-01-23 16:21:04 -07:00
@@ -7925,6 +7925,58 @@ SELECT @state, @exception;
DROP TABLE t1;
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 # ------------------------------------------------------------------
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy 2008-01-23 15:36:52 -07:00
+++ b/sql/sql_yacc.yy 2008-01-23 16:21:04 -07:00
@@ -1284,7 +1284,9 @@ END_OF_INPUT
%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_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_open sp_proc_stmt_fetch sp_proc_stmt_close
%type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt
@@ -1945,6 +1947,8 @@ ev_sql_stmt_inner:
| sp_proc_stmt_return
| sp_proc_stmt_if
| case_stmt_specification
+ | sp_labeled_block
+ | sp_unlabeled_block
| sp_labeled_control
| sp_proc_stmt_unlabeled
| sp_proc_stmt_leave
@@ -2519,6 +2523,8 @@ sp_proc_stmt:
| sp_proc_stmt_return
| sp_proc_stmt_if
| case_stmt_specification
+ | sp_labeled_block
+ | sp_unlabeled_block
| sp_labeled_control
| sp_proc_stmt_unlabeled
| sp_proc_stmt_leave
@@ -2645,14 +2651,35 @@ sp_proc_stmt_leave:
sp_instr_jump *i;
uint ip= sp->instructions();
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)
- 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)
- 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);
+ if (i == NULL)
+ MYSQL_YYABORT;
sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i);
}
@@ -2680,10 +2707,20 @@ sp_proc_stmt_iterate:
n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
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. */
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 */
sp->add_instr(i);
}
@@ -2967,19 +3004,17 @@ sp_labeled_control:
sp_unlabeled_control sp_opt_label
{
LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->pop_label();
if ($5.str)
{
- sp_label_t *lab= lex->spcont->find_label($5.str);
-
- if (!lab ||
- my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
+ if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
{
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
MYSQL_YYABORT;
}
}
- lex->sphead->backpatch(lex->spcont->pop_label());
+ lex->sphead->backpatch(lab);
}
;
@@ -2988,15 +3023,59 @@ sp_opt_label:
| 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
{ /* QQ This is just a dummy for grouping declarations and statements
together. No [[NOT] ATOMIC] yet, and we need to figure out how
make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
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);
}
sp_decls
@@ -3016,7 +3095,10 @@ sp_unlabeled_control:
$3.curs));
lex->spcont= ctx->pop_context();
}
- | LOOP_SYM
+ ;
+
+sp_unlabeled_control:
+ LOOP_SYM
sp_proc_stmts1 END LOOP_SYM
{
LEX *lex= Lex;
| Thread |
|---|
| • bk commit into 5.1 tree (malff:1.2656) | marc.alff | 24 Jan |