diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 152 |
1 files changed, 95 insertions, 57 deletions
diff --git a/sql/item.cc b/sql/item.cc index 7f1adf7d7c5..e05ba7d6389 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1454,67 +1454,73 @@ Item *Item_param::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) As a extra convenience the time structure is reset on error or NULL values! */ -bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) +bool Item::get_date_from_int(MYSQL_TIME *ltime, ulonglong fuzzydate) { - if (field_type() == MYSQL_TYPE_TIME) - fuzzydate|= TIME_TIME_ONLY; + longlong value= val_int(); + 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 null_value|= make_zero_date(ltime, fuzzydate); + return null_value= false; +} - switch (result_type()) { - case INT_RESULT: - { - longlong value= val_int(); - bool neg= !unsigned_flag && value < 0; - if (field_type() == MYSQL_TYPE_YEAR) - { - if (max_length == 2) - { - if (value < 70) - value+= 2000; - else if (value <= 1900) - value+= 1900; - } - value*= 10000; /* make it YYYYMMHH */ - } - 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= val_real(); - if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate, - field_name_or_null())) - goto err; - break; - } - case DECIMAL_RESULT: - { - my_decimal value, *res; - if (!(res= val_decimal(&value)) || - decimal_to_datetime_with_warn(res, ltime, fuzzydate, - field_name_or_null())) - goto err; - break; - } - case STRING_RESULT: + +bool Item::get_date_from_year(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + longlong value= val_int(); + DBUG_ASSERT(unsigned_flag || value >= 0); + if (max_length == 2) { - char buff[40]; - String tmp(buff,sizeof(buff), &my_charset_bin),*res; - if (!(res=val_str(&tmp)) || - str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(), - ltime, fuzzydate)) - goto err; - break; - } - default: - DBUG_ASSERT(0); + if (value < 70) + value+= 2000; + else if (value <= 1900) + value+= 1900; } + value*= 10000; /* make it YYYYMMHH */ + if (null_value || int_to_datetime_with_warn(false, value, + ltime, fuzzydate, + field_name_or_null())) + return null_value|= make_zero_date(ltime, fuzzydate); + return null_value= false; +} - return null_value= 0; -err: +bool Item::get_date_from_real(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + double value= val_real(); + if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate, + field_name_or_null())) + return null_value|= make_zero_date(ltime, fuzzydate); + return null_value= false; +} + + +bool Item::get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + my_decimal value, *res; + if (!(res= val_decimal(&value)) || + decimal_to_datetime_with_warn(res, ltime, fuzzydate, + field_name_or_null())) + return null_value|= make_zero_date(ltime, fuzzydate); + return null_value= false; +} + + +bool Item::get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + char buff[40]; + String tmp(buff,sizeof(buff), &my_charset_bin),*res; + if (!(res=val_str(&tmp)) || + str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(), + ltime, fuzzydate)) + return null_value|= make_zero_date(ltime, fuzzydate); + return null_value= false; +} + + +bool Item::make_zero_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ /* if the item was not null and convertion failed, we return a zero date if allowed, otherwise - null. @@ -1536,7 +1542,7 @@ err: */ ltime->time_type= MYSQL_TIMESTAMP_TIME; } - return null_value|= !(fuzzydate & TIME_FUZZY_DATES); + return !(fuzzydate & TIME_FUZZY_DATES); } bool Item::get_seconds(ulonglong *sec, ulong *sec_part) @@ -1780,6 +1786,16 @@ my_decimal *Item_sp_variable::val_decimal(my_decimal *decimal_value) } +bool Item_sp_variable::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + DBUG_ASSERT(fixed); + Item *it= this_item(); + bool val= it->get_date(ltime, fuzzydate); + null_value= it->null_value; + return val; +} + + bool Item_sp_variable::is_null() { return this_item()->is_null(); @@ -2125,6 +2141,13 @@ my_decimal *Item_name_const::val_decimal(my_decimal *decimal_value) return val; } +bool Item_name_const::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + DBUG_ASSERT(fixed); + bool rc= value_item->get_date(ltime, fuzzydate); + null_value= value_item->null_value; + return rc; +} bool Item_name_const::is_null() { @@ -3731,6 +3754,15 @@ my_decimal *Item_null::val_decimal(my_decimal *decimal_value) } +bool Item_null::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + // following assert is redundant, because fixed=1 assigned in constructor + DBUG_ASSERT(fixed == 1); + make_zero_date(ltime, fuzzydate); + return (null_value= true); +} + + Item *Item_null::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) { return this; @@ -4201,7 +4233,7 @@ bool Item_param::get_date(MYSQL_TIME *res, ulonglong fuzzydate) *res= value.time; return 0; } - return Item::get_date(res, fuzzydate); + return type_handler()->Item_get_date(this, res, fuzzydate); } @@ -10191,6 +10223,12 @@ String *Item_type_holder::val_str(String*) return 0; } +bool Item_type_holder::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + DBUG_ASSERT(0); // should never be called + return true; +} + void Item_result_field::cleanup() { DBUG_ENTER("Item_result_field::cleanup()"); |