summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2019-02-28 14:44:38 -0800
committerIgor Babaev <igor@askmonty.org>2019-02-28 14:45:01 -0800
commit5a0874449a50187e70adf051754d9fbed27d549b (patch)
treed9d3b4d3289a19f9007fc0f3cd7a69e8a541c389 /sql
parentb10340998f33a04452a499ae8d13f8af7e1e69b0 (diff)
downloadmariadb-git-5a0874449a50187e70adf051754d9fbed27d549b.tar.gz
MDEV-18755 Assertion `inited==INDEX' failed in handler::ha_index_read_map
When the chosen execution plan accesses a join table employing a range rowid filter a quick select to scan this range has to be built. This quick select is built by a call of SQL_SELECT::test_quick_select(). At this call the function should allow to evaluate only single index range scans. In order to be able to do this a new parameter was added to this function.
Diffstat (limited to 'sql')
-rw-r--r--sql/opt_range.cc19
-rw-r--r--sql/opt_range.h6
-rw-r--r--sql/sql_select.cc20
3 files changed, 28 insertions, 17 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index fcf0d2228a5..1e60bb9ae92 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2586,6 +2586,9 @@ static int fill_used_fields_bitmap(PARAM *param)
limit Query limit
force_quick_range Prefer to use range (instead of full table scan) even
if it is more expensive.
+ remove_false_parts_of_where Remove parts of OR-clauses for which range
+ analysis produced SEL_TREE(IMPOSSIBLE)
+ only_single_index_range_scan Evaluate only single index range scans
NOTES
Updates the following in the select parameter:
@@ -2644,7 +2647,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_map prev_tables,
ha_rows limit, bool force_quick_range,
bool ordered_output,
- bool remove_false_parts_of_where)
+ bool remove_false_parts_of_where,
+ bool only_single_index_range_scan)
{
uint idx;
double scan_time;
@@ -2824,7 +2828,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
}
TABLE_READ_PLAN *best_trp= NULL;
- TRP_GROUP_MIN_MAX *group_trp;
+ TRP_GROUP_MIN_MAX *group_trp= NULL;
double best_read_time= read_time;
if (cond)
@@ -2859,7 +2863,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
Notice that it can be constructed no matter if there is a range tree.
*/
- group_trp= get_best_group_min_max(&param, tree, best_read_time);
+ if (!only_single_index_range_scan)
+ group_trp= get_best_group_min_max(&param, tree, best_read_time);
if (group_trp)
{
param.table->quick_condition_rows= MY_MIN(group_trp->records,
@@ -2907,7 +2912,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table deletes.
*/
if ((thd->lex->sql_command != SQLCOM_DELETE) &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
+ optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) &&
+ !only_single_index_range_scan)
{
/*
Get best non-covering ROR-intersection plan and prepare data for
@@ -2935,7 +2941,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
*/
if (param.table->covering_keys.is_clear_all() &&
optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT))
+ optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT) &&
+ !only_single_index_range_scan)
{
if ((intersect_trp= get_best_index_intersect(&param, tree,
best_read_time)))
@@ -2948,7 +2955,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
}
if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) &&
- head->stat_records() != 0)
+ head->stat_records() != 0 && !only_single_index_range_scan)
{
/* Try creating index_merge/ROR-union scan. */
SEL_IMERGE *imerge;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 7e92e1f54ee..2dab90b9f69 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -1645,7 +1645,8 @@ class SQL_SELECT :public Sql_alloc {
{
key_map tmp;
tmp.set_all();
- return test_quick_select(thd, tmp, 0, limit, force_quick_range, FALSE, FALSE) < 0;
+ return test_quick_select(thd, tmp, 0, limit, force_quick_range,
+ FALSE, FALSE, FALSE) < 0;
}
/*
RETURN
@@ -1662,7 +1663,8 @@ class SQL_SELECT :public Sql_alloc {
}
int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
ha_rows limit, bool force_quick_range,
- bool ordered_output, bool remove_false_parts_of_where);
+ bool ordered_output, bool remove_false_parts_of_where,
+ bool only_single_index_range_scan);
};
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 4f98153d752..211898f46d0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1606,7 +1606,7 @@ bool JOIN::make_range_rowid_filters()
tab->table->force_index= true;
(void) sel->test_quick_select(thd, filter_map, (table_map) 0,
(ha_rows) HA_POS_ERROR,
- true, false, true);
+ true, false, true, true);
tab->table->force_index= force_index_save;
if (thd->is_error())
goto no_filter;
@@ -4623,7 +4623,8 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
select->test_quick_select(thd, *(key_map *)keys,
(table_map) 0,
limit, 0, FALSE,
- TRUE /* remove_where_parts*/)) ==
+ TRUE, /* remove_where_parts*/
+ FALSE)) ==
1))
DBUG_RETURN(select->quick->records);
if (unlikely(error == -1))
@@ -11356,7 +11357,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
OPTION_FOUND_ROWS ?
HA_POS_ERROR :
join->unit->select_limit_cnt), 0,
- FALSE, FALSE) < 0)
+ FALSE, FALSE, FALSE) < 0)
{
/*
Before reporting "Impossible WHERE" for the whole query
@@ -11370,7 +11371,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
OPTION_FOUND_ROWS ?
HA_POS_ERROR :
join->unit->select_limit_cnt),0,
- FALSE, FALSE) < 0)
+ FALSE, FALSE, FALSE) < 0)
DBUG_RETURN(1); // Impossible WHERE
}
else
@@ -20899,7 +20900,8 @@ test_if_quick_select(JOIN_TAB *tab)
int res= tab->select->test_quick_select(tab->join->thd, tab->keys,
(table_map) 0, HA_POS_ERROR, 0,
- FALSE, /*remove where parts*/FALSE);
+ FALSE, /*remove where parts*/FALSE,
+ FALSE);
if (tab->explain_plan && tab->explain_plan->range_checked_fer)
tab->explain_plan->range_checked_fer->collect_data(tab->select->quick);
@@ -22763,9 +22765,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
res= select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
(tab->join->select_options &
OPTION_FOUND_ROWS) ?
- HA_POS_ERROR :
- tab->join->unit->select_limit_cnt,TRUE,
- TRUE, FALSE) <= 0;
+ HA_POS_ERROR :
+ tab->join->unit->select_limit_cnt,TRUE,
+ TRUE, FALSE, FALSE) <= 0;
if (res)
{
select->cond= save_cond;
@@ -22867,7 +22869,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
join->select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR :
join->unit->select_limit_cnt,
- TRUE, FALSE, FALSE);
+ TRUE, FALSE, FALSE, FALSE);
if (cond_saved)
select->cond= saved_cond;