Bug #121218 TIME column vs TIMESTAMP/DATETIME constant: the constant's date part is silently discarded

Submitted: 3 Sep 7:36 Modified: 3 Sep 12:04
Reporter: Chunling Qin Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:9.7.2 OS:Any
Assigned to: CPU Architecture:Any

[3 Sep 7:36] Chunling Qin
Description:
mysql> CREATE TABLE t (c TIME);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t VALUES ('16:52:49'),('00:00:01'),('23:59:59');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> 
mysql> -- Constant context (full-value numeric comparison — correct):
mysql> SELECT (TIME'16:52:49') < TIMESTAMP'1999-12-31 23:59:59';  -- 0 (165249 vs 19991231235959)
+---------------------------------------------------+
| (TIME'16:52:49') < TIMESTAMP'1999-12-31 23:59:59' |
+---------------------------------------------------+
|                                                 0 |
+---------------------------------------------------+
1 row in set (0.00 sec)

mysql> 
mysql> -- TIME column context (constant degraded to time-of-day — wrong):
mysql> SELECT c, c < TIMESTAMP'1999-12-31 23:59:59' FROM t;
+----------+------------------------------------+
| c        | c < TIMESTAMP'1999-12-31 23:59:59' |
+----------+------------------------------------+
| 16:52:49 |                                  1 |
| 00:00:01 |                                  1 |
| 23:59:59 |                                  0 |
+----------+------------------------------------+
3 rows in set (0.00 sec)

mysql> -- '16:52:49' → 1  (should be 0: constant truncated to 23:59:59 before comparing)
mysql> -- '00:00:01' → 1
mysql> -- '23:59:59' → 0

Mechanism proof: CAST(TIME'16:52:49' AS DATETIME) = current day + time — if the column were DATETIME-ized, 2026 > 1999 would give 0; the observed 1 proves the constant side is truncated (the comparator reduces the DATETIME constant to its time part and compares against the TIME column).

Masking: constants whose time part is 00:00:00 (e.g. TIMESTAMP'2024-01-01 00:00:00') coincide in both contexts — the bug surfaces only when the constant's time-of-day part is late. CAST(... AS DATETIME) explicit constants split identically; both TIME(0) and TIME(3) trigger.

Impact: WHERE c < TIMESTAMP'1999-12-31 23:59:59' returns 2 rows (should be 0) — the user intent "any time earlier than end of 1999" degrades to "time-of-day earlier than 23:59:59", silently changing the semantics.

How to repeat:
CREATE TABLE t (c TIME);
INSERT INTO t VALUES ('16:52:49'),('00:00:01'),('23:59:59');

-- Constant context (full-value numeric comparison — correct):
SELECT (TIME'16:52:49') < TIMESTAMP'1999-12-31 23:59:59';  -- 0 (165249 vs 19991231235959)

-- TIME column context (constant degraded to time-of-day — wrong):
SELECT c, c < TIMESTAMP'1999-12-31 23:59:59' FROM t;
-- '16:52:49' → 1  (should be 0: constant truncated to 23:59:59 before comparing)
-- '00:00:01' → 1
-- '23:59:59' → 0
[3 Sep 12:04] Roy Lyseng
Thank you for the bug report.
This is a bug, but not for the reason that you describe.

When comparing a TIME value against a TIMESTAMP, we implicitly cast the TIME value to a TIMESTAMP (DATETIME), before carrying out the operation. Today we would extend TIME'16:52:49' with 2026-09-03, which means all four results should be false.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.044 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.