summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2011-09-05 20:51:37 +0400
committerSergey Petrunya <psergey@askmonty.org>2011-09-05 20:51:37 +0400
commite1435a51786f7975da79f62fc430fc3b3bf1a45f (patch)
treea148ae7d5ffd283850762209dc11def9d522240f /sql
parent6035d0d755a2465421da3ac845ab970c504c90d7 (diff)
downloadmariadb-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.cc2
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_select.h3
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;