diff options
Diffstat (limited to 'sql/field.cc')
| -rw-r--r-- | sql/field.cc | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/sql/field.cc b/sql/field.cc index 13cad813b82..103a8920d7e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5316,12 +5316,41 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) } +/** + subtract a given number of days from DATETIME, return TIME + + optimized version of calc_time_diff() + + @note it might generate TIME values outside of the valid TIME range! +*/ +static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days) +{ + long daydiff= calc_daynr(ltime->year, ltime->month, ltime->day) - days; + ltime->year= ltime->month= 0; + if (daydiff >=0 ) + ltime->day= daydiff; + else + { + longlong timediff= ((((daydiff * 24LL + + ltime->hour) * 60LL + + ltime->minute) * 60LL + + ltime->second) * 1000000LL + + ltime->second_part); + unpack_time(timediff, ltime); + } + ltime->time_type= MYSQL_TIMESTAMP_TIME; +} + + int Field_time::store_time_dec(MYSQL_TIME *ltime, uint dec) { MYSQL_TIME l_time= *ltime; ErrConvTime str(ltime); int was_cut= 0; + if (curdays && l_time.time_type != MYSQL_TIMESTAMP_TIME) + calc_datetime_days_diff(&l_time, curdays); + int have_smth_to_conv= !check_time_range(&l_time, decimals(), &was_cut); return store_TIME_with_warning(&l_time, &str, was_cut, have_smth_to_conv); } @@ -5356,8 +5385,30 @@ int Field_time::store(longlong nr, bool unsigned_val) return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv); } - - + + +void Field_time::set_curdays(THD *thd) +{ + MYSQL_TIME ltime; + set_current_date(thd, <ime); + curdays= calc_daynr(ltime.year, ltime.month, ltime.day); +} + + +Field *Field_time::new_key_field(MEM_ROOT *root, TABLE *new_table, + uchar *new_ptr, uint32 length, + uchar *new_null_ptr, uint new_null_bit) +{ + THD *thd= get_thd(); + Field_time *res= + (Field_time*) Field::new_key_field(root, new_table, new_ptr, length, + new_null_ptr, new_null_bit); + if (!(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST) && res) + res->set_curdays(thd); + return res; +} + + double Field_time::val_real(void) { ASSERT_COLUMN_MARKED_FOR_READ; |
