diff options
-rw-r--r-- | mysql-test/main/timezone2.result | 23 | ||||
-rw-r--r-- | mysql-test/main/timezone2.test | 19 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 37 | ||||
-rw-r--r-- | sql/sql_time.cc | 30 | ||||
-rw-r--r-- | sql/sql_time.h | 2 | ||||
-rw-r--r-- | sql/sql_type.h | 16 |
6 files changed, 68 insertions, 59 deletions
diff --git a/mysql-test/main/timezone2.result b/mysql-test/main/timezone2.result index 096e996bffb..6de62d7ea30 100644 --- a/mysql-test/main/timezone2.result +++ b/mysql-test/main/timezone2.result @@ -332,3 +332,26 @@ NULL # # End of 5.3 tests # +# +# Start of 10.4 tests +# +# +# MDEV-17203 Move fractional second truncation from Item_xxx_typecast::get_date() to Time and Datetime constructors +# (an addition for the test for MDEV-4653) +SET timestamp=unix_timestamp('2001-02-03 10:20:30'); +SET old_mode=ZERO_DATE_TIME_CAST; +SELECT CONVERT_TZ(TIME('00:00:00'),'+00:00','+7:5'); +CONVERT_TZ(TIME('00:00:00'),'+00:00','+7:5') +NULL +Warnings: +Warning 1292 Truncated incorrect datetime value: '00:00:00' +SELECT CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5'); +CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5') +NULL +Warnings: +Warning 1292 Truncated incorrect datetime value: '00:00:00' +SET old_mode=DEFAULT; +SET timestamp=DEFAULT; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/timezone2.test b/mysql-test/main/timezone2.test index 7a38610ad95..773b40ec86c 100644 --- a/mysql-test/main/timezone2.test +++ b/mysql-test/main/timezone2.test @@ -308,3 +308,22 @@ SELECT CONVERT_TZ('2001-10-08 00:00:00', MAKE_SET(0,'+01:00'), '+00:00' ); --echo # --echo # End of 5.3 tests --echo # + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-17203 Move fractional second truncation from Item_xxx_typecast::get_date() to Time and Datetime constructors +--echo # (an addition for the test for MDEV-4653) + +SET timestamp=unix_timestamp('2001-02-03 10:20:30'); +SET old_mode=ZERO_DATE_TIME_CAST; +SELECT CONVERT_TZ(TIME('00:00:00'),'+00:00','+7:5'); +SELECT CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5'); +SET old_mode=DEFAULT; +SET timestamp=DEFAULT; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 84db154566a..1cc0d0bb2e1 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2474,43 +2474,26 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs) bool Item_time_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { - Time tm(args[0], Time::Options_for_cast()); - if ((null_value= !tm.is_valid_time())) - return true; - tm.copy_to_mysql_time(ltime); - if (decimals < TIME_SECOND_PART_DIGITS) - my_time_trunc(ltime, decimals); - return (fuzzy_date & TIME_TIME_ONLY) ? 0 : - (null_value= check_date_with_warn(ltime, fuzzy_date, - MYSQL_TIMESTAMP_ERROR)); + Time *tm= new(ltime) Time(args[0], Time::Options_for_cast(), + MY_MIN(decimals, TIME_SECOND_PART_DIGITS)); + return (null_value= !tm->is_valid_time()); } bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { - fuzzy_date |= sql_mode_for_dates(current_thd); - if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY)) - return 1; - - if (make_date_with_warn(ltime, fuzzy_date, MYSQL_TIMESTAMP_DATE)) - return (null_value= 1); - - return 0; + fuzzy_date= (fuzzy_date | sql_mode_for_dates(current_thd)) & ~TIME_TIME_ONLY; + Date *d= new(ltime) Date(current_thd, args[0], fuzzy_date); + return (null_value= !d->is_valid_date()); } bool Item_datetime_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { - fuzzy_date |= sql_mode_for_dates(current_thd); - if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY)) - return 1; - - if (decimals < TIME_SECOND_PART_DIGITS) - my_time_trunc(ltime, decimals); - - DBUG_ASSERT(ltime->time_type != MYSQL_TIMESTAMP_TIME); - ltime->time_type= MYSQL_TIMESTAMP_DATETIME; - return 0; + fuzzy_date= (fuzzy_date | sql_mode_for_dates(current_thd)) & ~TIME_TIME_ONLY; + Datetime *dt= new(ltime) Datetime(current_thd, args[0], fuzzy_date, + MY_MIN(decimals, TIME_SECOND_PART_DIGITS)); + return (null_value= !dt->is_valid_datetime()); } diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 7b1cb504f08..ee56022a868 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -1185,36 +1185,6 @@ bool time_to_datetime(MYSQL_TIME *ltime) } -/** - Return a valid DATE or DATETIME value from an arbitrary MYSQL_TIME. - If ltime is TIME, it's first converted to DATETIME. - If ts_type is DATE, hhmmss is set to zero. - The date part of the result is checked against fuzzy_date. - - @param ltime The value to convert. - @param fuzzy_date Flags to check date. - @param ts_type The type to convert to. - @return false on success, true of error (negative time).*/ -bool -make_date_with_warn(MYSQL_TIME *ltime, ulonglong fuzzy_date, - timestamp_type ts_type) -{ - DBUG_ASSERT(ts_type == MYSQL_TIMESTAMP_DATE || - ts_type == MYSQL_TIMESTAMP_DATETIME); - if (ltime->time_type == MYSQL_TIMESTAMP_TIME && time_to_datetime(ltime)) - { - /* e.g. negative time */ - ErrConvTime str(ltime); - make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, ts_type, 0); - return true; - } - if ((ltime->time_type= ts_type) == MYSQL_TIMESTAMP_DATE) - ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; - return check_date_with_warn(ltime, fuzzy_date, ts_type); -} - - /* Convert a TIME value to DAY-TIME interval, e.g. for extraction: EXTRACT(DAY FROM x), EXTRACT(HOUR FROM x), etc. diff --git a/sql/sql_time.h b/sql/sql_time.h index 862289ffdf1..47c057cd9b5 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -168,8 +168,6 @@ check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut) } bool check_date_with_warn(const MYSQL_TIME *ltime, ulonglong fuzzy_date, timestamp_type ts_type); -bool make_date_with_warn(MYSQL_TIME *ltime, - ulonglong fuzzy_date, timestamp_type ts_type); bool adjust_time_range_with_warn(MYSQL_TIME *ltime, uint dec); longlong pack_time(const MYSQL_TIME *my_time); diff --git a/sql/sql_type.h b/sql/sql_type.h index 4eaf578fac1..c497e041ea0 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -471,6 +471,12 @@ protected: bool str_to_datetime(MYSQL_TIME_STATUS *st, const char *str, size_t length, CHARSET_INFO *cs, sql_mode_t fuzzydate); public: + static void *operator new(size_t size, MYSQL_TIME *ltime) throw() + { + DBUG_ASSERT(size == sizeof(MYSQL_TIME)); + return ltime; + } + long fraction_remainder(uint dec) const { return my_time_fraction_remainder(second_part, dec); @@ -772,6 +778,11 @@ public: :Temporal(Time(warn, Sec6(d), Options())) { } + Time(Item *item, const Options opt, uint dec) + :Temporal(Time(item, opt)) + { + trunc(dec); + } Time(int *warn, const MYSQL_TIME *from, long curdays, uint dec) :Temporal(Time(warn, from, curdays)) { @@ -1125,6 +1136,11 @@ public: DBUG_ASSERT(is_valid_value_slow()); } + Datetime(THD *thd, Item *item, sql_mode_t flags, uint dec) + :Temporal_with_date(Datetime(thd, item, flags)) + { + trunc(dec); + } Datetime(MYSQL_TIME_STATUS *status, const char *str, size_t len, CHARSET_INFO *cs, sql_mode_t fuzzydate, uint dec) |