diff options
author | monty@mysql.com <> | 2005-02-08 14:41:09 +0200 |
---|---|---|
committer | monty@mysql.com <> | 2005-02-08 14:41:09 +0200 |
commit | 79ec81071a7a3468365e587be1ec7f68b11fe960 (patch) | |
tree | 7f61ad1d6f95b1672a681f050e260fa65e4b13a7 /sql/item_cmpfunc.cc | |
parent | 6c25300796d99d3cbd2d442de1fa44b74c2db7e4 (diff) | |
download | mariadb-git-79ec81071a7a3468365e587be1ec7f68b11fe960.tar.gz |
Better bugfix for "HAVING when refering to RAND()" (Bug #8216)
Ensure that references in HAVING, ORDER BY or GROUP BY are calculated after fields in SELECT.
This will ensure that any reference to these has a valid value.
Generalized the code for split_sum_func()
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 52 |
1 files changed, 6 insertions, 46 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2b9a612da18..a827f316ec1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1969,10 +1969,10 @@ bool Item_cond::walk(Item_processor processor, byte *arg) Move SUM items out from item tree and replace with reference SYNOPSIS - split_sum_func() - thd Thread handler - ref_pointer_array Pointer to array of reference fields - fields All fields in select + split_sum_func() + thd Thread handler + ref_pointer_array Pointer to array of reference fields + fields All fields in select NOTES This function is run on all expression (SELECT list, WHERE, HAVING etc) @@ -1982,16 +1982,6 @@ bool Item_cond::walk(Item_processor processor, byte *arg) so that we can easily find and calculate them. (Calculation done by update_sum_func() and copy_sum_funcs() in sql_select.cc) - - All found SUM items are added FIRST in the fields list and - we replace the item with a reference. - - We also replace all functions without side effects (like RAND() or UDF's) - that uses columns as arguments. - For functions with side effects, we just remember any fields referred - by the function to ensure that we get a copy of the field value for the - first accepted row. This ensures that we can do things like - SELECT a*SUM(b) FROM t1 WHERE a=1 */ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, @@ -1999,38 +1989,8 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, { List_iterator<Item> li(list); Item *item; - used_tables_cache=0; - const_item_cache=0; - while ((item=li++)) - { - /* with_sum_func is set for items that contains a SUM expression */ - if (item->type() != SUM_FUNC_ITEM && - (item->with_sum_func || - (item->used_tables() & PSEUDO_TABLE_BITS))) - item->split_sum_func(thd, ref_pointer_array, fields); - else if (item->type() == SUM_FUNC_ITEM || - (item->used_tables() && item->type() != REF_ITEM)) - { - /* - Replace item with a reference so that we can easily calculate - it (in case of sum functions) or copy it (in case of fields) - - The test above is to ensure we don't do a reference for things - that are constants or are not yet calculated as in: - SELECT RAND() as r1, SUM(a) as r2 FROM t1 HAVING r1 > 1 AND r2 > 0 - */ - Item **ref= li.ref(); - uint el= fields.elements; - ref_pointer_array[el]= item; - Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); - fields.push_front(item); - ref_pointer_array[el]= item; - thd->change_item_tree(ref, new_item); - } - item->update_used_tables(); - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); - } + while ((item= li++)) + item->split_sum_func2(thd, ref_pointer_array, fields, li.ref()); } |