Description:
If "insert .. on duplicate key" updates an existing row, it sometimes fails to copmpare the current date value to the new value returned by the values() function.
It seems to fail on the first call of a query, it works on repeated calls of the same query...
This applies to date, time and datetime columns.
As a workaround it is possible to use "cast as date" on the old value from the existing column.(casting the new value, makes no difference)
Here is the sql with DATE column (same results for datetime or time) (for result see how to repeat). The field x is only included to show that the rest of the row get updated correctly (and the select iis not cached).
create table tt1 ( a int not null primary key, b int, d date, x int );
insert into tt1 values (1,0,"2006-06-25",0);
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # wrong
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # wrong
insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
insert into tt1 values (1,2,cast("2006-06-25" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # wrong
insert into tt1 values (1,2,cast("2006-06-25" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # good
insert into tt1 values (1,2,cast("2006-06-26" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # wrong
insert into tt1 values (1,2,cast("2006-06-26" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=cast(values(d) as date) ; select * from tt1; # wrong
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=cast(values(d) as date) ; select * from tt1; # good
# with workaround
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
drop table tt1;
How to repeat:
mysql> create table tt1 ( a int not null primary key, b int, d date, x int );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into tt1 values (1,0,"2006-06-25",0);
Query OK, 1 row affected (0.01 sec)
# same data / expect b=1
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # wrong
Query OK, 2 rows affected (0.01 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 1 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 2 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 3 |
+---+------+------------+------+
1 row in set (0.00 sec)
# differnt data / expect b=0
mysql> insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # wrong
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 4 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 5 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= d=values(d), x=x+1 ; select * from tt1; # good
Query OK, 2 rows affected (0.09 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
# make sure the new value is a date, rather than a string
mysql> insert into tt1 values (1,2,cast("2006-06-25" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # wrong
Query OK, 2 rows affected (0.01 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,cast("2006-06-25" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql>
mysql> insert into tt1 values (1,2,cast("2006-06-26" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # wrong
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.01 sec)
mysql> insert into tt1 values (1,2,cast("2006-06-26" as date),0) on duplicate key update b= d=values(d) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=cast(values(d) as date) ; select * from tt1; # wrong
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= d=cast(values(d) as date) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
# with Workaround
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-25",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 1 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql>
mysql> insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> insert into tt1 values (1,2,"2006-06-26",0 ) on duplicate key update b= cast(d as date)=values(d) ; select * from tt1; # good
Query OK, 2 rows affected (0.00 sec)
+---+------+------------+------+
| a | b | d | x |
+---+------+------------+------+
| 1 | 0 | 2006-06-25 | 6 |
+---+------+------------+------+
1 row in set (0.00 sec)
mysql> drop table tt1;
Query OK, 0 rows affected (0.01 sec)
Suggested fix:
-