Bug #36100 | NULL-safe comparison does not work with TIMESTAMP, DATETIME | ||
---|---|---|---|
Submitted: | 15 Apr 2008 20:01 | Modified: | 6 Aug 2009 20:10 |
Reporter: | Anthony Bush | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S3 (Non-critical) |
Version: | 5.0.45,5.0.54, 5.0.58, 5.0.67 | OS: | Any |
Assigned to: | Evgeny Potemkin | CPU Architecture: | Any |
Tags: | datetime, null-safe, timestamp |
[15 Apr 2008 20:01]
Anthony Bush
[15 Apr 2008 20:22]
Anthony Bush
The very last work around example (check if two datetime fields are the same) has faulty logic. Instead try: SELECT * FROM null_safe WHERE datetime1 IS NULL AND datetime2 IS NULL OR (datetime1 IS NOT NULL AND datetime2 IS NOT NULL AND datetime1 = datetime2);
[16 Apr 2008 3:45]
Valeriy Kravchuk
Thank you for a bug report. Verified with 5.0.58 also: C:\Program Files\MySQL\MySQL Server 5.1\bin>mysql -uroot -proot test -P3308 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.0.58-enterprise-gpl-nt MySQL Enterprise Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE TABLE `null_safe` ( -> `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , -> `timestamp1` TIMESTAMP NULL , -> `timestamp2` TIMESTAMP NULL , -> `datetime1` DATETIME NULL , -> `datetime2` DATETIME NULL -> ) ENGINE = INNODB; Query OK, 0 rows affected (0.27 sec) mysql> INSERT INTO null_safe VALUES (NULL, CURRENT_TIMESTAMP, NULL, NOW(), NULL ); Query OK, 1 row affected (0.09 sec) mysql> select * from null_safe; +----+---------------------+------------+---------------------+-----------+ | id | timestamp1 | timestamp2 | datetime1 | datetime2 | +----+---------------------+------------+---------------------+-----------+ | 1 | 2008-04-16 06:38:12 | NULL | 2008-04-16 06:38:12 | NULL | +----+---------------------+------------+---------------------+-----------+ 1 row in set (0.01 sec) mysql> SELECT * FROM null_safe WHERE timestamp1 <=> timestamp2; +----+---------------------+------------+---------------------+-----------+ | id | timestamp1 | timestamp2 | datetime1 | datetime2 | +----+---------------------+------------+---------------------+-----------+ | 1 | 2008-04-16 06:38:12 | NULL | 2008-04-16 06:38:12 | NULL | +----+---------------------+------------+---------------------+-----------+ 1 row in set (0.01 sec) mysql> SELECT * FROM null_safe WHERE datetime1 <=> datetime2; +----+---------------------+------------+---------------------+-----------+ | id | timestamp1 | timestamp2 | datetime1 | datetime2 | +----+---------------------+------------+---------------------+-----------+ | 1 | 2008-04-16 06:38:12 | NULL | 2008-04-16 06:38:12 | NULL | +----+---------------------+------------+---------------------+-----------+ 1 row in set (0.00 sec) With INT column, for example, <=> works as expected: mysql> alter table null_safe add i1 int; Query OK, 1 row affected (0.39 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> alter table null_safe add i2 int; Query OK, 1 row affected (0.24 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> update null_safe set i1=1, i2=NULL; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT * FROM null_safe WHERE i1 <=> i2; Empty set (0.02 sec)
[4 Aug 2008 22:55]
Buks Hanekom
I also found this bug hile trying to create a trigger based audit trail for a table. I would just like to point out that this bug only happens if the right hand side of the comparrison is NULL. If the left hand side of the comparison is NULL, everything is fine. You can use this simple query to show the difference: SELECT CAST(NULL AS DATETIME) <=> CAST('2008/01/01' AS DATETIME) AS LEFT_NULL, CAST('2008/01/01' AS DATETIME) <=> CAST(NULL AS DATETIME) AS RIGHT_NULL; Result: +-----------+------------+ | LEFT_NULL | RIGHT_NULL | +-----------+------------+ | 0 | 1 | +-----------+------------+ It works when using CHAR: SELECT CAST(NULL AS CHAR(15)) <=> CAST('2008/01/01' AS CHAR(15)) AS LEFT_NULL, CAST('2008/01/01' AS CHAR(15)) <=> CAST(NULL AS CHAR(15)) AS RIGHT_NULL; +-----------+------------+ | LEFT_NULL | RIGHT_NULL | +-----------+------------+ | 0 | 0 | +-----------+------------+
[14 Apr 2009 15:42]
rancpine cui
Hmm... I can't repeat this via 5.1.32 mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> CREATE TABLE `null_safe` ( -> `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , -> `timestamp1` TIMESTAMP NULL , -> `timestamp2` TIMESTAMP NULL , -> `datetime1` DATETIME NULL , -> `datetime2` DATETIME NULL -> ) ENGINE = INNODB; INSERT INTO null_safe VALUES (NULL, CURRENT_TIMESTAMP, NULL, NOW(), NULL); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO null_safe VALUES (NULL, CURRENT_TIMESTAMP, NULL, NOW(), NULL); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM null_safe WHERE timestamp1 <=> timestamp2; Empty set (0.00 sec) mysql> SELECT * FROM null_safe WHERE datetime1 <=> datetime2; Empty set (0.00 sec) mysql> select version(); +------------+ | version() | +------------+ | 5.1.32-log | +------------+ 1 row in set (0.00 sec)
[6 May 2009 2:48]
Anthony Bush
Tested this again in 5.0.67 (still broke) and 5.0.81 (appears to be fixed): mysql> use test; Database changed mysql> CREATE TABLE `null_safe` ( -> `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , -> `timestamp1` TIMESTAMP NULL , -> `timestamp2` TIMESTAMP NULL , -> `datetime1` DATETIME NULL , -> `datetime2` DATETIME NULL -> ) ENGINE = INNODB; Query OK, 0 rows affected (0.09 sec) mysql> INSERT INTO null_safe VALUES (NULL, CURRENT_TIMESTAMP, NULL, NOW(), NULL); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM null_safe WHERE timestamp1 <=> timestamp2; Empty set (0.00 sec) mysql> SELECT * FROM null_safe WHERE datetime1 <=> datetime2; Empty set (0.00 sec) mysql> select version(); +-----------+ | version() | +-----------+ | 5.0.81 | +-----------+ 1 row in set (0.00 sec)
[6 Aug 2009 20:10]
Anthony Bush
Marking closed since this is fixed in 5.0.81 and 5.1.32 and hopefully the latest versions in each 5.0.x and 5.1.x series.