mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
MDEV-8024 Remove excessive update_used_tables() calls
This commit is contained in:
parent
e7a7ea7ec1
commit
fc1f301e91
12 changed files with 156 additions and 127 deletions
16
sql/item.cc
16
sql/item.cc
|
@ -4730,10 +4730,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
|||
else
|
||||
{
|
||||
Item::Type ref_type= (*reference)->type();
|
||||
prev_subselect_item->used_tables_cache|=
|
||||
(*reference)->used_tables();
|
||||
prev_subselect_item->const_item_cache&=
|
||||
(*reference)->const_item();
|
||||
prev_subselect_item->used_tables_and_const_cache_join(*reference);
|
||||
mark_as_dependent(thd, last_checked_context->select_lex,
|
||||
context->select_lex, this,
|
||||
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
|
||||
|
@ -4759,8 +4756,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
|||
if (ref != not_found_item)
|
||||
{
|
||||
DBUG_ASSERT(*ref && (*ref)->fixed);
|
||||
prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
|
||||
prev_subselect_item->const_item_cache&= (*ref)->const_item();
|
||||
prev_subselect_item->used_tables_and_const_cache_join(*ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6783,8 +6779,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||
if (ref != not_found_item)
|
||||
{
|
||||
DBUG_ASSERT(*ref && (*ref)->fixed);
|
||||
prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
|
||||
prev_subselect_item->const_item_cache&= (*ref)->const_item();
|
||||
prev_subselect_item->used_tables_and_const_cache_join(*ref);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
@ -6828,10 +6823,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||
if (from_field == view_ref_found)
|
||||
{
|
||||
Item::Type refer_type= (*reference)->type();
|
||||
prev_subselect_item->used_tables_cache|=
|
||||
(*reference)->used_tables();
|
||||
prev_subselect_item->const_item_cache&=
|
||||
(*reference)->const_item();
|
||||
prev_subselect_item->used_tables_and_const_cache_join(*reference);
|
||||
DBUG_ASSERT((*reference)->type() == REF_ITEM);
|
||||
mark_as_dependent(thd, last_checked_context->select_lex,
|
||||
context->select_lex, this,
|
||||
|
|
66
sql/item.h
66
sql/item.h
|
@ -3328,6 +3328,72 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class Used_tables_and_const_cache
|
||||
{
|
||||
public:
|
||||
/*
|
||||
In some cases used_tables_cache is not what used_tables() return
|
||||
so the method should be used where one need used tables bit map
|
||||
(even internally in Item_func_* code).
|
||||
*/
|
||||
table_map used_tables_cache;
|
||||
bool const_item_cache;
|
||||
|
||||
Used_tables_and_const_cache()
|
||||
:used_tables_cache(0),
|
||||
const_item_cache(true)
|
||||
{ }
|
||||
Used_tables_and_const_cache(const Used_tables_and_const_cache *other)
|
||||
:used_tables_cache(other->used_tables_cache),
|
||||
const_item_cache(other->const_item_cache)
|
||||
{ }
|
||||
void used_tables_and_const_cache_init()
|
||||
{
|
||||
used_tables_cache= 0;
|
||||
const_item_cache= true;
|
||||
}
|
||||
void used_tables_and_const_cache_copy(const Used_tables_and_const_cache *c)
|
||||
{
|
||||
*this= *c;
|
||||
}
|
||||
void used_tables_and_const_cache_join(const Item *item)
|
||||
{
|
||||
used_tables_cache|= item->used_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
}
|
||||
/*
|
||||
Call update_used_tables() for all "argc" items in the array "argv"
|
||||
and join with the current cache.
|
||||
"this" must be initialized with a constructor or
|
||||
re-initialized with used_tables_and_const_cache_init().
|
||||
*/
|
||||
void used_tables_and_const_cache_update_and_join(uint argc, Item **argv)
|
||||
{
|
||||
for (uint i=0 ; i < argc ; i++)
|
||||
{
|
||||
argv[i]->update_used_tables();
|
||||
used_tables_and_const_cache_join(argv[i]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
Call update_used_tables() for all items in the list
|
||||
and join with the current cache.
|
||||
"this" must be initialized with a constructor or
|
||||
re-initialized with used_tables_and_const_cache_init().
|
||||
*/
|
||||
void used_tables_and_const_cache_update_and_join(List<Item> &list)
|
||||
{
|
||||
List_iterator_fast<Item> li(list);
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
item->update_used_tables();
|
||||
used_tables_and_const_cache_join(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
An abstract class representing common features of
|
||||
regular functions and aggregate functions.
|
||||
|
|
|
@ -1520,9 +1520,8 @@ bool Item_in_optimizer::fix_left(THD *thd)
|
|||
if (args[1]->fixed)
|
||||
{
|
||||
/* to avoid overriding is called to update left expression */
|
||||
used_tables_cache|= args[1]->used_tables();
|
||||
used_tables_and_const_cache_join(args[1]);
|
||||
with_sum_func= with_sum_func || args[1]->with_sum_func;
|
||||
const_item_cache= const_item_cache && args[1]->const_item();
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -1551,8 +1550,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
|
|||
with_subselect= 1;
|
||||
with_sum_func= with_sum_func || args[1]->with_sum_func;
|
||||
with_field= with_field || args[1]->with_field;
|
||||
used_tables_cache|= args[1]->used_tables();
|
||||
const_item_cache&= args[1]->const_item();
|
||||
used_tables_and_const_cache_join(args[1]);
|
||||
fixed= 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2081,11 +2079,10 @@ void Item_func_interval::fix_length_and_dec()
|
|||
}
|
||||
maybe_null= 0;
|
||||
max_length= 2;
|
||||
used_tables_cache|= row->used_tables();
|
||||
used_tables_and_const_cache_join(row);
|
||||
not_null_tables_cache= row->not_null_tables();
|
||||
with_sum_func= with_sum_func || row->with_sum_func;
|
||||
with_field= with_field || row->with_field;
|
||||
const_item_cache&= row->const_item();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4302,8 +4299,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
|||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
uchar buff[sizeof(char*)]; // Max local vars in function
|
||||
not_null_tables_cache= used_tables_cache= 0;
|
||||
const_item_cache= 1;
|
||||
not_null_tables_cache= 0;
|
||||
used_tables_and_const_cache_init();
|
||||
|
||||
/*
|
||||
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)
|
|||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
|
||||
used_tables_cache=0;
|
||||
const_item_cache=1;
|
||||
used_tables_and_const_cache_init();
|
||||
|
||||
and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
|
||||
not_null_tables_cache= 0;
|
||||
|
@ -4464,8 +4460,7 @@ void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
|||
table_map tmp_table_map;
|
||||
item->fix_after_pullout(new_parent, li.ref());
|
||||
item= *li.ref();
|
||||
used_tables_cache|= item->used_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
used_tables_and_const_cache_join(item);
|
||||
|
||||
if (item->const_item())
|
||||
and_tables_cache= (table_map) 0;
|
||||
|
@ -4648,22 +4643,6 @@ Item_cond::used_tables() const
|
|||
}
|
||||
|
||||
|
||||
void Item_cond::update_used_tables()
|
||||
{
|
||||
List_iterator_fast<Item> li(list);
|
||||
Item *item;
|
||||
|
||||
used_tables_cache=0;
|
||||
const_item_cache=1;
|
||||
while ((item=li++))
|
||||
{
|
||||
item->update_used_tables();
|
||||
used_tables_cache|= item->used_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Item_cond::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
str->append('(');
|
||||
|
|
|
@ -1763,7 +1763,11 @@ public:
|
|||
enum Type type() const { return COND_ITEM; }
|
||||
List<Item>* argument_list() { return &list; }
|
||||
table_map used_tables() const;
|
||||
void update_used_tables();
|
||||
void update_used_tables()
|
||||
{
|
||||
used_tables_and_const_cache_init();
|
||||
used_tables_and_const_cache_update_and_join(list);
|
||||
}
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
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,
|
||||
|
|
|
@ -178,8 +178,14 @@ Item_func::fix_fields(THD *thd, Item **ref)
|
|||
Item **arg,**arg_end;
|
||||
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||
|
||||
used_tables_cache= not_null_tables_cache= 0;
|
||||
const_item_cache=1;
|
||||
/*
|
||||
The Used_tables_and_const_cache of "this" was initialized by
|
||||
the constructor, or by Item_func::cleanup().
|
||||
*/
|
||||
DBUG_ASSERT(used_tables_cache == 0);
|
||||
DBUG_ASSERT(const_item_cache == true);
|
||||
|
||||
not_null_tables_cache= 0;
|
||||
|
||||
/*
|
||||
Use stack limit of STACK_MIN_SIZE * 2 since
|
||||
|
@ -221,8 +227,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
|
|||
|
||||
with_sum_func= with_sum_func || item->with_sum_func;
|
||||
with_field= with_field || item->with_field;
|
||||
used_tables_cache|= item->used_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
used_tables_and_const_cache_join(item);
|
||||
with_subselect|= item->has_subquery();
|
||||
}
|
||||
}
|
||||
|
@ -269,8 +274,8 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
|||
{
|
||||
Item **arg,**arg_end;
|
||||
|
||||
used_tables_cache= not_null_tables_cache= 0;
|
||||
const_item_cache=1;
|
||||
used_tables_and_const_cache_init();
|
||||
not_null_tables_cache= 0;
|
||||
|
||||
if (arg_count)
|
||||
{
|
||||
|
@ -279,9 +284,8 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
|||
(*arg)->fix_after_pullout(new_parent, arg);
|
||||
Item *item= *arg;
|
||||
|
||||
used_tables_cache|= item->used_tables();
|
||||
used_tables_and_const_cache_join(item);
|
||||
not_null_tables_cache|= item->not_null_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,19 +440,6 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
|||
}
|
||||
|
||||
|
||||
void Item_func::update_used_tables()
|
||||
{
|
||||
used_tables_cache=0;
|
||||
const_item_cache=1;
|
||||
for (uint i=0 ; i < arg_count ; i++)
|
||||
{
|
||||
args[i]->update_used_tables();
|
||||
used_tables_cache|=args[i]->used_tables();
|
||||
const_item_cache&=args[i]->const_item();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
table_map Item_func::used_tables() const
|
||||
{
|
||||
return used_tables_cache;
|
||||
|
@ -3503,8 +3494,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
|
|||
|
||||
/* Fix all arguments */
|
||||
func->maybe_null=0;
|
||||
used_tables_cache=0;
|
||||
const_item_cache=1;
|
||||
used_tables_and_const_cache_init();
|
||||
|
||||
if ((f_args.arg_count=arg_count))
|
||||
{
|
||||
|
@ -3546,8 +3536,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
|
|||
func->with_sum_func= func->with_sum_func || item->with_sum_func;
|
||||
func->with_field= func->with_field || item->with_field;
|
||||
func->with_subselect|= item->with_subselect;
|
||||
used_tables_cache|=item->used_tables();
|
||||
const_item_cache&=item->const_item();
|
||||
used_tables_and_const_cache_join(item);
|
||||
f_args.arg_type[i]=item->result_type();
|
||||
}
|
||||
//TODO: why all following memory is not allocated with 1 call of sql_alloc?
|
||||
|
|
|
@ -31,7 +31,7 @@ extern "C" /* Bug in BSDI include file */
|
|||
#endif
|
||||
|
||||
|
||||
class Item_func :public Item_func_or_sum
|
||||
class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache
|
||||
{
|
||||
void sync_with_sum_func_and_with_field(List<Item> &list);
|
||||
protected:
|
||||
|
@ -42,15 +42,8 @@ protected:
|
|||
uint allowed_arg_cols;
|
||||
String *val_str_from_val_str_ascii(String *str, String *str2);
|
||||
public:
|
||||
/*
|
||||
In some cases used_tables_cache is not what used_tables() return
|
||||
so the method should be used where one need used tables bit map
|
||||
(even internally in Item_func_* code).
|
||||
*/
|
||||
table_map used_tables_cache;
|
||||
table_map not_null_tables_cache;
|
||||
|
||||
bool const_item_cache;
|
||||
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
|
||||
GE_FUNC,GT_FUNC,FT_FUNC,
|
||||
LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
|
||||
|
@ -118,19 +111,26 @@ public:
|
|||
}
|
||||
// Constructor used for Item_cond_and/or (see Item comment)
|
||||
Item_func(THD *thd, Item_func *item)
|
||||
:Item_func_or_sum(thd, item),
|
||||
:Item_func_or_sum(thd, item), Used_tables_and_const_cache(item),
|
||||
allowed_arg_cols(item->allowed_arg_cols),
|
||||
used_tables_cache(item->used_tables_cache),
|
||||
not_null_tables_cache(item->not_null_tables_cache),
|
||||
const_item_cache(item->const_item_cache)
|
||||
not_null_tables_cache(item->not_null_tables_cache)
|
||||
{
|
||||
}
|
||||
bool fix_fields(THD *, Item **ref);
|
||||
void cleanup()
|
||||
{
|
||||
Item_func_or_sum::cleanup();
|
||||
used_tables_and_const_cache_init();
|
||||
}
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
|
||||
void quick_fix_field();
|
||||
table_map used_tables() const;
|
||||
table_map not_null_tables() const;
|
||||
void update_used_tables();
|
||||
void update_used_tables()
|
||||
{
|
||||
used_tables_and_const_cache_init();
|
||||
used_tables_and_const_cache_update_and_join(arg_count, args);
|
||||
}
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
|
||||
virtual bool have_rev_func() const { return 0; }
|
||||
|
@ -1367,8 +1367,7 @@ public:
|
|||
{
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
bool res= udf.fix_fields(thd, this, arg_count, args);
|
||||
used_tables_cache= udf.used_tables_cache;
|
||||
const_item_cache= udf.const_item_cache;
|
||||
used_tables_and_const_cache_copy(&udf);
|
||||
fixed= 1;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
*/
|
||||
|
||||
Item_row::Item_row(List<Item> &arg):
|
||||
Item(), used_tables_cache(0), not_null_tables_cache(0),
|
||||
const_item_cache(1), with_null(0)
|
||||
Item(), Used_tables_and_const_cache(), not_null_tables_cache(0), with_null(0)
|
||||
{
|
||||
|
||||
//TODO: think placing 2-3 component items in item (as it done for function)
|
||||
|
@ -126,8 +125,7 @@ void Item_row::cleanup()
|
|||
|
||||
Item::cleanup();
|
||||
/* Reset to the original values */
|
||||
used_tables_cache= 0;
|
||||
const_item_cache= 1;
|
||||
used_tables_and_const_cache_init();
|
||||
with_null= 0;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -143,29 +141,14 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array,
|
|||
}
|
||||
|
||||
|
||||
void Item_row::update_used_tables()
|
||||
{
|
||||
used_tables_cache= 0;
|
||||
const_item_cache= 1;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
items[i]->update_used_tables();
|
||||
used_tables_cache|= items[i]->used_tables();
|
||||
const_item_cache&= items[i]->const_item();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
||||
{
|
||||
used_tables_cache= 0;
|
||||
const_item_cache= 1;
|
||||
used_tables_and_const_cache_init();
|
||||
not_null_tables_cache= 0;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
items[i]->fix_after_pullout(new_parent, &items[i]);
|
||||
used_tables_cache|= items[i]->used_tables();
|
||||
const_item_cache&= items[i]->const_item();
|
||||
used_tables_and_const_cache_join(items[i]);
|
||||
not_null_tables_cache|= items[i]->not_null_tables();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,22 +17,20 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
class Item_row: public Item
|
||||
class Item_row: public Item, private Used_tables_and_const_cache
|
||||
{
|
||||
Item **items;
|
||||
table_map used_tables_cache, not_null_tables_cache;
|
||||
table_map not_null_tables_cache;
|
||||
uint arg_count;
|
||||
bool const_item_cache;
|
||||
bool with_null;
|
||||
public:
|
||||
Item_row(List<Item> &);
|
||||
Item_row(Item_row *item):
|
||||
Item(),
|
||||
Used_tables_and_const_cache(item),
|
||||
items(item->items),
|
||||
used_tables_cache(item->used_tables_cache),
|
||||
not_null_tables_cache(0),
|
||||
arg_count(item->arg_count),
|
||||
const_item_cache(item->const_item_cache),
|
||||
with_null(0)
|
||||
{}
|
||||
|
||||
|
@ -71,7 +69,11 @@ public:
|
|||
bool const_item() const { return const_item_cache; };
|
||||
enum Item_result result_type() const { return ROW_RESULT; }
|
||||
Item_result cmp_type() const { return ROW_RESULT; }
|
||||
void update_used_tables();
|
||||
void update_used_tables()
|
||||
{
|
||||
used_tables_and_const_cache_init();
|
||||
used_tables_and_const_cache_update_and_join(arg_count, items);
|
||||
}
|
||||
table_map not_null_tables() const { return not_null_tables_cache; }
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
|
||||
|
|
|
@ -49,8 +49,9 @@ const char *exists_outer_expr_name= "<exists outer expr>";
|
|||
int check_and_do_in_subquery_rewrites(JOIN *join);
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), value_assigned(0), own_engine(0), thd(0), old_engine(0),
|
||||
used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1),
|
||||
Item_result_field(), Used_tables_and_const_cache(),
|
||||
value_assigned(0), own_engine(0), thd(0), old_engine(0),
|
||||
have_to_be_excluded(0),
|
||||
inside_first_fix_fields(0), done_first_fix_fields(FALSE),
|
||||
expr_cache(0), forced_const(FALSE), substitution(0), engine(0), eliminated(FALSE),
|
||||
changed(0), is_correlated(FALSE)
|
||||
|
|
|
@ -44,7 +44,8 @@ class Cached_item;
|
|||
|
||||
/* base class for subselects */
|
||||
|
||||
class Item_subselect :public Item_result_field
|
||||
class Item_subselect :public Item_result_field,
|
||||
protected Used_tables_and_const_cache
|
||||
{
|
||||
bool value_assigned; /* value already assigned to subselect */
|
||||
bool own_engine; /* the engine was not taken from other Item_subselect */
|
||||
|
@ -53,16 +54,12 @@ protected:
|
|||
THD *thd;
|
||||
/* old engine if engine was changed */
|
||||
subselect_engine *old_engine;
|
||||
/* cache of used external tables */
|
||||
table_map used_tables_cache;
|
||||
/* allowed number of columns (1 for single value subqueries) */
|
||||
uint max_columns;
|
||||
/* where subquery is placed */
|
||||
enum_parsing_place parsing_place;
|
||||
/* work with 'substitution' */
|
||||
bool have_to_be_excluded;
|
||||
/* cache of constant state */
|
||||
bool const_item_cache;
|
||||
|
||||
bool inside_first_fix_fields;
|
||||
bool done_first_fix_fields;
|
||||
|
|
|
@ -12770,7 +12770,9 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
|
|||
@param inherited path to all inherited multiple equality items
|
||||
|
||||
@return
|
||||
pointer to the transformed condition
|
||||
pointer to the transformed condition,
|
||||
whose Used_tables_and_const_cache is up to date,
|
||||
so no additional update_used_tables() is needed on the result.
|
||||
*/
|
||||
|
||||
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
|
@ -12784,9 +12786,9 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
|||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
List<Item> eq_list;
|
||||
bool and_level= ((Item_cond*) cond)->functype() ==
|
||||
Item_func::COND_AND_FUNC;
|
||||
List<Item> *args= ((Item_cond*) cond)->argument_list();
|
||||
Item_cond *cond_item= (Item_cond*) cond;
|
||||
bool and_level= cond_item->functype() == Item_func::COND_AND_FUNC;
|
||||
List<Item> *args= cond_item->argument_list();
|
||||
|
||||
List_iterator<Item> li(*args);
|
||||
Item *item;
|
||||
|
@ -12837,8 +12839,10 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
|||
/*
|
||||
Make replacement of equality predicates for lower levels
|
||||
of the condition expression.
|
||||
Update used_tables_cache and const_item_cache on the way.
|
||||
*/
|
||||
li.rewind();
|
||||
cond_item->used_tables_and_const_cache_init();
|
||||
while ((item= li++))
|
||||
{
|
||||
Item *new_item;
|
||||
|
@ -12853,12 +12857,27 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
|||
*/
|
||||
li.replace(new_item);
|
||||
}
|
||||
cond_item->used_tables_and_const_cache_join(new_item);
|
||||
}
|
||||
if (and_level)
|
||||
{
|
||||
args->append(&eq_list);
|
||||
args->append((List<Item> *)&cond_equal.current_level);
|
||||
/*
|
||||
Instead of the cond_item->update_used_tables() call below,
|
||||
we could do this:
|
||||
|
||||
cond_item->used_tables_and_const_cache_update_and_join(eq_list);
|
||||
cond_item->used_tables_and_const_cache_update_and_join(
|
||||
*(List<Item> *) &cond_equal.current_level);
|
||||
|
||||
But initializing 2 iterators will probably be even slower than
|
||||
redundant iterations over the topmost elements in "args",
|
||||
which were already processed in the "while" loop above.
|
||||
*/
|
||||
cond_item->update_used_tables();
|
||||
}
|
||||
return cond_item;
|
||||
}
|
||||
else if (cond->type() == Item::FUNC_ITEM ||
|
||||
cond->real_item()->type() == Item::FIELD_ITEM)
|
||||
|
@ -12890,8 +12909,9 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
|||
item_equal->upper_levels= inherited;
|
||||
return item_equal;
|
||||
}
|
||||
|
||||
return eq_list.pop();
|
||||
Item *res= eq_list.pop();
|
||||
res->update_used_tables();
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -12913,7 +12933,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
|||
and_cond->cond_equal.copy(cond_equal);
|
||||
cond_equal.current_level= and_cond->cond_equal.current_level;
|
||||
args->append((List<Item> *)&cond_equal.current_level);
|
||||
|
||||
and_cond->update_used_tables();
|
||||
return and_cond;
|
||||
}
|
||||
}
|
||||
|
@ -12928,8 +12948,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
|||
&is_subst_valid,
|
||||
&Item::equal_fields_propagator,
|
||||
(uchar *) inherited);
|
||||
cond->update_used_tables();
|
||||
}
|
||||
cond->update_used_tables();
|
||||
return cond;
|
||||
}
|
||||
|
||||
|
@ -13016,7 +13036,6 @@ static COND *build_equal_items(JOIN *join, COND *cond,
|
|||
if (cond)
|
||||
{
|
||||
cond= build_equal_items_for_cond(thd, cond, inherited, link_equal_fields);
|
||||
cond->update_used_tables();
|
||||
if (cond->type() == Item::COND_ITEM &&
|
||||
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
||||
cond_equal= &((Item_cond_and*) cond)->cond_equal;
|
||||
|
|
|
@ -52,7 +52,7 @@ typedef struct st_udf_func
|
|||
|
||||
class Item_result_field;
|
||||
|
||||
class udf_handler :public Sql_alloc
|
||||
class udf_handler :public Sql_alloc, public Used_tables_and_const_cache
|
||||
{
|
||||
protected:
|
||||
udf_func *u_d;
|
||||
|
@ -65,8 +65,6 @@ class udf_handler :public Sql_alloc
|
|||
Item **args;
|
||||
|
||||
public:
|
||||
table_map used_tables_cache;
|
||||
bool const_item_cache;
|
||||
bool not_original;
|
||||
udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0),
|
||||
is_null(0), initialized(0), not_original(0)
|
||||
|
|
Loading…
Reference in a new issue