diff options
author | unknown <bell@book.sanja.is.com.ua> | 2005-05-09 02:06:18 +0300 |
---|---|---|
committer | unknown <bell@book.sanja.is.com.ua> | 2005-05-09 02:06:18 +0300 |
commit | d214d5016058dc49c62ba67e6c6e65c10cfb729e (patch) | |
tree | d0fe4705999c1a1720b4dcf23eb8a2ce832f7545 | |
parent | 67312e3d5c9eee997e31ed55d5a1554ebf546667 (diff) | |
parent | a6b1546676ecb06a1e2d555ab8716d89bd359c31 (diff) | |
download | mariadb-git-d214d5016058dc49c62ba67e6c6e65c10cfb729e.tar.gz |
merge
mysql-test/t/sp.test:
Auto merged
sql/item.cc:
Auto merged
sql/sp_head.cc:
Auto merged
-rw-r--r-- | mysql-test/r/sp.result | 25 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 29 | ||||
-rw-r--r-- | sql/item.cc | 7 | ||||
-rw-r--r-- | sql/item.h | 14 | ||||
-rw-r--r-- | sql/sp_head.cc | 55 | ||||
-rw-r--r-- | sql/sp_rcontext.cc | 6 | ||||
-rw-r--r-- | sql/sp_rcontext.h | 10 | ||||
-rw-r--r-- | sql/sql_class.cc | 7 |
8 files changed, 130 insertions, 23 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 0cc16448625..c1164380f09 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3073,4 +3073,29 @@ update v1 set data = 10| call bug9841()| drop view v1| drop procedure bug9841| +drop procedure if exists bug5963| +create procedure bug5963_1 () begin declare v int; set v = (select s1 from t3); select v; end;| +create table t3 (s1 int)| +insert into t3 values (5)| +call bug5963_1()| +v +5 +call bug5963_1()| +v +5 +drop procedure bug5963_1| +drop table t3| +create procedure bug5963_2 (cfk_value int) +begin +if cfk_value in (select cpk from t3) then +set @x = 5; +end if; +end; +| +create table t3 (cpk int)| +insert into t3 values (1)| +call bug5963_2(1)| +call bug5963_2(1)| +drop procedure bug5963_2| +drop table t3| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index b4066df1666..80acaacfdb3 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3773,6 +3773,35 @@ drop procedure bug9841| # +# BUG#5963 subqueries in SET/IF +# +--disable_warnings +drop procedure if exists bug5963| +--enable_warnings + +create procedure bug5963_1 () begin declare v int; set v = (select s1 from t3); select v; end;| +create table t3 (s1 int)| +insert into t3 values (5)| +call bug5963_1()| +call bug5963_1()| +drop procedure bug5963_1| +drop table t3| + +create procedure bug5963_2 (cfk_value int) +begin + if cfk_value in (select cpk from t3) then + set @x = 5; + end if; + end; +| +create table t3 (cpk int)| +insert into t3 values (1)| +call bug5963_2(1)| +call bug5963_2(1)| +drop procedure bug5963_2| +drop table t3| + +# # BUG#NNNN: New bug synopsis # #--disable_warnings diff --git a/sql/item.cc b/sql/item.cc index 30c134ebdd5..8100e78491b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -740,6 +740,13 @@ Item_splocal::this_item() return thd->spcont->get_item(m_offset); } + +Item ** +Item_splocal::this_item_addr(THD *thd, Item **addr) +{ + return thd->spcont->get_item_addr(m_offset); +} + Item * Item_splocal::this_const_item() const { diff --git a/sql/item.h b/sql/item.h index 697194e2878..ab8059b8fd1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -525,8 +525,17 @@ public: virtual Item *equal_fields_propagator(byte * arg) { return this; } virtual Item *set_no_const_sub(byte *arg) { return this; } virtual Item *replace_equal_field(byte * arg) { return this; } - - virtual Item *this_item() { return this; } /* For SPs mostly. */ + + /* + For SP local variable returns pointer to Item representing its + current value and pointer to current Item otherwise. + */ + virtual Item *this_item() { return this; } + /* + For SP local variable returns address of pointer to Item representing its + current value and pointer passed via parameter otherwise. + */ + virtual Item **this_item_addr(THD *thd, Item **addr) { return addr; } virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */ // Row emulation @@ -573,6 +582,7 @@ public: bool is_splocal() { return 1; } /* Needed for error checking */ Item *this_item(); + Item **this_item_addr(THD *thd, Item **); Item *this_const_item() const; bool fix_fields(THD *, struct st_table_list *, Item **); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0be93c3e41c..2ffcd45b1a7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -97,19 +97,48 @@ sp_multi_results_command(enum enum_sql_command cmd) } } + +/* + Prepare Item for execution (call of fix_fields) + + SYNOPSIS + sp_prepare_func_item() + thd thread handler + it_addr pointer on item refernce + + RETURN + NULL error + prepared item +*/ + +static Item * +sp_prepare_func_item(THD* thd, Item **it_addr) +{ + Item *it= *it_addr; + DBUG_ENTER("sp_prepare_func_item"); + it_addr= it->this_item_addr(thd, it_addr); + + if (!it->fixed && (*it_addr)->fix_fields(thd, 0, it_addr)) + { + DBUG_PRINT("info", ("fix_fields() failed")); + DBUG_RETURN(NULL); + } + DBUG_RETURN(*it_addr); +} + + /* Evaluate a (presumed) func item. Always returns an item, the parameter ** if nothing else. */ Item * -sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) +sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) { DBUG_ENTER("sp_eval_func_item"); - it= it->this_item(); + Item *it= sp_prepare_func_item(thd, it_addr); DBUG_PRINT("info", ("type: %d", type)); - if (!it->fixed && it->fix_fields(thd, 0, &it)) + if (!it) { - DBUG_PRINT("info", ("fix_fields() failed")); DBUG_RETURN(NULL); } @@ -679,7 +708,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) for (i= 0 ; i < params && i < argcount ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); - Item *it= sp_eval_func_item(thd, *argp++, pvar->type); + Item *it= sp_eval_func_item(thd, argp++, pvar->type); if (it) nctx->push_item(it); @@ -761,7 +790,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) { Item_null *nit= NULL; // Re-use this, and only create if needed uint i; - List_iterator_fast<Item> li(*args); + List_iterator<Item> li(*args); Item *it; nctx= new sp_rcontext(csize, hmax, cmax); @@ -794,7 +823,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } else { - Item *it2= sp_eval_func_item(thd, it, pvar->type); + Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type); if (it2) nctx->push_item(it2); // IN or INOUT @@ -1439,7 +1468,7 @@ sp_instr_set::exec_core(THD *thd, uint *nextp) Item *it; int res; - it= sp_eval_func_item(thd, m_value, m_type); + it= sp_eval_func_item(thd, &m_value, m_type); if (! it) res= -1; else @@ -1569,13 +1598,13 @@ sp_instr_jump_if::exec_core(THD *thd, uint *nextp) Item *it; int res; - it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); + it= sp_prepare_func_item(thd, &m_expr); if (!it) res= -1; else { res= 0; - if (it->val_int()) + if (it->val_bool()) *nextp = m_dest; else *nextp = m_ip+1; @@ -1627,13 +1656,13 @@ sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp) Item *it; int res; - it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); + it= sp_prepare_func_item(thd, &m_expr); if (! it) res= -1; else { res= 0; - if (! it->val_int()) + if (! it->val_bool()) *nextp = m_dest; else *nextp = m_ip+1; @@ -1685,7 +1714,7 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp) Item *it; int res; - it= sp_eval_func_item(thd, m_value, m_type); + it= sp_eval_func_item(thd, &m_value, m_type); if (! it) res= -1; else diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index def38009eee..672491a97f2 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -41,10 +41,10 @@ sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax) } int -sp_rcontext::set_item_eval(uint idx, Item *i, enum_field_types type) +sp_rcontext::set_item_eval(uint idx, Item **item_addr, enum_field_types type) { - extern Item *sp_eval_func_item(THD *thd, Item *it, enum_field_types type); - Item *it= sp_eval_func_item(current_thd, i, type); + extern Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type); + Item *it= sp_eval_func_item(current_thd, item_addr, type); if (! it) return -1; diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index afcd937a369..c132032e32c 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -74,7 +74,7 @@ class sp_rcontext : public Sql_alloc /* Returns 0 on success, -1 on (eval) failure */ int - set_item_eval(uint idx, Item *i, enum_field_types type); + set_item_eval(uint idx, Item **i, enum_field_types type); inline Item * get_item(uint idx) @@ -82,6 +82,14 @@ class sp_rcontext : public Sql_alloc return m_frame[idx]; } + + inline Item ** + get_item_addr(uint idx) + { + return m_frame + idx; + } + + inline void set_result(Item *it) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a6a1f4d60ef..2d5c4722164 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1719,10 +1719,9 @@ bool select_dumpvar::send_data(List<Item> &items) 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); + List_iterator<Item> 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) @@ -1741,13 +1740,13 @@ bool select_dumpvar::send_data(List<Item> &items) my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); DBUG_RETURN(1); } - while ((zz=my_li++) && (item=it++)) + while ((zz=my_li++) && (it++)) { if (zz->local) { if ((yy=var_li++)) { - if (thd->spcont->set_item_eval(yy->get_offset(), item, zz->type)) + if (thd->spcont->set_item_eval(yy->get_offset(), it.ref(), zz->type)) DBUG_RETURN(1); } } |