Bug #40217 UNION [ALL] query results present faulty internal datetime
Submitted: 21 Oct 2008 18:03 Modified: 10 Feb 2018 16:58
Reporter: Serdar S. Kacar Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DML Severity:S3 (Non-critical)
Version:5.0, 5.1.28, 5.1, 6.0 bzr OS:Any
Assigned to: Evgeny Potemkin CPU Architecture:Any
Tags: date, datetime, regression, UNION
Triage: Triaged: D3 (Medium)

[21 Oct 2008 18:03] Serdar S. Kacar
Description:
UNION queries try to return widest data type for a column that would cover all datatypes for this column from the corresponding selects.

If datetime related function is used, the resultant data type is an internal datetime type, having a microsecond part.

As of version 5.1.28, UNION queries represent this columns as 29 bytes where first 19 bytes are 'YYYY-MM-DD HH:MM:SS' formated datetime and the last 10 bytes are "binary" 0.

This representation is not comprehensible by other SQL statements. INSERT ... SELECT is known to be affected, possibly cursors and others that can operate on resultsets.

How to repeat:
First run this query in MySQL Query Browser and see the 10 '|' chars appended field contents :

(SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 5 SECOND)) AS DT)
 UNION ALL
(SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 10 SECOND)) AS DT);
--> 2008-10-10 00:04:15||||||||||
--> 2008-10-10 00:04:25||||||||||
To see what is the binary content, you can right click any of those piped fields and select "View Filed in Popup Editor" and select the "Binary" tab.

Now, to observe the effect on INSERT ... SELECT by :

mysql> CREATE TEMPORARY TABLE  `test`.`ttmp` (`dt` datetime NOT NULL);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT `test`.`ttmp`
    -> (SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 5 SECOND)) AS DT)
    ->  UNION ALL
    -> (SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 10 SECOND)) AS DT);
ERROR 1292 (22007): Incorrect datetime value: '2008-10-10 00:04:20' for column '
dt' at row 1

Workaround
----------

CAST to the appropriate date/time datatype. The following works :

mysql> INSERT `test`.`ttmp`
    -> (SELECT CAST(DATE_ADD('2008-10-10 00:04:15', INTERVAL 5 SECOND) AS DATETI
ME) AS DT)
    ->  UNION ALL
    -> (SELECT CAST(DATE_ADD('2008-10-10 00:04:15', INTERVAL 10 SECOND) AS DATET
IME) AS DT);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM `test`.`ttmp`;
+---------------------+
| dt                  |
+---------------------+
| 2008-10-10 00:04:20 |
| 2008-10-10 00:04:25 |
+---------------------+
2 rows in set (0.00 sec)

Suggested fix:
There are various issues related to this one. In no particular order :

Date Type column problem when using UNION-Table.
http://bugs.mysql.com/bug.php?id=6931

INSERT + SELECT + UNION ALL + DATE to VARCHAR(8) conversion problem
http://bugs.mysql.com/bug.php?id=4937

UNION ALL with + INTERVAL N DAY crashes server
http://bugs.mysql.com/bug.php?id=9577

UNION query returns different datatype than SELECT in Access
http://bugs.mysql.com/bug.php?id=4782

UNION query can cause server to crash
http://bugs.mysql.com/bug.php?id=8660

Union returns wrong column type size
http://bugs.mysql.com/bug.php?id=30886

If a fix would broke various fixes for other bugs, simply document the behaviour.

Otherwise, UNION [ALL] queries should return (internal datetime) data that is comprehensible by other MySQL Server modules.
[21 Oct 2008 18:11] Serdar S. Kacar
Value formated as 'YYYY-MM-DD HH:MM:SS.uuuuuu' in string representation would work. E.g. '2008-10-10 00:04:25.000000'
[21 Oct 2008 18:36] Sveta Smirnova
Thank you for the report.

Verified as described.
[21 Oct 2008 18:37] Sveta Smirnova
Test output:

CREATE TEMPORARY TABLE  `ttmp` (`dt` datetime NOT NULL);
INSERT `ttmp` (SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 5 SECOND)) AS DT)
UNION ALL
(SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 10 SECOND)) AS DT);
Warnings:
Warning 1264    Out of range value for column 'dt' at row 1
Warning 1264    Out of range value for column 'dt' at row 2
INSERT `ttmp` SELECT (DATE_ADD('2008-10-10 00:04:15', INTERVAL 5 SECOND)) AS DT;

4.1 is not affected.
[10 Feb 2018 16:58] Roy Lyseng
Posted by developer:
 
Fixed in 5.6.40 and up.