1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off

- 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
This commit is contained in:
Sergey Petrunya
2010-03-07 18:41:45 +03:00
parent 1c7ba7ba2f
commit c2924e155e
8 changed files with 102 additions and 12 deletions

View File

@@ -3035,10 +3035,24 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
forwards, but do not destroy other duplicate elimination methods.
*/
uint first_table= i;
uint join_cache_level= join->thd->variables.join_cache_level;
for (uint j= i; j < i + pos->n_sj_tables; j++)
{
if (join->best_positions[j].use_join_buffer && j <= no_jbuf_after)
/*
When we'll properly take join buffering into account during
join optimization, the below check should be changed to
"if (join->best_positions[j].use_join_buffer &&
j <= no_jbuf_after)".
For now, use a rough criteria:
*/
JOIN_TAB *js_tab=join->join_tab + j;
if (j != join->const_tables && js_tab->use_quick != 2 &&
j <= no_jbuf_after &&
((js_tab->type == JT_ALL && join_cache_level != 0) ||
(join_cache_level > 4 && (tab->type == JT_REF ||
tab->type == JT_EQ_REF))))
{
/* Looks like we'll be using join buffer */
first_table= join->const_tables;
break;
}
@@ -3116,7 +3130,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
JOIN_TAB *j, *jump_to= tab-1;
for (j= tab; j != tab + pos->n_sj_tables; j++)
{
if (!tab->emb_sj_nest)
/*
NOTE: this loop probably doesn't do the right thing for the case
where FirstMatch's duplicate-generating range is interleaved with
"unrelated" tables (as specified in WL#3750, section 2.2).
*/
if (!j->emb_sj_nest)
jump_to= tab;
else
{