From: Date: May 9 2005 12:59am Subject: bk commit into 5.0 tree (bell:1.1923) BUG#5963 List-Archive: http://lists.mysql.com/internals/24700 X-Bug: 5963 Message-Id: <20050508225926.F1FBB438159@book.sanja.is.com.ua> Below is the list of changes that have just been committed into a local 5.0 repository of bell. When bell does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.1923 05/05/09 01:59:10 bell@stripped +8 -0 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 sql/sql_class.cc 1.177 05/05/09 01:59:01 bell@stripped +3 -4 support of correct item address passing to fix_field sql/sp_rcontext.h 1.16 05/05/09 01:59:00 bell@stripped +9 -1 support of correct address passing to fix_fields sql/sp_rcontext.cc 1.22 05/05/09 01:59:00 bell@stripped +3 -3 support of Item address passing to fix_fields sql/sp_head.cc 1.132 05/05/09 01:59:00 bell@stripped +42 -13 preparation of item made separate function we do not need new constant Item to check IF/IF NOT support of passing correct address of item for fix_fields method sql/item.h 1.122 05/05/09 01:59:00 bell@stripped +12 -2 comment fixed method added sql/item.cc 1.118 05/05/09 01:59:00 bell@stripped +7 -0 new method which return reference on Item for SP variables support mysql-test/t/sp.test 1.116 05/05/09 01:58:59 bell@stripped +29 -0 test for bug#5963 mysql-test/r/sp.result 1.122 05/05/09 01:58:59 bell@stripped +25 -0 test for bug#5963 # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: bell # Host: book.sanja.is.com.ua # Root: /Users/bell/mysql/bk/work-bug-5.0 --- 1.117/sql/item.cc 2005-05-05 18:09:11 +03:00 +++ 1.118/sql/item.cc 2005-05-09 01:59:00 +03:00 @@ -740,6 +740,13 @@ 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 { --- 1.121/sql/item.h 2005-05-05 18:10:47 +03:00 +++ 1.122/sql/item.h 2005-05-09 01:59:00 +03:00 @@ -525,8 +525,17 @@ 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(this); } /* For SPs mostly. */ // Row emulation @@ -573,6 +582,7 @@ 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 **); --- 1.176/sql/sql_class.cc 2005-04-13 00:08:01 +03:00 +++ 1.177/sql/sql_class.cc 2005-05-09 01:59:01 +03:00 @@ -1719,10 +1719,9 @@ List_iterator_fast li(vars); List_iterator_fast var_li(local_vars); List_iterator_fast my_li(var_list); - List_iterator_fast it(items); + List_iterator 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 @@ 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); } } --- 1.121/mysql-test/r/sp.result 2005-05-05 23:01:35 +03:00 +++ 1.122/mysql-test/r/sp.result 2005-05-09 01:58:59 +03:00 @@ -3057,4 +3057,29 @@ yes drop procedure bug7293| delete from t1| +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; --- 1.115/mysql-test/t/sp.test 2005-04-29 00:46:51 +03:00 +++ 1.116/mysql-test/t/sp.test 2005-05-09 01:58:59 +03:00 @@ -3742,6 +3742,35 @@ delete from t1| # +# 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 --- 1.131/sql/sp_head.cc 2005-05-05 18:05:58 +03:00 +++ 1.132/sql/sp_head.cc 2005-05-09 01:59:00 +03:00 @@ -97,19 +97,48 @@ } } + +/* + 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 @@ 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 @@ { Item_null *nit= NULL; // Re-use this, and only create if needed uint i; - List_iterator_fast li(*args); + List_iterator li(*args); Item *it; nctx= new sp_rcontext(csize, hmax, cmax); @@ -793,7 +822,7 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 --- 1.21/sql/sp_rcontext.cc 2005-04-14 15:52:30 +03:00 +++ 1.22/sql/sp_rcontext.cc 2005-05-09 01:59:00 +03:00 @@ -41,10 +41,10 @@ } 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; --- 1.15/sql/sp_rcontext.h 2005-04-14 15:52:30 +03:00 +++ 1.16/sql/sp_rcontext.h 2005-05-09 01:59:00 +03:00 @@ -74,13 +74,21 @@ /* 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) { return m_frame[idx]; } + + + inline Item ** + get_item_addr(uint idx) + { + return m_frame + idx; + } + inline void set_result(Item *it)