summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorJorgen Loland <jorgen.loland@oracle.com>2010-12-16 12:25:02 +0100
committerJorgen Loland <jorgen.loland@oracle.com>2010-12-16 12:25:02 +0100
commit47b774b21c7f2fa600bae2b7193805a25d286b54 (patch)
treecc86f2f7e5035b9e03483455840ea4e93b91796c /sql
parent8b1571d80341770818404c9cc9ed4b362ffe5710 (diff)
downloadmariadb-git-47b774b21c7f2fa600bae2b7193805a25d286b54.tar.gz
BUG#58456 - Assertion 0 in QUICK_INDEX_MERGE_SELECT::need_sorted_output
in opt_range.h In this bug, there are two alternative access plans: * Index merge range access * Const ref access best_access_path() decided that the ref access was preferrable, but make_join_select() still decided to point SQL_SELECT::quick to the index merge because the table had type==JT_CONST which was not handled. At the same time the table's ref.key still referred to the index the ref access would use indicating that ref access should be used. In this state, different parts of the optimizer code have different perceptions of which access path is in use (ref or range). test_if_skip_sort_order() was called to check if the ref access needed ordering, but test_if_skip_sort_order() got confused and requested the index merge to return records in sorted order. Index merge cannot do this, and fired an ASSERT. The fix is to take join_tab->type==JT_CONST into concideration when make_join_select() decides whether or not to use the range access method. mysql-test/r/join_outer_innodb.result: Add test for BUG#58456 mysql-test/t/join_outer_innodb.test: Add test for BUG#58456
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_select.cc16
1 files changed, 9 insertions, 7 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e5d574192b1..90a8727c56c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -6499,10 +6499,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
/* Use quick key read if it's a constant and it's not used
with key reading */
- if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
- && tab->type != JT_FT && (tab->type != JT_REF ||
- (uint) tab->ref.key == tab->quick->index))
- {
+ if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF &&
+ tab->type != JT_FT &&
+ ((tab->type != JT_CONST && tab->type != JT_REF) ||
+ (uint)tab->ref.key == tab->quick->index))
+ {
+ DBUG_ASSERT(tab->quick->index != MAX_KEY);
sel->quick=tab->quick; // Use value from get_quick_...
sel->quick_keys.clear_all();
sel->needed_reg.clear_all();
@@ -13857,7 +13859,7 @@ check_reverse_order:
SYNOPSIS
create_sort_index()
thd Thread handler
- tab Table to sort (in join structure)
+ join Join with table to sort
order How table should be sorted
filesort_limit Max number of rows that needs to be sorted
select_limit Max number of rows in final output
@@ -13867,8 +13869,8 @@ check_reverse_order:
IMPLEMENTATION
- - If there is an index that can be used, 'tab' is modified to use
- this index.
+ - If there is an index that can be used, the first non-const join_tab in
+ 'join' is modified to use this index.
- If no index, create with filesort() an index file that can be used to
retrieve rows in order (should be done with 'read_record').
The sorted data is stored in tab->table and will be freed when calling