diff options
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 169c68c1918..a9375a4f05e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3015,13 +3015,42 @@ int select_exists_subselect::send_data(List<Item> &items) int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { unit= u; + List_iterator_fast<my_var> var_li(var_list); + List_iterator_fast<Item> it(list); + Item *item; + my_var *mv; + Item_func_set_user_var **suv; if (var_list.elements != list.elements) { my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0)); return 1; - } + } + + /* + Iterate over the destination variables and mark them as being + updated in this query. + We need to do this at JOIN::prepare time to ensure proper + const detection of Item_func_get_user_var that is determined + by the presence of Item_func_set_user_vars + */ + + suv= set_var_items= (Item_func_set_user_var **) + sql_alloc(sizeof(Item_func_set_user_var *) * list.elements); + + while ((mv= var_li++) && (item= it++)) + { + if (!mv->local) + { + *suv= new Item_func_set_user_var(mv->s, item); + (*suv)->fix_fields(thd, 0); + } + else + *suv= NULL; + suv++; + } + return 0; } @@ -3341,6 +3370,7 @@ int select_dumpvar::send_data(List<Item> &items) List_iterator<Item> it(items); Item *item; my_var *mv; + Item_func_set_user_var **suv; DBUG_ENTER("select_dumpvar::send_data"); if (unit->offset_limit_cnt) @@ -3353,20 +3383,19 @@ int select_dumpvar::send_data(List<Item> &items) my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); DBUG_RETURN(1); } - while ((mv= var_li++) && (item= it++)) + for (suv= set_var_items; ((mv= var_li++) && (item= it++)); suv++) { if (mv->local) { + DBUG_ASSERT(!*suv); if (thd->spcont->set_variable(thd, mv->offset, &item)) DBUG_RETURN(1); } else { - Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item); - if (suv->fix_fields(thd, 0)) - DBUG_RETURN (1); - suv->save_item_result(item); - if (suv->update()) + DBUG_ASSERT(*suv); + (*suv)->save_item_result(item); + if ((*suv)->update()) DBUG_RETURN (1); } } |