diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2011-09-05 20:51:37 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2011-09-05 20:51:37 +0400 |
commit | e1435a51786f7975da79f62fc430fc3b3bf1a45f (patch) | |
tree | a148ae7d5ffd283850762209dc11def9d522240f /sql | |
parent | 6035d0d755a2465421da3ac845ab970c504c90d7 (diff) | |
download | mariadb-git-e1435a51786f7975da79f62fc430fc3b3bf1a45f.tar.gz |
BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
- Don't use join buffering for tables that are within ranges that are
covered by LooseScan strategy.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/opt_subselect.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 10 | ||||
-rw-r--r-- | sql/sql_select.h | 3 |
3 files changed, 15 insertions, 0 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 40a0195e554..9ea55390fc5 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3827,6 +3827,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, { /* We jump from the last table to the first one */ tab->loosescan_match_tab= tab + pos->n_sj_tables - 1; + for (uint j= i; j < pos->n_sj_tables; j++) + join->join_tab[j].inside_loosescan_range= TRUE; /* Calculate key length */ keylen= 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9aab58c1742..6ddb350db1d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7100,6 +7100,7 @@ get_best_combination(JOIN *join) goto loop_end; // Handled in make_join_stat.. j->loosescan_match_tab= NULL; //non-nulls will be set later + j->inside_loosescan_range= FALSE; j->ref.key = -1; j->ref.key_parts=0; @@ -8984,6 +8985,15 @@ uint check_join_cache_usage(JOIN_TAB *tab, if (tab->use_quick == 2) goto no_join_cache; + + /* + Don't use join cache if we're inside a join tab range covered by LooseScan + strategy (TODO: LooseScan is very similar to FirstMatch so theoretically it + should be possible to use join buffering in the same way we're using it for + multi-table firstmatch ranges). + */ + if (tab->inside_loosescan_range) + goto no_join_cache; if (tab->is_inner_table_of_semi_join_with_first_match() && !join->allowed_semijoin_with_cache) diff --git a/sql/sql_select.h b/sql/sql_select.h index 9b53c53f690..15711dca7b3 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -347,6 +347,9 @@ typedef struct st_join_table { NULL - Not doing a loose scan on this join tab. */ struct st_join_table *loosescan_match_tab; + + /* TRUE <=> we are inside LooseScan range */ + bool inside_loosescan_range; /* Buffer to save index tuple to be able to skip duplicates */ uchar *loosescan_buf; |