Commit 89bbb745 authored by Galina Shalygina's avatar Galina Shalygina

Changed is_deterministic() function implementation.

Changed tests.
parent 75b4e195
This diff is collapsed.
This diff is collapsed.
......@@ -10612,3 +10612,18 @@ void Item::register_in(THD *thd)
next= thd->free_list;
thd->free_list= this;
}
bool Item::is_deterministic_arg()
{
if (cmp_type() == STRING_RESULT)
{
if (!((collation.collation == &my_charset_bin) ||
((collation.collation->state & MY_CS_BINSORT) &&
(collation.collation->state & MY_CS_NOPAD))))
return false;
}
if (field_type() == MYSQL_TYPE_FLOAT)
return false;
return true;
}
......@@ -1840,17 +1840,14 @@ class Item: public Value_source,
{
(*traverser)(this, arg);
}
virtual void update_is_deterministic() {}
virtual bool is_deterministic() { return true; }
/*
TRUE if item argument is deterministic or doesn't make this
expression non-deterministic.
Return TRUE if an expression depends on determinstic functions only.
Deterministic function is a function that returns the same result
for equal input sets.
All non-functional items are deterministic by default;
*/
virtual bool is_arg_deterministic(Item **item)
{ return (*item)->is_deterministic(); }
virtual bool lead_to_deterministic_result()
{ return is_deterministic(); }
virtual bool is_deterministic() const { return true; }
virtual void update_is_deterministic() {}
/*========= Item processors, to be used with Item::walk() ========*/
virtual bool remove_dependence_processor(void *arg) { return 0; }
virtual bool cleanup_processor(void *arg);
......@@ -2398,6 +2395,7 @@ class Item: public Value_source,
cmp_type() == DECIMAL_RESULT ||
cmp_type() == REAL_RESULT);
}
bool is_deterministic_arg();
};
MEM_ROOT *get_thd_memroot(THD *thd);
......@@ -2700,6 +2698,15 @@ class Item_args
inline Item **arguments() const { return args; }
inline uint argument_count() const { return arg_count; }
inline void remove_arguments() { arg_count=0; }
bool has_deterministic_args()
{
for (uint i= 0; i < arg_count; i++)
{
if (!args[i]->is_deterministic_arg())
return false;
}
return true;
}
};
......@@ -3548,19 +3555,6 @@ class Item_field :public Item_ident,
{ return field ? 0 : cleanup_processor(arg); }
bool cleanup_excluding_const_fields_processor(void *arg)
{ return field && const_item() ? 0 : cleanup_processor(arg); }
/*
FALSE if the considered Item_field is of STRING type that
makes function where this Item_field is used (if there
is any) non-deterministic.
*/
bool lead_to_deterministic_result()
{
if (field->cmp_type() == STRING_RESULT &&
(!((field->charset()->state & MY_CS_BINSORT) &&
(field->charset()->state & MY_CS_NOPAD))))
return false;
return true;
}
bool excl_dep_on_fd_fields(List<Item> *gb_items, table_map forbid_fd,
Item **err_item);
bool check_usage_in_fd_field_extraction(THD *thd,
......@@ -5093,30 +5087,34 @@ class Is_deterministic_cache
:is_deterministic_cache(true) { }
Is_deterministic_cache(const Is_deterministic_cache *other)
:is_deterministic_cache(other->is_deterministic_cache) { }
void is_deterministic_init()
void is_deterministic_cache_init()
{
is_deterministic_cache= true;
}
void is_deterministic_join(Item *func_item, Item *item)
void is_deterministic_cache_set(bool init_val)
{
is_deterministic_cache= init_val;
}
void is_deterministic_cache_join(const Item *item)
{
is_deterministic_cache&= func_item->is_arg_deterministic(&item);
is_deterministic_cache&= item->is_deterministic();
}
void is_deterministic_update_and_join(Item *func_item, Item *item)
void is_deterministic_update_and_join(Item *item)
{
item->update_is_deterministic();
is_deterministic_join(func_item, item);
is_deterministic_cache_join(item);
}
void is_deterministic_update_and_join(Item *func_item, uint argc, Item **argv)
void is_deterministic_update_and_join(uint argc, Item **argv)
{
for (uint i=0 ; i < argc ; i++)
is_deterministic_update_and_join(func_item, argv[i]);
is_deterministic_update_and_join(argv[i]);
}
void is_deterministic_update_and_join(Item *func_item, List<Item> &list)
void is_deterministic_update_and_join(List<Item> &list)
{
List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
is_deterministic_update_and_join(func_item, item);
is_deterministic_update_and_join(item);
}
};
......@@ -5240,7 +5238,7 @@ class Item_func_or_sum: public Item_result_field,
virtual bool fix_length_and_dec()= 0;
bool const_item() const { return const_item_cache; }
table_map used_tables() const { return used_tables_cache; }
bool is_deterministic() { return is_deterministic_cache; }
bool is_deterministic() const { return is_deterministic_cache; }
Item* build_clone(THD *thd);
};
......@@ -5523,8 +5521,6 @@ class Item_ref :public Item_ident,
*ref= (*ref)->remove_item_direct_ref();
return this;
}
bool lead_to_deterministic_result()
{ return (*ref)->lead_to_deterministic_result(); }
bool excl_dep_on_fd_fields(List<Item> *gb_items, table_map forbid_fd,
Item **err_item);
bool check_usage_in_fd_field_extraction(THD *thd,
......
......@@ -4773,6 +4773,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
not_null_tables_cache= 0;
used_tables_and_const_cache_init();
is_deterministic_cache_init();
/*
and_table_cache is the value that Item_cond_or() returns for
......@@ -4831,7 +4832,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
return TRUE; /* purecov: inspected */
item= *li.ref(); // item can be substituted in fix_fields
used_tables_cache|= item->used_tables();
is_deterministic_join(this, item);
is_deterministic_cache_join(item);
if (item->const_item() && !item->with_param &&
!item->is_expensive() && !cond_has_datetime_is_null(item))
{
......
......@@ -390,6 +390,8 @@ class Item_in_optimizer: public Item_bool_func
{ return args[1]; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_in_optimizer>(thd, this); }
bool is_deterministic_func()
{ return true; }
};
......@@ -732,6 +734,8 @@ class Item_func_eq :public Item_bool_rowready_func2
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_eq>(thd, this); }
bool field_eq_const();
bool is_deterministic_func()
{ return is_deterministic_cache; }
};
class Item_func_equal :public Item_bool_rowready_func2
......@@ -2783,8 +2787,8 @@ class Item_func_like :public Item_bool_func2
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_like>(thd, this); }
bool is_arg_deterministic(Item **item)
{ return (*item)->lead_to_deterministic_result(); }
bool is_deterministic_func()
{ return Item_args::has_deterministic_args(); }
};
......@@ -3017,8 +3021,8 @@ class Item_cond :public Item_bool_func
bool excl_dep_on_grouping_fields(st_select_lex *sel);
void update_is_deterministic()
{
is_deterministic_init();
is_deterministic_update_and_join(this, list);
is_deterministic_cache_init();
is_deterministic_update_and_join(list);
}
bool excl_dep_on_fd_fields(List<Item> *gb_items, table_map forbid_fd,
Item **err_item);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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