Bug #26963 | Incorrect query results with CONST join compared to RANGE or ALL | ||
---|---|---|---|
Submitted: | 8 Mar 2007 16:49 | Modified: | 21 Mar 2007 18:19 |
Reporter: | Harrison Fisk | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.0.36 | OS: | MacOS (Mac OS X, Linux) |
Assigned to: | Igor Babaev | CPU Architecture: | Any |
Tags: | const, incorrect result, regression |
[8 Mar 2007 16:49]
Harrison Fisk
[12 Mar 2007 0:27]
Igor Babaev
The following EXPLAIN EXTENDED command reveals the source of the problem: mysql> EXPLAIN EXTENDED -> SELECT faqs.faq_id FROM faq_access f_acc INNER JOIN faqs ON (f_acc.access_id = -> faqs.access_id) LEFT JOIN faqs f2 on (f2.faq_group_id = faqs.faq_group_id AND -> find_in_set(f2.access_id, '1,4') < find_in_set(faqs.access_id, '1,4')) WHERE -> faqs.access_id IN (1,4) AND f2.access_id IS NULL AND faqs.faq_id in (265) \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: faqs type: const possible_keys: faqs$faq_id key: faqs$faq_id key_len: 4 ref: const rows: 1 Extra: *************************** 2. row *************************** id: 1 select_type: SIMPLE table: f2 type: ref possible_keys: faqs$group_id$faq_id key: faqs$group_id$faq_id key_len: 4 ref: const rows: 1 Extra: Using where *************************** 3. row *************************** id: 1 select_type: SIMPLE table: f_acc type: ref possible_keys: faq_access$access_id key: faq_access$access_id key_len: 2 ref: const rows: 1 Extra: Using where; Using index 3 rows in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS \G *************************** 1. row *************************** Level: Note Code: 1003 Message: select '265' AS `faq_id` from `test`.`faq_access` `f_acc` join `test`.`faqs` left join `test`.`faqs` `f2` on(((`test`.`f2`.`faq_group_id` = '261') and (find_in_set(`test`.`f2`.`access_id`,_latin1'1,4') < find_in_set(`test`.`f_acc`.`access_id`,_latin1'1,4')))) where ((`test`.`f_acc`.`access_id` = '1') and (`test`.`f_acc`.`access_id` in (1,4)) and isnull(`test`.`f2`.`access_id`)) 1 row in set (0.01 sec) We can see that in the predicate find_in_set(faqs.access_id, '1,4') the field faqs.access_id was substituted for the test.f_acc.access_id. This is not correct. It has be substituted for a constant after constant table substitution.
[12 Mar 2007 6:29]
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/21697 ChangeSet@1.2475, 2007-03-11 23:34:40-07:00, igor@olga.mysql.com +3 -0 Fixed bug #26963: invalid optimization of the pushdown conditions after single-row table substitution could lead to a wrong result set. The bug happened because the function Item_field::replace_equal_field erroniously assumed that any field included in a multiple equality with a constant has been already substituted for this constant. This not true for fields becoming constant after row substitutions for constant tables.
[17 Mar 2007 18:03]
Alexey Botchkov
Pushed in 5.0.40, 5.1.17
[21 Mar 2007 18:19]
Paul DuBois
Noted in 5.0.40, 5.1.17 changelogs. Invalid optimization of pushdown conditions for queries where an outer join was guaranteed to read only one row from the outer table led to results with too few rows.