summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2023-03-29 11:56:44 +0400
committerAlexander Barkov <bar@mariadb.com>2023-03-29 11:56:44 +0400
commit03b4a2d6e5b3d6e4bd88c3451cbff8ba4df7bd71 (patch)
tree0ec432d614947d88ee2e439086789e1147e1ad62
parent113bef50e33a838c5cb637ef4a042cbcad79e7a2 (diff)
downloadmariadb-git-03b4a2d6e5b3d6e4bd88c3451cbff8ba4df7bd71.tar.gz
MDEV-26765 UNIX_TIMESTAMP(CURRENT_TIME()) return null ?!?
Problem: UNIX_TIMESTAMP() called for a expression of the TIME data type returned NULL. Inside Type_handler_timestamp_common::Item_val_native_with_conversion the call for item->get_date() did not convert TIME to DATETIME automatically (because it does not have to, by design). As a result, Type_handler_timestamp_common::TIME_to_native() received a MYSQL_TIME value with zero date 0000-00-00 and therefore returned "true" (indicating SQL NULL value). Fix: Removing the call for item->get_date(). Instantiating Datetime(item) instead. This forces automatic TIME to DATETIME conversion (unless @@old_mode is zero_date_time_cast).
-rw-r--r--mysql-test/main/old-mode.result36
-rw-r--r--mysql-test/main/old-mode.test20
-rw-r--r--mysql-test/main/type_time.result26
-rw-r--r--mysql-test/main/type_time.test19
-rw-r--r--sql/sql_type.cc6
5 files changed, 104 insertions, 3 deletions
diff --git a/mysql-test/main/old-mode.result b/mysql-test/main/old-mode.result
index e0a3412bbdf..bb65acd54ce 100644
--- a/mysql-test/main/old-mode.result
+++ b/mysql-test/main/old-mode.result
@@ -221,3 +221,39 @@ a UNIX_TIMESTAMP(t1.a) a UNIX_TIMESTAMP(t2.a)
DROP TABLE t1;
SET time_zone=DEFAULT;
SET global mysql56_temporal_format=true;
+#
+# MDEV-26765 UNIX_TIMESTAMP(CURRENT_TIME()) return null ?!?
+#
+SET old_mode=zero_date_time_cast;
+SET @@time_zone='+00:00';
+SET timestamp=1234567;
+SELECT CURRENT_TIMESTAMP;
+CURRENT_TIMESTAMP
+1970-01-15 06:56:07
+SELECT UNIX_TIMESTAMP(CURRENT_TIME());
+UNIX_TIMESTAMP(CURRENT_TIME())
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '06:56:07'
+SELECT UNIX_TIMESTAMP(TIME'06:56:07');
+UNIX_TIMESTAMP(TIME'06:56:07')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '06:56:07'
+SELECT UNIX_TIMESTAMP(TIME'10:20:30');
+UNIX_TIMESTAMP(TIME'10:20:30')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '10:20:30'
+CREATE OR REPLACE TABLE t1 (a TIME);
+INSERT INTO t1 VALUES (TIME'06:56:07'),('10:20:30');
+SELECT UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
+UNIX_TIMESTAMP(a)
+NULL
+NULL
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 1
+Warning 1264 Out of range value for column 'a' at row 2
+DROP TABLE t1;
+SET @@time_zone=DEFAULT;
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/main/old-mode.test b/mysql-test/main/old-mode.test
index a09de1cf87d..d3fc254110d 100644
--- a/mysql-test/main/old-mode.test
+++ b/mysql-test/main/old-mode.test
@@ -149,3 +149,23 @@ SELECT t1.a, UNIX_TIMESTAMP(t1.a), t2.a, UNIX_TIMESTAMP(t2.a) FROM t1 t1, t1 t2
DROP TABLE t1;
SET time_zone=DEFAULT;
SET global mysql56_temporal_format=true;
+
+
+--echo #
+--echo # MDEV-26765 UNIX_TIMESTAMP(CURRENT_TIME()) return null ?!?
+--echo #
+
+SET old_mode=zero_date_time_cast;
+SET @@time_zone='+00:00';
+SET timestamp=1234567;
+SELECT CURRENT_TIMESTAMP;
+SELECT UNIX_TIMESTAMP(CURRENT_TIME());
+SELECT UNIX_TIMESTAMP(TIME'06:56:07');
+SELECT UNIX_TIMESTAMP(TIME'10:20:30');
+CREATE OR REPLACE TABLE t1 (a TIME);
+INSERT INTO t1 VALUES (TIME'06:56:07'),('10:20:30');
+SELECT UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+SET @@time_zone=DEFAULT;
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/main/type_time.result b/mysql-test/main/type_time.result
index e383704fdb8..7b40328892d 100644
--- a/mysql-test/main/type_time.result
+++ b/mysql-test/main/type_time.result
@@ -2420,5 +2420,31 @@ SET @@global.mysql56_temporal_format=default;
DROP PROCEDURE p1;
SET timestamp=DEFAULT;
#
+# MDEV-26765 UNIX_TIMESTAMP(CURRENT_TIME()) return null ?!?
+#
+SET @@time_zone='+00:00';
+SET timestamp=1234567;
+SELECT CURRENT_TIMESTAMP;
+CURRENT_TIMESTAMP
+1970-01-15 06:56:07
+SELECT UNIX_TIMESTAMP(CURRENT_TIME());
+UNIX_TIMESTAMP(CURRENT_TIME())
+1234567
+SELECT UNIX_TIMESTAMP(TIME'06:56:07');
+UNIX_TIMESTAMP(TIME'06:56:07')
+1234567
+SELECT UNIX_TIMESTAMP(TIME'10:20:30');
+UNIX_TIMESTAMP(TIME'10:20:30')
+1246830
+CREATE OR REPLACE TABLE t1 (a TIME);
+INSERT INTO t1 VALUES (TIME'06:56:07'),('10:20:30');
+SELECT UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
+UNIX_TIMESTAMP(a)
+1234567
+1246830
+DROP TABLE t1;
+SET @@time_zone=DEFAULT;
+SET TIMESTAMP=DEFAULT;
+#
# End of 10.4 tests
#
diff --git a/mysql-test/main/type_time.test b/mysql-test/main/type_time.test
index 0f67223238c..9ed5c3a73dc 100644
--- a/mysql-test/main/type_time.test
+++ b/mysql-test/main/type_time.test
@@ -1567,5 +1567,24 @@ DROP PROCEDURE p1;
SET timestamp=DEFAULT;
--echo #
+--echo # MDEV-26765 UNIX_TIMESTAMP(CURRENT_TIME()) return null ?!?
+--echo #
+
+SET @@time_zone='+00:00';
+SET timestamp=1234567;
+SELECT CURRENT_TIMESTAMP;
+SELECT UNIX_TIMESTAMP(CURRENT_TIME());
+SELECT UNIX_TIMESTAMP(TIME'06:56:07');
+SELECT UNIX_TIMESTAMP(TIME'10:20:30');
+CREATE OR REPLACE TABLE t1 (a TIME);
+INSERT INTO t1 VALUES (TIME'06:56:07'),('10:20:30');
+SELECT UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+SET @@time_zone=DEFAULT;
+SET TIMESTAMP=DEFAULT;
+
+
+--echo #
--echo # End of 10.4 tests
--echo #
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index a9610195e65..92bf2b39f90 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -8619,13 +8619,13 @@ Type_handler_timestamp_common::Item_val_native_with_conversion(THD *thd,
Item *item,
Native *to) const
{
- MYSQL_TIME ltime;
if (item->type_handler()->type_handler_for_native_format() ==
&type_handler_timestamp2)
return item->val_native(thd, to);
+ Datetime dt(thd, item, Datetime::Options(TIME_NO_ZERO_IN_DATE, thd));
return
- item->get_date(thd, &ltime, Datetime::Options(TIME_NO_ZERO_IN_DATE, thd)) ||
- TIME_to_native(thd, &ltime, to, item->datetime_precision(thd));
+ !dt.is_valid_datetime() ||
+ TIME_to_native(thd, dt.get_mysql_time(), to, item->datetime_precision(thd));
}
bool Type_handler_null::union_element_finalize(Item_type_holder *item) const