Commit be2038e3 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-7950 Item_func::type() takes 0.26% in OLTP RO

Step 4 (there will be more)
parent 16b6ec2e
...@@ -1128,9 +1128,11 @@ class Item: public Type_std_attributes ...@@ -1128,9 +1128,11 @@ class Item: public Type_std_attributes
void print_value(String *); void print_value(String *);
virtual void update_used_tables() {} virtual void update_used_tables() {}
virtual COND *build_equal_items(THD *thd, COND_EQUAL *inherited, virtual COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
update_used_tables(); update_used_tables();
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
return this; return this;
} }
/* /*
...@@ -2335,7 +2337,8 @@ class Item_field :public Item_ident ...@@ -2335,7 +2337,8 @@ class Item_field :public Item_ident
update_table_bitmaps(); update_table_bitmaps();
} }
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
/* /*
normilize_cond() replaced all conditions of type normilize_cond() replaced all conditions of type
...@@ -2351,7 +2354,8 @@ class Item_field :public Item_ident ...@@ -2351,7 +2354,8 @@ class Item_field :public Item_ident
SELECT * FROM t1 WHERE DEFAULT(a); SELECT * FROM t1 WHERE DEFAULT(a);
*/ */
DBUG_ASSERT(type() != FIELD_ITEM); DBUG_ASSERT(type() != FIELD_ITEM);
return Item_ident::build_equal_items(thd, inherited, link_item_fields); return Item_ident::build_equal_items(thd, inherited, link_item_fields,
cond_equal_ref);
} }
bool is_result_field() { return false; } bool is_result_field() { return false; }
void set_result_field(Field *field) {} void set_result_field(Field *field) {}
...@@ -3593,7 +3597,8 @@ class Item_ref :public Item_ident ...@@ -3593,7 +3597,8 @@ class Item_ref :public Item_ident
table_map used_tables() const; table_map used_tables() const;
void update_used_tables(); void update_used_tables();
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
/* /*
normilize_cond() replaced all conditions of type normilize_cond() replaced all conditions of type
...@@ -3604,7 +3609,8 @@ class Item_ref :public Item_ident ...@@ -3604,7 +3609,8 @@ class Item_ref :public Item_ident
already be replaced. No Item_ref referencing to Item_field are possible. already be replaced. No Item_ref referencing to Item_field are possible.
*/ */
DBUG_ASSERT(real_type() != FIELD_ITEM); DBUG_ASSERT(real_type() != FIELD_ITEM);
return Item_ident::build_equal_items(thd, inherited, link_item_fields); return Item_ident::build_equal_items(thd, inherited, link_item_fields,
cond_equal_ref);
} }
bool const_item() const bool const_item() const
{ {
......
...@@ -563,7 +563,8 @@ class Item_func_eq :public Item_bool_rowready_func2 ...@@ -563,7 +563,8 @@ class Item_func_eq :public Item_bool_rowready_func2
const char *func_name() const { return "="; } const char *func_name() const { return "="; }
Item *negated_item(); Item *negated_item();
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields); bool link_item_fields,
COND_EQUAL **cond_equal_ref);
bool check_equality(THD *thd, COND_EQUAL *cond, List<Item> *eq_list); bool check_equality(THD *thd, COND_EQUAL *cond, List<Item> *eq_list);
/* /*
- If this equality is created from the subquery's IN-equality: - If this equality is created from the subquery's IN-equality:
...@@ -1772,7 +1773,8 @@ class Item_cond :public Item_bool_func ...@@ -1772,7 +1773,8 @@ class Item_cond :public Item_bool_func
used_tables_and_const_cache_update_and_join(list); used_tables_and_const_cache_update_and_join(list);
} }
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields); bool link_item_fields,
COND_EQUAL **cond_equal_ref);
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields); void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
...@@ -1960,6 +1962,9 @@ class Item_equal: public Item_bool_func ...@@ -1960,6 +1962,9 @@ class Item_equal: public Item_bool_func
void fix_length_and_dec(); void fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref); bool fix_fields(THD *thd, Item **ref);
void update_used_tables(); void update_used_tables();
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields,
COND_EQUAL **cond_equal_ref);
bool walk(Item_processor processor, bool walk_subquery, uchar *arg); bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg); Item *transform(Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
...@@ -1989,6 +1994,11 @@ class COND_EQUAL: public Sql_alloc ...@@ -1989,6 +1994,11 @@ class COND_EQUAL: public Sql_alloc
{ {
upper_levels= 0; upper_levels= 0;
} }
COND_EQUAL(Item_equal *item, MEM_ROOT *mem_root)
:upper_levels(0)
{
current_level.push_back(item, mem_root);
}
void copy(COND_EQUAL &cond_equal) void copy(COND_EQUAL &cond_equal)
{ {
max_members= cond_equal.max_members; max_members= cond_equal.max_members;
...@@ -2107,7 +2117,8 @@ class Item_cond_and :public Item_cond ...@@ -2107,7 +2117,8 @@ class Item_cond_and :public Item_cond
virtual uint exists2in_reserved_items() { return list.elements; }; virtual uint exists2in_reserved_items() { return list.elements; };
bool walk_top_and(Item_processor processor, uchar *arg); bool walk_top_and(Item_processor processor, uchar *arg);
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields); bool link_item_fields,
COND_EQUAL **cond_equal_ref);
}; };
inline bool is_cond_and(Item *item) inline bool is_cond_and(Item *item)
......
...@@ -132,7 +132,8 @@ class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache ...@@ -132,7 +132,8 @@ class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache
used_tables_and_const_cache_update_and_join(arg_count, args); used_tables_and_const_cache_update_and_join(arg_count, args);
} }
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields); bool link_item_fields,
COND_EQUAL **cond_equal_ref);
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; } virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; } virtual bool have_rev_func() const { return 0; }
......
...@@ -445,7 +445,8 @@ class Item_sum :public Item_func_or_sum ...@@ -445,7 +445,8 @@ class Item_sum :public Item_func_or_sum
table_map used_tables() const { return used_tables_cache; } table_map used_tables() const { return used_tables_cache; }
void update_used_tables (); void update_used_tables ();
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
/* /*
Item_sum (and derivants) of the original WHERE/HAVING clauses Item_sum (and derivants) of the original WHERE/HAVING clauses
...@@ -453,7 +454,8 @@ class Item_sum :public Item_func_or_sum ...@@ -453,7 +454,8 @@ class Item_sum :public Item_func_or_sum
build_equal_items() is called. See Item::split_sum_func2(). build_equal_items() is called. See Item::split_sum_func2().
*/ */
DBUG_ASSERT(0); DBUG_ASSERT(0);
return Item::build_equal_items(thd, inherited, link_item_fields); return Item::build_equal_items(thd, inherited, link_item_fields,
cond_equal_ref);
} }
bool is_null() { return null_value; } bool is_null() { return null_value; }
void make_const () void make_const ()
......
...@@ -12776,7 +12776,8 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal, ...@@ -12776,7 +12776,8 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal,
COND *Item_cond_and::build_equal_items(THD *thd, COND *Item_cond_and::build_equal_items(THD *thd,
COND_EQUAL *inherited, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
Item_equal *item_equal; Item_equal *item_equal;
COND_EQUAL cond_equal; COND_EQUAL cond_equal;
...@@ -12788,6 +12789,7 @@ COND *Item_cond_and::build_equal_items(THD *thd, ...@@ -12788,6 +12789,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
List_iterator<Item> li(*args); List_iterator<Item> li(*args);
Item *item; Item *item;
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
/* /*
Retrieve all conjuncts of this level detecting the equality Retrieve all conjuncts of this level detecting the equality
that are subject to substitution by multiple equality items and that are subject to substitution by multiple equality items and
...@@ -12812,7 +12814,7 @@ COND *Item_cond_and::build_equal_items(THD *thd, ...@@ -12812,7 +12814,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
if (!args->elements && if (!args->elements &&
!cond_equal.current_level.elements && !cond_equal.current_level.elements &&
!eq_list.elements) !eq_list.elements)
return new Item_int((longlong) 1, 1); return new (thd->mem_root) Item_int((longlong) 1, 1);
List_iterator_fast<Item_equal> it(cond_equal.current_level); List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++)) while ((item_equal= it++))
...@@ -12836,7 +12838,7 @@ COND *Item_cond_and::build_equal_items(THD *thd, ...@@ -12836,7 +12838,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
while ((item= li++)) while ((item= li++))
{ {
Item *new_item; Item *new_item;
if ((new_item= item->build_equal_items(thd, inherited, FALSE)) if ((new_item= item->build_equal_items(thd, inherited, false, NULL))
!= item) != item)
{ {
/* This replacement happens only for standalone equalities */ /* This replacement happens only for standalone equalities */
...@@ -12851,19 +12853,23 @@ COND *Item_cond_and::build_equal_items(THD *thd, ...@@ -12851,19 +12853,23 @@ COND *Item_cond_and::build_equal_items(THD *thd,
args->append(&eq_list); args->append(&eq_list);
args->append((List<Item> *)&cond_equal.current_level); args->append((List<Item> *)&cond_equal.current_level);
update_used_tables(); update_used_tables();
if (cond_equal_ref)
*cond_equal_ref= &m_cond_equal;
return this; return this;
} }
COND *Item_cond::build_equal_items(THD *thd, COND *Item_cond::build_equal_items(THD *thd,
COND_EQUAL *inherited, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
List<Item> *args= argument_list(); List<Item> *args= argument_list();
List_iterator<Item> li(*args); List_iterator<Item> li(*args);
Item *item; Item *item;
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
/* /*
Make replacement of equality predicates for lower levels Make replacement of equality predicates for lower levels
of the condition expression. of the condition expression.
...@@ -12873,7 +12879,7 @@ COND *Item_cond::build_equal_items(THD *thd, ...@@ -12873,7 +12879,7 @@ COND *Item_cond::build_equal_items(THD *thd,
while ((item= li++)) while ((item= li++))
{ {
Item *new_item; Item *new_item;
if ((new_item= item->build_equal_items(thd, inherited, FALSE)) if ((new_item= item->build_equal_items(thd, inherited, false, NULL))
!= item) != item)
{ {
/* This replacement happens only for standalone equalities */ /* This replacement happens only for standalone equalities */
...@@ -12892,11 +12898,14 @@ COND *Item_cond::build_equal_items(THD *thd, ...@@ -12892,11 +12898,14 @@ COND *Item_cond::build_equal_items(THD *thd,
COND *Item_func_eq::build_equal_items(THD *thd, COND *Item_func_eq::build_equal_items(THD *thd,
COND_EQUAL *inherited, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
COND_EQUAL cond_equal; COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited; cond_equal.upper_levels= inherited;
List<Item> eq_list; List<Item> eq_list;
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
/* /*
If an equality predicate forms the whole and level, If an equality predicate forms the whole and level,
we call it standalone equality and it's processed here. we call it standalone equality and it's processed here.
...@@ -12912,7 +12921,7 @@ COND *Item_func_eq::build_equal_items(THD *thd, ...@@ -12912,7 +12921,7 @@ COND *Item_func_eq::build_equal_items(THD *thd,
Item_equal *item_equal; Item_equal *item_equal;
int n= cond_equal.current_level.elements + eq_list.elements; int n= cond_equal.current_level.elements + eq_list.elements;
if (n == 0) if (n == 0)
return new Item_int((longlong) 1,1); return new (thd->mem_root) Item_int((longlong) 1,1);
else if (n == 1) else if (n == 1)
{ {
if ((item_equal= cond_equal.current_level.pop())) if ((item_equal= cond_equal.current_level.pop()))
...@@ -12922,10 +12931,14 @@ COND *Item_func_eq::build_equal_items(THD *thd, ...@@ -12922,10 +12931,14 @@ COND *Item_func_eq::build_equal_items(THD *thd,
set_if_bigger(thd->lex->current_select->max_equal_elems, set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->n_field_items()); item_equal->n_field_items());
item_equal->upper_levels= inherited; item_equal->upper_levels= inherited;
if (cond_equal_ref)
*cond_equal_ref= new (thd->mem_root) COND_EQUAL(item_equal,
thd->mem_root);
return item_equal; return item_equal;
} }
Item *res= eq_list.pop(); Item *res= eq_list.pop();
res->update_used_tables(); res->update_used_tables();
DBUG_ASSERT(res->type() == FUNC_ITEM);
return res; return res;
} }
else else
...@@ -12949,15 +12962,19 @@ COND *Item_func_eq::build_equal_items(THD *thd, ...@@ -12949,15 +12962,19 @@ COND *Item_func_eq::build_equal_items(THD *thd,
cond_equal.current_level= and_cond->m_cond_equal.current_level; cond_equal.current_level= and_cond->m_cond_equal.current_level;
args->append((List<Item> *)&cond_equal.current_level); args->append((List<Item> *)&cond_equal.current_level);
and_cond->update_used_tables(); and_cond->update_used_tables();
if (cond_equal_ref)
*cond_equal_ref= &and_cond->m_cond_equal;
return and_cond; return and_cond;
} }
} }
return Item_func::build_equal_items(thd, inherited, link_item_fields); return Item_func::build_equal_items(thd, inherited, link_item_fields,
cond_equal_ref);
} }
COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited, COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields) bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{ {
/* /*
For each field reference in cond, not from equal item predicates, For each field reference in cond, not from equal item predicates,
...@@ -12971,6 +12988,20 @@ COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited, ...@@ -12971,6 +12988,20 @@ COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited,
&Item::equal_fields_propagator, &Item::equal_fields_propagator,
(uchar *) inherited); (uchar *) inherited);
cond->update_used_tables(); cond->update_used_tables();
DBUG_ASSERT(cond == this);
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
return cond;
}
COND *Item_equal::build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields,
COND_EQUAL **cond_equal_ref)
{
COND *cond= Item_func::build_equal_items(thd, inherited, link_item_fields,
cond_equal_ref);
if (cond_equal_ref)
*cond_equal_ref= new (thd->mem_root) COND_EQUAL(this, thd->mem_root);
return cond; return cond;
} }
...@@ -13052,28 +13083,19 @@ static COND *build_equal_items(JOIN *join, COND *cond, ...@@ -13052,28 +13083,19 @@ static COND *build_equal_items(JOIN *join, COND *cond,
bool link_equal_fields) bool link_equal_fields)
{ {
THD *thd= join->thd; THD *thd= join->thd;
COND_EQUAL *cond_equal= 0;
*cond_equal_ref= NULL;
if (cond) if (cond)
{ {
cond= cond->build_equal_items(thd, inherited, link_equal_fields); cond= cond->build_equal_items(thd, inherited, link_equal_fields,
if (cond->type() == Item::COND_ITEM && cond_equal_ref);
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) if (*cond_equal_ref)
cond_equal= &((Item_cond_and*) cond)->m_cond_equal;
else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{ {
cond_equal= new (thd->mem_root) COND_EQUAL; (*cond_equal_ref)->upper_levels= inherited;
cond_equal->current_level.push_back((Item_equal *) cond, thd->mem_root); inherited= *cond_equal_ref;
} }
} }
if (cond_equal)
{
cond_equal->upper_levels= inherited;
inherited= cond_equal;
}
*cond_equal_ref= cond_equal;
if (join_list && !ignore_on_conds) if (join_list && !ignore_on_conds)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment