SELECT ... INTO local_vars ...;

For Stored Procedures
parent 4b0adb20
...@@ -124,6 +124,15 @@ insert into test.t1 values ("h1", x); ...@@ -124,6 +124,15 @@ insert into test.t1 values ("h1", x);
else else
insert into test.t1 values ("h?", x); insert into test.t1 values ("h?", x);
end case; end case;
create procedure sinisa()
begin
declare x char(16);
declare y int;
set x="aaaaa";
set y=22;
select id,data into x,y from test.t1 limit 2,1;
insert into test.t1 values (x, y);
end;
call foo42(); call foo42();
select * from t1; select * from t1;
id data id data
...@@ -236,6 +245,13 @@ id data ...@@ -236,6 +245,13 @@ id data
h0 0 h0 0
h1 1 h1 1
h? 17 h? 17
call sinisa();
select * from t1;
id data
h0 0
h1 1
h? 17
h? 17
delete from t1; delete from t1;
drop procedure foo42; drop procedure foo42;
drop procedure bar; drop procedure bar;
...@@ -258,4 +274,5 @@ drop procedure e; ...@@ -258,4 +274,5 @@ drop procedure e;
drop procedure f; drop procedure f;
drop procedure g; drop procedure g;
drop procedure h; drop procedure h;
drop procedure sinisa;
drop table t1; drop table t1;
...@@ -187,6 +187,16 @@ else ...@@ -187,6 +187,16 @@ else
insert into test.t1 values ("h?", x); insert into test.t1 values ("h?", x);
end case| end case|
create procedure sinisa()
begin
declare x char(16);
declare y int;
set x="aaaaa";
set y=22;
select id,data into x,y from test.t1 limit 2,1;
insert into test.t1 values (x, y);
end|
delimiter ;| delimiter ;|
# Now, the CALL tests... # Now, the CALL tests...
...@@ -263,6 +273,8 @@ call h(0); ...@@ -263,6 +273,8 @@ call h(0);
call h(1); call h(1);
call h(17); call h(17);
select * from t1; select * from t1;
call sinisa();
select * from t1;
delete from t1; delete from t1;
drop procedure foo42; drop procedure foo42;
...@@ -286,5 +298,6 @@ drop procedure e; ...@@ -286,5 +298,6 @@ drop procedure e;
drop procedure f; drop procedure f;
drop procedure g; drop procedure g;
drop procedure h; drop procedure h;
drop procedure sinisa;
drop table t1; drop table t1;
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#endif #endif
#include <mysys_err.h> #include <mysys_err.h>
#include <assert.h> #include <assert.h>
#include <sp_rcontext.h>
/***************************************************************************** /*****************************************************************************
...@@ -960,37 +961,71 @@ bool select_exists_subselect::send_data(List<Item> &items) ...@@ -960,37 +961,71 @@ bool select_exists_subselect::send_data(List<Item> &items)
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{ {
List_iterator_fast<Item> li(list); List_iterator_fast<Item> li(list);
List_iterator_fast<LEX_STRING> gl(var_list); List_iterator_fast<my_var> gl(var_list);
Item *item; Item *item;
my_var *mv;
LEX_STRING *ls; LEX_STRING *ls;
if (var_list.elements != list.elements) if (var_list.elements != list.elements)
{ {
my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0));
return 1; return 1;
} }
unit=u;
while ((item=li++)) while ((item=li++))
{ {
ls= gl++; mv=gl++;
Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); ls= &mv->s;
xx->fix_fields(current_thd,(TABLE_LIST*) current_thd->lex.select_lex.table_list.first,&item); if (mv->local)
xx->fix_length_and_dec(); {
vars.push_back(xx); (void)local_vars.push_back(new Item_splocal(mv->offset));
}
else
{
Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item);
xx->fix_fields(thd,(TABLE_LIST*) thd->lex.select_lex.table_list.first,&item);
xx->fix_length_and_dec();
vars.push_back(xx);
}
} }
return 0; return 0;
} }
bool select_dumpvar::send_data(List<Item> &items) bool select_dumpvar::send_data(List<Item> &items)
{ {
List_iterator_fast<Item_func_set_user_var> li(vars); List_iterator_fast<Item_func_set_user_var> li(vars);
List_iterator_fast<Item_splocal> var_li(local_vars);
List_iterator_fast<my_var> my_li(var_list);
List_iterator_fast<Item> it(items);
Item_func_set_user_var *xx; Item_func_set_user_var *xx;
Item_splocal *yy;
Item *item;
my_var *zz;
DBUG_ENTER("send_data"); DBUG_ENTER("send_data");
if (unit->offset_limit_cnt)
{ // using limit offset,count
unit->offset_limit_cnt--;
DBUG_RETURN(0);
}
if (row_count++) if (row_count++)
{ {
my_error(ER_TOO_MANY_ROWS, MYF(0)); my_error(ER_TOO_MANY_ROWS, MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
while ((xx=li++)) while ((zz=my_li++) && (item=it++))
xx->update(); {
if (zz->local)
{
if ((yy=var_li++))
{
thd->spcont->set_item(yy->get_offset(), item);
}
}
else
{
if ((xx=li++))
xx->update();
}
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -987,13 +987,22 @@ class multi_update : public select_result ...@@ -987,13 +987,22 @@ class multi_update : public select_result
bool send_eof(); bool send_eof();
}; };
class my_var : public Sql_alloc {
public:
LEX_STRING s;
bool local;
uint offset;
my_var (LEX_STRING& j, bool i, uint o) : s(j), local(i), offset(o) {}
~my_var() {}
};
class select_dumpvar :public select_result { class select_dumpvar :public select_result {
ha_rows row_count; ha_rows row_count;
public: public:
List<LEX_STRING> var_list; List<my_var> var_list;
List<Item_func_set_user_var> vars; List<Item_func_set_user_var> vars;
select_dumpvar(void) { var_list.empty(); vars.empty(); row_count=0;} List<Item_splocal> local_vars;
select_dumpvar(void) { var_list.empty(); local_vars.empty(); vars.empty(); row_count=0;}
~select_dumpvar() {} ~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_fields(List<Item> &list, uint flag) {return 0;} bool send_fields(List<Item> &list, uint flag) {return 0;}
......
...@@ -3313,10 +3313,29 @@ select_var_list: ...@@ -3313,10 +3313,29 @@ select_var_list:
| select_var_ident {} | select_var_ident {}
; ;
select_var_ident: '@' ident_or_text select_var_ident:
'@' ident_or_text
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->result && ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) if (lex->result)
((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0));
else
YYABORT;
}
| ident_or_text
{
LEX *lex=Lex;
if (!lex->spcont)
YYABORT;
sp_pvar_t *t;
if (!(t=lex->spcont->find_pvar(&$1)))
{
send_error(lex->thd, ER_SYNTAX_ERROR);
YYABORT;
}
if (lex->result)
((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset));
else
YYABORT; YYABORT;
} }
; ;
......
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