summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/func_time.result6
-rw-r--r--mysql-test/main/func_time.test7
-rw-r--r--sql/item_timefunc.cc6
-rw-r--r--sql/sql_type.h32
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);
+ }
};