[MDEV-16765] missing rows with condition on subselect Created: 2018-07-16 Updated: 2019-03-07 Resolved: 2018-08-20 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.3.8, 10.2, 10.3 |
| Fix Version/s: | 10.2.18 |
| Type: | Bug | Priority: | Major |
| Reporter: | Benjamin Setzer | Assignee: | Galina Shalygina (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Environment: |
debian/jessie |
||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Description |
|
I got some strange behaviour with subselect and missing rows. following select produces 2 rows, and is_blacklisted equals 0 in both:
Now I add a condition on is_blacklisted and I only get 1 row. (I tried several versions, "IS false", "= 0", "IS NOT true", all with the same behaviour)
When I select into a temporary table, I get 2 rows again.
If I remove the syndication_white_flags_1.code in the group_by, it works too. Possibly related to: https://bugs.mysql.com/bug.php?id=88300 |
| Comments |
| Comment by Alice Sherepa [ 2018-07-17 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thanks for the report!
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2018-07-19 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
With
I have:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Galina Shalygina (Inactive) [ 2018-07-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Running the example above it can be seen that bug was caused by the pushdown into the materialized derived table/view optimization. From the explain of the query in json format it can be seen that "case when (tmp2.v1 is null or tmp2.v1 not like '%test%') then 1 else 0 end = 0" condition was pushed into the WHERE clause of the derived table tmp1. This condition depends only on constants and fields of the derived table so it can be pushed down into the HAVING clause of the derived table. Condition can be pushed into the WHERE clause of the derived table if it depends only on the fields of the derived tables that are used in the GROUP BY clause of the derived table definition. "tmp2.wf" is not a field used in the GROUP BY clause so this condition can't be pushed down into the WHERE clause. Also it should be mentioned that for the condition that was pushed down fields remain the same while they should be transformed to the appropriate values. Looking on the pushdown_cond_for_derived() method and check_cond_extraction_for_grouping_fields() call where it is checked if the condition should be pushed into the WHERE clause it can be seen how the condition is traversed. For the condition excl_dep_on_grouping_fields() method is recursively called. Looking on the CASE definition it can be seen that it is OR condition with two elements.
Going down trough the condition it can be mentioned that this condition is processed as Item_func. It tries to take its arg_count that is 0 and returns true (that condition depends on the GROUP BY fields only). That's why this condition is pushed into the WHERE clause. As it doesn't depend on GROUP BY fields but is processed as the condition that depends only on them it is not transformed in the right way. That causes wrong result.
To fix this problem Item_cond::excl_dep_on_grouping_fields() should be changed. It should be changed in the way that Item_cond type conditions in the CASE definition are processed in the right way. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2018-07-31 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ok to push into 10.2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Galina Shalygina (Inactive) [ 2018-08-20 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Pushed in 10.2 |