MDEV-16592 Change Item::with_sum_func from a member to a virtual method

This commit is contained in:
Alexander Barkov 2018-06-27 14:48:03 +04:00
parent d60fdb5814
commit e213b20e07
14 changed files with 127 additions and 70 deletions

View File

@ -506,7 +506,7 @@ Item::Item(THD *thd):
{ {
DBUG_ASSERT(thd); DBUG_ASSERT(thd);
marker= 0; marker= 0;
maybe_null=null_value=with_sum_func=with_window_func=with_field=0; maybe_null= null_value= with_window_func= with_field= false;
in_rollup= 0; in_rollup= 0;
with_param= 0; with_param= 0;
@ -550,7 +550,6 @@ Item::Item(THD *thd, Item *item):
maybe_null(item->maybe_null), maybe_null(item->maybe_null),
in_rollup(item->in_rollup), in_rollup(item->in_rollup),
null_value(item->null_value), null_value(item->null_value),
with_sum_func(item->with_sum_func),
with_param(item->with_param), with_param(item->with_param),
with_window_func(item->with_window_func), with_window_func(item->with_window_func),
with_field(item->with_field), with_field(item->with_field),
@ -2351,7 +2350,7 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
else else
{ {
/* Not a SUM() function */ /* Not a SUM() function */
if (unlikely((!with_sum_func && !(split_flags & SPLIT_SUM_SELECT)))) if (unlikely((!with_sum_func() && !(split_flags & SPLIT_SUM_SELECT))))
{ {
/* /*
This is not a SUM function and there are no SUM functions inside. This is not a SUM function and there are no SUM functions inside.
@ -2359,7 +2358,7 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
*/ */
return; return;
} }
if (likely(with_sum_func || if (likely(with_sum_func() ||
(type() == FUNC_ITEM && (type() == FUNC_ITEM &&
(((Item_func *) this)->functype() == (((Item_func *) this)->functype() ==
Item_func::ISNOTNULLTEST_FUNC || Item_func::ISNOTNULLTEST_FUNC ||
@ -5551,7 +5550,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
ref->alias_name_used= TRUE; ref->alias_name_used= TRUE;
/* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */
if (select->having_fix_field && !ref->with_sum_func && group_list) if (select->having_fix_field && !ref->with_sum_func() && group_list)
{ {
group_by_ref= find_field_in_group_list(ref, group_list); group_by_ref= find_field_in_group_list(ref, group_list);
@ -8270,13 +8269,13 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
*/ */
if (!((*ref)->type() == REF_ITEM && if (!((*ref)->type() == REF_ITEM &&
((Item_ref *)(*ref))->ref_type() == OUTER_REF) && ((Item_ref *)(*ref))->ref_type() == OUTER_REF) &&
(((*ref)->with_sum_func && name.str && (((*ref)->with_sum_func() && name.str &&
!(current_sel->linkage != GLOBAL_OPTIONS_TYPE && !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
current_sel->having_fix_field)) || current_sel->having_fix_field)) ||
!(*ref)->is_fixed())) !(*ref)->is_fixed()))
{ {
my_error(ER_ILLEGAL_REFERENCE, MYF(0), my_error(ER_ILLEGAL_REFERENCE, MYF(0),
name.str, ((*ref)->with_sum_func? name.str, ((*ref)->with_sum_func() ?
"reference to group function": "reference to group function":
"forward reference in item list")); "forward reference in item list"));
goto error; goto error;
@ -8302,7 +8301,7 @@ void Item_ref::set_properties()
We have to remember if we refer to a sum function, to ensure that We have to remember if we refer to a sum function, to ensure that
split_sum_func() doesn't try to change the reference. split_sum_func() doesn't try to change the reference.
*/ */
with_sum_func= (*ref)->with_sum_func; copy_with_sum_func(*ref);
with_param= (*ref)->with_param; with_param= (*ref)->with_param;
with_window_func= (*ref)->with_window_func; with_window_func= (*ref)->with_window_func;
with_field= (*ref)->with_field; with_field= (*ref)->with_field;
@ -8728,7 +8727,7 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg):
DBUG_ASSERT(orig_item->is_fixed()); DBUG_ASSERT(orig_item->is_fixed());
Type_std_attributes::set(orig_item); Type_std_attributes::set(orig_item);
maybe_null= orig_item->maybe_null; maybe_null= orig_item->maybe_null;
with_sum_func= orig_item->with_sum_func; copy_with_sum_func(orig_item);
with_param= orig_item->with_param; with_param= orig_item->with_param;
with_field= orig_item->with_field; with_field= orig_item->with_field;
name= item_arg->name; name= item_arg->name;
@ -9117,7 +9116,7 @@ int Item_cache_wrapper::save_in_field(Field *to, bool no_conversions)
Item* Item_cache_wrapper::get_tmp_table_item(THD *thd) Item* Item_cache_wrapper::get_tmp_table_item(THD *thd)
{ {
if (!orig_item->with_sum_func && !orig_item->const_item()) if (!orig_item->with_sum_func() && !orig_item->const_item())
return new (thd->mem_root) Item_temptable_field(thd, result_field); return new (thd->mem_root) Item_temptable_field(thd, result_field);
return copy_or_same(thd); return copy_or_same(thd);
} }

View File

@ -110,6 +110,7 @@ struct KEY_FIELD;
struct SARGABLE_PARAM; struct SARGABLE_PARAM;
class RANGE_OPT_PARAM; class RANGE_OPT_PARAM;
class SEL_TREE; class SEL_TREE;
class With_sum_func_cache;
enum precedence { enum precedence {
LOWEST_PRECEDENCE, LOWEST_PRECEDENCE,
@ -894,7 +895,6 @@ public:
bool in_rollup; /* If used in GROUP BY list bool in_rollup; /* If used in GROUP BY list
of a query with ROLLUP */ of a query with ROLLUP */
bool null_value; /* if item is null */ bool null_value; /* if item is null */
bool with_sum_func; /* True if item contains a sum func */
bool with_param; /* True if contains an SP parameter */ bool with_param; /* True if contains an SP parameter */
bool with_window_func; /* True if item contains a window func */ bool with_window_func; /* True if item contains a window func */
/** /**
@ -2178,6 +2178,9 @@ public:
*/ */
virtual bool with_subquery() const { DBUG_ASSERT(is_fixed()); return false; } virtual bool with_subquery() const { DBUG_ASSERT(is_fixed()); return false; }
virtual bool with_sum_func() const { return false; }
virtual With_sum_func_cache* get_with_sum_func_cache() { return NULL; }
Item* set_expr_cache(THD *thd); Item* set_expr_cache(THD *thd);
virtual Item_equal *get_item_equal() { return NULL; } virtual Item_equal *get_item_equal() { return NULL; }
@ -2299,6 +2302,47 @@ public:
}; };
#endif #endif
class With_sum_func_cache
{
protected:
bool m_with_sum_func; // True if the owner item contains a sum func
public:
With_sum_func_cache()
:m_with_sum_func(false)
{ }
With_sum_func_cache(const Item *a)
:m_with_sum_func(a->with_sum_func())
{ }
With_sum_func_cache(const Item *a, const Item *b)
:m_with_sum_func(a->with_sum_func() || b->with_sum_func())
{ }
With_sum_func_cache(const Item *a, const Item *b, const Item *c)
:m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
c->with_sum_func())
{ }
With_sum_func_cache(const Item *a, const Item *b, const Item *c,
const Item *d)
:m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
c->with_sum_func() || d->with_sum_func())
{ }
With_sum_func_cache(const Item *a, const Item *b, const Item *c,
const Item *d, const Item *e)
:m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
c->with_sum_func() || d->with_sum_func() ||
e->with_sum_func())
{ }
void set_with_sum_func() { m_with_sum_func= true; }
void reset_with_sum_func() { m_with_sum_func= false; }
void copy_with_sum_func(const Item *item)
{
m_with_sum_func= item->with_sum_func();
}
void join_with_sum_func(const Item *item)
{
m_with_sum_func|= item->with_sum_func();
}
};
/* /*
This class is a replacement for the former member Item::with_subselect. This class is a replacement for the former member Item::with_subselect.
@ -4962,7 +5006,8 @@ public:
bool *null_value, LEX_CSTRING *name); bool *null_value, LEX_CSTRING *name);
}; };
class Item_ref :public Item_ident class Item_ref :public Item_ident,
protected With_sum_func_cache
{ {
protected: protected:
void set_properties(); void set_properties();
@ -4998,7 +5043,8 @@ public:
/* Constructor need to process subselect with temporary tables (see Item) */ /* Constructor need to process subselect with temporary tables (see Item) */
Item_ref(THD *thd, Item_ref *item) Item_ref(THD *thd, Item_ref *item)
:Item_ident(thd, item), set_properties_only(0), ref(item->ref) {} :Item_ident(thd, item), With_sum_func_cache(*item),
set_properties_only(0), ref(item->ref) {}
enum Type type() const { return REF_ITEM; } enum Type type() const { return REF_ITEM; }
enum Type real_type() const { return ref ? (*ref)->type() : enum Type real_type() const { return ref ? (*ref)->type() :
REF_ITEM; } REF_ITEM; }
@ -5185,6 +5231,8 @@ public:
return 0; return 0;
return cleanup_processor(arg); return cleanup_processor(arg);
} }
bool with_sum_func() const { return m_with_sum_func; }
With_sum_func_cache* get_with_sum_func_cache() { return this; }
}; };
@ -5272,7 +5320,8 @@ class Expression_cache_tracker;
*/ */
class Item_cache_wrapper :public Item_result_field, class Item_cache_wrapper :public Item_result_field,
public With_subquery_cache public With_subquery_cache,
protected With_sum_func_cache
{ {
private: private:
/* Pointer on the cached expression */ /* Pointer on the cached expression */
@ -5300,6 +5349,8 @@ public:
enum Type type() const { return EXPR_CACHE_ITEM; } enum Type type() const { return EXPR_CACHE_ITEM; }
enum Type real_type() const { return orig_item->type(); } enum Type real_type() const { return orig_item->type(); }
bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; } bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
bool with_sum_func() const { return m_with_sum_func; }
With_sum_func_cache* get_with_sum_func_cache() { return this; }
bool set_cache(THD *thd); bool set_cache(THD *thd);
Expression_cache_tracker* init_tracker(MEM_ROOT *mem_root); Expression_cache_tracker* init_tracker(MEM_ROOT *mem_root);

View File

@ -1291,7 +1291,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
used_tables_cache= args[0]->used_tables(); used_tables_cache= args[0]->used_tables();
} }
eval_not_null_tables(NULL); eval_not_null_tables(NULL);
with_sum_func= args[0]->with_sum_func; copy_with_sum_func(args[0]);
with_param= args[0]->with_param || args[1]->with_param; with_param= args[0]->with_param || args[1]->with_param;
with_field= args[0]->with_field; with_field= args[0]->with_field;
if ((const_item_cache= args[0]->const_item())) if ((const_item_cache= args[0]->const_item()))
@ -1303,7 +1303,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
{ {
/* to avoid overriding is called to update left expression */ /* to avoid overriding is called to update left expression */
used_tables_and_const_cache_join(args[1]); used_tables_and_const_cache_join(args[1]);
with_sum_func= with_sum_func || args[1]->with_sum_func; join_with_sum_func(args[1]);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -1339,7 +1339,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
if (args[1]->maybe_null) if (args[1]->maybe_null)
maybe_null=1; maybe_null=1;
m_with_subquery= true; m_with_subquery= true;
with_sum_func= with_sum_func || args[1]->with_sum_func; join_with_sum_func(args[1]);
with_field= with_field || args[1]->with_field; with_field= with_field || args[1]->with_field;
with_param= args[0]->with_param || args[1]->with_param; with_param= args[0]->with_param || args[1]->with_param;
used_tables_and_const_cache_join(args[1]); used_tables_and_const_cache_join(args[1]);
@ -1890,7 +1890,7 @@ void Item_func_interval::fix_length_and_dec()
max_length= 2; max_length= 2;
used_tables_and_const_cache_join(row); used_tables_and_const_cache_join(row);
not_null_tables_cache= row->not_null_tables(); not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func; join_with_sum_func(row);
with_param= with_param || row->with_param; with_param= with_param || row->with_param;
with_field= with_field || row->with_field; with_field= with_field || row->with_field;
} }
@ -4634,7 +4634,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
const_item_cache= FALSE; const_item_cache= FALSE;
} }
with_sum_func|= item->with_sum_func; join_with_sum_func(item);
with_param|= item->with_param; with_param|= item->with_param;
with_field|= item->with_field; with_field|= item->with_field;
m_with_subquery|= item->with_subquery(); m_with_subquery|= item->with_subquery();
@ -6620,7 +6620,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables(); used_tables_cache|= item->used_tables();
tmp_table_map= item->not_null_tables(); tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map; not_null_tables_cache|= tmp_table_map;
DBUG_ASSERT(!item->with_sum_func && !item->with_subquery()); DBUG_ASSERT(!item->with_sum_func() && !item->with_subquery());
if (item->maybe_null) if (item->maybe_null)
maybe_null= 1; maybe_null= 1;
if (!item->get_item_equal()) if (!item->get_item_equal())

View File

@ -145,7 +145,7 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
Item *item; Item *item;
while ((item= li++)) while ((item= li++))
{ {
with_sum_func|= item->with_sum_func; join_with_sum_func(item);
with_window_func|= item->with_window_func; with_window_func|= item->with_window_func;
with_field|= item->with_field; with_field|= item->with_field;
with_param|= item->with_param; with_param|= item->with_param;
@ -367,7 +367,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
if (item->maybe_null) if (item->maybe_null)
maybe_null=1; maybe_null=1;
with_sum_func= with_sum_func || item->with_sum_func; join_with_sum_func(item);
with_param= with_param || item->with_param; with_param= with_param || item->with_param;
with_window_func= with_window_func || item->with_window_func; with_window_func= with_window_func || item->with_window_func;
with_field= with_field || item->with_field; with_field= with_field || item->with_field;
@ -738,7 +738,7 @@ void Item_func::signal_divide_by_null()
Item *Item_func::get_tmp_table_item(THD *thd) Item *Item_func::get_tmp_table_item(THD *thd)
{ {
if (!with_sum_func && !const_item()) if (!Item_func::with_sum_func() && !const_item())
return new (thd->mem_root) Item_temptable_field(thd, result_field); return new (thd->mem_root) Item_temptable_field(thd, result_field);
return copy_or_same(thd); return copy_or_same(thd);
} }
@ -3275,6 +3275,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
} }
uint i; uint i;
Item **arg,**arg_end; Item **arg,**arg_end;
With_sum_func_cache *with_sum_func_cache= func->get_with_sum_func_cache();
for (i=0, arg=arguments, arg_end=arguments+arg_count; for (i=0, arg=arguments, arg_end=arguments+arg_count;
arg != arg_end ; arg != arg_end ;
arg++,i++) arg++,i++)
@ -3298,7 +3299,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->collation.set(&my_charset_bin); func->collation.set(&my_charset_bin);
if (item->maybe_null) if (item->maybe_null)
func->maybe_null=1; func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func; if (with_sum_func_cache)
with_sum_func_cache->join_with_sum_func(item);
func->with_field= func->with_field || item->with_field; func->with_field= func->with_field || item->with_field;
func->with_param= func->with_param || item->with_param; func->with_param= func->with_param || item->with_param;
func->With_subquery_cache::join(item); func->With_subquery_cache::join(item);

View File

@ -35,7 +35,8 @@ extern "C" /* Bug in BSDI include file */
#include <cmath> #include <cmath>
class Item_func :public Item_func_or_sum class Item_func :public Item_func_or_sum,
protected With_sum_func_cache
{ {
void sync_with_sum_func_and_with_field(List<Item> &list); void sync_with_sum_func_and_with_field(List<Item> &list);
protected: protected:
@ -81,45 +82,38 @@ public:
virtual enum Functype functype() const { return UNKNOWN_FUNC; } virtual enum Functype functype() const { return UNKNOWN_FUNC; }
Item_func(THD *thd): Item_func_or_sum(thd) Item_func(THD *thd): Item_func_or_sum(thd)
{ {
with_sum_func= 0;
with_field= 0; with_field= 0;
with_param= 0; with_param= 0;
} }
Item_func(THD *thd, Item *a): Item_func_or_sum(thd, a) Item_func(THD *thd, Item *a)
:Item_func_or_sum(thd, a), With_sum_func_cache(a)
{ {
with_sum_func= a->with_sum_func;
with_param= a->with_param; with_param= a->with_param;
with_field= a->with_field; with_field= a->with_field;
} }
Item_func(THD *thd, Item *a, Item *b): Item_func(THD *thd, Item *a, Item *b)
Item_func_or_sum(thd, a, b) :Item_func_or_sum(thd, a, b), With_sum_func_cache(a, b)
{ {
with_sum_func= a->with_sum_func || b->with_sum_func;
with_param= a->with_param || b->with_param; with_param= a->with_param || b->with_param;
with_field= a->with_field || b->with_field; with_field= a->with_field || b->with_field;
} }
Item_func(THD *thd, Item *a, Item *b, Item *c): Item_func(THD *thd, Item *a, Item *b, Item *c)
Item_func_or_sum(thd, a, b, c) :Item_func_or_sum(thd, a, b, c), With_sum_func_cache(a, b, c)
{ {
with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
with_field= a->with_field || b->with_field || c->with_field; with_field= a->with_field || b->with_field || c->with_field;
with_param= a->with_param || b->with_param || c->with_param; with_param= a->with_param || b->with_param || c->with_param;
} }
Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d): Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d)
Item_func_or_sum(thd, a, b, c, d) :Item_func_or_sum(thd, a, b, c, d), With_sum_func_cache(a, b, c, d)
{ {
with_sum_func= a->with_sum_func || b->with_sum_func ||
c->with_sum_func || d->with_sum_func;
with_field= a->with_field || b->with_field || with_field= a->with_field || b->with_field ||
c->with_field || d->with_field; c->with_field || d->with_field;
with_param= a->with_param || b->with_param || with_param= a->with_param || b->with_param ||
c->with_param || d->with_param; c->with_param || d->with_param;
} }
Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e): Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e)
Item_func_or_sum(thd, a, b, c, d, e) :Item_func_or_sum(thd, a, b, c, d, e), With_sum_func_cache(a, b, c, d, e)
{ {
with_sum_func= a->with_sum_func || b->with_sum_func ||
c->with_sum_func || d->with_sum_func || e->with_sum_func;
with_field= a->with_field || b->with_field || with_field= a->with_field || b->with_field ||
c->with_field || d->with_field || e->with_field; c->with_field || d->with_field || e->with_field;
with_param= a->with_param || b->with_param || with_param= a->with_param || b->with_param ||
@ -131,11 +125,10 @@ public:
set_arguments(thd, list); set_arguments(thd, list);
} }
// Constructor used for Item_cond_and/or (see Item comment) // Constructor used for Item_cond_and/or (see Item comment)
Item_func(THD *thd, Item_func *item): Item_func(THD *thd, Item_func *item)
Item_func_or_sum(thd, item), :Item_func_or_sum(thd, item), With_sum_func_cache(item),
not_null_tables_cache(item->not_null_tables_cache) not_null_tables_cache(item->not_null_tables_cache)
{ { }
}
bool fix_fields(THD *, Item **ref); bool fix_fields(THD *, Item **ref);
void cleanup() void cleanup()
{ {
@ -382,6 +375,9 @@ public:
- or replaced to an Item_int_with_ref - or replaced to an Item_int_with_ref
*/ */
bool setup_args_and_comparator(THD *thd, Arg_comparator *cmp); bool setup_args_and_comparator(THD *thd, Arg_comparator *cmp);
bool with_sum_func() const { return m_with_sum_func; }
With_sum_func_cache* get_with_sum_func_cache() { return this; }
}; };

View File

@ -60,7 +60,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
} }
} }
maybe_null|= item->maybe_null; maybe_null|= item->maybe_null;
with_sum_func= with_sum_func || item->with_sum_func; join_with_sum_func(item);
with_window_func = with_window_func || item->with_window_func; with_window_func = with_window_func || item->with_window_func;
with_field= with_field || item->with_field; with_field= with_field || item->with_field;
m_with_subquery|= item->with_subquery(); m_with_subquery|= item->with_subquery();

View File

@ -36,7 +36,8 @@
class Item_row: public Item_fixed_hybrid, class Item_row: public Item_fixed_hybrid,
private Item_args, private Item_args,
private Used_tables_and_const_cache, private Used_tables_and_const_cache,
private With_subquery_cache private With_subquery_cache,
private With_sum_func_cache
{ {
table_map not_null_tables_cache; table_map not_null_tables_cache;
/** /**
@ -52,6 +53,7 @@ public:
Item_row(THD *thd, Item_row *row) Item_row(THD *thd, Item_row *row)
:Item_fixed_hybrid(thd), Item_args(thd, static_cast<Item_args*>(row)), :Item_fixed_hybrid(thd), Item_args(thd, static_cast<Item_args*>(row)),
Used_tables_and_const_cache(), Used_tables_and_const_cache(),
With_sum_func_cache(*row),
not_null_tables_cache(0), with_null(0) not_null_tables_cache(0), with_null(0)
{ } { }
@ -99,6 +101,8 @@ public:
void cleanup(); void cleanup();
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags); List<Item> &fields, uint flags);
bool with_sum_func() const { return m_with_sum_func; }
With_sum_func_cache* get_with_sum_func_cache() { return this; }
table_map used_tables() const { return used_tables_cache; }; table_map used_tables() const { return used_tables_cache; };
bool const_item() const { return const_item_cache; }; bool const_item() const { return const_item_cache; };
void update_used_tables() void update_used_tables()

View File

@ -933,7 +933,7 @@ bool Item_subselect::const_item() const
Item *Item_subselect::get_tmp_table_item(THD *thd_arg) Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
{ {
if (!with_sum_func && !const_item()) if (!Item_subselect::with_sum_func() && !const_item())
return new (thd->mem_root) Item_temptable_field(thd_arg, result_field); return new (thd->mem_root) Item_temptable_field(thd_arg, result_field);
return copy_or_same(thd_arg); return copy_or_same(thd_arg);
} }
@ -1136,7 +1136,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
if (!select_lex->master_unit()->is_unit_op() && if (!select_lex->master_unit()->is_unit_op() &&
!select_lex->table_list.elements && !select_lex->table_list.elements &&
select_lex->item_list.elements == 1 && select_lex->item_list.elements == 1 &&
!select_lex->item_list.head()->with_sum_func && !select_lex->item_list.head()->with_sum_func() &&
/* /*
We cant change name of Item_field or Item_ref, because it will We cant change name of Item_field or Item_ref, because it will
prevent it's correct resolving, but we should save name of prevent it's correct resolving, but we should save name of

View File

@ -47,7 +47,8 @@ class Cached_item;
/* base class for subselects */ /* base class for subselects */
class Item_subselect :public Item_result_field, class Item_subselect :public Item_result_field,
protected Used_tables_and_const_cache protected Used_tables_and_const_cache,
protected With_sum_func_cache
{ {
bool value_assigned; /* value already assigned to subselect */ bool value_assigned; /* value already assigned to subselect */
bool own_engine; /* the engine was not taken from other Item_subselect */ bool own_engine; /* the engine was not taken from other Item_subselect */
@ -184,6 +185,8 @@ public:
} }
bool fix_fields(THD *thd, Item **ref); bool fix_fields(THD *thd, Item **ref);
bool with_subquery() const { DBUG_ASSERT(fixed); return true; } bool with_subquery() const { DBUG_ASSERT(fixed); return true; }
bool with_sum_func() const { return m_with_sum_func; }
With_sum_func_cache* get_with_sum_func_cache() { return this; }
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item); bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void recalc_used_tables(st_select_lex *new_parent, bool after_pullout); void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);

View File

@ -404,7 +404,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
for (sl= thd->lex->current_select; for (sl= thd->lex->current_select;
sl && sl != aggr_sel && sl->master_unit()->item; sl && sl != aggr_sel && sl->master_unit()->item;
sl= sl->master_unit()->outer_select() ) sl= sl->master_unit()->outer_select() )
sl->master_unit()->item->with_sum_func= 1; sl->master_unit()->item->get_with_sum_func_cache()->set_with_sum_func();
} }
thd->lex->current_select->mark_as_dependent(thd, aggr_sel, NULL); thd->lex->current_select->mark_as_dependent(thd, aggr_sel, NULL);
@ -484,7 +484,6 @@ void Item_sum::mark_as_sum_func()
cur_select->n_sum_items++; cur_select->n_sum_items++;
cur_select->with_sum_func= 1; cur_select->with_sum_func= 1;
const_item_cache= false; const_item_cache= false;
with_sum_func= 1;
with_field= 0; with_field= 0;
window_func_sum_expr_flag= false; window_func_sum_expr_flag= false;
} }

View File

@ -582,6 +582,8 @@ public:
void mark_as_window_func_sum_expr() { window_func_sum_expr_flag= true; } void mark_as_window_func_sum_expr() { window_func_sum_expr_flag= true; }
bool is_window_func_sum_expr() { return window_func_sum_expr_flag; } bool is_window_func_sum_expr() { return window_func_sum_expr_flag; }
virtual void setup_caches(THD *thd) {}; virtual void setup_caches(THD *thd) {};
bool with_sum_func() const { return true; }
}; };

View File

@ -120,7 +120,6 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
const_item_cache= false; const_item_cache= false;
with_window_func= true; with_window_func= true;
with_sum_func= false;
fix_length_and_dec(); fix_length_and_dec();

View File

@ -7345,7 +7345,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
Item_window_func::split_sum_func. Item_window_func::split_sum_func.
*/ */
if (sum_func_list && if (sum_func_list &&
((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) || ((item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM) ||
item->with_window_func)) item->with_window_func))
{ {
item->split_sum_func(thd, ref_pointer_array, *sum_func_list, item->split_sum_func(thd, ref_pointer_array, *sum_func_list,

View File

@ -1046,7 +1046,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
while ((select_el= select_it++)) while ((select_el= select_it++))
{ {
if (select_el->with_sum_func) if (select_el->with_sum_func())
found_sum_func_elem= true; found_sum_func_elem= true;
if (select_el->with_field) if (select_el->with_field)
found_field_elem= true; found_field_elem= true;
@ -1214,14 +1214,14 @@ JOIN::prepare(TABLE_LIST *tables_init,
item->max_length))) item->max_length)))
real_order= TRUE; real_order= TRUE;
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) if (item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM)
item->split_sum_func(thd, ref_ptrs, all_fields, 0); item->split_sum_func(thd, ref_ptrs, all_fields, 0);
} }
if (!real_order) if (!real_order)
order= NULL; order= NULL;
} }
if (having && having->with_sum_func) if (having && having->with_sum_func())
having->split_sum_func2(thd, ref_ptrs, all_fields, having->split_sum_func2(thd, ref_ptrs, all_fields,
&having, SPLIT_SUM_SKIP_REGISTERED); &having, SPLIT_SUM_SKIP_REGISTERED);
if (select_lex->inner_sum_func_list) if (select_lex->inner_sum_func_list)
@ -2439,7 +2439,7 @@ int JOIN::optimize_stage2()
elements may be lost during further having elements may be lost during further having
condition transformation in JOIN::exec. condition transformation in JOIN::exec.
*/ */
if (having && const_table_map && !having->with_sum_func) if (having && const_table_map && !having->with_sum_func())
{ {
having->update_used_tables(); having->update_used_tables();
having= having->remove_eq_conds(thd, &select_lex->having_value, true); having= having->remove_eq_conds(thd, &select_lex->having_value, true);
@ -12967,7 +12967,7 @@ static void update_depend_map_for_order(JOIN *join, ORDER *order)
order->used= 0; order->used= 0;
// Not item_sum(), RAND() and no reference to table outside of sub select // Not item_sum(), RAND() and no reference to table outside of sub select
if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
&& !order->item[0]->with_sum_func && && !order->item[0]->with_sum_func() &&
join->join_tab) join->join_tab)
{ {
for (JOIN_TAB **tab=join->map2table; for (JOIN_TAB **tab=join->map2table;
@ -13058,7 +13058,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
for (order=first_order; order ; order=order->next) for (order=first_order; order ; order=order->next)
{ {
table_map order_tables=order->item[0]->used_tables(); table_map order_tables=order->item[0]->used_tables();
if (order->item[0]->with_sum_func || if (order->item[0]->with_sum_func() ||
/* /*
If the outer table of an outer join is const (either by itself or If the outer table of an outer join is const (either by itself or
after applying WHERE condition), grouping on a field from such a after applying WHERE condition), grouping on a field from such a
@ -13234,7 +13234,7 @@ ORDER *simple_remove_const(ORDER *order, COND *where)
ORDER *first= NULL, *prev= NULL; ORDER *first= NULL, *prev= NULL;
for (; order; order= order->next) for (; order; order= order->next)
{ {
DBUG_ASSERT(!order->item[0]->with_sum_func); // should never happen DBUG_ASSERT(!order->item[0]->with_sum_func()); // should never happen
if (!const_expression_in_where(where, order->item[0])) if (!const_expression_in_where(where, order->item[0]))
{ {
if (!first) if (!first)
@ -17169,7 +17169,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
} }
if (not_all_columns) if (not_all_columns)
{ {
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM) if (item->with_sum_func() && type != Item::SUM_FUNC_ITEM)
{ {
if (item->used_tables() & OUTER_REF_TABLE_BIT) if (item->used_tables() & OUTER_REF_TABLE_BIT)
item->update_used_tables(); item->update_used_tables();
@ -23058,7 +23058,7 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
all_fields, true, true, from_window_spec)) all_fields, true, true, from_window_spec))
return 1; return 1;
(*ord->item)->marker= UNDEF_POS; /* Mark found */ (*ord->item)->marker= UNDEF_POS; /* Mark found */
if ((*ord->item)->with_sum_func && context_analysis_place == IN_GROUP_BY) if ((*ord->item)->with_sum_func() && context_analysis_place == IN_GROUP_BY)
{ {
my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name()); my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name());
return 1; return 1;
@ -23216,7 +23216,7 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
li.rewind(); li.rewind();
while ((item=li++)) while ((item=li++))
{ {
if (!item->const_item() && !item->with_sum_func && !item->marker) if (!item->const_item() && !item->with_sum_func() && !item->marker)
{ {
/* /*
Don't put duplicate columns from the SELECT list into the Don't put duplicate columns from the SELECT list into the
@ -23313,9 +23313,11 @@ count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
} }
else else
{ {
With_sum_func_cache *cache= field->get_with_sum_func_cache();
param->func_count++; param->func_count++;
if (reset_with_sum_func) // "field" can point to Item_std_field, so "cache" can be NULL here.
field->with_sum_func=0; if (reset_with_sum_func && cache)
cache->reset_with_sum_func();
} }
} }
} }
@ -23719,7 +23721,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
real_pos->real_type() == Item::SUBSELECT_ITEM || real_pos->real_type() == Item::SUBSELECT_ITEM ||
real_pos->type() == Item::CACHE_ITEM || real_pos->type() == Item::CACHE_ITEM ||
real_pos->type() == Item::COND_ITEM) && real_pos->type() == Item::COND_ITEM) &&
!real_pos->with_sum_func) !real_pos->with_sum_func())
{ // Save for send fields { // Save for send fields
pos= real_pos; pos= real_pos;
/* TODO: /* TODO:
@ -23926,7 +23928,7 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
for (uint i= 0; (item= it++); i++) for (uint i= 0; (item= it++); i++)
{ {
Field *field; Field *field;
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) if (item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM)
item_field= item; item_field= item;
else if (item->type() == Item::FIELD_ITEM) else if (item->type() == Item::FIELD_ITEM)
{ {
@ -24453,7 +24455,7 @@ bool JOIN::rollup_init()
Marking the expression item as 'with_sum_func' will ensure this. Marking the expression item as 'with_sum_func' will ensure this.
*/ */
if (changed) if (changed)
item->with_sum_func= 1; item->get_with_sum_func_cache()->set_with_sum_func();
} }
} }
return 0; return 0;