Skip to content

Commit

Permalink
MDEV-11528 Split Item_func_min_max::val_xxx() and Item_func_min_max::…
Browse files Browse the repository at this point in the history
…get_date() into methods in Type_handler
  • Loading branch information
Alexander Barkov committed Dec 30, 2016
1 parent b4ef7b2 commit 9b2bcf1
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 81 deletions.
96 changes: 21 additions & 75 deletions sql/item_func.cc
Expand Up @@ -2766,7 +2766,7 @@ void Item_func_min_max::fix_length_and_dec()


/*
Compare item arguments in the DATETIME context.
Compare item arguments using DATETIME/DATE/TIME representation.
DESCRIPTION
Compare item arguments as DATETIME values and return the index of the
Expand All @@ -2779,21 +2779,11 @@ void Item_func_min_max::fix_length_and_dec()
0 Otherwise
*/

bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
longlong UNINIT_VAR(min_max);
DBUG_ASSERT(fixed == 1);

/*
just like ::val_int() method of a string item can be called,
for example, SELECT CONCAT("10", "12") + 1,
::get_date() can be called for non-temporal values,
for example, SELECT MONTH(GREATEST("2011-11-21", "2010-10-09"))
*/
if (Item_func_min_max::cmp_type() != TIME_RESULT)
return Item_func::get_date(ltime, fuzzy_date);

for (uint i=0; i < arg_count ; i++)
{
longlong res= args[i]->val_temporal_packed(Item_func_min_max::field_type());
Expand Down Expand Up @@ -2833,63 +2823,35 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
}


String *Item_func_min_max::val_str(String *str)
String *Item_func_min_max::val_str_native(String *str)
{
DBUG_ASSERT(fixed == 1);
if (Item_func_min_max::cmp_type() == TIME_RESULT)
return val_string_from_date(str);
switch (Item_func_min_max::result_type()) {
case INT_RESULT:
return val_string_from_int(str);
case DECIMAL_RESULT:
return val_string_from_decimal(str);
case REAL_RESULT:
return val_string_from_real(str);
case STRING_RESULT:
String *UNINIT_VAR(res);
for (uint i=0; i < arg_count ; i++)
{
String *UNINIT_VAR(res);
for (uint i=0; i < arg_count ; i++)
if (i == 0)
res=args[i]->val_str(str);
else
{
if (i == 0)
res=args[i]->val_str(str);
else
String *res2;
res2= args[i]->val_str(res == str ? &tmp_value : str);
if (res2)
{
String *res2;
res2= args[i]->val_str(res == str ? &tmp_value : str);
if (res2)
{
int cmp= sortcmp(res,res2,collation.collation);
if ((cmp_sign < 0 ? cmp : -cmp) < 0)
res=res2;
}
int cmp= sortcmp(res,res2,collation.collation);
if ((cmp_sign < 0 ? cmp : -cmp) < 0)
res=res2;
}
if ((null_value= args[i]->null_value))
return 0;
}
res->set_charset(collation.collation);
return res;
}
case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
return 0;
if ((null_value= args[i]->null_value))
return 0;
}
return 0; // Keep compiler happy
res->set_charset(collation.collation);
return res;
}


double Item_func_min_max::val_real()
double Item_func_min_max::val_real_native()
{
DBUG_ASSERT(fixed == 1);
double value=0.0;
if (Item_func_min_max::cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
if (get_date(&ltime, 0))
return 0;

return TIME_to_double(&ltime);
}
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
Expand All @@ -2907,18 +2869,10 @@ double Item_func_min_max::val_real()
}


longlong Item_func_min_max::val_int()
longlong Item_func_min_max::val_int_native()
{
DBUG_ASSERT(fixed == 1);
longlong value=0;
if (Item_func_min_max::cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
if (get_date(&ltime, 0))
return 0;

return TIME_to_ulonglong(&ltime);
}
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
Expand All @@ -2936,19 +2890,11 @@ longlong Item_func_min_max::val_int()
}


my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
my_decimal *Item_func_min_max::val_decimal_native(my_decimal *dec)
{
DBUG_ASSERT(fixed == 1);
my_decimal tmp_buf, *tmp, *UNINIT_VAR(res);

if (Item_func_min_max::cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
if (get_date(&ltime, 0))
return 0;

return date2my_decimal(&ltime, dec);
}
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
Expand Down
41 changes: 36 additions & 5 deletions sql/item_func.h
Expand Up @@ -1284,11 +1284,42 @@ class Item_func_min_max :public Item_hybrid_func
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg)
{}
double val_real();
longlong val_int();
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
String *val_str_native(String *str);
double val_real_native();
longlong val_int_native();
my_decimal *val_decimal_native(my_decimal *);
bool get_date_native(MYSQL_TIME *res, ulonglong fuzzydate);

double val_real()
{
DBUG_ASSERT(fixed);
return Item_func_min_max::type_handler()->
Item_func_min_max_val_real(this);
}
longlong val_int()
{
DBUG_ASSERT(fixed);
return Item_func_min_max::type_handler()->
Item_func_min_max_val_int(this);
}
String *val_str(String *str)
{
DBUG_ASSERT(fixed);
return Item_func_min_max::type_handler()->
Item_func_min_max_val_str(this, str);
}
my_decimal *val_decimal(my_decimal *dec)
{
DBUG_ASSERT(fixed);
return Item_func_min_max::type_handler()->
Item_func_min_max_val_decimal(this, dec);
}
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date)
{
DBUG_ASSERT(fixed);
return Item_func_min_max::type_handler()->
Item_func_min_max_get_date(this, res, fuzzy_date);
}
void fix_length_and_dec();
};

Expand Down
140 changes: 140 additions & 0 deletions sql/sql_type.cc
Expand Up @@ -1780,3 +1780,143 @@ bool Type_handler_row::Item_func_in_fix_comparator_compatible_types(THD *thd,
}

/***************************************************************************/

String *Type_handler_string_result::
Item_func_min_max_val_str(Item_func_min_max *func, String *str) const
{
return func->val_str_native(str);
}


String *Type_handler_temporal_result::
Item_func_min_max_val_str(Item_func_min_max *func, String *str) const
{
return func->val_string_from_date(str);
}


String *Type_handler_int_result::
Item_func_min_max_val_str(Item_func_min_max *func, String *str) const
{
return func->val_string_from_int(str);
}


String *Type_handler_decimal_result::
Item_func_min_max_val_str(Item_func_min_max *func, String *str) const
{
return func->val_string_from_decimal(str);
}


String *Type_handler_real_result::
Item_func_min_max_val_str(Item_func_min_max *func, String *str) const
{
return func->val_string_from_real(str);
}


double Type_handler_string_result::
Item_func_min_max_val_real(Item_func_min_max *func) const
{
return func->val_real_native();
}


double Type_handler_temporal_result::
Item_func_min_max_val_real(Item_func_min_max *func) const
{
MYSQL_TIME ltime;
if (func->get_date(&ltime, 0))
return 0;
return TIME_to_double(&ltime);
}


double Type_handler_numeric::
Item_func_min_max_val_real(Item_func_min_max *func) const
{
return func->val_real_native();
}


longlong Type_handler_string_result::
Item_func_min_max_val_int(Item_func_min_max *func) const
{
return func->val_int_native();
}


longlong Type_handler_temporal_result::
Item_func_min_max_val_int(Item_func_min_max *func) const
{
MYSQL_TIME ltime;
if (func->get_date(&ltime, 0))
return 0;
return TIME_to_ulonglong(&ltime);
}


longlong Type_handler_numeric::
Item_func_min_max_val_int(Item_func_min_max *func) const
{
return func->val_int_native();
}


my_decimal *Type_handler_string_result::
Item_func_min_max_val_decimal(Item_func_min_max *func,
my_decimal *dec) const
{
return func->val_decimal_native(dec);
}


my_decimal *Type_handler_numeric::
Item_func_min_max_val_decimal(Item_func_min_max *func,
my_decimal *dec) const
{
return func->val_decimal_native(dec);
}


my_decimal *Type_handler_temporal_result::
Item_func_min_max_val_decimal(Item_func_min_max *func,
my_decimal *dec) const
{
MYSQL_TIME ltime;
if (func->get_date(&ltime, 0))
return 0;
return date2my_decimal(&ltime, dec);
}


bool Type_handler_string_result::
Item_func_min_max_get_date(Item_func_min_max *func,
MYSQL_TIME *ltime, ulonglong fuzzydate) const
{
/*
just like ::val_int() method of a string item can be called,
for example, SELECT CONCAT("10", "12") + 1,
::get_date() can be called for non-temporal values,
for example, SELECT MONTH(GREATEST("2011-11-21", "2010-10-09"))
*/
return func->Item::get_date(ltime, fuzzydate);
}


bool Type_handler_numeric::
Item_func_min_max_get_date(Item_func_min_max *func,
MYSQL_TIME *ltime, ulonglong fuzzydate) const
{
return func->Item::get_date(ltime, fuzzydate);
}


bool Type_handler_temporal_result::
Item_func_min_max_get_date(Item_func_min_max *func,
MYSQL_TIME *ltime, ulonglong fuzzydate) const
{
return func->get_date_native(ltime, fuzzydate);
}

0 comments on commit 9b2bcf1

Please sign in to comment.