Commit 2dc3026c authored by pem@mysql.com's avatar pem@mysql.com

Merge mysql.com:/extern/mysql/bk/mysql-5.0-runtime

into  mysql.com:/extern/mysql/5.0/bug18949/mysql-5.0-runtime
parents 19e558a0 a6fbde9d
drop table if exists t1;
create table t1 (
id char(16) not null default '',
data int not null
);
drop procedure if exists goto1//
create procedure goto1()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end//
call goto1()//
id data
id data
j 0
id data
j 0
j 1
id data
j 0
j 1
j 2
drop procedure goto1//
drop procedure if exists goto2//
create procedure goto2(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end//
call goto2(0)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call goto2(1)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call goto2(2)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
drop procedure goto2//
delete from t1//
drop procedure if exists goto3//
create procedure goto3()
begin
label L1;
begin
end;
goto L1;
end//
drop procedure goto3//
drop procedure if exists goto4//
create procedure goto4()
begin
begin
label lab1;
begin
goto lab1;
end;
end;
end//
drop procedure goto4//
drop procedure if exists goto5//
create procedure goto5()
begin
begin
begin
goto lab1;
end;
label lab1;
end;
end//
drop procedure goto5//
drop procedure if exists goto6//
create procedure goto6()
begin
label L1;
goto L5;
begin
label L2;
goto L1;
goto L5;
begin
label L3;
goto L1;
goto L2;
goto L3;
goto L4;
goto L5;
end;
goto L2;
goto L4;
label L4;
end;
label L5;
goto L1;
end//
drop procedure goto6//
create procedure foo()
begin
goto foo;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
label foo;
end;
goto foo;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
goto foo;
begin
label foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
goto foo;
end;
begin
label foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
label foo;
end;
begin
goto foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure p()
begin
declare continue handler for sqlexception
begin
goto L1;
end;
select field from t1;
label L1;
end//
ERROR HY000: GOTO is not allowed in a stored procedure handler
drop procedure if exists bug6898//
create procedure bug6898()
begin
goto label1;
label label1;
begin end;
goto label1;
end//
drop procedure bug6898//
drop table t1;
...@@ -10,6 +10,5 @@ ...@@ -10,6 +10,5 @@
# #
############################################################################## ##############################################################################
sp-goto : GOTO is currently is disabled - will be fixed in the future
ndb_load : Bug#17233 ndb_load : Bug#17233
udf : Bug#18564 (Permission by Brian) udf : Bug#18564 (Permission by Brian)
#
# The non-standard GOTO, for compatibility
#
# QQQ The "label" syntax is temporary, it will (hopefully)
# change to the more common "L:" syntax soon.
# For the time being, this feature is disabled, until
# the syntax (and some other known bugs) can be fixed.
#
# Test cases for bugs are added at the end. See template there.
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (
id char(16) not null default '',
data int not null
);
delimiter //;
--disable_warnings
drop procedure if exists goto1//
--enable_warnings
create procedure goto1()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end//
call goto1()//
drop procedure goto1//
# With dummy handlers, just to test restore of contexts with jumps
--disable_warnings
drop procedure if exists goto2//
--enable_warnings
create procedure goto2(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end//
call goto2(0)//
call goto2(1)//
call goto2(2)//
drop procedure goto2//
delete from t1//
# Check label visibility for some more cases. We don't call these.
--disable_warnings
drop procedure if exists goto3//
--enable_warnings
create procedure goto3()
begin
label L1;
begin
end;
goto L1;
end//
drop procedure goto3//
--disable_warnings
drop procedure if exists goto4//
--enable_warnings
create procedure goto4()
begin
begin
label lab1;
begin
goto lab1;
end;
end;
end//
drop procedure goto4//
--disable_warnings
drop procedure if exists goto5//
--enable_warnings
create procedure goto5()
begin
begin
begin
goto lab1;
end;
label lab1;
end;
end//
drop procedure goto5//
--disable_warnings
drop procedure if exists goto6//
--enable_warnings
create procedure goto6()
begin
label L1;
goto L5;
begin
label L2;
goto L1;
goto L5;
begin
label L3;
goto L1;
goto L2;
goto L3;
goto L4;
goto L5;
end;
goto L2;
goto L4;
label L4;
end;
label L5;
goto L1;
end//
drop procedure goto6//
# Mismatching labels
--error 1308
create procedure foo()
begin
goto foo;
end//
--error 1308
create procedure foo()
begin
begin
label foo;
end;
goto foo;
end//
--error 1308
create procedure foo()
begin
goto foo;
begin
label foo;
end;
end//
--error 1308
create procedure foo()
begin
begin
goto foo;
end;
begin
label foo;
end;
end//
--error 1308
create procedure foo()
begin
begin
label foo;
end;
begin
goto foo;
end;
end//
# No goto in a handler
--error 1358
create procedure p()
begin
declare continue handler for sqlexception
begin
goto L1;
end;
select field from t1;
label L1;
end//
#
# Test cases for old bugs
#
#
# BUG#6898: Stored procedure crash if GOTO statements exist
#
--disable_warnings
drop procedure if exists bug6898//
--enable_warnings
create procedure bug6898()
begin
goto label1;
label label1;
begin end;
goto label1;
end//
drop procedure bug6898//
#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
#drop procedure if exists bugNNNN//
#--enable_warnings
#create procedure bugNNNN...
# Add bugs above this line. Use existing tables t1 and t2 when
# practical, or create table t3, t4 etc temporarily (and drop them).
delimiter ;//
drop table t1;
...@@ -215,9 +215,6 @@ static SYMBOL symbols[] = { ...@@ -215,9 +215,6 @@ static SYMBOL symbols[] = {
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)}, { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
{ "GET_FORMAT", SYM(GET_FORMAT)}, { "GET_FORMAT", SYM(GET_FORMAT)},
{ "GLOBAL", SYM(GLOBAL_SYM)}, { "GLOBAL", SYM(GLOBAL_SYM)},
#ifdef SP_GOTO
{ "GOTO", SYM(GOTO_SYM)},
#endif
{ "GRANT", SYM(GRANT)}, { "GRANT", SYM(GRANT)},
{ "GRANTS", SYM(GRANTS)}, { "GRANTS", SYM(GRANTS)},
{ "GROUP", SYM(GROUP)}, { "GROUP", SYM(GROUP)},
...@@ -265,10 +262,6 @@ static SYMBOL symbols[] = { ...@@ -265,10 +262,6 @@ static SYMBOL symbols[] = {
{ "KEY", SYM(KEY_SYM)}, { "KEY", SYM(KEY_SYM)},
{ "KEYS", SYM(KEYS)}, { "KEYS", SYM(KEYS)},
{ "KILL", SYM(KILL_SYM)}, { "KILL", SYM(KILL_SYM)},
#ifdef SP_GOTO
/* QQ This will go away when the GOTO label syntax is fixed */
{ "LABEL", SYM(LABEL_SYM)},
#endif
{ "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LANGUAGE", SYM(LANGUAGE_SYM)},
{ "LAST", SYM(LAST_SYM)}, { "LAST", SYM(LAST_SYM)},
{ "LEADING", SYM(LEADING)}, { "LEADING", SYM(LEADING)},
......
...@@ -1670,44 +1670,11 @@ sp_head::backpatch(sp_label_t *lab) ...@@ -1670,44 +1670,11 @@ sp_head::backpatch(sp_label_t *lab)
while ((bp= li++)) while ((bp= li++))
{ {
if (bp->lab == lab || if (bp->lab == lab)
(bp->lab->type == SP_LAB_REF && bp->instr->backpatch(dest, lab->ctx);
my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0))
{
if (bp->lab->type != SP_LAB_REF)
bp->instr->backpatch(dest, lab->ctx);
else
{
sp_label_t *dstlab= bp->lab->ctx->find_label(lab->name);
if (dstlab)
{
bp->lab= lab;
bp->instr->backpatch(dest, dstlab->ctx);
}
}
}
}
}
int
sp_head::check_backpatch(THD *thd)
{
bp_t *bp;
List_iterator_fast<bp_t> li(m_backpatch);
while ((bp= li++))
{
if (bp->lab->type == SP_LAB_REF)
{
my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name);
return -1;
}
} }
return 0;
} }
/* /*
Prepare an instance of create_field for field creation (fill all necessary Prepare an instance of create_field for field creation (fill all necessary
attributes). attributes).
......
...@@ -263,13 +263,6 @@ class sp_head :private Query_arena ...@@ -263,13 +263,6 @@ class sp_head :private Query_arena
void void
backpatch(struct sp_label *); backpatch(struct sp_label *);
// Check that no unresolved references exist.
// If none found, 0 is returned, otherwise errors have been issued
// and -1 is returned.
// This is called by the parser at the end of a create procedure/function.
int
check_backpatch(THD *thd);
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr. // Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
void void
new_cont_backpatch(sp_instr_opt_meta *i); new_cont_backpatch(sp_instr_opt_meta *i);
......
...@@ -241,7 +241,7 @@ sp_pcontext::push_label(char *name, uint ip) ...@@ -241,7 +241,7 @@ sp_pcontext::push_label(char *name, uint ip)
{ {
lab->name= name; lab->name= name;
lab->ip= ip; lab->ip= ip;
lab->type= SP_LAB_GOTO; lab->type= SP_LAB_IMPL;
lab->ctx= this; lab->ctx= this;
m_label.push_front(lab); m_label.push_front(lab);
} }
......
...@@ -48,10 +48,9 @@ typedef struct sp_variable ...@@ -48,10 +48,9 @@ typedef struct sp_variable
} sp_variable_t; } sp_variable_t;
#define SP_LAB_REF 0 // Unresolved reference (for goto) #define SP_LAB_IMPL 0 // Implicit label generated by parser
#define SP_LAB_GOTO 1 // Free goto label #define SP_LAB_BEGIN 1 // Label at BEGIN
#define SP_LAB_BEGIN 2 // Label at BEGIN #define SP_LAB_ITER 2 // Label at iteration control
#define SP_LAB_ITER 3 // Label at iteration control
/* /*
An SQL/PSM label. Can refer to the identifier used with the An SQL/PSM label. Can refer to the identifier used with the
......
...@@ -301,7 +301,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -301,7 +301,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token GEOMFROMWKB %token GEOMFROMWKB
%token GET_FORMAT %token GET_FORMAT
%token GLOBAL_SYM %token GLOBAL_SYM
%token GOTO_SYM
%token GRANT %token GRANT
%token GRANTS %token GRANTS
%token GREATEST_SYM %token GREATEST_SYM
...@@ -1332,8 +1331,6 @@ create_function_tail: ...@@ -1332,8 +1331,6 @@ create_function_tail:
if (sp->is_not_allowed_in_function("function")) if (sp->is_not_allowed_in_function("function"))
YYABORT; YYABORT;
if (sp->check_backpatch(YYTHD))
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION; lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex, lex->spname); sp->init_strings(YYTHD, lex, lex->spname);
if (!(sp->m_flags & sp_head::HAS_RETURN)) if (!(sp->m_flags & sp_head::HAS_RETURN))
...@@ -2054,91 +2051,6 @@ sp_proc_stmt: ...@@ -2054,91 +2051,6 @@ sp_proc_stmt:
sp->add_instr(i); sp->add_instr(i);
} }
} }
| LABEL_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($2.str);
if (lab)
{
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str);
YYABORT;
}
else
{
lab= ctx->push_label($2.str, sp->instructions());
lab->type= SP_LAB_GOTO;
lab->ctx= ctx;
sp->backpatch(lab);
}
#else
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
#endif
}
| GOTO_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint ip= lex->sphead->instructions();
sp_label_t *lab;
sp_instr_jump *i;
sp_instr_hpop *ih;
sp_instr_cpop *ic;
if (sp->m_in_handler)
{
my_message(ER_SP_GOTO_IN_HNDLR, ER(ER_SP_GOTO_IN_HNDLR), MYF(0));
YYABORT;
}
lab= ctx->find_label($2.str);
if (! lab)
{
lab= (sp_label_t *)YYTHD->alloc(sizeof(sp_label_t));
lab->name= $2.str;
lab->ip= 0;
lab->type= SP_LAB_REF;
lab->ctx= ctx;
ih= new sp_instr_hpop(ip++, ctx, 0);
sp->push_backpatch(ih, lab);
sp->add_instr(ih);
ic= new sp_instr_cpop(ip++, ctx, 0);
sp->add_instr(ic);
sp->push_backpatch(ic, lab);
i= new sp_instr_jump(ip, ctx);
sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i);
}
else
{
uint n;
n= ctx->diff_handlers(lab->ctx);
if (n)
{
ih= new sp_instr_hpop(ip++, ctx, n);
sp->add_instr(ih);
}
n= ctx->diff_cursors(lab->ctx);
if (n)
{
ic= new sp_instr_cpop(ip++, ctx, n);
sp->add_instr(ic);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
sp->add_instr(i);
}
#else
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
#endif
}
| OPEN_SYM ident | OPEN_SYM ident
{ {
LEX *lex= Lex; LEX *lex= Lex;
...@@ -9228,8 +9140,6 @@ sp_tail: ...@@ -9228,8 +9140,6 @@ sp_tail:
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp= lex->sphead; sp_head *sp= lex->sphead;
if (sp->check_backpatch(YYTHD))
YYABORT;
sp->init_strings(YYTHD, lex, $3); sp->init_strings(YYTHD, lex, $3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE; lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
......
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