diff options
author | unknown <monty@mysql.com> | 2005-02-07 19:42:03 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2005-02-07 19:42:03 +0200 |
commit | f9e0e5a7c5f01e6aa49a2925efb55bdc4f88d495 (patch) | |
tree | 5c11adf8670fa1044233b655ddda407c614e763a /sql/item_cmpfunc.cc | |
parent | bb05eab8e9aa1a25e46063af3ee510d4169de9e4 (diff) | |
parent | edae64f4cb319562bc9f6ea0a20b6cfe174fdaff (diff) | |
download | mariadb-git-f9e0e5a7c5f01e6aa49a2925efb55bdc4f88d495.tar.gz |
Merge with 4.1 to get bug fix
mysql-test/r/group_by.result:
Auto merged
mysql-test/r/user_var.result:
Auto merged
sql/item_row.cc:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/unireg.h:
Auto merged
sql/item_cmpfunc.cc:
manual merge
sql/item_func.cc:
no changes
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e63bafe4811..1079e31e23a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2029,6 +2029,35 @@ Item *Item_cond::transform(Item_transformer transformer, 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 + + 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) { @@ -2038,10 +2067,22 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, const_item_cache=1; 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; |