mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
SELECT ... INTO local_vars ...;
For Stored Procedures
This commit is contained in:
parent
838303a731
commit
69047e719a
5 changed files with 105 additions and 12 deletions
|
@ -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
|
||||||
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;
|
||||||
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
|
||||||
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);
|
||||||
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;
|
||||||
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 @@
|
||||||
#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)
|
||||||
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 @@ public:
|
||||||
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:
|
||||||
| 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;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
Loading…
Reference in a new issue