maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #10100
Please review MDEV-11330 Split Item_func_hybrid_field_type::val_xxx() into methods in Type_handler
Hello Vicențiu,
Please review a patch for MDEV-11330.
Thanks!
diff --git a/sql/item_func.cc b/sql/item_func.cc
index cbd272f..363bdc5 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -830,240 +830,6 @@ void Item_func_num1::fix_length_and_dec()
}
-String *Item_func_hybrid_field_type::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- switch (Item_func_hybrid_field_type::cmp_type()) {
- case DECIMAL_RESULT:
- {
- my_decimal decimal_value, *val;
- if (!(val= decimal_op_with_null_check(&decimal_value)))
- return 0; // null is set
- my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val);
- str->set_charset(collation.collation);
- my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
- break;
- }
- case INT_RESULT:
- {
- longlong nr= int_op();
- if (null_value)
- return 0; /* purecov: inspected */
- str->set_int(nr, unsigned_flag, collation.collation);
- break;
- }
- case REAL_RESULT:
- {
- double nr= real_op();
- if (null_value)
- return 0; /* purecov: inspected */
- str->set_real(nr, decimals, collation.collation);
- break;
- }
- case TIME_RESULT:
- {
- MYSQL_TIME ltime;
- if (date_op_with_null_check(<ime) ||
- (null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
- return (String *) 0;
- ltime.time_type= mysql_type_to_time_type(field_type());
- str->length(my_TIME_to_str(<ime, const_cast<char*>(str->ptr()), decimals));
- str->set_charset(&my_charset_bin);
- DBUG_ASSERT(!null_value);
- return str;
- }
- case STRING_RESULT:
- return str_op_with_null_check(&str_value);
- case ROW_RESULT:
- DBUG_ASSERT(0);
- }
- DBUG_ASSERT(!null_value || (str == NULL));
- return str;
-}
-
-
-double Item_func_hybrid_field_type::val_real()
-{
- DBUG_ASSERT(fixed == 1);
- switch (Item_func_hybrid_field_type::cmp_type()) {
- case DECIMAL_RESULT:
- {
- my_decimal decimal_value, *val;
- double result;
- if (!(val= decimal_op_with_null_check(&decimal_value)))
- return 0.0; // null is set
- my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
- return result;
- }
- case INT_RESULT:
- {
- longlong result= int_op();
- return unsigned_flag ? (double) ((ulonglong) result) : (double) result;
- }
- case REAL_RESULT:
- return real_op();
- case TIME_RESULT:
- {
- MYSQL_TIME ltime;
- if (date_op_with_null_check(<ime))
- return 0;
- ltime.time_type= mysql_type_to_time_type(field_type());
- return TIME_to_double(<ime);
- }
- case STRING_RESULT:
- {
- String *res= str_op_with_null_check(&str_value);
- return res ? double_from_string_with_check(res) : 0.0;
- }
- case ROW_RESULT:
- DBUG_ASSERT(0);
- }
- return 0.0;
-}
-
-
-longlong Item_func_hybrid_field_type::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- switch (Item_func_hybrid_field_type::cmp_type()) {
- case DECIMAL_RESULT:
- {
- my_decimal decimal_value, *val;
- if (!(val= decimal_op_with_null_check(&decimal_value)))
- return 0; // null is set
- longlong result;
- my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
- return result;
- }
- case INT_RESULT:
- return int_op();
- case REAL_RESULT:
- return (longlong) rint(real_op());
- case TIME_RESULT:
- {
- MYSQL_TIME ltime;
- if (date_op_with_null_check(<ime))
- return 0;
- ltime.time_type= mysql_type_to_time_type(field_type());
- return TIME_to_ulonglong(<ime);
- }
- case STRING_RESULT:
- {
- String *res= str_op_with_null_check(&str_value);
- return res ? longlong_from_string_with_check(res) : 0;
- }
- case ROW_RESULT:
- DBUG_ASSERT(0);
- }
- return 0;
-}
-
-
-my_decimal *Item_func_hybrid_field_type::val_decimal(my_decimal *decimal_value)
-{
- my_decimal *val= decimal_value;
- DBUG_ASSERT(fixed == 1);
- switch (Item_func_hybrid_field_type::cmp_type()) {
- case DECIMAL_RESULT:
- val= decimal_op_with_null_check(decimal_value);
- break;
- case INT_RESULT:
- {
- longlong result= int_op();
- if (null_value)
- return NULL;
- int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
- break;
- }
- case REAL_RESULT:
- {
- double result= (double)real_op();
- if (null_value)
- return NULL;
- double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
- break;
- }
- case TIME_RESULT:
- {
- MYSQL_TIME ltime;
- if (date_op_with_null_check(<ime))
- {
- my_decimal_set_zero(decimal_value);
- return 0;
- }
- ltime.time_type= mysql_type_to_time_type(field_type());
- return date2my_decimal(<ime, decimal_value);
- }
- case STRING_RESULT:
- {
- String *res= str_op_with_null_check(&str_value);
- return res ? decimal_from_string_with_check(decimal_value, res) : 0;
- }
- case ROW_RESULT:
- DBUG_ASSERT(0);
- }
- return val;
-}
-
-
-bool Item_func_hybrid_field_type::get_date(MYSQL_TIME *ltime,
- ulonglong fuzzydate)
-{
- DBUG_ASSERT(fixed == 1);
- switch (Item_func_hybrid_field_type::cmp_type()) {
- case DECIMAL_RESULT:
- {
- my_decimal value, *res;
- if (!(res= decimal_op_with_null_check(&value)) ||
- decimal_to_datetime_with_warn(res, ltime, fuzzydate,
- field_name_or_null()))
- goto err;
- break;
- }
- case INT_RESULT:
- {
- longlong value= int_op();
- bool neg= !unsigned_flag && value < 0;
- if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
- ltime, fuzzydate,
- field_name_or_null()))
- goto err;
- break;
- }
- case REAL_RESULT:
- {
- double value= real_op();
- if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
- field_name_or_null()))
- goto err;
- break;
- }
- case TIME_RESULT:
- return date_op(ltime,
- fuzzydate |
- (field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0));
- case STRING_RESULT:
- {
- char buff[40];
- String tmp(buff,sizeof(buff), &my_charset_bin),*res;
- if (!(res= str_op_with_null_check(&tmp)) ||
- str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
- ltime, fuzzydate))
- goto err;
- break;
- }
- case ROW_RESULT:
- DBUG_ASSERT(0);
- }
-
- return (null_value= 0);
-
-err:
- bzero(ltime, sizeof(*ltime));
- return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
-}
-
-
void Item_func_signed::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
diff --git a/sql/item_func.h b/sql/item_func.h
index aaf1df0..bb613a4 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -428,6 +428,7 @@ class Item_hybrid_func: public Item_func,
*/
class Item_func_hybrid_field_type: public Item_hybrid_func
{
+protected:
/*
Helper methods to make sure that the result of
decimal_op(), str_op() and date_op() is properly synched with null_value.
@@ -451,6 +452,11 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
DBUG_ASSERT((res != NULL) ^ null_value);
return res;
}
+ bool make_zero_mysql_time(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ bzero(ltime, sizeof(*ltime));
+ return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
+ }
public:
Item_func_hybrid_field_type(THD *thd):
@@ -469,11 +475,38 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
Item_hybrid_func(thd, list)
{ collation.set_numeric(); }
- double val_real();
- longlong val_int();
- my_decimal *val_decimal(my_decimal *);
- String *val_str(String*str);
- bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
+ double val_real()
+ {
+ DBUG_ASSERT(fixed);
+ return Item_func_hybrid_field_type::type_handler()->
+ Item_func_hybrid_field_type_val_real(this);
+ }
+ longlong val_int()
+ {
+ DBUG_ASSERT(fixed);
+ return Item_func_hybrid_field_type::type_handler()->
+ Item_func_hybrid_field_type_val_int(this);
+ }
+ my_decimal *val_decimal(my_decimal *dec)
+ {
+ DBUG_ASSERT(fixed);
+ return Item_func_hybrid_field_type::type_handler()->
+ Item_func_hybrid_field_type_val_decimal(this, dec);
+ }
+ String *val_str(String*str)
+ {
+ DBUG_ASSERT(fixed);
+ String *res= Item_func_hybrid_field_type::type_handler()->
+ Item_func_hybrid_field_type_val_str(this, str);
+ DBUG_ASSERT(null_value == (res == NULL));
+ return res;
+ }
+ bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date)
+ {
+ DBUG_ASSERT(fixed);
+ return Item_func_hybrid_field_type::type_handler()->
+ Item_func_hybrid_field_type_get_date(this, res, fuzzy_date);
+ }
/**
@brief Performs the operation that this functions implements when the
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index a80417f..d7f5a54 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -17,6 +17,7 @@
#include "sql_type.h"
#include "sql_const.h"
#include "sql_class.h"
+#include "sql_time.h"
#include "item.h"
#include "log.h"
@@ -640,3 +641,509 @@ Field *Type_handler_set::make_conversion_table_field(TABLE *table,
metadata & 0x00ff/*pack_length()*/,
((const Field_enum*) target)->typelib, target->charset());
}
+
+
+/***************************************************************************/
+
+/**
+ The classes Item_func_hybrid_field_type_xxx are used only in static_cast
+ in various value extraction methods,
+ e.g. Type_handler_decimal_result::Item_func_hybrid_field_type_val_int().
+ We never create instances of these classes, hence no constructor.
+
+ Every data type has its own class Item_func_hybrid_field_type_xxx.
+ The purpose of these classes include:
+ - data type conversion from the native representation returned by xxx_op()
+ to the requested representation
+ - access to protected members and methods of Item_func_hybrid_field_type
+
+ Every data type handler Type_handler_xxx:
+ - casts Item_func_hybrid_type to its own Item_func_hybrid_type_xxx
+ - calls Item_func_hybrid_type_xxx::val_XXX() statically.
+*/
+class Item_func_hybrid_field_type_decimal_result:
+ public Item_func_hybrid_field_type
+{
+public:
+ String *val_str(String *str)
+ {
+ my_decimal decimal_value, *val;
+ if (!(val= decimal_op_with_null_check(&decimal_value)))
+ return 0; // null is set
+ DBUG_ASSERT(!null_value);
+ my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val);
+ str->set_charset(collation.collation);
+ my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
+ return str;
+ }
+ double val_real()
+ {
+ DBUG_ASSERT(fixed == 1);
+ my_decimal decimal_value, *val;
+ double result;
+ if (!(val= decimal_op_with_null_check(&decimal_value)))
+ return 0.0; // null is set
+ my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
+ return result;
+ }
+ longlong val_int()
+ {
+ my_decimal decimal_value, *val;
+ if (!(val= decimal_op_with_null_check(&decimal_value)))
+ return 0; // null is set
+ longlong result;
+ my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
+ return result;
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ return decimal_op_with_null_check(decimal_value);
+ }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ my_decimal value, *res;
+ if (!(res= decimal_op_with_null_check(&value)) ||
+ decimal_to_datetime_with_warn(res, ltime, fuzzydate,
+ field_name_or_null()))
+ return make_zero_mysql_time(ltime, fuzzydate);
+ return (null_value= 0);
+ }
+};
+
+
+String *
+Type_handler_decimal_result::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ // The type qualifier in the call below is to call the method statically
+ return static_cast<Item_func_hybrid_field_type_decimal_result*>(item)->
+ Item_func_hybrid_field_type_decimal_result::val_str(str);
+}
+
+
+double
+Type_handler_decimal_result::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_decimal_result*>(item)->
+ Item_func_hybrid_field_type_decimal_result::val_real();
+}
+
+
+longlong
+Type_handler_decimal_result::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_decimal_result*>(item)->
+ Item_func_hybrid_field_type_decimal_result::val_int();
+}
+
+
+my_decimal *
+Type_handler_decimal_result::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return static_cast<Item_func_hybrid_field_type_decimal_result*>(item)->
+ Item_func_hybrid_field_type_decimal_result::val_decimal(dec);
+}
+
+
+bool
+Type_handler_decimal_result::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return static_cast<Item_func_hybrid_field_type_decimal_result*>(item)->
+ Item_func_hybrid_field_type_decimal_result::get_date(ltime, fuzzydate);
+}
+
+
+/***************************************************************************/
+
+
+class Item_func_hybrid_field_type_int_result:
+ public Item_func_hybrid_field_type
+{
+public:
+ String *val_str(String *str)
+ {
+ longlong nr= int_op();
+ if (null_value)
+ return 0; /* purecov: inspected */
+ str->set_int(nr, unsigned_flag, collation.collation);
+ return str;
+ }
+ double val_real()
+ {
+ longlong result= int_op();
+ return unsigned_flag ? (double) ((ulonglong) result) : (double) result;
+ }
+ longlong val_int()
+ {
+ return int_op();
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ longlong result= int_op();
+ if (null_value)
+ return NULL;
+ int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
+ return decimal_value;
+ }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ longlong value= int_op();
+ bool neg= !unsigned_flag && value < 0;
+ if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
+ ltime, fuzzydate,
+ field_name_or_null()))
+ return make_zero_mysql_time(ltime, fuzzydate);
+ return (null_value= 0);
+ }
+};
+
+
+String *
+Type_handler_int_result::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ return static_cast<Item_func_hybrid_field_type_int_result*>(item)->
+ Item_func_hybrid_field_type_int_result::val_str(str);
+}
+
+
+double
+Type_handler_int_result::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_int_result*>(item)->
+ Item_func_hybrid_field_type_int_result::val_real();
+}
+
+
+longlong
+Type_handler_int_result::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_int_result*>(item)->
+ Item_func_hybrid_field_type_int_result::val_int();
+}
+
+
+my_decimal *
+Type_handler_int_result::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return static_cast<Item_func_hybrid_field_type_int_result*>(item)->
+ Item_func_hybrid_field_type_int_result::val_decimal(dec);
+}
+
+
+bool
+Type_handler_int_result::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return static_cast<Item_func_hybrid_field_type_int_result*>(item)->
+ Item_func_hybrid_field_type_int_result::get_date(ltime, fuzzydate);
+}
+
+
+
+/***************************************************************************/
+
+class Item_func_hybrid_field_type_real_result:
+ public Item_func_hybrid_field_type
+{
+public:
+ String *val_str(String *str)
+ {
+ double nr= real_op();
+ if (null_value)
+ return 0; /* purecov: inspected */
+ str->set_real(nr, decimals, collation.collation);
+ return str;
+ }
+ double val_real()
+ {
+ return real_op();
+ }
+ longlong val_int()
+ {
+ return (longlong) rint(real_op());
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ double result= (double)real_op();
+ if (null_value)
+ return NULL;
+ double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
+ return decimal_value;
+ }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ double value= real_op();
+ if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
+ field_name_or_null()))
+ return make_zero_mysql_time(ltime, fuzzydate);
+ return (null_value= 0);
+ }
+};
+
+
+String *
+Type_handler_real_result::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ return static_cast<Item_func_hybrid_field_type_real_result*>(item)->
+ Item_func_hybrid_field_type_real_result::val_str(str);
+}
+
+
+double
+Type_handler_real_result::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_real_result*>(item)->
+ Item_func_hybrid_field_type_real_result::val_real();
+}
+
+
+longlong
+Type_handler_real_result::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_real_result*>(item)->
+ Item_func_hybrid_field_type_real_result::val_int();
+}
+
+
+my_decimal *
+Type_handler_real_result::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return static_cast<Item_func_hybrid_field_type_real_result*>(item)->
+ Item_func_hybrid_field_type_real_result::val_decimal(dec);
+}
+
+
+bool
+Type_handler_real_result::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return static_cast<Item_func_hybrid_field_type_real_result*>(item)->
+ Item_func_hybrid_field_type_real_result::get_date(ltime, fuzzydate);
+}
+
+
+/***************************************************************************/
+
+class Item_func_hybrid_field_type_temporal_result:
+ public Item_func_hybrid_field_type
+{
+public:
+ String *val_str(String *str)
+ {
+ MYSQL_TIME ltime;
+ if (date_op_with_null_check(<ime) ||
+ (null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
+ return (String *) 0;
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ str->length(my_TIME_to_str(<ime, const_cast<char*>(str->ptr()), decimals));
+ str->set_charset(&my_charset_bin);
+ DBUG_ASSERT(!null_value);
+ return str;
+ }
+ double val_real()
+ {
+ MYSQL_TIME ltime;
+ if (date_op_with_null_check(<ime))
+ return 0;
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ return TIME_to_double(<ime);
+ }
+ longlong val_int()
+ {
+ MYSQL_TIME ltime;
+ if (date_op_with_null_check(<ime))
+ return 0;
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ return TIME_to_ulonglong(<ime);
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ MYSQL_TIME ltime;
+ if (date_op_with_null_check(<ime))
+ {
+ my_decimal_set_zero(decimal_value);
+ return 0;
+ }
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ return date2my_decimal(<ime, decimal_value);
+ }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return date_op(ltime,
+ fuzzydate |
+ (field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0));
+ }
+};
+
+
+String *
+Type_handler_temporal_result::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ return static_cast<Item_func_hybrid_field_type_temporal_result*>(item)->
+ Item_func_hybrid_field_type_temporal_result::val_str(str);
+}
+
+
+double
+Type_handler_temporal_result::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_temporal_result*>(item)->
+ Item_func_hybrid_field_type_temporal_result::val_real();
+}
+
+
+longlong
+Type_handler_temporal_result::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_temporal_result*>(item)->
+ Item_func_hybrid_field_type_temporal_result::val_int();
+}
+
+
+my_decimal *
+Type_handler_temporal_result::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return static_cast<Item_func_hybrid_field_type_temporal_result*>(item)->
+ Item_func_hybrid_field_type_temporal_result::val_decimal(dec);
+}
+
+
+bool
+Type_handler_temporal_result::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return static_cast<Item_func_hybrid_field_type_temporal_result*>(item)->
+ Item_func_hybrid_field_type_temporal_result::get_date(ltime, fuzzydate);
+}
+
+
+
+/***************************************************************************/
+
+class Item_func_hybrid_field_type_string_result:
+ public Item_func_hybrid_field_type
+{
+public:
+ String *val_str(String *str)
+ {
+ return str_op_with_null_check(&str_value);
+ }
+ double val_real()
+ {
+ String *res= str_op_with_null_check(&str_value);
+ return res ? double_from_string_with_check(res) : 0.0;
+ }
+ longlong val_int()
+ {
+ String *res= str_op_with_null_check(&str_value);
+ return res ? longlong_from_string_with_check(res) : 0;
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ String *res= str_op_with_null_check(&str_value);
+ return res ? decimal_from_string_with_check(decimal_value, res) : 0;
+ }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ StringBuffer<40> tmp;
+ String *res;
+ if (!(res= str_op_with_null_check(&tmp)) ||
+ str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
+ ltime, fuzzydate))
+ return make_zero_mysql_time(ltime, fuzzydate);
+ return (null_value= 0);
+ }
+};
+
+
+String *
+Type_handler_string_result::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ return static_cast<Item_func_hybrid_field_type_string_result*>(item)->
+ Item_func_hybrid_field_type_string_result::val_str(str);
+}
+
+
+double
+Type_handler_string_result::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_string_result*>(item)->
+ Item_func_hybrid_field_type_string_result::val_real();
+}
+
+
+longlong
+Type_handler_string_result::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return static_cast<Item_func_hybrid_field_type_string_result*>(item)->
+ Item_func_hybrid_field_type_string_result::val_int();
+}
+
+
+my_decimal *
+Type_handler_string_result::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return static_cast<Item_func_hybrid_field_type_string_result*>(item)->
+ Item_func_hybrid_field_type_string_result::val_decimal(dec);
+}
+
+
+bool
+Type_handler_string_result::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return static_cast<Item_func_hybrid_field_type_string_result*>(item)->
+ Item_func_hybrid_field_type_string_result::get_date(ltime, fuzzydate);
+}
+
+/***************************************************************************/
diff --git a/sql/sql_type.h b/sql/sql_type.h
index de5c31a..d22f472 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -25,6 +25,7 @@
class Field;
class Item;
+class Item_func_hybrid_field_type;
class Type_std_attributes;
class Sort_param;
struct TABLE;
@@ -272,6 +273,24 @@ class Type_handler
virtual void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const= 0;
+
+ virtual
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const= 0;
+ virtual
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const= 0;
+ virtual
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const= 0;
+ virtual
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const= 0;
+ virtual
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const= 0;
};
@@ -288,6 +307,18 @@ class Type_handler_real_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
};
@@ -303,6 +334,18 @@ class Type_handler_decimal_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
};
@@ -318,6 +361,18 @@ class Type_handler_int_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
};
@@ -332,6 +387,18 @@ class Type_handler_temporal_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
};
@@ -349,6 +416,18 @@ class Type_handler_string_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
};