Skip to content

Commit be2038e

Browse files
author
Alexander Barkov
committed
MDEV-7950 Item_func::type() takes 0.26% in OLTP RO
Step 4 (there will be more)
1 parent 16b6ec2 commit be2038e

File tree

5 files changed

+78
-36
lines changed

5 files changed

+78
-36
lines changed

sql/item.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,11 @@ class Item: public Type_std_attributes
11281128
void print_value(String *);
11291129
virtual void update_used_tables() {}
11301130
virtual COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
1131-
bool link_item_fields)
1131+
bool link_item_fields,
1132+
COND_EQUAL **cond_equal_ref)
11321133
{
11331134
update_used_tables();
1135+
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
11341136
return this;
11351137
}
11361138
/*
@@ -2335,7 +2337,8 @@ class Item_field :public Item_ident
23352337
update_table_bitmaps();
23362338
}
23372339
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
2338-
bool link_item_fields)
2340+
bool link_item_fields,
2341+
COND_EQUAL **cond_equal_ref)
23392342
{
23402343
/*
23412344
normilize_cond() replaced all conditions of type
@@ -2351,7 +2354,8 @@ class Item_field :public Item_ident
23512354
SELECT * FROM t1 WHERE DEFAULT(a);
23522355
*/
23532356
DBUG_ASSERT(type() != FIELD_ITEM);
2354-
return Item_ident::build_equal_items(thd, inherited, link_item_fields);
2357+
return Item_ident::build_equal_items(thd, inherited, link_item_fields,
2358+
cond_equal_ref);
23552359
}
23562360
bool is_result_field() { return false; }
23572361
void set_result_field(Field *field) {}
@@ -3593,7 +3597,8 @@ class Item_ref :public Item_ident
35933597
table_map used_tables() const;
35943598
void update_used_tables();
35953599
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
3596-
bool link_item_fields)
3600+
bool link_item_fields,
3601+
COND_EQUAL **cond_equal_ref)
35973602
{
35983603
/*
35993604
normilize_cond() replaced all conditions of type
@@ -3604,7 +3609,8 @@ class Item_ref :public Item_ident
36043609
already be replaced. No Item_ref referencing to Item_field are possible.
36053610
*/
36063611
DBUG_ASSERT(real_type() != FIELD_ITEM);
3607-
return Item_ident::build_equal_items(thd, inherited, link_item_fields);
3612+
return Item_ident::build_equal_items(thd, inherited, link_item_fields,
3613+
cond_equal_ref);
36083614
}
36093615
bool const_item() const
36103616
{

sql/item_cmpfunc.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,8 @@ class Item_func_eq :public Item_bool_rowready_func2
563563
const char *func_name() const { return "="; }
564564
Item *negated_item();
565565
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
566-
bool link_item_fields);
566+
bool link_item_fields,
567+
COND_EQUAL **cond_equal_ref);
567568
bool check_equality(THD *thd, COND_EQUAL *cond, List<Item> *eq_list);
568569
/*
569570
- If this equality is created from the subquery's IN-equality:
@@ -1772,7 +1773,8 @@ class Item_cond :public Item_bool_func
17721773
used_tables_and_const_cache_update_and_join(list);
17731774
}
17741775
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
1775-
bool link_item_fields);
1776+
bool link_item_fields,
1777+
COND_EQUAL **cond_equal_ref);
17761778
virtual void print(String *str, enum_query_type query_type);
17771779
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
17781780
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
@@ -1960,6 +1962,9 @@ class Item_equal: public Item_bool_func
19601962
void fix_length_and_dec();
19611963
bool fix_fields(THD *thd, Item **ref);
19621964
void update_used_tables();
1965+
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
1966+
bool link_item_fields,
1967+
COND_EQUAL **cond_equal_ref);
19631968
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
19641969
Item *transform(Item_transformer transformer, uchar *arg);
19651970
virtual void print(String *str, enum_query_type query_type);
@@ -1989,6 +1994,11 @@ class COND_EQUAL: public Sql_alloc
19891994
{
19901995
upper_levels= 0;
19911996
}
1997+
COND_EQUAL(Item_equal *item, MEM_ROOT *mem_root)
1998+
:upper_levels(0)
1999+
{
2000+
current_level.push_back(item, mem_root);
2001+
}
19922002
void copy(COND_EQUAL &cond_equal)
19932003
{
19942004
max_members= cond_equal.max_members;
@@ -2107,7 +2117,8 @@ class Item_cond_and :public Item_cond
21072117
virtual uint exists2in_reserved_items() { return list.elements; };
21082118
bool walk_top_and(Item_processor processor, uchar *arg);
21092119
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
2110-
bool link_item_fields);
2120+
bool link_item_fields,
2121+
COND_EQUAL **cond_equal_ref);
21112122
};
21122123

21132124
inline bool is_cond_and(Item *item)

sql/item_func.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache
132132
used_tables_and_const_cache_update_and_join(arg_count, args);
133133
}
134134
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
135-
bool link_item_fields);
135+
bool link_item_fields,
136+
COND_EQUAL **cond_equal_ref);
136137
bool eq(const Item *item, bool binary_cmp) const;
137138
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
138139
virtual bool have_rev_func() const { return 0; }

sql/item_sum.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,15 +445,17 @@ class Item_sum :public Item_func_or_sum
445445
table_map used_tables() const { return used_tables_cache; }
446446
void update_used_tables ();
447447
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
448-
bool link_item_fields)
448+
bool link_item_fields,
449+
COND_EQUAL **cond_equal_ref)
449450
{
450451
/*
451452
Item_sum (and derivants) of the original WHERE/HAVING clauses
452453
should already be replaced to Item_aggregate_ref by the time when
453454
build_equal_items() is called. See Item::split_sum_func2().
454455
*/
455456
DBUG_ASSERT(0);
456-
return Item::build_equal_items(thd, inherited, link_item_fields);
457+
return Item::build_equal_items(thd, inherited, link_item_fields,
458+
cond_equal_ref);
457459
}
458460
bool is_null() { return null_value; }
459461
void make_const ()

sql/sql_select.cc

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12776,7 +12776,8 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal,
1277612776

1277712777
COND *Item_cond_and::build_equal_items(THD *thd,
1277812778
COND_EQUAL *inherited,
12779-
bool link_item_fields)
12779+
bool link_item_fields,
12780+
COND_EQUAL **cond_equal_ref)
1278012781
{
1278112782
Item_equal *item_equal;
1278212783
COND_EQUAL cond_equal;
@@ -12788,6 +12789,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
1278812789
List_iterator<Item> li(*args);
1278912790
Item *item;
1279012791

12792+
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
1279112793
/*
1279212794
Retrieve all conjuncts of this level detecting the equality
1279312795
that are subject to substitution by multiple equality items and
@@ -12812,7 +12814,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
1281212814
if (!args->elements &&
1281312815
!cond_equal.current_level.elements &&
1281412816
!eq_list.elements)
12815-
return new Item_int((longlong) 1, 1);
12817+
return new (thd->mem_root) Item_int((longlong) 1, 1);
1281612818

1281712819
List_iterator_fast<Item_equal> it(cond_equal.current_level);
1281812820
while ((item_equal= it++))
@@ -12836,7 +12838,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
1283612838
while ((item= li++))
1283712839
{
1283812840
Item *new_item;
12839-
if ((new_item= item->build_equal_items(thd, inherited, FALSE))
12841+
if ((new_item= item->build_equal_items(thd, inherited, false, NULL))
1284012842
!= item)
1284112843
{
1284212844
/* This replacement happens only for standalone equalities */
@@ -12851,19 +12853,23 @@ COND *Item_cond_and::build_equal_items(THD *thd,
1285112853
args->append(&eq_list);
1285212854
args->append((List<Item> *)&cond_equal.current_level);
1285312855
update_used_tables();
12856+
if (cond_equal_ref)
12857+
*cond_equal_ref= &m_cond_equal;
1285412858
return this;
1285512859
}
1285612860

1285712861

1285812862
COND *Item_cond::build_equal_items(THD *thd,
1285912863
COND_EQUAL *inherited,
12860-
bool link_item_fields)
12864+
bool link_item_fields,
12865+
COND_EQUAL **cond_equal_ref)
1286112866
{
1286212867
List<Item> *args= argument_list();
1286312868

1286412869
List_iterator<Item> li(*args);
1286512870
Item *item;
1286612871

12872+
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
1286712873
/*
1286812874
Make replacement of equality predicates for lower levels
1286912875
of the condition expression.
@@ -12873,7 +12879,7 @@ COND *Item_cond::build_equal_items(THD *thd,
1287312879
while ((item= li++))
1287412880
{
1287512881
Item *new_item;
12876-
if ((new_item= item->build_equal_items(thd, inherited, FALSE))
12882+
if ((new_item= item->build_equal_items(thd, inherited, false, NULL))
1287712883
!= item)
1287812884
{
1287912885
/* This replacement happens only for standalone equalities */
@@ -12892,11 +12898,14 @@ COND *Item_cond::build_equal_items(THD *thd,
1289212898

1289312899
COND *Item_func_eq::build_equal_items(THD *thd,
1289412900
COND_EQUAL *inherited,
12895-
bool link_item_fields)
12901+
bool link_item_fields,
12902+
COND_EQUAL **cond_equal_ref)
1289612903
{
1289712904
COND_EQUAL cond_equal;
1289812905
cond_equal.upper_levels= inherited;
1289912906
List<Item> eq_list;
12907+
12908+
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
1290012909
/*
1290112910
If an equality predicate forms the whole and level,
1290212911
we call it standalone equality and it's processed here.
@@ -12912,7 +12921,7 @@ COND *Item_func_eq::build_equal_items(THD *thd,
1291212921
Item_equal *item_equal;
1291312922
int n= cond_equal.current_level.elements + eq_list.elements;
1291412923
if (n == 0)
12915-
return new Item_int((longlong) 1,1);
12924+
return new (thd->mem_root) Item_int((longlong) 1,1);
1291612925
else if (n == 1)
1291712926
{
1291812927
if ((item_equal= cond_equal.current_level.pop()))
@@ -12922,10 +12931,14 @@ COND *Item_func_eq::build_equal_items(THD *thd,
1292212931
set_if_bigger(thd->lex->current_select->max_equal_elems,
1292312932
item_equal->n_field_items());
1292412933
item_equal->upper_levels= inherited;
12934+
if (cond_equal_ref)
12935+
*cond_equal_ref= new (thd->mem_root) COND_EQUAL(item_equal,
12936+
thd->mem_root);
1292512937
return item_equal;
1292612938
}
1292712939
Item *res= eq_list.pop();
1292812940
res->update_used_tables();
12941+
DBUG_ASSERT(res->type() == FUNC_ITEM);
1292912942
return res;
1293012943
}
1293112944
else
@@ -12949,15 +12962,19 @@ COND *Item_func_eq::build_equal_items(THD *thd,
1294912962
cond_equal.current_level= and_cond->m_cond_equal.current_level;
1295012963
args->append((List<Item> *)&cond_equal.current_level);
1295112964
and_cond->update_used_tables();
12965+
if (cond_equal_ref)
12966+
*cond_equal_ref= &and_cond->m_cond_equal;
1295212967
return and_cond;
1295312968
}
1295412969
}
12955-
return Item_func::build_equal_items(thd, inherited, link_item_fields);
12970+
return Item_func::build_equal_items(thd, inherited, link_item_fields,
12971+
cond_equal_ref);
1295612972
}
1295712973

1295812974

1295912975
COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited,
12960-
bool link_item_fields)
12976+
bool link_item_fields,
12977+
COND_EQUAL **cond_equal_ref)
1296112978
{
1296212979
/*
1296312980
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,
1297112988
&Item::equal_fields_propagator,
1297212989
(uchar *) inherited);
1297312990
cond->update_used_tables();
12991+
DBUG_ASSERT(cond == this);
12992+
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
12993+
return cond;
12994+
}
12995+
12996+
12997+
COND *Item_equal::build_equal_items(THD *thd, COND_EQUAL *inherited,
12998+
bool link_item_fields,
12999+
COND_EQUAL **cond_equal_ref)
13000+
{
13001+
COND *cond= Item_func::build_equal_items(thd, inherited, link_item_fields,
13002+
cond_equal_ref);
13003+
if (cond_equal_ref)
13004+
*cond_equal_ref= new (thd->mem_root) COND_EQUAL(this, thd->mem_root);
1297413005
return cond;
1297513006
}
1297613007

@@ -13052,28 +13083,19 @@ static COND *build_equal_items(JOIN *join, COND *cond,
1305213083
bool link_equal_fields)
1305313084
{
1305413085
THD *thd= join->thd;
13055-
COND_EQUAL *cond_equal= 0;
13086+
13087+
*cond_equal_ref= NULL;
1305613088

1305713089
if (cond)
1305813090
{
13059-
cond= cond->build_equal_items(thd, inherited, link_equal_fields);
13060-
if (cond->type() == Item::COND_ITEM &&
13061-
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
13062-
cond_equal= &((Item_cond_and*) cond)->m_cond_equal;
13063-
13064-
else if (cond->type() == Item::FUNC_ITEM &&
13065-
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
13091+
cond= cond->build_equal_items(thd, inherited, link_equal_fields,
13092+
cond_equal_ref);
13093+
if (*cond_equal_ref)
1306613094
{
13067-
cond_equal= new (thd->mem_root) COND_EQUAL;
13068-
cond_equal->current_level.push_back((Item_equal *) cond, thd->mem_root);
13095+
(*cond_equal_ref)->upper_levels= inherited;
13096+
inherited= *cond_equal_ref;
1306913097
}
1307013098
}
13071-
if (cond_equal)
13072-
{
13073-
cond_equal->upper_levels= inherited;
13074-
inherited= cond_equal;
13075-
}
13076-
*cond_equal_ref= cond_equal;
1307713099

1307813100
if (join_list && !ignore_on_conds)
1307913101
{

0 commit comments

Comments
 (0)