diff options
author | unknown <monty@mysql.com> | 2005-02-07 18:14:31 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2005-02-07 18:14:31 +0200 |
commit | edae64f4cb319562bc9f6ea0a20b6cfe174fdaff (patch) | |
tree | 52bd15591cacd4fcb417957f538bc26953ef3025 /sql | |
parent | 4a196cc4d3ef589d5d2aa1b39e31ff6ab82ac271 (diff) | |
parent | d6ed8cd7097391b55936a1dfec248da65e7f64f9 (diff) | |
download | mariadb-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')
-rw-r--r-- | sql/item_cmpfunc.cc | 46 | ||||
-rw-r--r-- | sql/item_func.cc | 8 | ||||
-rw-r--r-- | sql/item_row.cc | 11 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 7 | ||||
-rw-r--r-- | sql/unireg.h | 2 |
5 files changed, 65 insertions, 9 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; diff --git a/sql/item_func.cc b/sql/item_func.cc index f226603d9d1..d5d0ac8cd49 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -351,6 +351,7 @@ bool Item_func::walk (Item_processor processor, byte *argument) return (this->*processor)(argument); } + void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields) { @@ -358,9 +359,12 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++) { Item *item=* arg; - if (item->with_sum_func && item->type() != SUM_FUNC_ITEM) + 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)) { uint el= fields.elements; ref_pointer_array[el]= item; diff --git a/sql/item_row.cc b/sql/item_row.cc index 4e4957b980e..0ace0fc0451 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -84,15 +84,20 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) return 0; } + void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields) { Item **arg, **arg_end; for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) { - if ((*arg)->with_sum_func && (*arg)->type() != SUM_FUNC_ITEM) - (*arg)->split_sum_func(thd, ref_pointer_array, fields); - else if ((*arg)->used_tables() || (*arg)->type() == SUM_FUNC_ITEM) + Item *item= *arg; + 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)) { uint el= fields.elements; ref_pointer_array[el]=*arg; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1fb68561374..b22b65eddd0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1758,9 +1758,12 @@ String *Item_func_elt::val_str(String *str) void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields) { - if (item->with_sum_func && item->type() != SUM_FUNC_ITEM) + 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)) { uint el= fields.elements; ref_pointer_array[el]=item; diff --git a/sql/unireg.h b/sql/unireg.h index 4ab2ba26b15..70df9a89c8f 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -72,6 +72,8 @@ #define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3)) #define OUTER_REF_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-2)) #define RAND_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-1)) +#define PSEUDO_TABLE_BITS (PARAM_TABLE_BIT | OUTER_REF_TABLE_BIT | \ + RAND_TABLE_BIT) #define MAX_FIELDS 4096 /* Limit in the .frm file */ #define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD) |