diff options
-rw-r--r-- | sql/item.h | 9 | ||||
-rw-r--r-- | sql/item_func.cc | 6 | ||||
-rw-r--r-- | sql/item_func.h | 8 | ||||
-rw-r--r-- | sql/item_sum.cc | 13 | ||||
-rw-r--r-- | sql/item_sum.h | 40 |
5 files changed, 32 insertions, 44 deletions
diff --git a/sql/item.h b/sql/item.h index a498e7fd455..3b0dddc4ab1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3663,7 +3663,9 @@ public: An abstract class representing common features of regular functions and aggregate functions. */ -class Item_func_or_sum: public Item_result_field, public Item_args +class Item_func_or_sum: public Item_result_field, + public Item_args, + public Used_tables_and_const_cache { bool agg_item_collations(DTCollation &c, const char *name, Item **items, uint nitems, @@ -3794,7 +3796,8 @@ public: Item_func_or_sum(THD *thd, Item *a, Item *b, Item *c, Item *d, Item *e): Item_result_field(thd), Item_args(a, b, c, d, e) { } Item_func_or_sum(THD *thd, Item_func_or_sum *item): - Item_result_field(thd, item), Item_args(thd, item) { } + Item_result_field(thd, item), Item_args(thd, item), + Used_tables_and_const_cache(item) { } Item_func_or_sum(THD *thd, List<Item> &list): Item_result_field(thd), Item_args(thd, list) { } bool walk(Item_processor processor, bool walk_subquery, uchar *arg) @@ -3821,6 +3824,8 @@ public: */ virtual const char *func_name() const= 0; virtual void fix_length_and_dec()= 0; + bool const_item() const { return const_item_cache; } + table_map used_tables() const { return used_tables_cache; } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index ed6722fac4a..c1df7bd6a6e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -441,12 +441,6 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, } -table_map Item_func::used_tables() const -{ - return used_tables_cache; -} - - table_map Item_func::not_null_tables() const { return not_null_tables_cache; diff --git a/sql/item_func.h b/sql/item_func.h index d524e62c374..eca798dcaf7 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -31,7 +31,7 @@ extern "C" /* Bug in BSDI include file */ #endif -class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache +class Item_func :public Item_func_or_sum { void sync_with_sum_func_and_with_field(List<Item> &list); protected: @@ -106,8 +106,8 @@ public: set_arguments(thd, list); } // Constructor used for Item_cond_and/or (see Item comment) - Item_func(THD *thd, Item_func *item) - :Item_func_or_sum(thd, item), Used_tables_and_const_cache(item), + Item_func(THD *thd, Item_func *item): + Item_func_or_sum(thd, item), allowed_arg_cols(item->allowed_arg_cols), not_null_tables_cache(item->not_null_tables_cache) { @@ -120,7 +120,6 @@ public: } void fix_after_pullout(st_select_lex *new_parent, Item **ref); void quick_fix_field(); - table_map used_tables() const; table_map not_null_tables() const; void update_used_tables() { @@ -137,7 +136,6 @@ public: } bool eq(const Item *item, bool binary_cmp) const; virtual Item *key_item() const { return args[0]; } - virtual bool const_item() const { return const_item_cache; } void set_arguments(THD *thd, List<Item> &list) { allowed_arg_cols= 1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 28323b9304b..e44a371d264 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -401,8 +401,7 @@ bool Item_sum::collect_outer_ref_processor(uchar *param) } -Item_sum::Item_sum(THD *thd, List<Item> &list): Item_func_or_sum(thd, list), - forced_const(FALSE) +Item_sum::Item_sum(THD *thd, List<Item> &list): Item_func_or_sum(thd, list) { if (!(orig_args= (Item **) thd->alloc(sizeof(Item *) * arg_count))) { @@ -423,9 +422,7 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): aggr_sel(item->aggr_sel), nest_level(item->nest_level), aggr_level(item->aggr_level), quick_group(item->quick_group), - orig_args(NULL), - used_tables_cache(item->used_tables_cache), - forced_const(item->forced_const) + orig_args(NULL) { if (arg_count <= 2) { @@ -449,6 +446,7 @@ void Item_sum::mark_as_sum_func() SELECT_LEX *cur_select= current_thd->lex->current_select; cur_select->n_sum_items++; cur_select->with_sum_func= 1; + const_item_cache= false; with_sum_func= 1; with_field= 0; } @@ -538,7 +536,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table, void Item_sum::update_used_tables () { - if (!forced_const) + if (!Item_sum::const_item()) { used_tables_cache= 0; for (uint i=0 ; i < arg_count ; i++) @@ -610,7 +608,7 @@ void Item_sum::cleanup() aggr= NULL; } Item_result_field::cleanup(); - forced_const= FALSE; + const_item_cache= false; } Item *Item_sum::result_item(THD *thd, Field *field) @@ -2073,7 +2071,6 @@ void Item_sum_hybrid::cleanup() { DBUG_ENTER("Item_sum_hybrid::cleanup"); Item_sum::cleanup(); - forced_const= FALSE; if (cmp) delete cmp; cmp= 0; diff --git a/sql/item_sum.h b/sql/item_sum.h index 170c6bdbb89..9486317c401 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -302,7 +302,13 @@ class st_select_lex; We assume that the nesting level of subquries does not exceed 127. TODO: to catch queries where the limit is exceeded to make the code clean here. - + + @note + The implementation takes into account the used strategy: + - Items resolved at optimization phase return 0 from Item_sum::used_tables(). + - Items that depend on the number of join output records, but not columns of + any particular table (like COUNT(*)), returm 0 from Item_sum::used_tables(), + but still return false from Item_sum::const_item(). */ class Item_sum :public Item_func_or_sum @@ -368,32 +374,25 @@ protected: the current argument list can be altered by usage of temporary tables. */ Item **orig_args, *tmp_orig_args[2]; - table_map used_tables_cache; - /* - TRUE <=> We've managed to calculate the value of this Item in - opt_sum_query(), hence it can be considered constant at all subsequent - steps. - */ - bool forced_const; static ulonglong ram_limitation(THD *thd); public: void mark_as_sum_func(); - Item_sum(THD *thd): Item_func_or_sum(thd), quick_group(1), forced_const(FALSE) + Item_sum(THD *thd): Item_func_or_sum(thd), quick_group(1) { mark_as_sum_func(); init_aggregator(); } Item_sum(THD *thd, Item *a): Item_func_or_sum(thd, a), quick_group(1), - orig_args(tmp_orig_args), forced_const(FALSE) + orig_args(tmp_orig_args) { mark_as_sum_func(); init_aggregator(); } Item_sum(THD *thd, Item *a, Item *b): Item_func_or_sum(thd, a, b), - quick_group(1), orig_args(tmp_orig_args), forced_const(FALSE) + quick_group(1), orig_args(tmp_orig_args) { mark_as_sum_func(); init_aggregator(); @@ -433,16 +432,6 @@ public: virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } virtual Item *result_item(THD *thd, Field *field); - /* - Return bitmap of tables that are needed to evaluate the item. - - The implementation takes into account the used strategy: items resolved - at optimization phase will report 0. - Items that depend on the number of join output records, but not columns - of any particular table (like COUNT(*)) will report 0 from used_tables(), - but will still return false from const_item(). - */ - table_map used_tables() const { return used_tables_cache; } void update_used_tables (); COND *build_equal_items(THD *thd, COND_EQUAL *inherited, bool link_item_fields, @@ -458,12 +447,17 @@ public: cond_equal_ref); } bool is_null() { return null_value; } + /** + make_const() + Called if we've managed to calculate the value of this Item in + opt_sum_query(), hence it can be considered constant at all subsequent + steps. + */ void make_const () { used_tables_cache= 0; - forced_const= TRUE; + const_item_cache= true; } - virtual bool const_item() const { return forced_const; } virtual bool const_during_execution() const { return false; } virtual void print(String *str, enum_query_type query_type); void fix_num_length_and_dec(); |