summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-02-07 18:14:31 +0200
committerunknown <monty@mysql.com>2005-02-07 18:14:31 +0200
commitedae64f4cb319562bc9f6ea0a20b6cfe174fdaff (patch)
tree52bd15591cacd4fcb417957f538bc26953ef3025 /sql/item_cmpfunc.cc
parent4a196cc4d3ef589d5d2aa1b39e31ff6ab82ac271 (diff)
parentd6ed8cd7097391b55936a1dfec248da65e7f64f9 (diff)
downloadmariadb-git-edae64f4cb319562bc9f6ea0a20b6cfe174fdaff.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/my/mysql-4.1 sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc46
1 files changed, 44 insertions, 2 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 46ef3281dd1..2b9a612da18 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1964,6 +1964,36 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
return Item_func::walk(processor, 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
+
+ NOTES
+ This function is run on all expression (SELECT list, WHERE, HAVING etc)
+ that have or refer (HAVING) to a SUM expression.
+
+ The split is done to get an unique item for each SUM function
+ 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,
List<Item> &fields)
{
@@ -1973,10 +2003,22 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
const_item_cache=0;
while ((item=li++))
{
- if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
+ /* 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->used_tables() || item->type() == SUM_FUNC_ITEM)
+ 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;