[MDEV-15293] CAST(AS TIME) returns bad results for LAST_VALUE(),NAME_CONST(),SP variable Created: 2018-02-13  Updated: 2018-06-20  Resolved: 2018-02-13

Status: Closed
Project: MariaDB Server
Component/s: Temporal Types
Affects Version/s: 10.0, 10.1, 10.2, 10.3
Fix Version/s: 10.3.5

Type: Bug Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Blocks
blocks MDEV-4912 Data type plugin API version 1 Closed
blocks MDEV-8894 Inserting fractional seconds into My... Closed
Duplicate
is duplicated by MDEV-5757 CAST(date_sp_variable AS TIME) return... Closed
Relates
relates to MDEV-16489 when lead() returns null on a datetim... Closed

 Description   

SELECT CAST(DATE'2001-01-01' AS TIME), CAST(LAST_VALUE(DATE'2001-01-01') AS TIME);

+--------------------------------+--------------------------------------------+
| CAST(DATE'2001-01-01' AS TIME) | CAST(LAST_VALUE(DATE'2001-01-01') AS TIME) |
+--------------------------------+--------------------------------------------+
| 00:00:00                       | 00:20:01                                   |
+--------------------------------+--------------------------------------------+
1 row in set, 1 warning (0.00 sec)

The expected behavior would be to return '00:00:00' in both columns.

The same problem is repeatable with NAME_CONST:

SELECT CAST(NAME_CONST('name',DATE'2001-01-01') AS TIME);

+---------------------------------------------------+
| CAST(NAME_CONST('name',DATE'2001-01-01') AS TIME) |
+---------------------------------------------------+
| 00:20:01                                          |
+---------------------------------------------------+
Query OK, 0 rows affected, 1 warning (0.00 sec)

The same problem is repeatable with SP variables:

DELIMITER $$
BEGIN NOT ATOMIC
  DECLARE a DATE DEFAULT '2001-01-01';
  SELECT CAST(a AS TIME);
END;
$$
DELIMITER ;

+-----------------+
| CAST(a AS TIME) |
+-----------------+
| 00:20:01        |
+-----------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)

The problem is that the underlying classes Item_func_last_value, Item_name_const, Item_splocal do not implement their own version of the virtual method get_date(), and the default implementation in Item::get_date() does not handle conversion between different temporal data types.
So instead of doing direct date->time conversion, execution goes throw two conversions: date->string->time.

The same problem is repeatable with Window functions, both with CAST(AS TIME), and with functions that expect a TIME inpute, like HOUR():

CREATE OR REPLACE TABLE t1 (dt DATE,country VARCHAR(10), amount INT);
INSERT INTO t1 VALUES ('2000-01-01','DE',102);
INSERT INTO t1 VALUES ('2000-01-02','DE',101);
SELECT
  dt, country, amount,
  FIRST_VALUE(dt) OVER () AS first,
  MINUTE(FIRST_VALUE(dt) OVER ()) AS m_first,
  LAST_VALUE(dt) OVER () AS last,
  MINUTE(LAST_VALUE(dt) OVER ()) AS m_last
FROM t1
ORDER BY country, dt;

+------------+---------+--------+------------+---------+------------+--------+
| dt         | country | amount | first      | m_first | last       | m_last |
+------------+---------+--------+------------+---------+------------+--------+
| 2000-01-01 | DE      |    102 | 2000-01-01 |      20 | 2000-01-02 |     20 |
| 2000-01-02 | DE      |    101 | 2000-01-01 |      20 | 2000-01-02 |     20 |
+------------+---------+--------+------------+---------+------------+--------+
2 rows in set, 4 warnings (0.00 sec)

Notice, the result of HOUR() is 20, which is something unexpected. It should be 0.



 Comments   
Comment by Alexander Barkov [ 2018-02-13 ]

Pushed to bb-10.2-ext

Generated at Thu Feb 08 08:20:10 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.