From 74c756583edadf5c797bd0dd3c92674241000f94 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Aug 2004 20:20:58 +0200 Subject: 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. --- sql/sp_head.cc | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'sql/sp_head.cc') 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 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(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 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; } -- cgit v1.2.1