From 69047e719a6845800d0f05c04dca55d2de95feed Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 18 Jan 2003 18:21:13 +0200 Subject: [PATCH] SELECT ... INTO local_vars ...; For Stored Procedures --- mysql-test/r/sp.result | 17 ++++++++++++++ mysql-test/t/sp.test | 13 +++++++++++ sql/sql_class.cc | 51 +++++++++++++++++++++++++++++++++++------- sql/sql_class.h | 13 +++++++++-- sql/sql_yacc.yy | 23 +++++++++++++++++-- 5 files changed, 105 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 0e2dfc52c52..59259c1225e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -124,6 +124,15 @@ insert into test.t1 values ("h1", x); else insert into test.t1 values ("h?", x); 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(); select * from t1; id data @@ -236,6 +245,13 @@ id data h0 0 h1 1 h? 17 +call sinisa(); +select * from t1; +id data +h0 0 +h1 1 +h? 17 +h? 17 delete from t1; drop procedure foo42; drop procedure bar; @@ -258,4 +274,5 @@ drop procedure e; drop procedure f; drop procedure g; drop procedure h; +drop procedure sinisa; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6b90d700b58..d9b04afa333 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -187,6 +187,16 @@ else insert into test.t1 values ("h?", x); 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 ;| # Now, the CALL tests... @@ -263,6 +273,8 @@ call h(0); call h(1); call h(17); select * from t1; +call sinisa(); +select * from t1; delete from t1; drop procedure foo42; @@ -286,5 +298,6 @@ drop procedure e; drop procedure f; drop procedure g; drop procedure h; +drop procedure sinisa; drop table t1; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a5fb7922243..8e66e1ca068 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -36,6 +36,7 @@ #endif #include #include +#include /***************************************************************************** @@ -960,37 +961,71 @@ bool select_exists_subselect::send_data(List &items) int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) { List_iterator_fast li(list); - List_iterator_fast gl(var_list); + List_iterator_fast gl(var_list); Item *item; + my_var *mv; LEX_STRING *ls; if (var_list.elements != list.elements) { my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); return 1; } + unit=u; while ((item=li++)) { - ls= gl++; - Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); - xx->fix_fields(current_thd,(TABLE_LIST*) current_thd->lex.select_lex.table_list.first,&item); - xx->fix_length_and_dec(); - vars.push_back(xx); + mv=gl++; + ls= &mv->s; + if (mv->local) + { + (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; } bool select_dumpvar::send_data(List &items) { List_iterator_fast li(vars); + List_iterator_fast var_li(local_vars); + List_iterator_fast my_li(var_list); + List_iterator_fast it(items); Item_func_set_user_var *xx; + Item_splocal *yy; + Item *item; + my_var *zz; DBUG_ENTER("send_data"); + if (unit->offset_limit_cnt) + { // using limit offset,count + unit->offset_limit_cnt--; + DBUG_RETURN(0); + } if (row_count++) { my_error(ER_TOO_MANY_ROWS, MYF(0)); DBUG_RETURN(1); } - while ((xx=li++)) - xx->update(); + while ((zz=my_li++) && (item=it++)) + { + if (zz->local) + { + if ((yy=var_li++)) + { + thd->spcont->set_item(yy->get_offset(), item); + } + } + else + { + if ((xx=li++)) + xx->update(); + } + } DBUG_RETURN(0); } diff --git a/sql/sql_class.h b/sql/sql_class.h index a078c4bd286..f367b089fd3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -987,13 +987,22 @@ public: 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 { ha_rows row_count; public: - List var_list; + List var_list; List vars; - select_dumpvar(void) { var_list.empty(); vars.empty(); row_count=0;} + List local_vars; + select_dumpvar(void) { var_list.empty(); local_vars.empty(); vars.empty(); row_count=0;} ~select_dumpvar() {} int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) {return 0;} diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2cc2f674d4a..33ec3788b22 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3313,10 +3313,29 @@ select_var_list: | select_var_ident {} ; -select_var_ident: '@' ident_or_text +select_var_ident: + '@' ident_or_text { 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; } ;