Skip to content

Commit fc1f301

Browse files
author
Alexander Barkov
committed
MDEV-8024 Remove excessive update_used_tables() calls
1 parent e7a7ea7 commit fc1f301

File tree

12 files changed

+156
-127
lines changed

12 files changed

+156
-127
lines changed

sql/item.cc

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4730,10 +4730,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
47304730
else
47314731
{
47324732
Item::Type ref_type= (*reference)->type();
4733-
prev_subselect_item->used_tables_cache|=
4734-
(*reference)->used_tables();
4735-
prev_subselect_item->const_item_cache&=
4736-
(*reference)->const_item();
4733+
prev_subselect_item->used_tables_and_const_cache_join(*reference);
47374734
mark_as_dependent(thd, last_checked_context->select_lex,
47384735
context->select_lex, this,
47394736
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
@@ -4759,8 +4756,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
47594756
if (ref != not_found_item)
47604757
{
47614758
DBUG_ASSERT(*ref && (*ref)->fixed);
4762-
prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
4763-
prev_subselect_item->const_item_cache&= (*ref)->const_item();
4759+
prev_subselect_item->used_tables_and_const_cache_join(*ref);
47644760
break;
47654761
}
47664762
}
@@ -6783,8 +6779,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
67836779
if (ref != not_found_item)
67846780
{
67856781
DBUG_ASSERT(*ref && (*ref)->fixed);
6786-
prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
6787-
prev_subselect_item->const_item_cache&= (*ref)->const_item();
6782+
prev_subselect_item->used_tables_and_const_cache_join(*ref);
67886783
break;
67896784
}
67906785
/*
@@ -6828,10 +6823,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
68286823
if (from_field == view_ref_found)
68296824
{
68306825
Item::Type refer_type= (*reference)->type();
6831-
prev_subselect_item->used_tables_cache|=
6832-
(*reference)->used_tables();
6833-
prev_subselect_item->const_item_cache&=
6834-
(*reference)->const_item();
6826+
prev_subselect_item->used_tables_and_const_cache_join(*reference);
68356827
DBUG_ASSERT((*reference)->type() == REF_ITEM);
68366828
mark_as_dependent(thd, last_checked_context->select_lex,
68376829
context->select_lex, this,

sql/item.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3328,6 +3328,72 @@ class Item_args
33283328
};
33293329

33303330

3331+
class Used_tables_and_const_cache
3332+
{
3333+
public:
3334+
/*
3335+
In some cases used_tables_cache is not what used_tables() return
3336+
so the method should be used where one need used tables bit map
3337+
(even internally in Item_func_* code).
3338+
*/
3339+
table_map used_tables_cache;
3340+
bool const_item_cache;
3341+
3342+
Used_tables_and_const_cache()
3343+
:used_tables_cache(0),
3344+
const_item_cache(true)
3345+
{ }
3346+
Used_tables_and_const_cache(const Used_tables_and_const_cache *other)
3347+
:used_tables_cache(other->used_tables_cache),
3348+
const_item_cache(other->const_item_cache)
3349+
{ }
3350+
void used_tables_and_const_cache_init()
3351+
{
3352+
used_tables_cache= 0;
3353+
const_item_cache= true;
3354+
}
3355+
void used_tables_and_const_cache_copy(const Used_tables_and_const_cache *c)
3356+
{
3357+
*this= *c;
3358+
}
3359+
void used_tables_and_const_cache_join(const Item *item)
3360+
{
3361+
used_tables_cache|= item->used_tables();
3362+
const_item_cache&= item->const_item();
3363+
}
3364+
/*
3365+
Call update_used_tables() for all "argc" items in the array "argv"
3366+
and join with the current cache.
3367+
"this" must be initialized with a constructor or
3368+
re-initialized with used_tables_and_const_cache_init().
3369+
*/
3370+
void used_tables_and_const_cache_update_and_join(uint argc, Item **argv)
3371+
{
3372+
for (uint i=0 ; i < argc ; i++)
3373+
{
3374+
argv[i]->update_used_tables();
3375+
used_tables_and_const_cache_join(argv[i]);
3376+
}
3377+
}
3378+
/*
3379+
Call update_used_tables() for all items in the list
3380+
and join with the current cache.
3381+
"this" must be initialized with a constructor or
3382+
re-initialized with used_tables_and_const_cache_init().
3383+
*/
3384+
void used_tables_and_const_cache_update_and_join(List<Item> &list)
3385+
{
3386+
List_iterator_fast<Item> li(list);
3387+
Item *item;
3388+
while ((item=li++))
3389+
{
3390+
item->update_used_tables();
3391+
used_tables_and_const_cache_join(item);
3392+
}
3393+
}
3394+
};
3395+
3396+
33313397
/**
33323398
An abstract class representing common features of
33333399
regular functions and aggregate functions.

sql/item_cmpfunc.cc

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,9 +1520,8 @@ bool Item_in_optimizer::fix_left(THD *thd)
15201520
if (args[1]->fixed)
15211521
{
15221522
/* to avoid overriding is called to update left expression */
1523-
used_tables_cache|= args[1]->used_tables();
1523+
used_tables_and_const_cache_join(args[1]);
15241524
with_sum_func= with_sum_func || args[1]->with_sum_func;
1525-
const_item_cache= const_item_cache && args[1]->const_item();
15261525
}
15271526
DBUG_RETURN(0);
15281527
}
@@ -1551,8 +1550,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
15511550
with_subselect= 1;
15521551
with_sum_func= with_sum_func || args[1]->with_sum_func;
15531552
with_field= with_field || args[1]->with_field;
1554-
used_tables_cache|= args[1]->used_tables();
1555-
const_item_cache&= args[1]->const_item();
1553+
used_tables_and_const_cache_join(args[1]);
15561554
fixed= 1;
15571555
return FALSE;
15581556
}
@@ -2081,11 +2079,10 @@ void Item_func_interval::fix_length_and_dec()
20812079
}
20822080
maybe_null= 0;
20832081
max_length= 2;
2084-
used_tables_cache|= row->used_tables();
2082+
used_tables_and_const_cache_join(row);
20852083
not_null_tables_cache= row->not_null_tables();
20862084
with_sum_func= with_sum_func || row->with_sum_func;
20872085
with_field= with_field || row->with_field;
2088-
const_item_cache&= row->const_item();
20892086
}
20902087

20912088

@@ -4302,8 +4299,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
43024299
List_iterator<Item> li(list);
43034300
Item *item;
43044301
uchar buff[sizeof(char*)]; // Max local vars in function
4305-
not_null_tables_cache= used_tables_cache= 0;
4306-
const_item_cache= 1;
4302+
not_null_tables_cache= 0;
4303+
used_tables_and_const_cache_init();
43074304

43084305
/*
43094306
and_table_cache is the value that Item_cond_or() returns for
@@ -4453,8 +4450,7 @@ void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
44534450
List_iterator<Item> li(list);
44544451
Item *item;
44554452

4456-
used_tables_cache=0;
4457-
const_item_cache=1;
4453+
used_tables_and_const_cache_init();
44584454

44594455
and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
44604456
not_null_tables_cache= 0;
@@ -4464,8 +4460,7 @@ void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
44644460
table_map tmp_table_map;
44654461
item->fix_after_pullout(new_parent, li.ref());
44664462
item= *li.ref();
4467-
used_tables_cache|= item->used_tables();
4468-
const_item_cache&= item->const_item();
4463+
used_tables_and_const_cache_join(item);
44694464

44704465
if (item->const_item())
44714466
and_tables_cache= (table_map) 0;
@@ -4648,22 +4643,6 @@ Item_cond::used_tables() const
46484643
}
46494644

46504645

4651-
void Item_cond::update_used_tables()
4652-
{
4653-
List_iterator_fast<Item> li(list);
4654-
Item *item;
4655-
4656-
used_tables_cache=0;
4657-
const_item_cache=1;
4658-
while ((item=li++))
4659-
{
4660-
item->update_used_tables();
4661-
used_tables_cache|= item->used_tables();
4662-
const_item_cache&= item->const_item();
4663-
}
4664-
}
4665-
4666-
46674646
void Item_cond::print(String *str, enum_query_type query_type)
46684647
{
46694648
str->append('(');

sql/item_cmpfunc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,11 @@ class Item_cond :public Item_bool_func
17631763
enum Type type() const { return COND_ITEM; }
17641764
List<Item>* argument_list() { return &list; }
17651765
table_map used_tables() const;
1766-
void update_used_tables();
1766+
void update_used_tables()
1767+
{
1768+
used_tables_and_const_cache_init();
1769+
used_tables_and_const_cache_update_and_join(list);
1770+
}
17671771
virtual void print(String *str, enum_query_type query_type);
17681772
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
17691773
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,

sql/item_func.cc

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,14 @@ Item_func::fix_fields(THD *thd, Item **ref)
178178
Item **arg,**arg_end;
179179
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
180180

181-
used_tables_cache= not_null_tables_cache= 0;
182-
const_item_cache=1;
181+
/*
182+
The Used_tables_and_const_cache of "this" was initialized by
183+
the constructor, or by Item_func::cleanup().
184+
*/
185+
DBUG_ASSERT(used_tables_cache == 0);
186+
DBUG_ASSERT(const_item_cache == true);
187+
188+
not_null_tables_cache= 0;
183189

184190
/*
185191
Use stack limit of STACK_MIN_SIZE * 2 since
@@ -221,8 +227,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
221227

222228
with_sum_func= with_sum_func || item->with_sum_func;
223229
with_field= with_field || item->with_field;
224-
used_tables_cache|= item->used_tables();
225-
const_item_cache&= item->const_item();
230+
used_tables_and_const_cache_join(item);
226231
with_subselect|= item->has_subquery();
227232
}
228233
}
@@ -269,8 +274,8 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
269274
{
270275
Item **arg,**arg_end;
271276

272-
used_tables_cache= not_null_tables_cache= 0;
273-
const_item_cache=1;
277+
used_tables_and_const_cache_init();
278+
not_null_tables_cache= 0;
274279

275280
if (arg_count)
276281
{
@@ -279,9 +284,8 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
279284
(*arg)->fix_after_pullout(new_parent, arg);
280285
Item *item= *arg;
281286

282-
used_tables_cache|= item->used_tables();
287+
used_tables_and_const_cache_join(item);
283288
not_null_tables_cache|= item->not_null_tables();
284-
const_item_cache&= item->const_item();
285289
}
286290
}
287291
}
@@ -436,19 +440,6 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
436440
}
437441

438442

439-
void Item_func::update_used_tables()
440-
{
441-
used_tables_cache=0;
442-
const_item_cache=1;
443-
for (uint i=0 ; i < arg_count ; i++)
444-
{
445-
args[i]->update_used_tables();
446-
used_tables_cache|=args[i]->used_tables();
447-
const_item_cache&=args[i]->const_item();
448-
}
449-
}
450-
451-
452443
table_map Item_func::used_tables() const
453444
{
454445
return used_tables_cache;
@@ -3503,8 +3494,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
35033494

35043495
/* Fix all arguments */
35053496
func->maybe_null=0;
3506-
used_tables_cache=0;
3507-
const_item_cache=1;
3497+
used_tables_and_const_cache_init();
35083498

35093499
if ((f_args.arg_count=arg_count))
35103500
{
@@ -3546,8 +3536,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
35463536
func->with_sum_func= func->with_sum_func || item->with_sum_func;
35473537
func->with_field= func->with_field || item->with_field;
35483538
func->with_subselect|= item->with_subselect;
3549-
used_tables_cache|=item->used_tables();
3550-
const_item_cache&=item->const_item();
3539+
used_tables_and_const_cache_join(item);
35513540
f_args.arg_type[i]=item->result_type();
35523541
}
35533542
//TODO: why all following memory is not allocated with 1 call of sql_alloc?

sql/item_func.h

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extern "C" /* Bug in BSDI include file */
3131
#endif
3232

3333

34-
class Item_func :public Item_func_or_sum
34+
class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache
3535
{
3636
void sync_with_sum_func_and_with_field(List<Item> &list);
3737
protected:
@@ -42,15 +42,8 @@ class Item_func :public Item_func_or_sum
4242
uint allowed_arg_cols;
4343
String *val_str_from_val_str_ascii(String *str, String *str2);
4444
public:
45-
/*
46-
In some cases used_tables_cache is not what used_tables() return
47-
so the method should be used where one need used tables bit map
48-
(even internally in Item_func_* code).
49-
*/
50-
table_map used_tables_cache;
5145
table_map not_null_tables_cache;
5246

53-
bool const_item_cache;
5447
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
5548
GE_FUNC,GT_FUNC,FT_FUNC,
5649
LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
@@ -118,19 +111,26 @@ class Item_func :public Item_func_or_sum
118111
}
119112
// Constructor used for Item_cond_and/or (see Item comment)
120113
Item_func(THD *thd, Item_func *item)
121-
:Item_func_or_sum(thd, item),
114+
:Item_func_or_sum(thd, item), Used_tables_and_const_cache(item),
122115
allowed_arg_cols(item->allowed_arg_cols),
123-
used_tables_cache(item->used_tables_cache),
124-
not_null_tables_cache(item->not_null_tables_cache),
125-
const_item_cache(item->const_item_cache)
116+
not_null_tables_cache(item->not_null_tables_cache)
126117
{
127118
}
128119
bool fix_fields(THD *, Item **ref);
120+
void cleanup()
121+
{
122+
Item_func_or_sum::cleanup();
123+
used_tables_and_const_cache_init();
124+
}
129125
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
130126
void quick_fix_field();
131127
table_map used_tables() const;
132128
table_map not_null_tables() const;
133-
void update_used_tables();
129+
void update_used_tables()
130+
{
131+
used_tables_and_const_cache_init();
132+
used_tables_and_const_cache_update_and_join(arg_count, args);
133+
}
134134
bool eq(const Item *item, bool binary_cmp) const;
135135
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
136136
virtual bool have_rev_func() const { return 0; }
@@ -1367,8 +1367,7 @@ class Item_udf_func :public Item_func
13671367
{
13681368
DBUG_ASSERT(fixed == 0);
13691369
bool res= udf.fix_fields(thd, this, arg_count, args);
1370-
used_tables_cache= udf.used_tables_cache;
1371-
const_item_cache= udf.const_item_cache;
1370+
used_tables_and_const_cache_copy(&udf);
13721371
fixed= 1;
13731372
return res;
13741373
}

0 commit comments

Comments
 (0)