diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 116 |
1 files changed, 75 insertions, 41 deletions
diff --git a/sql/item.cc b/sql/item.cc index 6c74f509915..002621acb5a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -329,7 +329,7 @@ int Item::save_time_in_field(Field *field) if (get_time(<ime)) return set_field_to_null_with_conversions(field, 0); field->set_notnull(); - return field->store_time(<ime, MYSQL_TIMESTAMP_TIME); + return field->store_time_dec(<ime, decimals); } @@ -339,7 +339,7 @@ int Item::save_date_in_field(Field *field) if (get_date(<ime, TIME_FUZZY_DATE)) return set_field_to_null_with_conversions(field, 0); field->set_notnull(); - return field->store_time(<ime, MYSQL_TIMESTAMP_DATETIME); + return field->store_time_dec(<ime, decimals); } @@ -984,27 +984,59 @@ bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate) { if (field_type() == MYSQL_TYPE_TIME) fuzzydate|= TIME_TIME_ONLY; - if (result_type() != INT_RESULT || fuzzydate & TIME_TIME_ONLY) + + Item_result res_type= result_type(); + + enum_field_types f_type= MYSQL_TYPE_SET; // a.k.a. use fuzzydate flags + + switch (res_type) { + case INT_RESULT: + { + longlong value= val_int(); + if (field_type() == MYSQL_TYPE_YEAR) + { + f_type= MYSQL_TYPE_YEAR; + if (value < 70) + value+= 2000; + else if (value <= 1900) + value+= 1900; + } + if (null_value || int_to_datetime_with_warn(value, ltime, fuzzydate, + f_type, 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, + f_type, 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, + f_type, field_name_or_null())) + goto err; + break; + } + case STRING_RESULT: { char buff[40]; String tmp(buff,sizeof(buff), &my_charset_bin),*res; if (!(res=val_str(&tmp)) || - str_to_datetime_with_warn(res->ptr(), res->length(), ltime, - fuzzydate) <= MYSQL_TIMESTAMP_ERROR) + str_to_datetime_with_warn(res->ptr(), res->length(), + ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR) goto err; + break; } - else - { - longlong value= val_int(); - int was_cut; - if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == LL(-1)) - { - Lazy_string_num str(value); - make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_NONE, NullS); - goto err; - } + default: + DBUG_ASSERT(0); } + return 0; err: @@ -1012,17 +1044,27 @@ err: return 1; } -/** - Get time of first argument. - - As a extra convenience the time structure is reset on error! -*/ - bool Item::get_time(MYSQL_TIME *ltime) { return get_date(ltime, TIME_TIME_ONLY | TIME_FUZZY_DATE); } +bool Item::get_seconds(ulonglong *sec, ulong *sec_part) +{ + if (result_type() == INT_RESULT) + { // optimize for an important special case + longlong val= val_int(); + bool neg= val < 0 && !unsigned_flag; + *sec= neg ? -val : val; + *sec_part= 0; + return neg; + } + my_decimal tmp, *dec= val_decimal(&tmp); + if (!dec) + return 0; + return my_decimal2seconds(dec, sec, sec_part); +} + CHARSET_INFO *Item::default_charset() { return current_thd->variables.collation_connection; @@ -2951,7 +2993,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions) case DECIMAL_VALUE: return field->store_decimal(&decimal_value); case TIME_VALUE: - field->store_time(&value.time, value.time.time_type); + field->store_time_dec(&value.time, decimals); return 0; case STRING_VALUE: case LONG_DATA_VALUE: @@ -5247,7 +5289,7 @@ void Item_datetime::set(longlong packed) int Item_datetime::save_in_field(Field *field, bool no_conversions) { field->set_notnull(); - return field->store_time(<ime, ltime.time_type); + return field->store_time_dec(<ime, decimals); } longlong Item_datetime::val_int() @@ -7194,30 +7236,22 @@ longlong Item_cache_int::val_int() bool Item_cache_int::get_date(MYSQL_TIME *ltime, uint fuzzydate) { + Lazy_string_num str(value); + if (!value_cached && !cache_value()) - goto err; + { + bzero((char*) ltime,sizeof(*ltime)); + return 1; + } if (cmp_type() == TIME_RESULT) { unpack_time(value, ltime); ltime->time_type= mysql_type_to_time_type(field_type()); + return 0; } - else - { - int was_cut; - if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == -1LL) - { - Lazy_string_num str(value); - make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_NONE, NullS); - goto err; - } - } - return 0; -err: - bzero((char*) ltime,sizeof(*ltime)); - return 1; + return Item::get_date(ltime, fuzzydate); } int Item_cache_int::save_in_field(Field *field, bool no_conversions) @@ -7232,7 +7266,7 @@ int Item_cache_int::save_in_field(Field *field, bool no_conversions) MYSQL_TIME ltime; unpack_time(value, <ime); ltime.time_type= mysql_type_to_time_type(field_type()); - error= field->store_time(<ime, ltime.time_type); + error= field->store_time_dec(<ime, decimals); } else error= field->store(value, unsigned_flag); |