|
The code in str_to_time() in sql-common/my_time.c is not portable.
It can return different results on different architectures.
Platforms with sizeof(ulong)==4 (e.g. Linux 32bit, Windows)
SELECT TIME('42949672955959-01'), TIME('42949672965959-01');
|
+---------------------------+---------------------------+
|
| TIME('42949672955959-01') | TIME('42949672965959-01') |
|
+---------------------------+---------------------------+
|
| 838:59:59 | 00:59:59 |
|
+---------------------------+---------------------------+
|
1 row in set, 2 warnings (0.001 sec)
|
The result for the second column is wrong.
Platforms with sizeof(ulong)==8 (e.g. Linux 64bit)
SELECT TIME('42949672955959-01'), TIME('42949672965959-01');
|
+---------------------------+---------------------------+
|
| TIME('42949672955959-01') | TIME('42949672965959-01') |
|
+---------------------------+---------------------------+
|
| 838:59:59 | NULL |
|
+---------------------------+---------------------------+
|
1 row in set, 2 warnings (0.00 sec)
|
The result for the second column is correct.
The underlying code description
else
|
{
|
/* String given as one number; assume HHMMSS format */
|
date[0]= 0;
|
date[1]= (ulong) (value/10000); //This line is not portable
|
date[2]= (ulong) (value/100 % 100);
|
date[3]= (ulong) (value % 100);
|
state=4;
|
goto fractional;
|
}
|
The difference happens in the line assigning date[1]. For TIME('42949672965959-01'), "value" is 4294967296595.
Assigning (4294967296595/10000) to data[1]:
- makes 4294967296 on platforms with sizeof(ulong)=8
- overflows to 0 on platforms with sizeof(ulong)=4
On 64bit platforms a similar problem is repeatable with TIME('18446744073709551616-01')
SELECT TIME('18446744073709551615-01'), TIME('18446744073709551616-01');
|
+---------------------------------+---------------------------------+
|
| TIME('18446744073709551615-01') | TIME('18446744073709551616-01') |
|
+---------------------------------+---------------------------------+
|
| NULL | 00:00:00 |
|
+---------------------------------+---------------------------------+
|
Notice, the value for the second column is wrong. The expected value is NULL.
|