summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-02-08 14:41:09 +0200
committerunknown <monty@mysql.com>2005-02-08 14:41:09 +0200
commit63982db93ceac93bf6dd72f8cae41f8ea06cda0a (patch)
tree7f61ad1d6f95b1672a681f050e260fa65e4b13a7 /sql/item_cmpfunc.cc
parent6a1e75621155f700bc6912f9669a5a374342b712 (diff)
downloadmariadb-git-63982db93ceac93bf6dd72f8cae41f8ea06cda0a.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() BitKeeper/etc/ignore: added support-files/ndb-config-2-node.ini mysql-test/r/group_by.result: More complicated test to assure that rand() is only calulated once mysql-test/r/user_var.result: Back to old results :( (ok but not perfect) mysql-test/t/group_by.test: More complicated test to assure that rand() is only calulated once sql/item.cc: Better bugfix for "HAVING when refering to RAND()" This will ensure that when refering to things like RAND() in HAVING through an alias we will not recalculate that rand() value in the HAVING part but use the value in the row Generalize split_sum_func() sql/item.h: Better bugfix for "HAVING when refering to RAND()" T sql/item_cmpfunc.cc: Better bugfix for "HAVING when refering to RAND()" Use generalized split_sum_func2() function sql/item_func.cc: Better bugfix for "HAVING when refering to RAND()" Use generalized split_sum_func2() function sql/item_row.cc: Better bugfix for "HAVING when refering to RAND()" Use generalized split_sum_func2() function sql/item_strfunc.cc: Better bugfix for "HAVING when refering to RAND()" Use generalized split_sum_func2() function sql/sql_list.h: Add functions to concatenate lists sql/sql_select.cc: Better bugfix for "HAVING when refering to RAND()" 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.
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());
}