diff options
-rw-r--r-- | mysql-test/main/func_time.result | 6 | ||||
-rw-r--r-- | mysql-test/main/func_time.test | 7 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 6 | ||||
-rw-r--r-- | sql/sql_type.h | 32 |
4 files changed, 47 insertions, 4 deletions
diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 8546a7bc84b..0b5fb46c1d5 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -6345,3 +6345,9 @@ NULL SELECT CONCAT(MAKETIME('01', '01', LEAST( -100, NULL ))); CONCAT(MAKETIME('01', '01', LEAST( -100, NULL ))) NULL +# +# MDEV-19774 Assertion `sec.se c() <= 0x7FFFFFFFL' failed in Item_func_from_unixtime::get_date +# +SELECT FROM_UNIXTIME(LEAST(3696610869, NULL)); +FROM_UNIXTIME(LEAST(3696610869, NULL)) +NULL diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index 5760553e0dd..2e44df5a0d0 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -3170,3 +3170,10 @@ SET time_zone=DEFAULT; SELECT MAKETIME('01', '01', LEAST( -100, NULL )); SELECT CONCAT(MAKETIME('01', '01', LEAST( -100, NULL ))); + + +--echo # +--echo # MDEV-19774 Assertion `sec.se c() <= 0x7FFFFFFFL' failed in Item_func_from_unixtime::get_date +--echo # + +SELECT FROM_UNIXTIME(LEAST(3696610869, NULL)); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 81d5bfed981..2c527154108 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1933,7 +1933,7 @@ bool Item_func_from_unixtime::get_date(THD *thd, MYSQL_TIME *ltime, ltime->time_type= MYSQL_TIMESTAMP_TIME; VSec9 sec(thd, args[0], "unixtime", TIMESTAMP_MAX_VALUE); - DBUG_ASSERT(sec.sec() <= TIMESTAMP_MAX_VALUE); + DBUG_ASSERT(sec.is_null() || sec.sec() <= TIMESTAMP_MAX_VALUE); if (sec.is_null() || sec.truncated() || sec.neg()) return (null_value= 1); @@ -2601,8 +2601,8 @@ bool Item_func_maketime::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy return (null_value= 1); int warn; - new(ltime) Time(&warn, hour.neg(), hour.abs(), (uint) minute, sec, - thd->temporal_round_mode(), decimals); + new(ltime) Time(&warn, hour.neg(), hour.abs(), (uint) minute, + sec.to_const_sec9(), thd->temporal_round_mode(), decimals); if (warn) { // use check_time_range() to set ltime to the max value depending on dec diff --git a/sql/sql_type.h b/sql/sql_type.h index 6d9d802913f..a80ceb46838 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -499,12 +499,42 @@ public: }; -class VSec9: public Sec9 +class VSec9: protected Sec9 { bool m_is_null; + Sec9& to_sec9() + { + DBUG_ASSERT(!is_null()); + return *this; + } public: VSec9(THD *thd, Item *item, const char *type_str, ulonglong limit); bool is_null() const { return m_is_null; } + const Sec9& to_const_sec9() const + { + DBUG_ASSERT(!is_null()); + return *this; + } + bool neg() const { return to_const_sec9().neg(); } + bool truncated() const { return to_const_sec9().truncated(); } + ulonglong sec() const { return to_const_sec9().sec(); } + long usec() const { return to_const_sec9().usec(); } + bool sec_to_time(MYSQL_TIME *ltime, uint dec) const + { + return to_const_sec9().sec_to_time(ltime, dec); + } + void make_truncated_warning(THD *thd, const char *type_str) const + { + return to_const_sec9().make_truncated_warning(thd, type_str); + } + Sec9 &round(uint dec) + { + return to_sec9().round(dec); + } + Sec9 &round(uint dec, time_round_mode_t mode) + { + return to_sec9().round(dec, mode); + } }; |