[MDEV-6706] Wrong result (missing rows) with joins, SQ, ORDER BY, semijoin=on Created: 2014-09-06 Updated: 2018-01-18 Resolved: 2018-01-18 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 5.3.12, 5.5.39, 10.0.13, 10.1.30 |
| Fix Version/s: | 5.5.59 |
| Type: | Bug | Priority: | Major |
| Reporter: | Elena Stepanova | Assignee: | Igor Babaev |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Sprint: | 5.5.59 |
| Description |
|
Test case:
Actual result:
Result without ORDER BY or with semijoin=off:
The problem appeared in 5.3 tree with the following revision:
|
| Comments |
| Comment by Igor Babaev [ 2018-01-12 ] | |||||||||||||||||
|
The code of get_sort_by_table() that checks that ordering can be done using fields of only one table
was incorrect. The code uses the previously calculated value of 'map' containing table_map bits for all tables the order by items depend on. It includes bits for all const (single_row) tables that should be excluded before the the loop in the above code starts.
The function get_sort_by_table() is called in make_join_statistics() to set the value of JOIN::sort_by_table.
This code is executed for the reported query. The code prohibits using sorting by the first non constant joined table and, as a result, it requires creation of a temporary table containing all rows from the result set. Sorting the records from the temporary table produces the necessary ordering. Let's see what's going on when executing the reported query with the current code. The call of the function get_sort_by_table() set JOIN::sort_by_table to 0. As a result the above call join->get_sort_by_join_tab() returns 0 and the code join->simple_order= 0; is skipped. So the value of join->simple_order is not changed and it remains the same as it was set by the previously called function remove_const that does not use the value of join->sort_by_table. After the above 'if' statement the function setup_semijoin_dups_elimination() calls init_dups_weedout(). The latter sets JOIN_TAB::keep_current_rowid to TRUE for the third joined table, namely for the table t2. It also sets the field JOIN::flush_weedout_table for this table. | |||||||||||||||||
| Comment by Oleksandr Byelkin [ 2018-01-12 ] | |||||||||||||||||
|
OK to push. | |||||||||||||||||
| Comment by Igor Babaev [ 2018-01-18 ] | |||||||||||||||||
|
A fix for this bug was pushed into the 5.5 tree. |