summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2005-09-13 12:50:21 +0200
committerunknown <pem@mysql.com>2005-09-13 12:50:21 +0200
commit902932a1e86ea728a8cc62d2ab5b1e0544d797ae (patch)
treee9be1a621c9e211cb4daf7e3f100a113c29249fd
parentb50eb4cd42d2d5073afb2af5af8b19c825a9cca1 (diff)
downloadmariadb-git-902932a1e86ea728a8cc62d2ab5b1e0544d797ae.tar.gz
Fixed BUG#13133: Local variables in stored procedures are not initialized correctly.
Have to init. all local variables in their frames, not just once at the beginning of invocation. mysql-test/r/sp.result: New test case for BUG#13133. mysql-test/t/sp.test: New test case for BUG#13133. sql/sp_head.cc: Just init. local variable slots in the fram to NULL. (Real init. will be done in each block.) sql/sp_pcontext.cc: Removed isset flag, since it's not used. sql/sp_pcontext.h: Removed isset flag, since it's not used. sql/sql_yacc.yy: Initialize local variables in the block to null, or the default value, given. (Untabifed block too.)
-rw-r--r--mysql-test/r/sp.result39
-rw-r--r--mysql-test/t/sp.test45
-rw-r--r--sql/sp_head.cc35
-rw-r--r--sql/sp_pcontext.cc1
-rw-r--r--sql/sp_pcontext.h10
-rw-r--r--sql/sql_yacc.yy67
6 files changed, 124 insertions, 73 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index cb696f93f79..4454f818efb 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3225,4 +3225,43 @@ select @var|
@var
abcdabcd
drop procedure bug12849_2|
+drop procedure if exists bug131333|
+drop function if exists bug131333|
+create procedure bug131333()
+begin
+begin
+declare a int;
+select a;
+set a = 1;
+select a;
+end;
+begin
+declare b int;
+select b;
+end;
+end|
+create function bug131333()
+returns int
+begin
+begin
+declare a int;
+set a = 1;
+end;
+begin
+declare b int;
+return b;
+end;
+end|
+call bug131333()|
+a
+NULL
+a
+1
+b
+NULL
+select bug131333()|
+bug131333()
+NULL
+drop procedure bug131333|
+drop function bug131333|
drop table t1,t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 3d315fa12df..2b705329961 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -4064,6 +4064,51 @@ select @var|
drop procedure bug12849_2|
#
+# BUG#13133: Local variables in stored procedures are not initialized correctly.
+#
+--disable_warnings
+drop procedure if exists bug131333|
+drop function if exists bug131333|
+--enable_warnings
+create procedure bug131333()
+begin
+ begin
+ declare a int;
+
+ select a;
+ set a = 1;
+ select a;
+ end;
+ begin
+ declare b int;
+
+ select b;
+ end;
+end|
+
+create function bug131333()
+ returns int
+begin
+ begin
+ declare a int;
+
+ set a = 1;
+ end;
+ begin
+ declare b int;
+
+ return b;
+ end;
+end|
+
+call bug131333()|
+select bug131333()|
+
+drop procedure bug131333|
+drop function bug131333|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0444499de48..a11907373cd 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1078,7 +1078,6 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
sp_rcontext *octx = thd->spcont;
sp_rcontext *nctx = NULL;
uint i;
- Item_null *nit;
int ret= -1; // Assume error
if (argcount != params)
@@ -1109,22 +1108,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
nctx->push_item(it);
}
+
/*
The rest of the frame are local variables which are all IN.
- Default all variables to null (those with default clauses will
- be set by an set instruction).
+ Push NULLs to get the right size (and make the reuse mechanism work) -
+ the will be initialized by set instructions in each frame.
*/
-
- nit= NULL; // Re-use this, and only create if needed
for (; i < csize ; i++)
- {
- if (! nit)
- {
- if (!(nit= new Item_null()))
- DBUG_RETURN(-1);
- }
- nctx->push_item(nit);
- }
+ nctx->push_item(NULL);
+
thd->spcont= nctx;
binlog_save_options= thd->options;
@@ -1321,23 +1313,14 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
close_thread_tables(thd, 0, 0);
DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str));
+
/*
The rest of the frame are local variables which are all IN.
- Default all variables to null (those with default clauses will
- be set by an set instruction).
+ Push NULLs to get the right size (and make the reuse mechanism work) -
+ the will be initialized by set instructions in each frame.
*/
for (; i < csize ; i++)
- {
- if (! nit)
- {
- if (!(nit= new Item_null()))
- {
- ret= -1;
- break;
- }
- }
- nctx->push_item(nit);
- }
+ nctx->push_item(NULL);
}
thd->spcont= nctx;
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 0de7fe212c0..f873b676925 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -184,7 +184,6 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
p->type= type;
p->mode= mode;
p->offset= current_pvars();
- p->isset= (mode == sp_param_out ? FALSE : TRUE);
p->dflt= NULL;
insert_dynamic(&m_pvar, (gptr)&p);
}
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 196f9ccb24b..bd2259cb6fb 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -35,7 +35,6 @@ typedef struct sp_pvar
enum enum_field_types type;
sp_param_mode_t mode;
uint offset; // Offset in current frame
- my_bool isset;
Item *dflt;
} sp_pvar_t;
@@ -148,15 +147,6 @@ class sp_pcontext : public Sql_alloc
}
inline void
- set_isset(uint i, my_bool val)
- {
- sp_pvar_t *p= find_pvar(i);
-
- if (p)
- p->isset= val;
- }
-
- inline void
set_default(uint i, Item *it)
{
sp_pvar_t *p= find_pvar(i);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 520b6190410..104f9ca8445 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1657,42 +1657,41 @@ sp_decls:
;
sp_decl:
- DECLARE_SYM sp_decl_idents type
+ DECLARE_SYM sp_decl_idents type
{ Lex->sphead->reset_lex(YYTHD); }
sp_opt_default
- {
- LEX *lex= Lex;
- sp_pcontext *ctx= lex->spcont;
- uint max= ctx->context_pvars();
- enum enum_field_types type= (enum enum_field_types)$3;
- Item *it= $5;
+ {
+ LEX *lex= Lex;
+ sp_pcontext *ctx= lex->spcont;
+ uint max= ctx->context_pvars();
+ enum enum_field_types type= (enum enum_field_types)$3;
+ Item *it= $5;
+ bool has_default= (it != NULL);
- for (uint i = max-$2 ; i < max ; i++)
- {
- ctx->set_type(i, type);
- if (! it)
- ctx->set_isset(i, FALSE);
- else
- {
- sp_instr_set *in= new sp_instr_set(lex->sphead->instructions(),
- ctx,
- ctx->pvar_context2index(i),
- it, type, lex,
- (i == max - 1));
-
- /*
- The last instruction is assigned to be responsible for
- freeing LEX.
- */
- lex->sphead->add_instr(in);
- ctx->set_isset(i, TRUE);
- ctx->set_default(i, it);
- }
- }
+ for (uint i = max-$2 ; i < max ; i++)
+ {
+ sp_instr_set *in;
+
+ ctx->set_type(i, type);
+ if (! has_default)
+ it= new Item_null(); /* QQ Set to the type with null_value? */
+ in = new sp_instr_set(lex->sphead->instructions(),
+ ctx,
+ ctx->pvar_context2index(i),
+ it, type, lex,
+ (i == max - 1));
+
+ /*
+ The last instruction is assigned to be responsible for
+ freeing LEX.
+ */
+ lex->sphead->add_instr(in);
+ ctx->set_default(i, it);
+ }
lex->sphead->restore_lex(YYTHD);
- $$.vars= $2;
- $$.conds= $$.hndlrs= $$.curs= 0;
- }
+ $$.vars= $2;
+ $$.conds= $$.hndlrs= $$.curs= 0;
+ }
| DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
{
LEX *lex= Lex;
@@ -2268,7 +2267,6 @@ sp_fetch_list:
sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
i->add_to_varlist(spv);
- spv->isset= TRUE;
}
}
|
@@ -2290,7 +2288,6 @@ sp_fetch_list:
sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
i->add_to_varlist(spv);
- spv->isset= TRUE;
}
}
;
@@ -5894,7 +5891,6 @@ select_var_ident:
else
{
((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset,t->type));
- t->isset= TRUE;
}
}
;
@@ -7925,7 +7921,6 @@ sys_option_value:
sp_set= new sp_instr_set(lex->sphead->instructions(), ctx,
spv->offset, it, spv->type, lex, TRUE);
lex->sphead->add_instr(sp_set);
- spv->isset= TRUE;
}
}
| option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types