maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #10175
Please review MDEV-11528 Split Item_func_min_max::val_xxx() and Item_func_min_max::get_date() into methods in Type_handler
Hello Alexey,
Can you please review a patch for MDEV-11528.
Thanks!
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 90bec7b..0b3c246 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2795,7 +2795,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
@@ -2808,21 +2808,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());
@@ -2862,63 +2852,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(<ime, 0))
- return 0;
-
- return TIME_to_double(<ime);
- }
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
@@ -2936,18 +2898,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(<ime, 0))
- return 0;
-
- return TIME_to_ulonglong(<ime);
- }
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
@@ -2965,19 +2919,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(<ime, 0))
- return 0;
-
- return date2my_decimal(<ime, dec);
- }
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
diff --git a/sql/item_func.h b/sql/item_func.h
index 2ec3297..ce716e0 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1235,11 +1235,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();
};
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 1e6ed4d..74e8fbe 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -1231,3 +1231,143 @@ longlong Type_handler_decimal_result::
}
/***************************************************************************/
+
+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(<ime, 0))
+ return 0;
+ return TIME_to_double(<ime);
+}
+
+
+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(<ime, 0))
+ return 0;
+ return TIME_to_ulonglong(<ime);
+}
+
+
+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(<ime, 0))
+ return 0;
+ return date2my_decimal(<ime, 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);
+}
+
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 9086e60..1b2b2c5 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -28,6 +28,7 @@ class Item;
class Item_cache;
class Item_sum_hybrid;
class Item_func_hex;
+class Item_func_min_max;
class Item_func_hybrid_field_type;
class Item_func_between;
class Type_std_attributes;
@@ -314,7 +315,18 @@ class Type_handler
bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
MYSQL_TIME *,
ulonglong fuzzydate) const= 0;
-
+ virtual
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const= 0;
+ virtual
+ double Item_func_min_max_val_real(Item_func_min_max *) const= 0;
+ virtual
+ longlong Item_func_min_max_val_int(Item_func_min_max *) const= 0;
+ virtual
+ my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
+ my_decimal *) const= 0;
+ virtual
+ bool Item_func_min_max_get_date(Item_func_min_max*,
+ MYSQL_TIME *, ulonglong fuzzydate) const= 0;
virtual longlong
Item_func_between_val_int(Item_func_between *func) const= 0;
};
@@ -413,6 +425,33 @@ class Type_handler_row: public Type_handler
return true;
}
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const
+ {
+ DBUG_ASSERT(0);
+ return NULL;
+ }
+ double Item_func_min_max_val_real(Item_func_min_max *) const
+ {
+ DBUG_ASSERT(0);
+ return 0;
+ }
+ longlong Item_func_min_max_val_int(Item_func_min_max *) const
+ {
+ DBUG_ASSERT(0);
+ return 0;
+ }
+ my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
+ my_decimal *) const
+ {
+ DBUG_ASSERT(0);
+ return NULL;
+ }
+ bool Item_func_min_max_get_date(Item_func_min_max*,
+ MYSQL_TIME *, ulonglong fuzzydate) const
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
longlong Item_func_between_val_int(Item_func_between *func) const;
};
@@ -427,6 +466,12 @@ class Type_handler_numeric: public Type_handler
const Type_handler *handler)
const;
public:
+ double Item_func_min_max_val_real(Item_func_min_max *) const;
+ longlong Item_func_min_max_val_int(Item_func_min_max *) const;
+ my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
+ my_decimal *) const;
+ bool Item_func_min_max_get_date(Item_func_min_max*,
+ MYSQL_TIME *, ulonglong fuzzydate) const;
virtual ~Type_handler_numeric() { }
};
@@ -461,6 +506,7 @@ class Type_handler_real_result: public Type_handler_numeric
bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
MYSQL_TIME *,
ulonglong fuzzydate) const;
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
};
@@ -494,6 +540,7 @@ class Type_handler_decimal_result: public Type_handler_numeric
bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
MYSQL_TIME *,
ulonglong fuzzydate) const;
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
};
@@ -527,6 +574,7 @@ class Type_handler_int_result: public Type_handler_numeric
bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
MYSQL_TIME *,
ulonglong fuzzydate) const;
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
};
@@ -558,6 +606,13 @@ class Type_handler_temporal_result: public Type_handler
bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
MYSQL_TIME *,
ulonglong fuzzydate) const;
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
+ double Item_func_min_max_val_real(Item_func_min_max *) const;
+ longlong Item_func_min_max_val_int(Item_func_min_max *) const;
+ my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
+ my_decimal *) const;
+ bool Item_func_min_max_get_date(Item_func_min_max*,
+ MYSQL_TIME *, ulonglong fuzzydate) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
};
@@ -593,6 +648,13 @@ class Type_handler_string_result: public Type_handler
bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
MYSQL_TIME *,
ulonglong fuzzydate) const;
+ String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
+ double Item_func_min_max_val_real(Item_func_min_max *) const;
+ longlong Item_func_min_max_val_int(Item_func_min_max *) const;
+ my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
+ my_decimal *) const;
+ bool Item_func_min_max_get_date(Item_func_min_max*,
+ MYSQL_TIME *, ulonglong fuzzydate) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
};