cleanup: Item::can_eval_in_optimize()

a helper method to check whether an item can be evaluated
in the query optimization phase (in and below JOIN::optimize()).
This commit is contained in:
Sergei Golubchik 2021-05-17 00:59:51 +02:00
parent 30f0a246a0
commit 6de84e6f4e
11 changed files with 33 additions and 32 deletions

View File

@ -1636,6 +1636,10 @@ public:
DBUG_ASSERT(!is_expensive());
return val_bool();
}
bool can_eval_in_optimize()
{
return const_item() && !is_expensive();
}
/*
save_val() is method of val_* family which stores value in the given

View File

@ -318,7 +318,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
field_item->field_type() != MYSQL_TYPE_YEAR)
return 1;
if ((*item)->const_item() && !(*item)->is_expensive())
if ((*item)->can_eval_in_optimize())
{
TABLE *table= field->table;
Sql_mode_save sql_mode(thd);
@ -4899,8 +4899,8 @@ 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();
if (item->const_item() && !item->with_sp_var() &&
!item->is_expensive() && !cond_has_datetime_is_null(item))
if (item->can_eval_in_optimize() && !item->with_sp_var() &&
!cond_has_datetime_is_null(item))
{
if (item->eval_const_cond() == is_and_cond && top_level())
{
@ -4956,8 +4956,8 @@ Item_cond::eval_not_null_tables(void *opt_arg)
while ((item=li++))
{
table_map tmp_table_map;
if (item->const_item() && !item->with_sp_var() &&
!item->is_expensive() && !cond_has_datetime_is_null(item))
if (item->can_eval_in_optimize() && !item->with_sp_var() &&
!cond_has_datetime_is_null(item))
{
if (item->eval_const_cond() == is_and_cond && top_level())
{
@ -5640,7 +5640,7 @@ bool Item_func_like::with_sargable_pattern() const
if (negated)
return false;
if (!args[1]->const_item() || args[1]->is_expensive())
if (!args[1]->can_eval_in_optimize())
return false;
String* res2= args[1]->val_str((String *) &cmp_value2);
@ -5785,8 +5785,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
We could also do boyer-more for non-const items, but as we would have to
recompute the tables for each row it's not worth it.
*/
if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
!args[1]->is_expensive())
if (args[1]->can_eval_in_optimize() && !use_strnxfrm(collation.collation))
{
String* res2= args[1]->val_str(&cmp_value2);
if (!res2)
@ -6980,7 +6979,7 @@ void Item_equal::update_const(THD *thd)
Item *item;
while ((item= it++))
{
if (item->const_item() && !item->is_expensive() &&
if (item->can_eval_in_optimize() &&
/*
Don't propagate constant status of outer-joined column.
Such a constant status here is a result of:

View File

@ -2486,7 +2486,7 @@ class Item_func_in :public Item_func_opt_neg,
{
for (uint i= 0; i < nitems; i++)
{
if (!items[i]->const_item() || items[i]->is_expensive())
if (!items[i]->can_eval_in_optimize())
return false;
}
return true;

View File

@ -2525,7 +2525,7 @@ void Item_func_round::fix_arg_temporal(const Type_handler *h,
uint int_part_length)
{
set_handler(h);
if (args[1]->const_item() && !args[1]->is_expensive())
if (args[1]->can_eval_in_optimize())
{
Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null();
fix_attributes_temporal(int_part_length,
@ -2561,7 +2561,7 @@ bool Item_func_round::test_if_length_can_increase()
{
if (truncate)
return false;
if (args[1]->const_item() && !args[1]->is_expensive())
if (args[1]->can_eval_in_optimize())
{
// Length can increase in some cases: e.g. ROUND(9,-1) -> 10.
Longlong_hybrid val1= args[1]->to_longlong_hybrid();

View File

@ -1639,7 +1639,7 @@ String *Item_func_left::val_str(String *str)
void Item_str_func::left_right_max_length()
{
uint32 char_length= args[0]->max_char_length();
if (args[1]->const_item() && !args[1]->is_expensive())
if (args[1]->can_eval_in_optimize())
{
uint32 length= max_length_for_string(args[1]);
set_if_smaller(char_length, length);
@ -2669,7 +2669,7 @@ bool Item_func_format::fix_length_and_dec()
the number of decimals and round to the next integer.
*/
bool need_extra_digit_for_rounding= args[0]->decimals > 0;
if (args[1]->const_item() && !args[1]->is_expensive())
if (args[1]->can_eval_in_optimize())
{
Longlong_hybrid tmp= args[1]->to_longlong_hybrid();
if (!args[1]->null_value)
@ -3034,7 +3034,7 @@ bool Item_func_repeat::fix_length_and_dec()
if (agg_arg_charsets_for_string_result(collation, args, 1))
return TRUE;
DBUG_ASSERT(collation.collation != NULL);
if (args[1]->const_item() && !args[1]->is_expensive())
if (args[1]->can_eval_in_optimize())
{
uint32 length= max_length_for_string(args[1]);
ulonglong char_length= (ulonglong) args[0]->max_char_length() * length;
@ -3108,7 +3108,7 @@ err:
bool Item_func_space::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
if (args[0]->const_item() && !args[0]->is_expensive())
if (args[0]->can_eval_in_optimize())
{
fix_char_length_ulonglong(max_length_for_string(args[0]));
return false;
@ -3228,7 +3228,7 @@ bool Item_func_pad::fix_length_and_dec()
}
DBUG_ASSERT(collation.collation->mbmaxlen > 0);
if (args[1]->const_item() && !args[1]->is_expensive())
if (args[1]->can_eval_in_optimize())
{
fix_char_length_ulonglong(max_length_for_string(args[1]));
return false;

View File

@ -1706,7 +1706,7 @@ public:
Item_str_func(thd, a)
{
collation.set(cs, DERIVATION_IMPLICIT);
if (cache_if_const && args[0]->const_item() && !args[0]->is_expensive())
if (cache_if_const && args[0]->can_eval_in_optimize())
{
uint errors= 0;
String tmp, *str= args[0]->val_str(&tmp);

View File

@ -2775,7 +2775,7 @@ bool Item_in_subselect::create_in_to_exists_cond(JOIN *join_arg)
/*
The IN=>EXISTS transformation makes non-correlated subqueries correlated.
*/
if (!left_expr->const_item() || left_expr->is_expensive())
if (!left_expr->can_eval_in_optimize())
{
join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
join_arg->select_lex->master_unit()->uncacheable|=

View File

@ -668,7 +668,7 @@ public:
void disable_cond_guard_for_const_null_left_expr(int i)
{
if (left_expr->const_item() && !left_expr->is_expensive())
if (left_expr->can_eval_in_optimize())
{
if (left_expr->element_index(i)->is_null())
set_cond_guard_var(i,FALSE);

View File

@ -14368,7 +14368,7 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
&has_min_max, &has_other))
DBUG_RETURN(FALSE);
}
else if (cur_arg->const_item() && !cur_arg->is_expensive())
else if (cur_arg->can_eval_in_optimize())
{
/*
For predicates of the form "const OP expr" we also have to check 'expr'

View File

@ -5939,8 +5939,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
new_fields->null_rejecting);
}
else if (old->eq_func && new_fields->eq_func &&
((old->val->const_item() && !old->val->is_expensive() &&
old->val->is_null()) ||
((old->val->can_eval_in_optimize() && old->val->is_null()) ||
(!new_fields->val->is_expensive() &&
new_fields->val->is_null())))
{
@ -11212,8 +11211,7 @@ static void add_not_null_conds(JOIN *join)
Item *item= tab->ref.items[keypart];
Item *notnull;
Item *real= item->real_item();
if (real->const_item() && real->type() != Item::FIELD_ITEM &&
!real->is_expensive())
if (real->can_eval_in_optimize() && real->type() != Item::FIELD_ITEM)
{
/*
It could be constant instead of field after constant
@ -14982,7 +14980,7 @@ bool check_simple_equality(THD *thd, const Item::Context &ctx,
Item *orig_field_item= 0;
if (left_item->type() == Item::FIELD_ITEM &&
!((Item_field*)left_item)->get_depended_from() &&
right_item->const_item() && !right_item->is_expensive())
right_item->can_eval_in_optimize())
{
orig_field_item= orig_left_item;
field_item= (Item_field *) left_item;
@ -14990,7 +14988,7 @@ bool check_simple_equality(THD *thd, const Item::Context &ctx,
}
else if (right_item->type() == Item::FIELD_ITEM &&
!((Item_field*)right_item)->get_depended_from() &&
left_item->const_item() && !left_item->is_expensive())
left_item->can_eval_in_optimize())
{
orig_field_item= orig_right_item;
field_item= (Item_field *) right_item;
@ -16432,8 +16430,8 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
{
Item_bool_func2 *func= dynamic_cast<Item_bool_func2*>(cond);
Item **args= func->arguments();
bool left_const= args[0]->const_item() && !args[0]->is_expensive();
bool right_const= args[1]->const_item() && !args[1]->is_expensive();
bool left_const= args[0]->can_eval_in_optimize();
bool right_const= args[1]->can_eval_in_optimize();
if (!(left_const && right_const) &&
args[0]->cmp_type() == args[1]->cmp_type())
{
@ -17736,7 +17734,7 @@ Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
COND *
Item::remove_eq_conds(THD *thd, Item::cond_result *cond_value, bool top_level_arg)
{
if (const_item() && !is_expensive())
if (can_eval_in_optimize())
{
*cond_value= eval_const_cond() ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
@ -17750,7 +17748,7 @@ COND *
Item_bool_func2::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
bool top_level_arg)
{
if (const_item() && !is_expensive())
if (can_eval_in_optimize())
{
*cond_value= eval_const_cond() ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;

View File

@ -725,7 +725,7 @@ uint Interval_DDhhmmssff::fsp(THD *thd, Item *item)
case STRING_RESULT:
break;
}
if (!item->const_item() || item->is_expensive())
if (!item->can_eval_in_optimize())
return TIME_SECOND_PART_DIGITS;
Status st;
Interval_DDhhmmssff it(thd, &st, false/*no warnings*/, item, UINT_MAX32,