diff options
author | unknown <pem@mysql.com> | 2005-11-01 14:58:52 +0100 |
---|---|---|
committer | unknown <pem@mysql.com> | 2005-11-01 14:58:52 +0100 |
commit | 2c4c542ba2a82d42d3109f5257d0323e99bb321d (patch) | |
tree | d8e18d83d387b0b8b5cfd092973e6441f0ccec8a | |
parent | 389018280db5fab79ec76fb286071734b014fc0e (diff) | |
download | mariadb-git-2c4c542ba2a82d42d3109f5257d0323e99bb321d.tar.gz |
Fixed BUG#14376: MySQL crash on scoped variable (re)initialization
Added finer scope control for default clauses of local variable
declarations.
mysql-test/r/sp.result:
New test case for BUG#14376.
mysql-test/t/sp.test:
New test case for BUG#14376.
sql/sp_pcontext.cc:
Added boundary variable for local parameters/variables,
for better scope control of default values.
sql/sp_pcontext.h:
Added boundary variable for local parameters/variables,
for better scope control of default values.
sql/sql_yacc.yy:
Make the variables of the current DECLARE "invisible" to its DEFAULT clause.
-rw-r--r-- | mysql-test/r/sp.result | 29 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 45 | ||||
-rw-r--r-- | sql/sp_pcontext.cc | 5 | ||||
-rw-r--r-- | sql/sp_pcontext.h | 16 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 8 |
5 files changed, 100 insertions, 3 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1f3f7dba7da..1e4d3de5dfa 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3575,4 +3575,33 @@ DROP VIEW bug13095_v1 DROP PROCEDURE IF EXISTS bug13095; DROP VIEW IF EXISTS bug13095_v1; DROP TABLE IF EXISTS bug13095_t1; +drop procedure if exists bug14376| +create procedure bug14376() +begin +declare x int default x; +end| +call bug14376()| +ERROR 42S22: Unknown column 'x' in 'field list' +drop procedure bug14376| +create procedure bug14376() +begin +declare x int default 42; +begin +declare x int default x; +select x; +end; +end| +call bug14376()| +x +42 +drop procedure bug14376| +create procedure bug14376(x int) +begin +declare x int default x; +select x; +end| +call bug14376(4711)| +x +4711 +drop procedure bug14376| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ab57139bb77..f1b76686c4a 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4490,6 +4490,51 @@ delimiter |; # +# BUG#14376: MySQL crash on scoped variable (re)initialization +# +--disable_warnings +drop procedure if exists bug14376| +--enable_warnings + +create procedure bug14376() +begin + declare x int default x; +end| + +# Not the error we want, but that's what we got for now... +--error ER_BAD_FIELD_ERROR +call bug14376()| +drop procedure bug14376| + +create procedure bug14376() +begin + declare x int default 42; + + begin + declare x int default x; + + select x; + end; +end| + +call bug14376()| + +drop procedure bug14376| + +create procedure bug14376(x int) +begin + declare x int default x; + + select x; +end| + +call bug14376(4711)| + +drop procedure bug14376| + + + +# # BUG#NNNN: New bug synopsis # #--disable_warnings diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index f873b676925..cca3e03d69c 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -52,7 +52,7 @@ sp_cond_check(LEX_STRING *sqlstate) sp_pcontext::sp_pcontext(sp_pcontext *prev) : Sql_alloc(), m_psubsize(0), m_csubsize(0), m_hsubsize(0), - m_handlers(0), m_parent(prev) + m_handlers(0), m_parent(prev), m_pboundary(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)); @@ -150,7 +150,7 @@ sp_pcontext::diff_cursors(sp_pcontext *ctx) sp_pvar_t * sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped) { - uint i= m_pvar.elements; + uint i= m_pboundary; while (i--) { @@ -186,6 +186,7 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type, p->offset= current_pvars(); p->dflt= NULL; insert_dynamic(&m_pvar, (gptr)&p); + m_pboundary= m_pvar.elements; } } diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index bd2259cb6fb..fbeac37c058 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -164,6 +164,7 @@ class sp_pcontext : public Sql_alloc { while (num--) pop_dynamic(&m_pvar); + m_pboundary= m_pvar.elements; } // Find by name @@ -183,6 +184,14 @@ class sp_pcontext : public Sql_alloc return p; } + // Set the current scope boundary (for default values) + // The argument is the number of variables to skip. + inline void + declare_var_boundary(uint n) + { + m_pboundary= m_pvar.elements-n; + } + // // Labels // @@ -287,6 +296,13 @@ private: uint m_poffset; // Variable offset for this context uint m_coffset; // Cursor offset for this context + /* + Boundary for finding variables in this in this context. + This is normally the same as m_pvar.elements, but differs during + parsing of DECLARE ... DEFAULT, to get the scope right for DEFAULT + values. + */ + uint m_pboundary; DYNAMIC_ARRAY m_pvar; // Parameters/variables DYNAMIC_ARRAY m_cond; // Conditions diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 109dcd7e86a..c3c53b2f611 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1660,7 +1660,12 @@ sp_decls: sp_decl: DECLARE_SYM sp_decl_idents type - { Lex->sphead->reset_lex(YYTHD); } + { + LEX *lex= Lex; + + lex->sphead->reset_lex(YYTHD); + lex->spcont->declare_var_boundary($2); + } sp_opt_default { LEX *lex= Lex; @@ -1690,6 +1695,7 @@ sp_decl: lex->sphead->add_instr(in); ctx->set_default(i, it); } + ctx->declare_var_boundary(0); lex->sphead->restore_lex(YYTHD); $$.vars= $2; $$.conds= $$.hndlrs= $$.curs= 0; |