diff options
author | unknown <pem@mysql.comhem.se> | 2004-08-17 20:20:58 +0200 |
---|---|---|
committer | unknown <pem@mysql.comhem.se> | 2004-08-17 20:20:58 +0200 |
commit | 9b5a6f7228850479abe0e4e2439dcf6b27a87136 (patch) | |
tree | 0a14fd07bbceeceb892fb762e8f9af5e74153b89 /sql/sp_pcontext.cc | |
parent | f43fe31e571bb5e127d5e0ca4ad6680a15104aa7 (diff) | |
download | mariadb-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_pcontext.cc')
-rw-r--r-- | sql/sp_pcontext.cc | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 03333a2da72..6f999531e58 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -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); +} |