Bug #70740 Don't lose microseconds without warning

Submitted: 27 Oct 2013 10:00 Modified: 28 Oct 2013 11:54
Reporter: Daniël van Eeden Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DML Severity:S3 (Non-critical)
Version:5.6.14 OS:Any
Assigned to: CPU Architecture:Any

[27 Oct 2013 10:00] Daniël van Eeden
Description:
The microsecond part of a value inserted in a TIMESTAMP(0) column gets lost without warning.

How to repeat:
mysql> CREATE TABLE t1 (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES(CURRENT_TIMESTAMP(6));
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM t1;
+---------------------+
| ts                  |
+---------------------+
| 2013-10-27 10:56:12 |
+---------------------+
1 row in set (0.00 sec)

Suggested fix:
Add a sql_mode to generate warnings on lost microseconds (e.g. WARN_ON_TIMESTAMP_CASTING) and one to generate errors (e.g. ERROR_ON_TIMESTAMP_CASTING)

A warning is already generated if the time part is lost:
mysql> CREATE TABLE t1 (d DATE);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES(CURRENT_TIMESTAMP);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> SHOW WARNINGS;
+-------+------+---------------------------------------------------------------------+
| Level | Code | Message                                                             |
+-------+------+---------------------------------------------------------------------+
| Note  | 1292 | Incorrect date value: '2013-10-27 10:59:14' for column 'd' at row 1 |
+-------+------+---------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM t1;
+------------+
| d          |
+------------+
| 2013-10-27 |
+------------+
1 row in set (0.00 sec)
[28 Oct 2013 11:54] MySQL Verification Team
Thank you for the bug report.
[30 Oct 2013 6:40] Roy Lyseng
We consider this to be a feature request.

The SQL standard has this to say about assignment to timestamp and time values when fractional seconds are truncated, in chapter 9.2 Store assignment:

Let T be the TARGET and let V be the VALUE 
...
If the declared type DT of T is datetime, then
...
A) If V is a member of the declared type of T, then T is set to V.
B) If a member of the declared type of T can be obtained from V by rounding or truncation, then T is set to that value. It is implementation-defined whether the approximation is obtained by rounding or truncation.
C) Otherwise, an exception condition is raised: data exception — datetime field overflow.

Thus, there is no mention of a warning in the case of rounding or truncation.

However, there is precedent in the MySQL behavior for e.g. assignment between DECIMAL values:

create table td(a decimal(20,10), b decimal(10,0));
Query OK, 0 rows affected (0.04 sec)

insert into td values(987654321.0123456789, 0);
Query OK, 1 row affected (0.00 sec)

update td set b=a;
Query OK, 1 row affected, 1 warning (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 1

show warnings;
+-------+------+----------------------------------------+
| Level | Code | Message                                |
+-------+------+----------------------------------------+
| Note  | 1265 | Data truncated for column 'b' at row 1 |
+-------+------+----------------------------------------+
1 row in set (0.00 sec)

select * from td;
+----------------------+-----------+
| a                    | b         |
+----------------------+-----------+
| 987654321.0123456789 | 987654321 |
+----------------------+-----------+
1 row in set (1.67 sec)

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

Page generated in 0.049 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.