summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-08-05 14:41:17 +0400
committerAlexander Barkov <bar@mariadb.com>2019-08-05 14:41:17 +0400
commitc99f9766b11bda7eb15d6875f2f1e64c2d01b461 (patch)
treec9fadd3d0e98b6d3fd9bdb0696c3c2440779373c
parente244652831932ab9deed83d38dd3f6f1958b91ef (diff)
downloadmariadb-git-c99f9766b11bda7eb15d6875f2f1e64c2d01b461.tar.gz
MDEV-19166 Assertion `!is_zero_datetime()' failed in Timestamp_or_zero_datetime::tv
-rw-r--r--mysql-test/main/type_temporal_innodb.result13
-rw-r--r--mysql-test/main/type_temporal_innodb.test15
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_timefunc.cc2
-rw-r--r--sql/sql_type.h17
5 files changed, 39 insertions, 10 deletions
diff --git a/mysql-test/main/type_temporal_innodb.result b/mysql-test/main/type_temporal_innodb.result
index 55b398b3b02..2aad1e02d02 100644
--- a/mysql-test/main/type_temporal_innodb.result
+++ b/mysql-test/main/type_temporal_innodb.result
@@ -172,3 +172,16 @@ CREATE TABLE tbl SELECT * FROM t1 WHERE t1.c1 = (SELECT c2 FROM t2 WHERE pk = 6)
ERROR 22007: Truncated incorrect datetime value: '0000-00-00 00:00:00'
DROP TABLE t1,t2;
SET sql_mode=DEFAULT;
+#
+# MDEV-19166 Assertion `!is_zero_datetime()' failed in Timestamp_or_zero_datetime::tv
+#
+CREATE TABLE t1 (f TIMESTAMP DEFAULT 0) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('2024-02-29');
+SELECT * FROM t1 WHERE SUBSTR(1 FROM BIT_LENGTH(f) FOR DEFAULT(f));
+f
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: ''
+DROP TABLE t1;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/main/type_temporal_innodb.test b/mysql-test/main/type_temporal_innodb.test
index 3debb798018..b8c7720f8b6 100644
--- a/mysql-test/main/type_temporal_innodb.test
+++ b/mysql-test/main/type_temporal_innodb.test
@@ -81,3 +81,18 @@ CREATE TABLE tbl SELECT * FROM t1 WHERE t1.c1 = (SELECT c2 FROM t2 WHERE pk = 6)
# ^^^ there is no column c2 in table t2
DROP TABLE t1,t2;
SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-19166 Assertion `!is_zero_datetime()' failed in Timestamp_or_zero_datetime::tv
+--echo #
+
+CREATE TABLE t1 (f TIMESTAMP DEFAULT 0) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('2024-02-29');
+SELECT * FROM t1 WHERE SUBSTR(1 FROM BIT_LENGTH(f) FOR DEFAULT(f));
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/sql/item.cc b/sql/item.cc
index 4bcaaa8aaf9..eaec0a2a737 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9909,7 +9909,7 @@ Datetime Item_cache_timestamp::to_datetime(THD *thd)
null_value= true;
return Datetime();
}
- return Datetime(thd, Timestamp_or_zero_datetime(m_native).tv());
+ return m_native.to_datetime(thd);
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 2c527154108..d3433963c25 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1220,7 +1220,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
Timestamp_or_zero_datetime_native_null native(current_thd, args[0], true);
if ((null_value= native.is_null() || native.is_zero_datetime()))
return true;
- Timestamp_or_zero_datetime tm(native);
+ Timestamp tm(native);
*seconds= tm.tv().tv_sec;
*second_part= tm.tv().tv_usec;
return false;
diff --git a/sql/sql_type.h b/sql/sql_type.h
index a80ceb46838..f1f5995b3ec 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -2377,6 +2377,10 @@ public:
}
bool to_TIME(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) const;
bool to_native(Native *to, uint decimals) const;
+ Datetime to_datetime(THD *thd) const
+ {
+ return Datetime(thd, *this);
+ }
long fraction_remainder(uint dec) const
{
return my_time_fraction_remainder(tv_usec, dec);
@@ -2417,7 +2421,7 @@ public:
- real TIMESTAMP (seconds and microseconds since epoch), or
- zero datetime '0000-00-00 00:00:00.000000'
*/
-class Timestamp_or_zero_datetime: public Timestamp
+class Timestamp_or_zero_datetime: protected Timestamp
{
bool m_is_zero_datetime;
public:
@@ -2434,14 +2438,11 @@ public:
Timestamp_or_zero_datetime(THD *thd, const MYSQL_TIME *ltime, uint *err_code);
Datetime to_datetime(THD *thd) const
{
- return Datetime(thd, *this);
+ if (is_zero_datetime())
+ return Datetime();
+ return Timestamp::to_datetime(thd);
}
bool is_zero_datetime() const { return m_is_zero_datetime; }
- const struct timeval &tv() const
- {
- DBUG_ASSERT(!is_zero_datetime());
- return Timestamp::tv();
- }
void trunc(uint decimals)
{
if (!is_zero_datetime())
@@ -2487,7 +2488,7 @@ public:
{
return is_zero_datetime() ?
Datetime() :
- Datetime(thd, Timestamp_or_zero_datetime(*this).tv());
+ Datetime(thd, Timestamp(*this).tv());
}
bool is_zero_datetime() const
{