Commit 1f1a8531 authored by pem@mysql.telia.com's avatar pem@mysql.telia.com

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

parent c258c861
...@@ -93,8 +93,12 @@ id data ...@@ -93,8 +93,12 @@ id data
zip 100 zip 100
delete from t1; delete from t1;
drop procedure zip; drop procedure zip;
drop procedure zap;
drop procedure bar; drop procedure bar;
call zap(7, @zap);
select @zap;
@zap
8
drop procedure zap;
create procedure c1(x int) create procedure c1(x int)
call c2("c", x); call c2("c", x);
create procedure c2(s char(16), x int) create procedure c2(s char(16), x int)
...@@ -132,7 +136,17 @@ io1 1 ...@@ -132,7 +136,17 @@ io1 1
delete from t1; delete from t1;
drop procedure iotest; drop procedure iotest;
drop procedure inc2; 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 inc;
drop procedure incr;
create procedure cbv1() create procedure cbv1()
begin begin
declare y int default 3; declare y int default 3;
......
...@@ -122,9 +122,14 @@ call zip("zip", 99)| ...@@ -122,9 +122,14 @@ call zip("zip", 99)|
select * from t1| select * from t1|
delete from t1| delete from t1|
drop procedure zip| drop procedure zip|
drop procedure zap|
drop procedure bar| drop procedure bar|
# Top-level OUT parameter
call zap(7, @zap)|
select @zap|
drop procedure zap|
# "Deep" calls... # "Deep" calls...
create procedure c1(x int) create procedure c1(x int)
...@@ -165,8 +170,19 @@ select * from t1| ...@@ -165,8 +170,19 @@ select * from t1|
delete from t1| delete from t1|
drop procedure iotest| drop procedure iotest|
drop procedure inc2| 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 # Call-by-value test
# The expected result is: # The expected result is:
......
...@@ -46,7 +46,8 @@ public: ...@@ -46,7 +46,8 @@ public:
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, 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 optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
enum Type type() const { return FUNC_ITEM; } enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; } virtual enum Functype functype() const { return UNKNOWN_FUNC; }
...@@ -926,6 +927,8 @@ public: ...@@ -926,6 +927,8 @@ public:
Item_func_get_user_var(LEX_STRING a): Item_func_get_user_var(LEX_STRING a):
Item_func(), name(a) {} Item_func(), name(a) {}
user_var_entry *get_entry(); user_var_entry *get_entry();
enum Functype functype() const { return GUSERVAR_FUNC; }
LEX_STRING get_name() { return name; }
double val(); double val();
longlong val_int(); longlong val_int();
String *val_str(String* str); String *val_str(String* str);
......
...@@ -389,7 +389,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -389,7 +389,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
else else
nctx->push_item(sp_eval_func_item(thd, it,pvar->type)); // IN or INOUT 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. // 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) if (pvar->mode == sp_param_in)
nctx->set_oindex(i, -1); // IN nctx->set_oindex(i, -1); // IN
else // OUT or INOUT else // OUT or INOUT
...@@ -427,22 +428,27 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -427,22 +428,27 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (! tmp_octx) if (! tmp_octx)
octx->set_item(nctx->get_oindex(i), nctx->get_item(i)); octx->set_item(nctx->get_oindex(i), nctx->get_item(i));
else else
{
// 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 { // 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 *item= nctx->get_item(i);
Item_func_set_user_var *suv; Item_func_set_user_var *suv;
Item_func_get_user_var *guv= static_cast<Item_func_get_user_var*>(it); 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= new Item_func_set_user_var(guv->get_name(), item);
suv->fix_fields(thd, NULL, &item); suv->fix_fields(thd, NULL, &item);
suv->fix_length_and_dec(); suv->fix_length_and_dec();
suv->update(); suv->update();
#endif }
}
} }
} }
} }
......
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