Commit 12a0546d authored by unknown's avatar unknown

Handle user variables (@-vars) as OUT and INOUT parameters in SPs.


mysql-test/r/sp.result:
  Test cases for user variables (@-vars) as OUT and INOUT parameters.
mysql-test/t/sp.test:
  Test cases for user variables (@-vars) as OUT and INOUT parameters.
sql/item_func.h:
  We need to be able to detect Item_func_get_user_vars when used as arguments to SPs.
sql/sp_head.cc:
  Handle user variables (@-vars) as OUT and INOUT parameters.
  But we still just ignore it, if it's anything else.
parent 9aa680a0
......@@ -93,8 +93,12 @@ id data
zip 100
delete from t1;
drop procedure zip;
drop procedure zap;
drop procedure bar;
call zap(7, @zap);
select @zap;
@zap
8
drop procedure zap;
create procedure c1(x int)
call c2("c", x);
create procedure c2(s char(16), x int)
......@@ -132,7 +136,17 @@ io1 1
delete from t1;
drop procedure iotest;
drop procedure inc2;
create procedure incr(inout x int)
call inc(x);
select @zap;
@zap
8
call incr(@zap);
select @zap;
@zap
9
drop procedure inc;
drop procedure incr;
create procedure cbv1()
begin
declare y int default 3;
......
......@@ -122,9 +122,14 @@ call zip("zip", 99)|
select * from t1|
delete from t1|
drop procedure zip|
drop procedure zap|
drop procedure bar|
# Top-level OUT parameter
call zap(7, @zap)|
select @zap|
drop procedure zap|
# "Deep" calls...
create procedure c1(x int)
......@@ -165,8 +170,19 @@ select * from t1|
delete from t1|
drop procedure iotest|
drop procedure inc2|
drop procedure inc|
# Propagating top-level @-vars
create procedure incr(inout x int)
call inc(x)|
# Before
select @zap|
call incr(@zap)|
# After
select @zap|
drop procedure inc|
drop procedure incr|
# Call-by-value test
# The expected result is:
......
......@@ -46,7 +46,8 @@ class Item_func :public Item_result_field
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN};
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
GUSERVAR_FUNC};
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
......@@ -926,6 +927,8 @@ class Item_func_get_user_var :public Item_func
Item_func_get_user_var(LEX_STRING a):
Item_func(), name(a) {}
user_var_entry *get_entry();
enum Functype functype() const { return GUSERVAR_FUNC; }
LEX_STRING get_name() { return name; }
double val();
longlong val_int();
String *val_str(String* str);
......
......@@ -389,7 +389,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
else
nctx->push_item(sp_eval_func_item(thd, it,pvar->type)); // IN or INOUT
// Note: If it's OUT or INOUT, it must be a variable.
// QQ: Need to handle "global" user/host variables too!!!
// QQ: We can check for global variables here, or should we do it
// while parsing?
if (pvar->mode == sp_param_in)
nctx->set_oindex(i, -1); // IN
else // OUT or INOUT
......@@ -427,22 +428,27 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (! tmp_octx)
octx->set_item(nctx->get_oindex(i), nctx->get_item(i));
else
{ // A global user variable
#if NOT_USED_NOW
// QQ This works if the parameter really is a user variable, but
// for the moment we can't assure that, so it will crash if it's
// something else. So for now, we just do nothing, to avoid a crash.
// Note: This also assumes we have a get_name() method in
// the Item_func_get_user_var class.
Item *item= nctx->get_item(i);
Item_func_set_user_var *suv;
Item_func_get_user_var *guv= static_cast<Item_func_get_user_var*>(it);
suv= new Item_func_set_user_var(guv->get_name(), item);
suv->fix_fields(thd, NULL, &item);
suv->fix_length_and_dec();
suv->update();
#endif
{
// QQ Currently we just silently ignore non-user-variable arguments.
// We should check this during parsing, when setting up the call
// above
if (it->type() == Item::FUNC_ITEM)
{
Item_func *fi= static_cast<Item_func*>(it);
if (fi->functype() == Item_func::GUSERVAR_FUNC)
{ // A global user variable
Item *item= nctx->get_item(i);
Item_func_set_user_var *suv;
Item_func_get_user_var *guv=
static_cast<Item_func_get_user_var*>(fi);
suv= new Item_func_set_user_var(guv->get_name(), item);
suv->fix_fields(thd, NULL, &item);
suv->fix_length_and_dec();
suv->update();
}
}
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment