1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-12707 Split resolve_const_item() into virtual methods in Type_handler

This commit is contained in:
Alexander Barkov
2017-05-06 00:04:15 +04:00
parent ac53b49b1b
commit 26fa7232cf
7 changed files with 234 additions and 170 deletions

View File

@ -457,7 +457,19 @@ const Type_handler *Type_handler_time_common::type_handler_for_comparison() cons
return &type_handler_time;
}
const Type_handler *Type_handler_temporal_with_date::type_handler_for_comparison() const
const Type_handler *Type_handler_date_common::type_handler_for_comparison() const
{
return &type_handler_newdate;
}
const Type_handler *Type_handler_datetime_common::type_handler_for_comparison() const
{
return &type_handler_datetime;
}
const Type_handler *Type_handler_timestamp_common::type_handler_for_comparison() const
{
return &type_handler_datetime;
}
@ -652,9 +664,14 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h)
{
/*
We're here if both m_type_handler and h are temporal data types.
- If both data types are TIME, we preserve TIME.
- If both data types are DATE, we preserve DATE.
Preserving DATE is needed for EXPLAIN FORMAT=JSON,
to print DATE constants using proper format:
'YYYY-MM-DD' rather than 'YYYY-MM-DD 00:00:00'.
*/
if (field_type() != MYSQL_TYPE_TIME || h->field_type() != MYSQL_TYPE_TIME)
m_type_handler= &type_handler_datetime; // DATETIME bits TIME
if (field_type() != h->field_type())
m_type_handler= &type_handler_datetime;
}
}
else if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
@ -1917,9 +1934,15 @@ bool Type_handler_string_result::set_comparator_func(Arg_comparator *cmp) const
return cmp->set_cmp_func_string();
}
bool Type_handler_temporal_result::set_comparator_func(Arg_comparator *cmp) const
bool Type_handler_time_common::set_comparator_func(Arg_comparator *cmp) const
{
return cmp->set_cmp_func_temporal();
return cmp->set_cmp_func_time();
}
bool
Type_handler_temporal_with_date::set_comparator_func(Arg_comparator *cmp) const
{
return cmp->set_cmp_func_datetime();
}
@ -4211,3 +4234,113 @@ bool Type_handler::
}
/***************************************************************************/
Item *Type_handler_int_result::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
longlong result= item->val_int();
if (item->null_value)
return new (thd->mem_root) Item_null(thd, item->name.str);
return new (thd->mem_root) Item_int(thd, item->name.str, result,
item->max_length);
}
Item *Type_handler_real_result::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
double result= item->val_real();
if (item->null_value)
return new (thd->mem_root) Item_null(thd, item->name.str);
return new (thd->mem_root) Item_float(thd, item->name.str, result,
item->decimals, item->max_length);
}
Item *Type_handler_decimal_result::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
my_decimal decimal_value;
my_decimal *result= item->val_decimal(&decimal_value);
if (item->null_value)
return new (thd->mem_root) Item_null(thd, item->name.str);
return new (thd->mem_root) Item_decimal(thd, item->name.str, result,
item->max_length, item->decimals);
}
Item *Type_handler_string_result::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
StringBuffer<MAX_FIELD_WIDTH> tmp;
String *result= item->val_str(&tmp);
if (item->null_value)
return new (thd->mem_root) Item_null(thd, item->name.str);
uint length= result->length();
char *tmp_str= thd->strmake(result->ptr(), length);
return new (thd->mem_root) Item_string(thd, item->name.str,
tmp_str, length, result->charset());
}
Item *Type_handler_time_common::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
Item_cache_temporal *cache;
longlong value= item->val_time_packed();
if (item->null_value)
return new (thd->mem_root) Item_null(thd, item->name.str);
cache= new (thd->mem_root) Item_cache_temporal(thd, field_type());
if (cache)
cache->store_packed(value, item);
return cache;
}
Item *Type_handler_temporal_with_date::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
Item_cache_temporal *cache;
longlong value= item->val_datetime_packed();
if (item->null_value)
return new (thd->mem_root) Item_null(thd, item->name.str);
cache= new (thd->mem_root) Item_cache_temporal(thd, field_type());
if (cache)
cache->store_packed(value, item);
return cache;
}
Item *Type_handler_row::
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
{
if (item->type() == Item::ROW_ITEM && cmp->type() == Item::ROW_ITEM)
{
/*
Substitute constants only in Item_row's. Don't affect other Items
with ROW_RESULT (eg Item_singlerow_subselect).
For such Items more optimal is to detect if it is constant and replace
it with Item_row. This would optimize queries like this:
SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
*/
Item_row *item_row= (Item_row*) item;
Item_row *comp_item_row= (Item_row*) cmp;
uint col;
/*
If item and comp_item are both Item_row's and have same number of cols
then process items in Item_row one by one.
We can't ignore NULL values here as this item may be used with <=>, in
which case NULL's are significant.
*/
DBUG_ASSERT(item->result_type() == cmp->result_type());
DBUG_ASSERT(item_row->cols() == comp_item_row->cols());
col= item_row->cols();
while (col-- > 0)
resolve_const_item(thd, item_row->addr(col),
comp_item_row->element_index(col));
}
return NULL;
}
/***************************************************************************/