summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authormonty@mysql.com <>2005-02-08 14:41:09 +0200
committermonty@mysql.com <>2005-02-08 14:41:09 +0200
commit79ec81071a7a3468365e587be1ec7f68b11fe960 (patch)
tree7f61ad1d6f95b1672a681f050e260fa65e4b13a7 /sql/item_cmpfunc.cc
parent6c25300796d99d3cbd2d442de1fa44b74c2db7e4 (diff)
downloadmariadb-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.cc52
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());
}