mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/home/pem/work/mysql-5.0-merge
This commit is contained in:
commit
d7ace78921
10 changed files with 481 additions and 38 deletions
|
@ -63,6 +63,11 @@ iterate foo;
|
|||
end|
|
||||
ERROR 42000: ITERATE with no matching label: foo
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
end|
|
||||
ERROR 42000: GOTO with no matching label: foo
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
foo: loop
|
||||
set @x=2;
|
||||
|
|
|
@ -398,6 +398,87 @@ id data
|
|||
i 3
|
||||
delete from t1|
|
||||
drop procedure i|
|
||||
create procedure j()
|
||||
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 j()|
|
||||
id data
|
||||
id data
|
||||
j 0
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
drop procedure j|
|
||||
create procedure k(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 k(0)|
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
call k(1)|
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
j 2
|
||||
call k(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 k|
|
||||
delete from t1|
|
||||
insert into t1 values ("foo", 3), ("bar", 19)|
|
||||
insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
|
||||
create procedure sel1()
|
||||
|
@ -1487,7 +1568,7 @@ Grants for root@localhost
|
|||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 22185
|
||||
master-bin.000001 22451
|
||||
Database Table In_use Name_locked
|
||||
Privilege Context Comment
|
||||
Alter Tables To alter the table
|
||||
|
@ -1541,7 +1622,7 @@ Grants for root@localhost
|
|||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 22185
|
||||
master-bin.000001 22451
|
||||
Database Table In_use Name_locked
|
||||
Privilege Context Comment
|
||||
Alter Tables To alter the table
|
||||
|
@ -1580,10 +1661,10 @@ show processlist;
|
|||
end|
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Query 0 NULL call bug4902_2()
|
||||
# root localhost test Query # NULL call bug4902_2()
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Query 0 NULL call bug4902_2()
|
||||
# root localhost test Query # NULL call bug4902_2()
|
||||
drop procedure bug4902_2|
|
||||
drop table if exists t3|
|
||||
create procedure bug4904()
|
||||
|
|
|
@ -82,7 +82,7 @@ drop procedure if exists foo|
|
|||
--error 1304
|
||||
show create procedure foo|
|
||||
|
||||
# LEAVE/ITERATE with no match
|
||||
# LEAVE/ITERATE/GOTO with no match
|
||||
--error 1307
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
|
@ -98,6 +98,11 @@ create procedure foo()
|
|||
foo: begin
|
||||
iterate foo;
|
||||
end|
|
||||
--error 1307
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
end|
|
||||
|
||||
# Redefining label
|
||||
--error 1308
|
||||
|
|
|
@ -468,6 +468,65 @@ delete from t1|
|
|||
drop procedure i|
|
||||
|
||||
|
||||
# The non-standard GOTO, for compatibility
|
||||
#
|
||||
# QQQ The "label" syntax is temporary.
|
||||
# QQQ This is no nearly enough, more tests are needed
|
||||
#
|
||||
create procedure j()
|
||||
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 j()|
|
||||
|
||||
drop procedure j|
|
||||
|
||||
# With dummy handlers, just to test restore of contexts with jumps
|
||||
create procedure k(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 k(0)|
|
||||
call k(1)|
|
||||
call k(2)|
|
||||
|
||||
drop procedure k|
|
||||
delete from t1|
|
||||
|
||||
# SELECT with one of more result set sent back to the clinet
|
||||
insert into t1 values ("foo", 3), ("bar", 19)|
|
||||
insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
|
||||
|
@ -1725,9 +1784,9 @@ create procedure bug4902_2()
|
|||
begin
|
||||
show processlist;
|
||||
end|
|
||||
--replace_column 1 #
|
||||
--replace_column 1 # 6 #
|
||||
call bug4902_2()|
|
||||
--replace_column 1 #
|
||||
--replace_column 1 # 6 #
|
||||
call bug4902_2()|
|
||||
drop procedure bug4902_2|
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ static SYMBOL symbols[] = {
|
|||
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
|
||||
{ "GET_FORMAT", SYM(GET_FORMAT)},
|
||||
{ "GLOBAL", SYM(GLOBAL_SYM)},
|
||||
{ "GOTO", SYM(GOTO_SYM)},
|
||||
{ "GRANT", SYM(GRANT)},
|
||||
{ "GRANTS", SYM(GRANTS)},
|
||||
{ "GROUP", SYM(GROUP)},
|
||||
|
@ -256,6 +257,7 @@ static SYMBOL symbols[] = {
|
|||
{ "KEY", SYM(KEY_SYM)},
|
||||
{ "KEYS", SYM(KEYS)},
|
||||
{ "KILL", SYM(KILL_SYM)},
|
||||
{ "LABEL", SYM(LABEL_SYM)},
|
||||
{ "LANGUAGE", SYM(LANGUAGE_SYM)},
|
||||
{ "LAST", SYM(LAST_SYM)},
|
||||
{ "LEADING", SYM(LEADING)},
|
||||
|
|
|
@ -846,12 +846,36 @@ sp_head::backpatch(sp_label_t *lab)
|
|||
List_iterator_fast<bp_t> li(m_backpatch);
|
||||
|
||||
while ((bp= li++))
|
||||
if (bp->lab == lab)
|
||||
{
|
||||
if (bp->lab == lab ||
|
||||
(bp->lab->type == SP_LAB_REF &&
|
||||
my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0))
|
||||
{
|
||||
sp_instr_jump *i= static_cast<sp_instr_jump *>(bp->instr);
|
||||
sp_scope_t sdiff;
|
||||
|
||||
i->set_destination(dest);
|
||||
if (bp->lab->type == SP_LAB_REF)
|
||||
bp->lab= lab;
|
||||
m_pcont->diff_scopes(0, &sdiff);
|
||||
bp->instr->backpatch(dest, sdiff.hndlrs, sdiff.curs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
net_printf(thd, ER_SP_LILABEL_MISMATCH, "GOTO", bp->lab->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1199,8 +1223,9 @@ sp_instr_jump::print(String *str)
|
|||
uint
|
||||
sp_instr_jump::opt_mark(sp_head *sp)
|
||||
{
|
||||
marked= 1;
|
||||
m_dest= opt_shortcut_jump(sp);
|
||||
if (m_dest != m_ip+1) /* Jumping to following instruction? */
|
||||
marked= 1;
|
||||
m_optdest= sp->get_instr(m_dest);
|
||||
return m_dest;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,13 @@ public:
|
|||
void
|
||||
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);
|
||||
|
||||
char *name(uint *lenp = 0) const
|
||||
{
|
||||
if (lenp)
|
||||
|
@ -272,7 +279,7 @@ public:
|
|||
|
||||
virtual void print(String *str) = 0;
|
||||
|
||||
virtual void set_destination(uint dest)
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
{}
|
||||
|
||||
virtual uint opt_mark(sp_head *sp)
|
||||
|
@ -394,8 +401,7 @@ public:
|
|||
|
||||
virtual void opt_move(uint dst, List<sp_instr> *ibp);
|
||||
|
||||
virtual void
|
||||
set_destination(uint dest)
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
{
|
||||
if (m_dest == 0) // Don't reset
|
||||
m_dest= dest;
|
||||
|
@ -575,6 +581,21 @@ public:
|
|||
|
||||
virtual void print(String *str);
|
||||
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
{
|
||||
if (hpop > m_count)
|
||||
m_count= 0;
|
||||
else
|
||||
m_count-= hpop;
|
||||
}
|
||||
|
||||
virtual uint opt_mark(sp_head *sp)
|
||||
{
|
||||
if (m_count)
|
||||
marked= 1;
|
||||
return m_ip+1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint m_count;
|
||||
|
@ -655,6 +676,21 @@ public:
|
|||
|
||||
virtual void print(String *str);
|
||||
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
{
|
||||
if (cpop > m_count)
|
||||
m_count= 0;
|
||||
else
|
||||
m_count-= cpop;
|
||||
}
|
||||
|
||||
virtual uint opt_mark(sp_head *sp)
|
||||
{
|
||||
if (m_count)
|
||||
marked= 1;
|
||||
return m_ip+1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint m_count;
|
||||
|
|
|
@ -27,12 +27,14 @@
|
|||
#include "sp_head.h"
|
||||
|
||||
sp_pcontext::sp_pcontext()
|
||||
: Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_cursmax(0)
|
||||
: Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_cursmax(0),
|
||||
m_hndlrlev(0)
|
||||
{
|
||||
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_scopes, sizeof(sp_scope_t), 16, 8));
|
||||
VOID(my_init_dynamic_array(&m_glabel, sizeof(sp_label_t *), 16, 8));
|
||||
m_label.empty();
|
||||
}
|
||||
|
||||
|
@ -43,6 +45,7 @@ sp_pcontext::destroy()
|
|||
delete_dynamic(&m_cond);
|
||||
delete_dynamic(&m_cursor);
|
||||
delete_dynamic(&m_scopes);
|
||||
delete_dynamic(&m_glabel);
|
||||
m_label.empty();
|
||||
}
|
||||
|
||||
|
@ -53,14 +56,46 @@ sp_pcontext::push_scope()
|
|||
|
||||
s.vars= m_pvar.elements;
|
||||
s.conds= m_cond.elements;
|
||||
s.hndlrs= m_hndlrlev;
|
||||
s.curs= m_cursor.elements;
|
||||
s.glab= m_glabel.elements;
|
||||
insert_dynamic(&m_scopes, (gptr)&s);
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::pop_scope()
|
||||
sp_pcontext::pop_scope(sp_scope_t *sp)
|
||||
{
|
||||
(void)pop_dynamic(&m_scopes);
|
||||
byte *p= pop_dynamic(&m_scopes);
|
||||
|
||||
if (sp && p)
|
||||
memcpy(sp, p, sizeof(sp_scope_t));
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::diff_scopes(uint sold, sp_scope_t *diffs)
|
||||
{
|
||||
uint snew= m_scopes.elements;
|
||||
sp_scope_t scope;
|
||||
|
||||
diffs->vars= diffs->conds= diffs->hndlrs= diffs->curs= diffs->glab= 0;
|
||||
while (snew-- > sold)
|
||||
{
|
||||
get_dynamic(&m_scopes, (gptr)&scope, snew);
|
||||
diffs->vars+= scope.vars;
|
||||
diffs->conds+= scope.conds;
|
||||
diffs->hndlrs+= scope.hndlrs;
|
||||
diffs->curs+= scope.curs;
|
||||
diffs->glab+= scope.glab;
|
||||
}
|
||||
if (sold)
|
||||
{
|
||||
get_dynamic(&m_scopes, (gptr)&scope, sold-1);
|
||||
diffs->vars-= scope.vars;
|
||||
diffs->conds-= scope.conds;
|
||||
diffs->hndlrs-= scope.hndlrs;
|
||||
diffs->curs-= scope.curs;
|
||||
diffs->glab-= scope.glab;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,7 +167,8 @@ sp_pcontext::push_label(char *name, uint ip)
|
|||
{
|
||||
lab->name= name;
|
||||
lab->ip= ip;
|
||||
lab->isbegin= FALSE;
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->scopes= 0;
|
||||
m_label.push_front(lab);
|
||||
}
|
||||
return lab;
|
||||
|
@ -245,3 +281,41 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
|
|||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sp_label_t *
|
||||
sp_pcontext::push_glabel(char *name, uint ip)
|
||||
{
|
||||
sp_label_t *lab = (sp_label_t *)sql_alloc(sizeof(sp_label_t));
|
||||
|
||||
if (lab)
|
||||
{
|
||||
lab->name= name;
|
||||
lab->ip= ip;
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->scopes= 0;
|
||||
insert_dynamic(&m_glabel, (gptr)&lab);
|
||||
}
|
||||
return lab;
|
||||
}
|
||||
|
||||
sp_label_t *
|
||||
sp_pcontext::find_glabel(char *name)
|
||||
{
|
||||
uint i= m_glabel.elements;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
sp_label_t *lab;
|
||||
|
||||
get_dynamic(&m_glabel, (gptr)&lab, i);
|
||||
if (my_strcasecmp(system_charset_info, name, lab->name) == 0)
|
||||
return lab;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::pop_glabel(uint count)
|
||||
{
|
||||
(void)pop_dynamic(&m_glabel);
|
||||
}
|
||||
|
|
|
@ -39,11 +39,18 @@ typedef struct sp_pvar
|
|||
Item *dflt;
|
||||
} sp_pvar_t;
|
||||
|
||||
|
||||
#define SP_LAB_REF 0 // Unresolved reference (for goto)
|
||||
#define SP_LAB_GOTO 1 // Free goto label
|
||||
#define SP_LAB_BEGIN 2 // Label at BEGIN
|
||||
#define SP_LAB_ITER 3 // Label at iteration control
|
||||
|
||||
typedef struct sp_label
|
||||
{
|
||||
char *name;
|
||||
uint ip; // Instruction index
|
||||
my_bool isbegin; // For ITERATE error checking
|
||||
int type; // begin/iter or ref/free
|
||||
uint scopes; // No. of scopes at label
|
||||
} sp_label_t;
|
||||
|
||||
typedef struct sp_cond_type
|
||||
|
@ -61,7 +68,7 @@ typedef struct sp_cond
|
|||
|
||||
typedef struct sp_scope
|
||||
{
|
||||
uint vars, conds, curs;
|
||||
uint vars, conds, hndlrs, curs, glab;
|
||||
} sp_scope_t;
|
||||
|
||||
class sp_pcontext : public Sql_alloc
|
||||
|
@ -82,7 +89,18 @@ class sp_pcontext : public Sql_alloc
|
|||
push_scope();
|
||||
|
||||
void
|
||||
pop_scope();
|
||||
pop_scope(sp_scope_t *sp = 0);
|
||||
|
||||
uint
|
||||
scopes()
|
||||
{
|
||||
return m_scopes.elements;
|
||||
}
|
||||
|
||||
// Sets '*diffs' to the differences between current scope index snew and sold
|
||||
void
|
||||
diff_scopes(uint sold, sp_scope_t *diffs);
|
||||
|
||||
|
||||
//
|
||||
// Parameters and variables
|
||||
|
@ -223,6 +241,18 @@ class sp_pcontext : public Sql_alloc
|
|||
return m_handlers;
|
||||
}
|
||||
|
||||
inline void
|
||||
push_handlers(uint count)
|
||||
{
|
||||
m_hndlrlev+= count;
|
||||
}
|
||||
|
||||
inline void
|
||||
pop_handlers(uint count)
|
||||
{
|
||||
m_hndlrlev-= count;
|
||||
}
|
||||
|
||||
//
|
||||
// Cursors
|
||||
//
|
||||
|
@ -246,17 +276,32 @@ class sp_pcontext : public Sql_alloc
|
|||
return m_cursmax;
|
||||
}
|
||||
|
||||
//
|
||||
// GOTO labels
|
||||
//
|
||||
|
||||
sp_label_t *
|
||||
push_glabel(char *name, uint ip);
|
||||
|
||||
sp_label_t *
|
||||
find_glabel(char *name);
|
||||
|
||||
void
|
||||
pop_glabel(uint count);
|
||||
|
||||
private:
|
||||
|
||||
uint m_params; // The number of parameters
|
||||
uint m_framesize; // The maximum framesize
|
||||
uint m_handlers; // The total number of handlers
|
||||
uint m_cursmax; // The maximum number of cursors
|
||||
uint m_hndlrlev; // Current number of active handlers
|
||||
|
||||
DYNAMIC_ARRAY m_pvar; // Parameters/variables
|
||||
DYNAMIC_ARRAY m_cond; // Conditions
|
||||
DYNAMIC_ARRAY m_cursor; // Cursors
|
||||
DYNAMIC_ARRAY m_scopes; // For error checking
|
||||
DYNAMIC_ARRAY m_glabel; // Goto labels
|
||||
|
||||
List<sp_label_t> m_label; // The label list
|
||||
|
||||
|
|
145
sql/sql_yacc.yy
145
sql/sql_yacc.yy
|
@ -611,6 +611,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token CURSOR_SYM
|
||||
%token ELSEIF_SYM
|
||||
%token ITERATE_SYM
|
||||
%token GOTO_SYM
|
||||
%token LABEL_SYM
|
||||
%token LEAVE_SYM
|
||||
%token LOOP_SYM
|
||||
%token REPEAT_SYM
|
||||
|
@ -1180,13 +1182,16 @@ create:
|
|||
sp_proc_stmt
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
|
||||
lex->sphead->init_strings(YYTHD, lex, $3);
|
||||
if (sp->check_backpatch(YYTHD))
|
||||
YYABORT;
|
||||
sp->init_strings(YYTHD, lex, $3);
|
||||
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
|
||||
/* Restore flag if it was cleared above */
|
||||
if (lex->sphead->m_old_cmq)
|
||||
if (sp->m_old_cmq)
|
||||
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
||||
lex->sphead->restore_thd_mem_root(YYTHD);
|
||||
sp->restore_thd_mem_root(YYTHD);
|
||||
}
|
||||
| CREATE or_replace algorithm VIEW_SYM table_ident
|
||||
{
|
||||
|
@ -1286,6 +1291,8 @@ create_function_tail:
|
|||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
|
||||
if (sp->check_backpatch(YYTHD))
|
||||
YYABORT;
|
||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||
sp->init_strings(YYTHD, lex, lex->spname);
|
||||
/* Restore flag if it was cleared above */
|
||||
|
@ -1816,7 +1823,8 @@ sp_proc_stmt:
|
|||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp = lex->sphead;
|
||||
sp_label_t *lab= lex->spcont->find_label($2.str);
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
|
||||
if (! lab)
|
||||
{
|
||||
|
@ -1825,8 +1833,20 @@ sp_proc_stmt:
|
|||
}
|
||||
else
|
||||
{
|
||||
sp_instr_jump *i= new sp_instr_jump(sp->instructions());
|
||||
uint ip= sp->instructions();
|
||||
sp_scope_t sdiff;
|
||||
sp_instr_jump *i;
|
||||
sp_instr_hpop *ih;
|
||||
sp_instr_cpop *ic;
|
||||
|
||||
ctx->diff_scopes(0, &sdiff);
|
||||
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
|
||||
sp->push_backpatch(ih, lab);
|
||||
sp->add_instr(ih);
|
||||
ic= new sp_instr_cpop(ip++, sdiff.curs);
|
||||
sp->push_backpatch(ic, lab);
|
||||
sp->add_instr(ic);
|
||||
i= new sp_instr_jump(ip);
|
||||
sp->push_backpatch(i, lab); /* Jumping forward */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
|
@ -1834,19 +1854,101 @@ sp_proc_stmt:
|
|||
| ITERATE_SYM IDENT
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_label_t *lab= lex->spcont->find_label($2.str);
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
|
||||
if (! lab || lab->isbegin)
|
||||
if (! lab || lab->type != SP_LAB_ITER)
|
||||
{
|
||||
net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str);
|
||||
YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_instr_jump *i= new sp_instr_jump(ip, lab->ip); /* Jump back */
|
||||
sp_instr_jump *i;
|
||||
uint ip= sp->instructions();
|
||||
sp_scope_t sdiff;
|
||||
|
||||
lex->sphead->add_instr(i);
|
||||
ctx->diff_scopes(lab->scopes, &sdiff);
|
||||
if (sdiff.hndlrs)
|
||||
sp->add_instr(new sp_instr_hpop(ip++, sdiff.hndlrs));
|
||||
if (sdiff.curs)
|
||||
sp->add_instr(new sp_instr_cpop(ip++, sdiff.curs));
|
||||
i= new sp_instr_jump(ip, lab->ip); /* Jump back */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
}
|
||||
| LABEL_SYM IDENT
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
|
||||
if (! lab)
|
||||
lab= ctx->find_glabel($2.str);
|
||||
if (lab)
|
||||
{
|
||||
net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $2.str);
|
||||
YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
lab= ctx->push_glabel($2.str, sp->instructions());
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->scopes= ctx->scopes();
|
||||
sp->backpatch(lab);
|
||||
}
|
||||
}
|
||||
| GOTO_SYM IDENT
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
sp_scope_t sdiff;
|
||||
sp_instr_jump *i;
|
||||
sp_instr_hpop *ih;
|
||||
sp_instr_cpop *ic;
|
||||
|
||||
if (! lab)
|
||||
lab= ctx->find_glabel($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->scopes= 0;
|
||||
|
||||
ctx->diff_scopes(0, &sdiff);
|
||||
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
|
||||
sp->push_backpatch(ih, lab);
|
||||
sp->add_instr(ih);
|
||||
ic= new sp_instr_cpop(ip++, sdiff.curs);
|
||||
sp->add_instr(ic);
|
||||
sp->push_backpatch(ic, lab);
|
||||
i= new sp_instr_jump(ip);
|
||||
sp->push_backpatch(i, lab); /* Jumping forward */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->diff_scopes(lab->scopes, &sdiff);
|
||||
if (sdiff.hndlrs)
|
||||
{
|
||||
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
|
||||
sp->add_instr(ih);
|
||||
}
|
||||
if (sdiff.curs)
|
||||
{
|
||||
ic= new sp_instr_cpop(ip++, sdiff.curs);
|
||||
sp->add_instr(ic);
|
||||
}
|
||||
i= new sp_instr_jump(ip, lab->ip); /* Jump back */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
}
|
||||
| OPEN_SYM ident
|
||||
|
@ -2041,7 +2143,8 @@ sp_labeled_control:
|
|||
IDENT ':'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_label_t *lab= lex->spcont->find_label($1.str);
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *lab= ctx->find_label($1.str);
|
||||
|
||||
if (lab)
|
||||
{
|
||||
|
@ -2050,8 +2153,10 @@ sp_labeled_control:
|
|||
}
|
||||
else
|
||||
{
|
||||
lex->spcont->push_label($1.str,
|
||||
lex->sphead->instructions());
|
||||
lab= lex->spcont->push_label($1.str,
|
||||
lex->sphead->instructions());
|
||||
lab->type= SP_LAB_ITER;
|
||||
lab->scopes= ctx->scopes();
|
||||
}
|
||||
}
|
||||
sp_unlabeled_control sp_opt_label
|
||||
|
@ -2088,27 +2193,33 @@ sp_unlabeled_control:
|
|||
LEX *lex= Lex;
|
||||
sp_label_t *lab= lex->spcont->last_label();
|
||||
|
||||
lab->isbegin= TRUE;
|
||||
lab->type= SP_LAB_BEGIN;
|
||||
/* Scope duplicate checking */
|
||||
lex->spcont->push_scope();
|
||||
}
|
||||
sp_decls
|
||||
{
|
||||
Lex->spcont->push_handlers($3.hndlrs);
|
||||
}
|
||||
sp_proc_stmts
|
||||
END
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_scope_t scope;
|
||||
|
||||
sp->backpatch(ctx->last_label()); /* We always has a label */
|
||||
sp->backpatch(ctx->last_label()); /* We always have a label */
|
||||
ctx->pop_pvar($3.vars);
|
||||
ctx->pop_cond($3.conds);
|
||||
ctx->pop_handlers($3.hndlrs);
|
||||
ctx->pop_cursor($3.curs);
|
||||
if ($3.hndlrs)
|
||||
sp->add_instr(new sp_instr_hpop(sp->instructions(),$3.hndlrs));
|
||||
sp->add_instr(new sp_instr_hpop(sp->instructions(), $3.hndlrs));
|
||||
if ($3.curs)
|
||||
sp->add_instr(new sp_instr_cpop(sp->instructions(), $3.curs));
|
||||
ctx->pop_scope();
|
||||
ctx->pop_scope(&scope);
|
||||
ctx->pop_glabel(scope.glab);
|
||||
}
|
||||
| LOOP_SYM
|
||||
sp_proc_stmts END LOOP_SYM
|
||||
|
|
Loading…
Reference in a new issue