diff options
Diffstat (limited to 'sql')
28 files changed, 337 insertions, 353 deletions
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 264bc38117a..9d1c429d5b6 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -369,3 +369,4 @@ character-set=latin2 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index c0f915e0b53..b2d2fdf4d77 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -363,3 +363,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 9bfca16ad54..85c0443869f 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -371,3 +371,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index c159e6b49c7..641f267d67e 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -360,3 +360,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 4c679a2967a..e64c0c17e74 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -365,3 +365,4 @@ character-set=latin7 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 2f8cccbc6fb..f3443457346 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -360,3 +360,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index dc18cfa9b34..498a230faed 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -372,3 +372,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index b8cbe9b5a75..2827517ba9a 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -360,3 +360,4 @@ character-set=greek "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index b7cc9fe34d7..fab0b156322 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -362,3 +362,4 @@ character-set=latin2 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 0c9576cab47..24634514a23 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -360,3 +360,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index d5ef9f22a56..68f2857aeca 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -362,3 +362,4 @@ character-set=ujis "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 4f03bedc717..70267c82364 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -360,3 +360,4 @@ character-set=euckr "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 821453e6119..1d84a3a5e5a 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -362,3 +362,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 5a60042b19e..be881d54473 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -362,3 +362,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 2f9f5b4bbce..8a576b5bf82 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -364,3 +364,4 @@ character-set=latin2 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 2a32c80138b..6794db726cc 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -361,3 +361,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 211a0072934..9eaa4860b64 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -364,3 +364,4 @@ character-set=latin2 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 907cece485f..eec85d611fc 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -362,3 +362,4 @@ character-set=koi8r "ïÂÎÏ×ÌÑÅÍÙÊ view ÎÅ ÓÏÄÅÒÖÉÔ ËÌÀÞÁ ÉÓÐÏÌØÚÏ×ÁÎÎÏÊ × ÎÅÍ ÔÁÂÌÉÃ(Ù)" "View '%-.64s.%-.64s' ÓÓÙÌÁÅÔÓÑ ÎÁ ÎÅÓÕÝÅÓÔ×ÕÀÝÉÅ ÔÁÂÌÉÃÙ ÉÌÉ ÓÌÏÌÂÃÙ" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 5b74999a3cd..4039268f446 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -366,3 +366,4 @@ character-set=cp1250 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 5d7fce940e2..9be5ce01d6a 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -368,3 +368,4 @@ character-set=latin2 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 570da612be9..dc15f8b8d5e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -362,3 +362,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 4e97393b0b1..ee5436c3b80 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -360,3 +360,4 @@ character-set=latin1 "View being updated does not have complete key of underlying table in it" "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index a043b6eb651..cb1d99e2fec 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -365,3 +365,4 @@ character-set=koi8u "View, ÝÏ ÏÎÏ×ÌÀÅÔØÓÑ, ΊͦÓÔÉÔØ ÐÏ×ÎÏÇÏ ËÌÀÞÁ ÔÁÂÌÉæ(Ø), ÝÏ ×ÉËÏÒ¦ÓÔÁÎÁ × ÎØÀÏÍÕ" "View '%-.64s.%-.64s' ÐÏÓÉÌÁ¤ÔÓÑ ÎÁ ÎŦÓÎÕÀÞ¦ ÔÁÂÌÉæ ÁÂÏ ÓÔÏ×Âæ" "Can't drop a %s from within another stored routine" +"GOTO is not allowed in a stored procedure handler" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 5a58c32d2da..fd95767b7cd 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -257,7 +257,7 @@ sp_head::operator delete(void *ptr, size_t size) sp_head::sp_head() :Item_arena((bool)FALSE), m_returns_cs(NULL), m_has_return(FALSE), - m_simple_case(FALSE), m_multi_results(FALSE) + m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE) { DBUG_ENTER("sp_head::sp_head"); @@ -272,7 +272,7 @@ sp_head::init(LEX *lex) { DBUG_ENTER("sp_head::init"); - lex->spcont= m_pcont= new sp_pcontext(); + lex->spcont= m_pcont= new sp_pcontext(NULL); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_param_begin= m_param_end= m_returns_begin= m_returns_end= m_body_begin= 0; m_qname.str= m_db.str= m_name.str= m_params.str= m_retstr.str= @@ -514,10 +514,10 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) { DBUG_ENTER("sp_head::execute_function"); DBUG_PRINT("info", ("function %s", m_name.str)); - uint csize = m_pcont->max_framesize(); - uint params = m_pcont->params(); - uint hmax = m_pcont->handlers(); - uint cmax = m_pcont->cursors(); + uint csize = m_pcont->max_pvars(); + uint params = m_pcont->current_pvars(); + uint hmax = m_pcont->max_handlers(); + uint cmax = m_pcont->max_cursors(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; uint i; @@ -594,10 +594,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) DBUG_ENTER("sp_head::execute_procedure"); DBUG_PRINT("info", ("procedure %s", m_name.str)); int ret= 0; - uint csize = m_pcont->max_framesize(); - uint params = m_pcont->params(); - uint hmax = m_pcont->handlers(); - uint cmax = m_pcont->cursors(); + uint csize = m_pcont->max_pvars(); + uint params = m_pcont->current_pvars(); + uint hmax = m_pcont->max_handlers(); + uint cmax = m_pcont->max_cursors(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx @@ -851,12 +851,18 @@ sp_head::backpatch(sp_label_t *lab) (bp->lab->type == SP_LAB_REF && my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0)) { - sp_scope_t sdiff; + 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 (bp->lab->type == SP_LAB_REF) - bp->lab= lab; - m_pcont->diff_scopes(0, &sdiff); - bp->instr->backpatch(dest, sdiff.hndlrs, sdiff.curs); + if (dstlab) + { + bp->lab= lab; + bp->instr->backpatch(dest, dstlab->ctx); + } + } } } } @@ -1236,7 +1242,7 @@ sp_instr_jump::print(String *str) uint sp_instr_jump::opt_mark(sp_head *sp) { - m_dest= opt_shortcut_jump(sp); + m_dest= opt_shortcut_jump(sp, this); if (m_dest != m_ip+1) /* Jumping to following instruction? */ marked= 1; m_optdest= sp->get_instr(m_dest); @@ -1244,15 +1250,18 @@ sp_instr_jump::opt_mark(sp_head *sp) } uint -sp_instr_jump::opt_shortcut_jump(sp_head *sp) +sp_instr_jump::opt_shortcut_jump(sp_head *sp, sp_instr *start) { uint dest= m_dest; sp_instr *i; while ((i= sp->get_instr(dest))) { - uint ndest= i->opt_shortcut_jump(sp); + uint ndest; + if (start == i) + break; + ndest= i->opt_shortcut_jump(sp, start); if (ndest == dest) break; dest= ndest; @@ -1320,7 +1329,7 @@ sp_instr_jump_if::opt_mark(sp_head *sp) marked= 1; if ((i= sp->get_instr(m_dest))) { - m_dest= i->opt_shortcut_jump(sp); + m_dest= i->opt_shortcut_jump(sp, this); m_optdest= sp->get_instr(m_dest); } sp->opt_mark(m_dest); @@ -1377,7 +1386,7 @@ sp_instr_jump_if_not::opt_mark(sp_head *sp) marked= 1; if ((i= sp->get_instr(m_dest))) { - m_dest= i->opt_shortcut_jump(sp); + m_dest= i->opt_shortcut_jump(sp, this); m_optdest= sp->get_instr(m_dest); } sp->opt_mark(m_dest); @@ -1460,7 +1469,7 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp) marked= 1; if ((i= sp->get_instr(m_dest))) { - m_dest= i->opt_shortcut_jump(sp); + m_dest= i->opt_shortcut_jump(sp, this); m_optdest= sp->get_instr(m_dest); } sp->opt_mark(m_dest); @@ -1487,6 +1496,13 @@ sp_instr_hpop::print(String *str) str->qs_append(m_count); } +void +sp_instr_hpop::backpatch(uint dest, sp_pcontext *dst_ctx) +{ + m_count= m_ctx->diff_handlers(dst_ctx); +} + + // // sp_instr_hreturn // @@ -1551,6 +1567,12 @@ sp_instr_cpop::print(String *str) str->qs_append(m_count); } +void +sp_instr_cpop::backpatch(uint dest, sp_pcontext *dst_ctx) +{ + m_count= m_ctx->diff_cursors(dst_ctx); +} + // // sp_instr_copen // diff --git a/sql/sp_head.h b/sql/sp_head.h index 9c29297180d..c0881661ad1 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -86,6 +86,7 @@ public: my_bool m_has_return; // For FUNCTIONs only my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_multi_results; // TRUE if a procedure with SELECT(s) + my_bool m_in_handler; // TRUE if parser in a handler body uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value st_sp_chistics *m_chistics; ulong m_sql_mode; // For SHOW CREATE @@ -262,10 +263,11 @@ public: uint marked; Item *free_list; // My Items uint m_ip; // My index + sp_pcontext *m_ctx; // My parse context // Should give each a name or type code for debugging purposes? - sp_instr(uint ip) - :Sql_alloc(), marked(0), free_list(0), m_ip(ip) + sp_instr(uint ip, sp_pcontext *ctx) + :Sql_alloc(), marked(0), free_list(0), m_ip(ip), m_ctx(ctx) {} virtual ~sp_instr() @@ -279,7 +281,7 @@ public: virtual void print(String *str) = 0; - virtual void backpatch(uint dest, uint hpop, uint cpop) + virtual void backpatch(uint dest, sp_pcontext *dst_ctx) {} virtual uint opt_mark(sp_head *sp) @@ -288,7 +290,7 @@ public: return m_ip+1; } - virtual uint opt_shortcut_jump(sp_head *sp) + virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) { return m_ip; } @@ -311,8 +313,8 @@ class sp_instr_stmt : public sp_instr public: - sp_instr_stmt(uint ip) - : sp_instr(ip), m_lex(NULL) + sp_instr_stmt(uint ip, sp_pcontext *ctx) + : sp_instr(ip, ctx), m_lex(NULL) {} virtual ~sp_instr_stmt(); @@ -353,8 +355,10 @@ public: TABLE_LIST *tables; - sp_instr_set(uint ip, uint offset, Item *val, enum enum_field_types type) - : sp_instr(ip), tables(NULL), m_offset(offset), m_value(val), m_type(type) + sp_instr_set(uint ip, sp_pcontext *ctx, + uint offset, Item *val, enum enum_field_types type) + : sp_instr(ip, ctx), + tables(NULL), m_offset(offset), m_value(val), m_type(type) {} virtual ~sp_instr_set() @@ -382,12 +386,12 @@ public: uint m_dest; // Where we will go - sp_instr_jump(uint ip) - : sp_instr(ip), m_dest(0), m_optdest(0) + sp_instr_jump(uint ip, sp_pcontext *ctx) + : sp_instr(ip, ctx), m_dest(0), m_optdest(0) {} - sp_instr_jump(uint ip, uint dest) - : sp_instr(ip), m_dest(dest), m_optdest(0) + sp_instr_jump(uint ip, sp_pcontext *ctx, uint dest) + : sp_instr(ip, ctx), m_dest(dest), m_optdest(0) {} virtual ~sp_instr_jump() @@ -399,11 +403,11 @@ public: virtual uint opt_mark(sp_head *sp); - virtual uint opt_shortcut_jump(sp_head *sp); + virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start); virtual void opt_move(uint dst, List<sp_instr> *ibp); - virtual void backpatch(uint dest, uint hpop, uint cpop) + virtual void backpatch(uint dest, sp_pcontext *dst_ctx) { if (m_dest == 0) // Don't reset m_dest= dest; @@ -425,12 +429,12 @@ public: TABLE_LIST *tables; - sp_instr_jump_if(uint ip, Item *i) - : sp_instr_jump(ip), tables(NULL), m_expr(i) + sp_instr_jump_if(uint ip, sp_pcontext *ctx, Item *i) + : sp_instr_jump(ip, ctx), tables(NULL), m_expr(i) {} - sp_instr_jump_if(uint ip, Item *i, uint dest) - : sp_instr_jump(ip, dest), tables(NULL), m_expr(i) + sp_instr_jump_if(uint ip, sp_pcontext *ctx, Item *i, uint dest) + : sp_instr_jump(ip, ctx, dest), tables(NULL), m_expr(i) {} virtual ~sp_instr_jump_if() @@ -442,7 +446,7 @@ public: virtual uint opt_mark(sp_head *sp); - virtual uint opt_shortcut_jump(sp_head *sp) + virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) { return m_ip; } @@ -463,12 +467,12 @@ public: TABLE_LIST *tables; - sp_instr_jump_if_not(uint ip, Item *i) - : sp_instr_jump(ip), tables(NULL), m_expr(i) + sp_instr_jump_if_not(uint ip, sp_pcontext *ctx, Item *i) + : sp_instr_jump(ip, ctx), tables(NULL), m_expr(i) {} - sp_instr_jump_if_not(uint ip, Item *i, uint dest) - : sp_instr_jump(ip, dest), tables(NULL), m_expr(i) + sp_instr_jump_if_not(uint ip, sp_pcontext *ctx, Item *i, uint dest) + : sp_instr_jump(ip, ctx, dest), tables(NULL), m_expr(i) {} virtual ~sp_instr_jump_if_not() @@ -480,7 +484,7 @@ public: virtual uint opt_mark(sp_head *sp); - virtual uint opt_shortcut_jump(sp_head *sp) + virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) { return m_ip; } @@ -501,8 +505,9 @@ public: TABLE_LIST *tables; - sp_instr_freturn(uint ip, Item *val, enum enum_field_types type) - : sp_instr(ip), tables(NULL), m_value(val), m_type(type) + sp_instr_freturn(uint ip, sp_pcontext *ctx, + Item *val, enum enum_field_types type) + : sp_instr(ip, ctx), tables(NULL), m_value(val), m_type(type) {} virtual ~sp_instr_freturn() @@ -533,8 +538,8 @@ class sp_instr_hpush_jump : public sp_instr_jump public: - sp_instr_hpush_jump(uint ip, int htype, uint fp) - : sp_instr_jump(ip), m_type(htype), m_frame(fp) + sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp) + : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp) { m_handler= ip+1; m_cond.empty(); @@ -551,7 +556,7 @@ public: virtual uint opt_mark(sp_head *sp); - virtual uint opt_shortcut_jump(sp_head *sp) + virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start) { return m_ip; } @@ -578,8 +583,8 @@ class sp_instr_hpop : public sp_instr public: - sp_instr_hpop(uint ip, uint count) - : sp_instr(ip), m_count(count) + sp_instr_hpop(uint ip, sp_pcontext *ctx, uint count) + : sp_instr(ip, ctx), m_count(count) {} virtual ~sp_instr_hpop() @@ -589,13 +594,7 @@ 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 void backpatch(uint dest, sp_pcontext *dst_ctx); virtual uint opt_mark(sp_head *sp) { @@ -618,8 +617,8 @@ class sp_instr_hreturn : public sp_instr public: - sp_instr_hreturn(uint ip, uint fp) - : sp_instr(ip), m_frame(fp) + sp_instr_hreturn(uint ip, sp_pcontext *ctx, uint fp) + : sp_instr(ip, ctx), m_frame(fp) {} virtual ~sp_instr_hreturn() @@ -649,8 +648,8 @@ class sp_instr_cpush : public sp_instr public: - sp_instr_cpush(uint ip, LEX *lex) - : sp_instr(ip), m_lex(lex) + sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *lex) + : sp_instr(ip, ctx), m_lex(lex) {} virtual ~sp_instr_cpush(); @@ -673,8 +672,8 @@ class sp_instr_cpop : public sp_instr public: - sp_instr_cpop(uint ip, uint count) - : sp_instr(ip), m_count(count) + sp_instr_cpop(uint ip, sp_pcontext *ctx, uint count) + : sp_instr(ip, ctx), m_count(count) {} virtual ~sp_instr_cpop() @@ -684,13 +683,7 @@ 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 void backpatch(uint dest, sp_pcontext *dst_ctx); virtual uint opt_mark(sp_head *sp) { @@ -713,8 +706,8 @@ class sp_instr_copen : public sp_instr_stmt public: - sp_instr_copen(uint ip, uint c) - : sp_instr_stmt(ip), m_cursor(c) + sp_instr_copen(uint ip, sp_pcontext *ctx, uint c) + : sp_instr_stmt(ip, ctx), m_cursor(c) {} virtual ~sp_instr_copen() @@ -738,8 +731,8 @@ class sp_instr_cclose : public sp_instr public: - sp_instr_cclose(uint ip, uint c) - : sp_instr(ip), m_cursor(c) + sp_instr_cclose(uint ip, sp_pcontext *ctx, uint c) + : sp_instr(ip, ctx), m_cursor(c) {} virtual ~sp_instr_cclose() @@ -763,8 +756,8 @@ class sp_instr_cfetch : public sp_instr public: - sp_instr_cfetch(uint ip, uint c) - : sp_instr(ip), m_cursor(c) + sp_instr_cfetch(uint ip, sp_pcontext *ctx, uint c) + : sp_instr(ip, ctx), m_cursor(c) { m_varlist.empty(); } @@ -796,8 +789,8 @@ class sp_instr_error : public sp_instr public: - sp_instr_error(uint ip, int errcode) - : sp_instr(ip), m_errcode(errcode) + sp_instr_error(uint ip, sp_pcontext *ctx, int errcode) + : sp_instr(ip, ctx), m_errcode(errcode) {} virtual ~sp_instr_error() diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 6f999531e58..c83259c3926 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -26,79 +26,98 @@ #include "sp_pcontext.h" #include "sp_head.h" -sp_pcontext::sp_pcontext() - : Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_cursmax(0), - m_hndlrlev(0) +sp_pcontext::sp_pcontext(sp_pcontext *prev) + : Sql_alloc(), m_psubsize(0), m_csubsize(0), m_hsubsize(0), + m_parent(prev), m_handlers(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(); + m_children.empty(); + if (!prev) + m_poffset= m_coffset= 0; + else + { + m_poffset= prev->current_pvars(); + m_coffset= prev->current_cursors(); + } } void sp_pcontext::destroy() { + List_iterator_fast<sp_pcontext> li(m_children); + sp_pcontext *child; + + while ((child= li++)) + child->destroy(); + + m_children.empty(); + m_label.empty(); delete_dynamic(&m_pvar); delete_dynamic(&m_cond); delete_dynamic(&m_cursor); - delete_dynamic(&m_scopes); - delete_dynamic(&m_glabel); - m_label.empty(); } -void -sp_pcontext::push_scope() +sp_pcontext * +sp_pcontext::push_context() { - sp_scope_t s; - - 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); + sp_pcontext *child= new sp_pcontext(this); + + if (child) + m_children.push_back(child); + return child; } -void -sp_pcontext::pop_scope(sp_scope_t *sp) +sp_pcontext * +sp_pcontext::pop_context() { - byte *p= pop_dynamic(&m_scopes); - - if (sp && p) - memcpy(sp, p, sizeof(sp_scope_t)); + uint submax= max_pvars(); + + if (submax > m_parent->m_psubsize) + m_parent->m_psubsize= submax; + submax= max_handlers(); + if (submax > m_parent->m_hsubsize) + m_parent->m_hsubsize= submax; + submax= max_cursors(); + if (submax > m_parent->m_csubsize) + m_parent->m_csubsize= submax; + return m_parent; } -void -sp_pcontext::diff_scopes(uint sold, sp_scope_t *diffs) +uint +sp_pcontext::diff_handlers(sp_pcontext *ctx) { - uint snew= m_scopes.elements; - sp_scope_t scope; + uint n= 0; + sp_pcontext *pctx= this; - diffs->vars= diffs->conds= diffs->hndlrs= diffs->curs= diffs->glab= 0; - while (snew-- > sold) + while (pctx && pctx != ctx) { - 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; + n+= pctx->max_handlers(); + pctx= pctx->parent_context(); } - if (sold) + if (pctx) + return n; + return 0; // Didn't find ctx +} + +uint +sp_pcontext::diff_cursors(sp_pcontext *ctx) +{ + uint n= 0; + sp_pcontext *pctx= this; + + while (pctx && pctx != ctx) { - 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; + n+= pctx->max_cursors(); + pctx= pctx->parent_context(); } + if (pctx) + return n; + return 0; // Didn't find ctx } - /* This does a linear search (from newer to older variables, in case ** we have shadowed names). ** It's possible to have a more efficient allocation and search method, @@ -109,20 +128,9 @@ sp_pcontext::diff_scopes(uint sold, sp_scope_t *diffs) sp_pvar_t * sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped) { - uint i = m_pvar.elements; - uint limit; - - if (! scoped || m_scopes.elements == 0) - limit= 0; - else - { - sp_scope_t s; + uint i= m_pvar.elements; - get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1); - limit= s.vars; - } - - while (i-- > limit) + while (i--) { sp_pvar_t *p; @@ -134,6 +142,8 @@ sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped) return p; } } + if (!scoped && m_parent) + return m_parent->find_pvar(name, scoped); return NULL; } @@ -145,13 +155,13 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type, if (p) { - if (m_pvar.elements == m_framesize) - m_framesize += 1; + if (m_pvar.elements == m_psubsize) + m_psubsize+= 1; p->name.str= name->str; p->name.length= name->length; p->type= type; p->mode= mode; - p->offset= m_pvar.elements; + p->offset= current_pvars(); p->isset= (mode == sp_param_out ? FALSE : TRUE); p->dflt= NULL; insert_dynamic(&m_pvar, (gptr)&p); @@ -168,7 +178,7 @@ sp_pcontext::push_label(char *name, uint ip) lab->name= name; lab->ip= ip; lab->type= SP_LAB_GOTO; - lab->scopes= 0; + lab->ctx= this; m_label.push_front(lab); } return lab; @@ -184,6 +194,8 @@ sp_pcontext::find_label(char *name) if (my_strcasecmp(system_charset_info, name, lab->name) == 0) return lab; + if (m_parent) + return m_parent->find_label(name); return NULL; } @@ -207,20 +219,9 @@ sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val) sp_cond_type_t * sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped) { - uint i = m_cond.elements; - uint limit; + uint i= m_cond.elements; - if (! scoped || m_scopes.elements == 0) - limit= 0; - else - { - sp_scope_t s; - - get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1); - limit= s.conds; - } - - while (i-- > limit) + while (i--) { sp_cond_t *p; @@ -232,6 +233,8 @@ sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped) return p->val; } } + if (!scoped && m_parent) + return m_parent->find_cond(name, scoped); return NULL; } @@ -240,11 +243,11 @@ sp_pcontext::push_cursor(LEX_STRING *name) { LEX_STRING n; + if (m_cursor.elements == m_csubsize) + m_csubsize+= 1; n.str= name->str; n.length= name->length; insert_dynamic(&m_cursor, (gptr)&n); - if (m_cursor.elements > m_cursmax) - m_cursmax= m_cursor.elements; } /* @@ -253,20 +256,9 @@ sp_pcontext::push_cursor(LEX_STRING *name) my_bool sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped) { - uint i = m_cursor.elements; - uint limit; + uint i= m_cursor.elements; - if (! scoped || m_scopes.elements == 0) - limit= 0; - else - { - sp_scope_t s; - - get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1); - limit= s.curs; - } - - while (i-- > limit) + while (i--) { LEX_STRING n; @@ -279,43 +271,7 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped) return TRUE; } } + if (!scoped && m_parent) + return m_parent->find_cursor(name, poff, 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); -} diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index e3bdc41779a..6db62614aa5 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -50,7 +50,7 @@ typedef struct sp_label char *name; uint ip; // Instruction index int type; // begin/iter or ref/free - uint scopes; // No. of scopes at label + struct sp_pcontext *ctx; // The label's context } sp_label_t; typedef struct sp_cond_type @@ -66,11 +66,6 @@ typedef struct sp_cond sp_cond_type_t *val; } sp_cond_t; -typedef struct sp_scope -{ - uint vars, conds, hndlrs, curs, glab; -} sp_scope_t; - class sp_pcontext : public Sql_alloc { sp_pcontext(const sp_pcontext &); /* Prevent use of these */ @@ -78,28 +73,30 @@ class sp_pcontext : public Sql_alloc public: - sp_pcontext(); + sp_pcontext(sp_pcontext *prev); // Free memory void destroy(); - // For error checking of duplicate things - void - push_scope(); + sp_pcontext * + push_context(); - void - pop_scope(sp_scope_t *sp = 0); + // Returns the previous context, not the one we pop + sp_pcontext * + pop_context(); - uint - scopes() + sp_pcontext * + parent_context() { - return m_scopes.elements; + return m_parent; } - // Sets '*diffs' to the differences between current scope index snew and sold - void - diff_scopes(uint sold, sp_scope_t *diffs); + uint + diff_handlers(sp_pcontext *ctx); + + uint + diff_cursors(sp_pcontext *ctx); // @@ -107,28 +104,27 @@ class sp_pcontext : public Sql_alloc // inline uint - max_framesize() + max_pvars() { - return m_framesize; + return m_psubsize + m_pvar.elements; } inline uint - current_framesize() + current_pvars() { - return m_pvar.elements; + return m_poffset + m_pvar.elements; } inline uint - params() + context_pvars() { - return m_params; + return m_pvar.elements; } - // Set the number of parameters to the current esize - inline void - set_params() + inline uint + pvar_context2index(uint i) { - m_params= m_pvar.elements; + return m_poffset + i; } inline void @@ -199,7 +195,11 @@ class sp_pcontext : public Sql_alloc inline sp_label_t * last_label() { - return m_label.head(); + sp_label_t *lab= m_label.head(); + + if (!lab && m_parent) + lab= m_parent->last_label(); + return lab; } inline sp_label_t * @@ -236,23 +236,17 @@ class sp_pcontext : public Sql_alloc } inline uint - handlers() + max_handlers() { - return m_handlers; + return m_hsubsize + m_handlers; } inline void - push_handlers(uint count) + push_handlers(uint n) { - m_hndlrlev+= count; + m_handlers+= n; } - inline void - pop_handlers(uint count) - { - m_hndlrlev-= count; - } - // // Cursors // @@ -263,48 +257,41 @@ class sp_pcontext : public Sql_alloc my_bool find_cursor(LEX_STRING *name, uint *poff, my_bool scoped=0); - inline void - pop_cursor(uint num) + inline uint + max_cursors() { - while (num--) - pop_dynamic(&m_cursor); + return m_csubsize + m_cursor.elements; } inline uint - cursors() + current_cursors() { - return m_cursmax; + return m_coffset + m_cursor.elements; } - // - // GOTO labels - // - - sp_label_t * - push_glabel(char *name, uint ip); +protected: - sp_label_t * - find_glabel(char *name); - - void - pop_glabel(uint count); + // The maximum sub context's framesizes + uint m_psubsize; + uint m_csubsize; + uint m_hsubsize; 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 + sp_pcontext *m_parent; // Parent context + + uint m_poffset; // Variable offset for this context + uint m_coffset; // Cursor offset for this context + uint m_handlers; // No. of handlers in this context 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 + List<sp_pcontext> m_children; // Children contexts, used for destruction + }; // class sp_pcontext : public Sql_alloc diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a01abd9141b..1b15bc9a516 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1169,7 +1169,6 @@ create: LEX *lex= Lex; lex->sphead->m_param_end= lex->tok_start; - lex->spcont->set_params(); bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); } sp_c_chistics @@ -1258,7 +1257,6 @@ create_function_tail: { LEX *lex= Lex; - lex->spcont->set_params(); lex->sphead->m_param_end= lex->tok_start; } RETURNS_SYM @@ -1470,25 +1468,28 @@ sp_decl: DECLARE_SYM sp_decl_idents type sp_opt_default { LEX *lex= Lex; - uint max= lex->spcont->current_framesize(); + sp_pcontext *ctx= lex->spcont; + uint max= ctx->context_pvars(); enum enum_field_types type= (enum enum_field_types)$3; Item *it= $4; for (uint i = max-$2 ; i < max ; i++) { - lex->spcont->set_type(i, type); + ctx->set_type(i, type); if (! it) - lex->spcont->set_isset(i, FALSE); + ctx->set_isset(i, FALSE); else { sp_instr_set *in= new sp_instr_set(lex->sphead->instructions(), - i, it, type); + ctx, + ctx->pvar_context2index(i), + it, type); in->tables= lex->query_tables; lex->query_tables= 0; lex->sphead->add_instr(in); - lex->spcont->set_isset(i, TRUE); - lex->spcont->set_default(i, it); + ctx->set_isset(i, TRUE); + ctx->set_default(i, it); } } $$.vars= $2; @@ -1514,30 +1515,33 @@ sp_decl: sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; sp_instr_hpush_jump *i= - new sp_instr_hpush_jump(sp->instructions(), $2, - ctx->current_framesize()); + new sp_instr_hpush_jump(sp->instructions(), ctx, $2, + ctx->current_pvars()); sp->add_instr(i); sp->push_backpatch(i, ctx->push_label((char *)"", 0)); ctx->add_handler(); + sp->m_in_handler= TRUE; } sp_hcond_list sp_proc_stmt { LEX *lex= Lex; sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; sp_label_t *hlab= lex->spcont->pop_label(); /* After this hdlr */ if ($2 == SP_HANDLER_CONTINUE) - sp->add_instr(new sp_instr_hreturn(sp->instructions(), - lex->spcont->current_framesize())); + sp->add_instr(new sp_instr_hreturn(sp->instructions(), ctx, + ctx->current_pvars())); else { /* EXIT or UNDO handler, just jump to the end of the block */ - sp_instr_jump *i= new sp_instr_jump(sp->instructions()); + sp_instr_jump *i= new sp_instr_jump(sp->instructions(), ctx); sp->add_instr(i); sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */ } lex->sphead->backpatch(hlab); + sp->m_in_handler= FALSE; $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= $6; } @@ -1545,19 +1549,19 @@ sp_decl: { LEX *lex= Lex; sp_head *sp= lex->sphead; - sp_pcontext *spc= lex->spcont; + sp_pcontext *ctx= lex->spcont; uint offp; sp_instr_cpush *i; - if (spc->find_cursor(&$2, &offp, TRUE)) + if (ctx->find_cursor(&$2, &offp, TRUE)) { net_printf(YYTHD, ER_SP_DUP_CURS, $2.str); delete $5; YYABORT; } - i= new sp_instr_cpush(sp->instructions(), $5); + i= new sp_instr_cpush(sp->instructions(), ctx, $5); sp->add_instr(i); - lex->spcont->push_cursor(&$2); + ctx->push_cursor(&$2); $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; } @@ -1748,7 +1752,8 @@ sp_proc_stmt: } else { - sp_instr_stmt *i=new sp_instr_stmt(lex->sphead->instructions()); + sp_instr_stmt *i=new sp_instr_stmt(lex->sphead->instructions(), + lex->spcont); i->set_lex(lex); lex->sphead->add_instr(i); @@ -1776,6 +1781,7 @@ sp_proc_stmt: YYABORT; } i= new sp_instr_freturn(lex->sphead->instructions(), + lex->spcont, $2, lex->sphead->m_returns); lex->sphead->add_instr(i); lex->sphead->m_has_return= TRUE; @@ -1794,8 +1800,9 @@ sp_proc_stmt: at the same frame level, so we then know that it's the top-most variable in the frame. */ LEX *lex= Lex; - uint offset= lex->spcont->current_framesize(); + uint offset= lex->spcont->current_pvars(); sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(), + lex->spcont, offset, $2, MYSQL_TYPE_STRING); LEX_STRING dummy; @@ -1839,19 +1846,17 @@ sp_proc_stmt: else { 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); + ih= new sp_instr_hpop(ip++, ctx, 0); sp->push_backpatch(ih, lab); sp->add_instr(ih); - ic= new sp_instr_cpop(ip++, sdiff.curs); + ic= new sp_instr_cpop(ip++, ctx, 0); sp->push_backpatch(ic, lab); sp->add_instr(ic); - i= new sp_instr_jump(ip); + i= new sp_instr_jump(ip, ctx); sp->push_backpatch(i, lab); /* Jumping forward */ sp->add_instr(i); } @@ -1872,14 +1877,15 @@ sp_proc_stmt: { sp_instr_jump *i; uint ip= sp->instructions(); - sp_scope_t sdiff; - - 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 */ + uint n; + + n= ctx->diff_handlers(lab->ctx); + if (n) + sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); + n= ctx->diff_cursors(lab->ctx); + if (n) + sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); + i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ sp->add_instr(i); } } @@ -1890,8 +1896,6 @@ sp_proc_stmt: 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); @@ -1899,9 +1903,9 @@ sp_proc_stmt: } else { - lab= ctx->push_glabel($2.str, sp->instructions()); + lab= ctx->push_label($2.str, sp->instructions()); lab->type= SP_LAB_GOTO; - lab->scopes= ctx->scopes(); + lab->ctx= ctx; sp->backpatch(lab); } } @@ -1911,48 +1915,52 @@ sp_proc_stmt: 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_label_t *lab; sp_instr_jump *i; sp_instr_hpop *ih; sp_instr_cpop *ic; - if (! lab) - lab= ctx->find_glabel($2.str); - + if (sp->m_in_handler) + { + send_error(lex->thd, ER_SP_GOTO_IN_HNDLR); + 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->scopes= 0; + lab->ctx= ctx; - ctx->diff_scopes(0, &sdiff); - ih= new sp_instr_hpop(ip++, sdiff.hndlrs); + ih= new sp_instr_hpop(ip++, ctx, 0); sp->push_backpatch(ih, lab); sp->add_instr(ih); - ic= new sp_instr_cpop(ip++, sdiff.curs); + ic= new sp_instr_cpop(ip++, ctx, 0); sp->add_instr(ic); sp->push_backpatch(ic, lab); - i= new sp_instr_jump(ip); + i= new sp_instr_jump(ip, ctx); sp->push_backpatch(i, lab); /* Jumping forward */ sp->add_instr(i); } else { - ctx->diff_scopes(lab->scopes, &sdiff); - if (sdiff.hndlrs) + uint n; + + n= ctx->diff_handlers(lab->ctx); + if (n) { - ih= new sp_instr_hpop(ip++, sdiff.hndlrs); + ih= new sp_instr_hpop(ip++, ctx, n); sp->add_instr(ih); } - if (sdiff.curs) + n= ctx->diff_cursors(lab->ctx); + if (n) { - ic= new sp_instr_cpop(ip++, sdiff.curs); + ic= new sp_instr_cpop(ip++, ctx, n); sp->add_instr(ic); } - i= new sp_instr_jump(ip, lab->ip); /* Jump back */ + i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ sp->add_instr(i); } } @@ -1968,7 +1976,7 @@ sp_proc_stmt: net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); YYABORT; } - i= new sp_instr_copen(sp->instructions(), offset); + i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); sp->add_instr(i); } | FETCH_SYM ident INTO @@ -1983,7 +1991,7 @@ sp_proc_stmt: net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); YYABORT; } - i= new sp_instr_cfetch(sp->instructions(), offset); + i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); sp->add_instr(i); } sp_fetch_list @@ -2000,7 +2008,7 @@ sp_proc_stmt: net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); YYABORT; } - i= new sp_instr_cclose(sp->instructions(), offset); + i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); sp->add_instr(i); } ; @@ -2056,7 +2064,7 @@ sp_if: sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; uint ip= sp->instructions(); - sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $1); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, $1); i->tables= lex->query_tables; lex->query_tables= 0; @@ -2068,7 +2076,7 @@ sp_if: sp_head *sp= Lex->sphead; sp_pcontext *ctx= Lex->spcont; uint ip= sp->instructions(); - sp_instr_jump *i = new sp_instr_jump(ip); + sp_instr_jump *i = new sp_instr_jump(ip, ctx); sp->add_instr(i); sp->backpatch(ctx->pop_label()); @@ -2098,7 +2106,7 @@ sp_case: sp_instr_jump_if_not *i; if (! sp->m_simple_case) - i= new sp_instr_jump_if_not(ip, $1); + i= new sp_instr_jump_if_not(ip, ctx, $1); else { /* Simple case: <caseval> = <whenval> */ LEX_STRING ivar; @@ -2106,10 +2114,10 @@ sp_case: ivar.str= (char *)"_tmp_"; ivar.length= 5; Item *var= (Item*) new Item_splocal(ivar, - ctx->current_framesize()-1); + ctx->current_pvars()-1); Item *expr= new Item_func_eq(var, $1); - i= new sp_instr_jump_if_not(ip, expr); + i= new sp_instr_jump_if_not(ip, ctx, expr); lex->variables_used= 1; } sp->push_backpatch(i, ctx->push_label((char *)"", 0)); @@ -2122,7 +2130,7 @@ sp_case: sp_head *sp= Lex->sphead; sp_pcontext *ctx= Lex->spcont; uint ip= sp->instructions(); - sp_instr_jump *i = new sp_instr_jump(ip); + sp_instr_jump *i = new sp_instr_jump(ip, ctx); sp->add_instr(i); sp->backpatch(ctx->pop_label()); @@ -2141,7 +2149,8 @@ sp_whens: { sp_head *sp= Lex->sphead; uint ip= sp->instructions(); - sp_instr_error *i= new sp_instr_error(ip, ER_SP_CASE_NOT_FOUND); + sp_instr_error *i= new sp_instr_error(ip, Lex->spcont, + ER_SP_CASE_NOT_FOUND); sp->add_instr(i); } @@ -2166,7 +2175,6 @@ sp_labeled_control: 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 @@ -2204,32 +2212,24 @@ sp_unlabeled_control: sp_label_t *lab= lex->spcont->last_label(); lab->type= SP_LAB_BEGIN; - /* Scope duplicate checking */ - lex->spcont->push_scope(); + lex->spcont= lex->spcont->push_context(); } 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 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(), ctx, + $3.hndlrs)); if ($3.curs) - sp->add_instr(new sp_instr_cpop(sp->instructions(), $3.curs)); - ctx->pop_scope(&scope); - ctx->pop_glabel(scope.glab); + sp->add_instr(new sp_instr_cpop(sp->instructions(), ctx, + $3.curs)); + lex->spcont= ctx->pop_context(); } | LOOP_SYM sp_proc_stmts END LOOP_SYM @@ -2237,7 +2237,7 @@ sp_unlabeled_control: LEX *lex= Lex; uint ip= lex->sphead->instructions(); sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ - sp_instr_jump *i = new sp_instr_jump(ip, lab->ip); + sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); lex->sphead->add_instr(i); } @@ -2246,7 +2246,8 @@ sp_unlabeled_control: LEX *lex= Lex; sp_head *sp= lex->sphead; uint ip= sp->instructions(); - sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $2); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, + $2); /* Jumping forward */ sp->push_backpatch(i, lex->spcont->last_label()); @@ -2259,7 +2260,7 @@ sp_unlabeled_control: LEX *lex= Lex; uint ip= lex->sphead->instructions(); sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ - sp_instr_jump *i = new sp_instr_jump(ip, lab->ip); + sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); lex->sphead->add_instr(i); } @@ -2268,7 +2269,8 @@ sp_unlabeled_control: LEX *lex= Lex; uint ip= lex->sphead->instructions(); sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ - sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $4, lab->ip); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, + $4, lab->ip); i->tables= lex->query_tables; lex->query_tables= 0; @@ -6786,11 +6788,12 @@ option_value: } else { /* An SP local variable */ + sp_pcontext *ctx= lex->spcont; sp_pvar_t *spv; sp_instr_set *i; Item *it; - spv= lex->spcont->find_pvar(&$1.base_name); + spv= ctx->find_pvar(&$1.base_name); if ($3) it= $3; @@ -6798,7 +6801,7 @@ option_value: it= spv->dflt; else it= new Item_null(); - i= new sp_instr_set(lex->sphead->instructions(), + i= new sp_instr_set(lex->sphead->instructions(), ctx, spv->offset, it, spv->type); i->tables= lex->query_tables; lex->query_tables= 0; |