When adding a new record into the join buffer that is employed by
BNLH join algorithm the writing procedure JOIN_CACHE::write_record_data
checks whether there is enough space for the record in the buffer.
When doing this it must take into account a possible new key entry
added to the buffer. It might happen, as it has been demonstrated by
the bug test case, that there is enough remaining space in the buffer
for the record, but not for the additional key entry for this record.
In this case the key entry overwrites the end of the record that might
cause a crash or wrong results.
Fixed by taking into account a possible addition of new key entry when
estimating the remaining free space in the buffer.
Employed the same kind of optimization as in the fix for the cases
when join buffer is used.
The optimization performs early evaluation of the conditions from
on expression with table references to only outer tables of
an outer join.
The fix aligns join_null_complements() with join_matching_records()
making both call generate_full_extensions().
There should not be any difference between how the WHERE clause
is applied to NULL-complemented records from a partial join and how
it is applied to other partially joined records:the latter happens in
join_matching_records(), precisely in generate_full_extensions().
When an incremental join cache is used to join a table whose
fields are not referenced anywhere in the query the association
pointer to the last record in the such cache can be the same
as the pointer to the end of the buffer.
The function JOIN_CACHE_BKA::get_next_key must take into
consideration this when iterating over the keys of the records
from the join buffer.
The assertion in JOIN_TAB_SCAN_MRR::next also must take this
into consideration.
Borrowed a slightly changed test case from a patch attached to the
bug #52394.
- Lots of TODO comments
- add mrr_sort_keys flag to @@optimizer_switch
- [from Igor] SQL layer part passes HA_MRR_MATERIALIZED_KEYS flag
- Don't call rnd_pos() many times in a row if sorted rowid buffer
has the same rowid value for multiple consequive (rowid, range_id) pairs.
join cache module.
Without these calls SELECTs over tables with virtual columns
that used join cache could return wrong results. This could
be seen with the test case added into vcol_misc.test
- Make join buffering take into account that join_tabs are not a
single linear array anymore
- Remove outer join + SJ-Materialization crash (OJ+SJ the processing
is most likely still incorrect)
- The problem was that DuplicateWeedout strategy setup code wasn't aware of the
fact that join buffering will be used and applied optimization that doesn't work
together with join buffering. Fixed by making DuplicateWeedout setup code to have
a pessimistic check about whether there is a chance that join buffering will be
used.
- Make JOIN_CACHE_BKA::init() correctly process Copy_field elements that denote saving
current rowids in the join buffer.
mysql-test/r/subselect_sj2.result:
Update test results
mysql-test/r/subselect_sj2_jcl6.result:
Update test results
mysql-test/r/subselect_sj_jcl6.result:
Testcase
mysql-test/t/subselect_sj2.test:
Update test results
mysql-test/t/subselect_sj_jcl6.test:
Testcase
sql/opt_subselect.cc:
- The problem was that DuplicateWeedout strategy setup code wasn't aware of the
fact that join buffering will be used and applied optimization that doesn't work
together with join buffering. Fixed by making DuplicateWeedout setup code to have
a pessimistic check about whether there is a chance that join buffering will be
used.
sql/sql_join_cache.cc:
Make JOIN_CACHE_BKA::init() correctly process Copy_field elements that denote saving current rowids in the join buffer.
sql/sql_select.cc:
Added a question note
The function JOIN_CACHE::read_all_record_fields could return 0
for an incremental join cache in two cases:
1. there were no more records in the associated join buffer
2. there was no table fields stored in the join buffer.
As a result the function JOIN_CACHE::get_record() could
return prematurely and did not read all needed fields from
join buffers into the record buffer.
Now the function JOIN_CACHE::read_all_record_fields returns
-1 if there are no more records in the associated join buffer.