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 @@ public: ...@@ -1128,9 +1128,11 @@ public:
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 @@ public: ...@@ -2335,7 +2337,8 @@ public:
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 @@ public: ...@@ -2351,7 +2354,8 @@ public:
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 @@ public: ...@@ -3593,7 +3597,8 @@ public:
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 @@ public: ...@@ -3604,7 +3609,8 @@ public:
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 @@ public: ...@@ -563,7 +563,8 @@ public:
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 @@ public: ...@@ -1772,7 +1773,8 @@ public:
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 @@ public: ...@@ -1960,6 +1962,9 @@ public:
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 @@ public: ...@@ -1989,6 +1994,11 @@ public:
{ {
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 @@ public: ...@@ -2107,7 +2117,8 @@ public:
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 @@ public: ...@@ -132,7 +132,8 @@ public:
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 @@ public: ...@@ -445,7 +445,8 @@ public:
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 @@ public: ...@@ -453,7 +454,8 @@ public:
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