mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Manual merge
This commit is contained in:
@ -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;
|
|||||||
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;
|
|||||||
|
|
||||||
--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;
|
|||||||
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 # ------------------------------------------------------------------
|
||||||
|
116
sql/sql_yacc.yy
116
sql/sql_yacc.yy
@ -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:
|
|||||||
| 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:
|
|||||||
| 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:
|
|||||||
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:
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
| 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:
|
|||||||
$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;
|
||||||
|
Reference in New Issue
Block a user