diff options
author | bell@book.sanja.is.com.ua <> | 2005-05-09 01:59:10 +0300 |
---|---|---|
committer | bell@book.sanja.is.com.ua <> | 2005-05-09 01:59:10 +0300 |
commit | 91dccaa36f66b298b3fb83793939f5d9929a7cea (patch) | |
tree | 8d33320966b89e4ec888a4f4fbd50dc50071ad92 /sql | |
parent | b93385de8f6c45305b965fdb603734dc510fd039 (diff) | |
download | mariadb-git-91dccaa36f66b298b3fb83793939f5d9929a7cea.tar.gz |
Item::fix_field need correct pointer on item reference to chnge it if itis need, so support of correct item address added to SP commands (BUG#5963)
some optimisation of IF/NOT IF ptomised to Pem
Diffstat (limited to 'sql')
-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 |
6 files changed, 76 insertions, 23 deletions
diff --git a/sql/item.cc b/sql/item.cc index f5c7f2d7c05..ec93480499e 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 9fb4b1c7fac..1b336278f07 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); } @@ -678,7 +707,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); @@ -760,7 +789,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); @@ -793,7 +822,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 @@ -1438,7 +1467,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 @@ -1568,13 +1597,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; @@ -1626,13 +1655,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; @@ -1684,7 +1713,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); } } |