summaryrefslogtreecommitdiff
path: root/sql/sp_pcontext.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.comhem.se>2004-08-26 12:54:30 +0200
committerunknown <pem@mysql.comhem.se>2004-08-26 12:54:30 +0200
commit071651efbd5d910047f458121ca1222428d7aa58 (patch)
treee80e61a8c32e018499a7a29eacd653c2d0fd2fbd /sql/sp_pcontext.cc
parentac06195caa5176a0245e635bb7678413c26cb7ab (diff)
downloadmariadb-git-071651efbd5d910047f458121ca1222428d7aa58.tar.gz
Major rehacking and cleanup of sp_pcontext.
This finishes (almost) WL#2002: Implement stored procedure GOTO. Only the syntax issue for free labels remains ("label L;" vs "L:"). include/mysqld_error.h: New error code for GOTO in SP handler. mysql-test/r/sp-error.result: New error test cases for GOTO. mysql-test/r/sp.result: New test cases for GOTO. Also removed some things that made it impossible to run the test in an external (debugged) mysqld. mysql-test/t/sp-error.test: New error test cases for GOTO. mysql-test/t/sp.test: New test cases for GOTO. Also removed some things that made it impossible to run the test in an external (debugged) mysqld. sql/share/czech/errmsg.txt: New error message for GOTO in SP handler. sql/share/danish/errmsg.txt: New error message for GOTO in SP handler. sql/share/dutch/errmsg.txt: New error message for GOTO in SP handler. sql/share/english/errmsg.txt: New error message for GOTO in SP handler. sql/share/estonian/errmsg.txt: New error message for GOTO in SP handler. sql/share/french/errmsg.txt: New error message for GOTO in SP handler. sql/share/german/errmsg.txt: New error message for GOTO in SP handler. sql/share/greek/errmsg.txt: New error message for GOTO in SP handler. sql/share/hungarian/errmsg.txt: New error message for GOTO in SP handler. sql/share/italian/errmsg.txt: New error message for GOTO in SP handler. sql/share/japanese/errmsg.txt: New error message for GOTO in SP handler. sql/share/korean/errmsg.txt: New error message for GOTO in SP handler. sql/share/norwegian-ny/errmsg.txt: New error message for GOTO in SP handler. sql/share/norwegian/errmsg.txt: New error message for GOTO in SP handler. sql/share/polish/errmsg.txt: New error message for GOTO in SP handler. sql/share/portuguese/errmsg.txt: New error message for GOTO in SP handler. sql/share/romanian/errmsg.txt: New error message for GOTO in SP handler. sql/share/russian/errmsg.txt: New error message for GOTO in SP handler. sql/share/serbian/errmsg.txt: New error message for GOTO in SP handler. sql/share/slovak/errmsg.txt: New error message for GOTO in SP handler. sql/share/spanish/errmsg.txt: New error message for GOTO in SP handler. sql/share/swedish/errmsg.txt: New error message for GOTO in SP handler. sql/share/ukrainian/errmsg.txt: New error message for GOTO in SP handler. sql/sp_head.cc: Code cleanup (renaming of pcontext methods), support goto, and fixed bug in jump shortcutting in the optimizer (detect infinite loops). sql/sp_head.h: Code cleanup (renaming of pcontext methods), support goto, and fixed bug in jump shortcutting in the optimizer (detect infinite loops). sql/sp_pcontext.cc: Major rehack and cleanup: - We now push and pop a chain of contexts during parsing (instead of having a single one). - Makes error detection for GOTO easier and enables some optmizations and debugger support. - Makes it a little trickier to keep track on variable and cursor indexes instead. - Renamed things to get a more consistent naming scheme too. sql/sp_pcontext.h: Major rehack and cleanup: - We now push and pop a chain of contexts during parsing (instead of having a single one). - Makes error detection for GOTO easier and enables some optmizations and debugger support. - Makes it a little trickier to keep track on variable and cursor indexes instead. - Renamed things to get a more consistent naming scheme too. sql/sql_yacc.yy: Changes to reflect the rework and renamings in sp_pcontext, and fixed some GOTO error checking.
Diffstat (limited to 'sql/sp_pcontext.cc')
-rw-r--r--sql/sp_pcontext.cc210
1 files changed, 83 insertions, 127 deletions
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);
-}