| Bug #18618 | Joining tables with DATE BETWEEN in WHERE clause gives unexpected results | ||
|---|---|---|---|
| Submitted: | 29 Mar 2006 15:14 | Modified: | 17 Apr 2006 18:46 |
| Reporter: | Nathan Tanner | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
| Version: | 5.0.20-BK, 5.0.19 | OS: | Linux (Linux) |
| Assigned to: | Igor Babaev | CPU Architecture: | Any |
[29 Mar 2006 15:14]
Nathan Tanner
[29 Mar 2006 15:18]
Nathan Tanner
FYI, I did some more searching, and this bug may be the same as bug 14360, but there are some differences. I will leave that to your discretion.
[29 Mar 2006 15:56]
Valeriy Kravchuk
Thank you for a problem report. Sorry, but I was not able to repeat exactly the behaviour you described on today's 5.0.20-BK (with your test case):
mysql> SELECT * FROM test, test2 WHERE test.Day BETWEEN CURDATE() - INTERVAL 6 MONTH
-> AND test2.Day;
+----+------------+----+------------+
| ID | Day | ID | Day |
+----+------------+----+------------+
| 7 | 2006-02-16 | 5 | 2006-03-16 |
| 13 | 2006-02-10 | 5 | 2006-03-16 |
+----+------------+----+------------+
2 rows in set (0.01 sec)
mysql> SELECT * FROM test, test2 WHERE CAST(test.Day AS DATE) BETWEEN CURDATE() -
-> INTERVAL 6 MONTH AND test2.Day;
+----+------------+----+------------+
| ID | Day | ID | Day |
+----+------------+----+------------+
| 3 | 2005-12-11 | 3 | 2005-12-26 |
| 5 | 2005-10-12 | 3 | 2005-12-26 |
| 6 | 2005-12-10 | 3 | 2005-12-26 |
| 12 | 2005-11-27 | 3 | 2005-12-26 |
| 3 | 2005-12-11 | 5 | 2006-03-16 |
| 5 | 2005-10-12 | 5 | 2006-03-16 |
| 6 | 2005-12-10 | 5 | 2006-03-16 |
| 7 | 2006-02-16 | 5 | 2006-03-16 |
| 12 | 2005-11-27 | 5 | 2006-03-16 |
| 13 | 2006-02-10 | 5 | 2006-03-16 |
| 5 | 2005-10-12 | 7 | 2005-11-16 |
| 3 | 2005-12-11 | 8 | 2006-02-06 |
| 5 | 2005-10-12 | 8 | 2006-02-06 |
| 6 | 2005-12-10 | 8 | 2006-02-06 |
| 12 | 2005-11-27 | 8 | 2006-02-06 |
| 3 | 2005-12-11 | 12 | 2005-12-25 |
| 5 | 2005-10-12 | 12 | 2005-12-25 |
| 6 | 2005-12-10 | 12 | 2005-12-25 |
| 12 | 2005-11-27 | 12 | 2005-12-25 |
| 5 | 2005-10-12 | 13 | 2005-10-20 |
| 5 | 2005-10-12 | 15 | 2005-10-24 |
+----+------------+----+------------+
21 rows in set (0.00 sec)
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.0.20 |
+-----------+
1 row in set (0.00 sec)
So, it may not be exactly related to that bug #14360. Patch for that bug should be included into 5.0.20-BK already, but I am not sure.
The real problem now is:
mysql> explain extended SELECT * FROM test, test2 WHERE test.Day BETWEEN CURDATE() - INTERVAL 6 MONTH AND test2.Day\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 15
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: test2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 15
Extra: Using where
2 rows in set, 1 warning (0.01 sec)
mysql> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: select sql_no_cache `test`.`test`.`ID` AS `ID`,`test`.`test`.`Day` AS `Day`,`test`.`test2`.`ID` AS `ID`,`test`.`test2`.`Day` AS `Day` from `test`.`test
` join `test`.`test2` where (`test`.`test`.`Day` between 20050929 and `test`.`test2`.`Day`)
1 row in set (0.01 sec)
mysql> explain extended SELECT * FROM test, test2 WHERE CAST(test.Day AS DATE)
BETWEEN CURDATE() - INTERVAL 6 MONTH AND test2.Day\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 15
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: test2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 15
Extra: Using where
2 rows in set, 1 warning (0.01 sec)
mysql> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: select sql_no_cache `test`.`test`.`ID` AS `ID`,`test`.`test`.`Day` AS `Day`,`test`.`test2`.`ID` AS `ID`,`test`.`test2`.`Day` AS `Day` from `test`.`test
` join `test`.`test2` where (cast(`test`.`test`.`Day` as date) between (curdate() - interval 6 month) and `test`.`test2`.`Day`)
1 row in set (0.01 sec)
The difference in optimization (why "curdate() - interval 6 month" is converted to 20050929 in the first case, but not in the second), and, surely, different results.
[11 Apr 2006 5:05]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/4761
[11 Apr 2006 17:03]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/4805
[17 Apr 2006 2:08]
Igor Babaev
ChangeSet 1.2151 06/04/10 22:05:13 igor@rurik.mysql.com +2 -0 Fixed bug #18618. If the second or the third argument of a BETWEEN predicate was a constant expression, like '2005.09.01' - INTERVAL 6 MONTH, while the other two arguments were fields then the predicate was evaluated incorrectly and the query returned a wrong result set. The bug was introduced in 5.0.17 by the fix for 12612. The fix will appear in 5.0.21 and 5.1.10
[17 Apr 2006 18:46]
Paul DuBois
Noted in 5.0.21, 5.1.10 changelogs. If the second or third argument to <literal>BETWEEN</literal> was a constant expression such as <literal>'2005-09-01 - INTERVAL 6 MONTH</literal> and the other two arguments were columns, <literal>BETWEEN</literal> was evaluated incorrectly. (Bug #18618)
