summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.comhem.se>2004-08-17 20:20:58 +0200
committerunknown <pem@mysql.comhem.se>2004-08-17 20:20:58 +0200
commit9b5a6f7228850479abe0e4e2439dcf6b27a87136 (patch)
tree0a14fd07bbceeceb892fb762e8f9af5e74153b89 /sql/sp_head.cc
parentf43fe31e571bb5e127d5e0ca4ad6680a15104aa7 (diff)
downloadmariadb-git-9b5a6f7228850479abe0e4e2439dcf6b27a87136.tar.gz
WL#2002: Implement stored procedure GOTO.
Mostly done, it works, but the temporary LABEL syntax still to be fixed. mysql-test/r/sp-error.result: New test case for WL#2002 (GOTO). mysql-test/r/sp.result: New test case for WL#2002 (GOTO). (Also corrected another test) mysql-test/t/sp-error.test: New test case for WL#2002 (GOTO). mysql-test/t/sp.test: New test case for WL#2002 (GOTO). (Also corrected another test) sql/lex.h: New symbol GOTO. Also a temporary symbol LABEL, which hopefully will go away soon. sql/sp_head.cc: Fixed backpatching to cope with free GOTO labels an hpop and cpop instructions. Also optimized away pointless jump instructions. sql/sp_head.h: Fixed backpatching to cope with free GOTO labels an hpop and cpop instructions. We now sometimes generate hpop/cpop 0 instructions but the optimizer removes them. sql/sp_pcontext.cc: Added free GOTO labels, and support for coping with jumps out of blocks with handlers or cursors. sql/sp_pcontext.h: Added free GOTO labels, and support for coping with jumps out of blocks with handlers or cursors. sql/sql_yacc.yy: Added GOTO and LABEL, and adjusted backpatching accordingly. Also fixed LEAVE out of blocks. The LABEL syntax will go away soon, hopefully.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc33
1 files changed, 29 insertions, 4 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 6ba72215e39..bc6251903c2 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -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;
}