mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge branch '11.0' into 11.1
This commit is contained in:
@@ -141,9 +141,10 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b);
|
||||
static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables);
|
||||
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
bool allow_full_scan, table_map used_tables);
|
||||
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
|
||||
static bool get_quick_record_count(THD *thd, SQL_SELECT *select,
|
||||
TABLE *table,
|
||||
const key_map *keys,ha_rows limit);
|
||||
const key_map *keys,ha_rows limit,
|
||||
ha_rows *quick_count);
|
||||
static void optimize_straight_join(JOIN *join, table_map join_tables);
|
||||
static bool greedy_search(JOIN *join, table_map remaining_tables,
|
||||
uint depth, uint use_cond_selectivity);
|
||||
@@ -241,8 +242,8 @@ static int join_read_last_key(JOIN_TAB *tab);
|
||||
static int join_no_more_records(READ_RECORD *info);
|
||||
static int join_read_next(READ_RECORD *info);
|
||||
static int join_init_quick_read_record(JOIN_TAB *tab);
|
||||
static int test_if_quick_select(JOIN_TAB *tab);
|
||||
static bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab);
|
||||
static quick_select_return test_if_quick_select(JOIN_TAB *tab);
|
||||
static int test_if_use_dynamic_range_scan(JOIN_TAB *join_tab);
|
||||
static int join_read_first(JOIN_TAB *tab);
|
||||
static int join_read_next(READ_RECORD *info);
|
||||
static int join_read_next_same(READ_RECORD *info);
|
||||
@@ -279,7 +280,8 @@ static bool test_if_cheaper_ordering(const JOIN_TAB *tab,
|
||||
static int test_if_order_by_key(JOIN *, ORDER *, TABLE *, uint, uint *);
|
||||
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
|
||||
ha_rows select_limit, bool no_changes,
|
||||
const key_map *map);
|
||||
const key_map *map,
|
||||
bool *fatal_error);
|
||||
static bool list_contains_unique_index(TABLE *table,
|
||||
bool (*find_func) (Field *, void *), void *data);
|
||||
static bool find_field_in_item_list (Field *field, void *data);
|
||||
@@ -1974,7 +1976,8 @@ int JOIN::optimize()
|
||||
object a pointer to which is set in the field JOIN_TAB::rowid_filter of
|
||||
the joined table.
|
||||
|
||||
@retval false always
|
||||
@retval false Ok
|
||||
@retval true Error
|
||||
*/
|
||||
|
||||
bool JOIN::make_range_rowid_filters()
|
||||
@@ -2015,17 +2018,20 @@ bool JOIN::make_range_rowid_filters()
|
||||
filter_map.clear_all();
|
||||
filter_map.set_bit(tab->range_rowid_filter_info->get_key_no());
|
||||
filter_map.merge(tab->table->with_impossible_ranges);
|
||||
int rc= sel->test_quick_select(thd, filter_map, (table_map) 0,
|
||||
(ha_rows) HA_POS_ERROR,
|
||||
true /* force index */, false, true, true);
|
||||
if (thd->is_error())
|
||||
goto no_filter;
|
||||
quick_select_return rc;
|
||||
rc= sel->test_quick_select(thd, filter_map, (table_map) 0,
|
||||
(ha_rows) HA_POS_ERROR, true, false, true,
|
||||
true);
|
||||
if (rc == SQL_SELECT::ERROR || thd->is_error())
|
||||
{
|
||||
DBUG_RETURN(true); /* Fatal error */
|
||||
}
|
||||
/*
|
||||
If SUBS_IN_TO_EXISTS strtrategy is chosen for the subquery then
|
||||
additional conditions are injected into WHERE/ON/HAVING and it may
|
||||
happen that the call of test_quick_select() discovers impossible range.
|
||||
*/
|
||||
if (rc == -1)
|
||||
if (rc == SQL_SELECT::IMPOSSIBLE_RANGE)
|
||||
{
|
||||
const_table_map|= tab->table->map;
|
||||
goto no_filter;
|
||||
@@ -3050,20 +3056,29 @@ int JOIN::optimize_stage2()
|
||||
tab= &join_tab[const_tables];
|
||||
if (order)
|
||||
{
|
||||
bool fatal_err;
|
||||
skip_sort_order=
|
||||
test_if_skip_sort_order(tab, order, select_limit,
|
||||
true, // no_changes
|
||||
&tab->table->keys_in_use_for_order_by);
|
||||
&tab->table->keys_in_use_for_order_by,
|
||||
&fatal_err);
|
||||
if (fatal_err)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
|
||||
order, fields_list, all_fields,
|
||||
&all_order_fields_used)))
|
||||
{
|
||||
bool fatal_err= 0;
|
||||
const bool skip_group=
|
||||
skip_sort_order &&
|
||||
test_if_skip_sort_order(tab, group_list, select_limit,
|
||||
true, // no_changes
|
||||
&tab->table->keys_in_use_for_group_by);
|
||||
true, // no_changes
|
||||
&tab->table->keys_in_use_for_group_by,
|
||||
&fatal_err);
|
||||
if (fatal_err)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
count_field_types(select_lex, &tmp_table_param, all_fields, 0);
|
||||
if ((skip_group && all_order_fields_used) ||
|
||||
select_limit == HA_POS_ERROR ||
|
||||
@@ -3328,12 +3343,16 @@ int JOIN::optimize_stage2()
|
||||
'need_tmp' implies that there will be more postprocessing
|
||||
so the specified 'limit' should not be enforced yet.
|
||||
*/
|
||||
bool fatal_err;
|
||||
const ha_rows limit = need_tmp ? HA_POS_ERROR : select_limit;
|
||||
if (test_if_skip_sort_order(tab, group_list, limit, false,
|
||||
&tab->table->keys_in_use_for_group_by))
|
||||
&tab->table->keys_in_use_for_group_by,
|
||||
&fatal_err))
|
||||
{
|
||||
ordered_index_usage= ordered_index_group_by;
|
||||
}
|
||||
if (fatal_err)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3356,11 +3375,15 @@ int JOIN::optimize_stage2()
|
||||
else if (order && // ORDER BY wo/ preceding GROUP BY
|
||||
(simple_order || skip_sort_order)) // which is possibly skippable
|
||||
{
|
||||
bool fatal_err;
|
||||
if (test_if_skip_sort_order(tab, order, select_limit, false,
|
||||
&tab->table->keys_in_use_for_order_by))
|
||||
&tab->table->keys_in_use_for_order_by,
|
||||
&fatal_err))
|
||||
{
|
||||
ordered_index_usage= ordered_index_order_by;
|
||||
}
|
||||
if (fatal_err)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5281,50 +5304,70 @@ err:
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Create JOIN_TABS, make a guess about the table types,
|
||||
Approximate how many records will be used in each table
|
||||
*****************************************************************************/
|
||||
/**
|
||||
Approximate how many records are going to be returned by this table in this
|
||||
select with this key.
|
||||
|
||||
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
|
||||
@param thd Thread handle
|
||||
@param select Select to be examined
|
||||
@param table The table of interest
|
||||
@param keys The keys of interest
|
||||
@param limit Maximum number of rows of interest
|
||||
@param quick_count Pointer to where we want the estimate written
|
||||
|
||||
@return Status
|
||||
@retval false Success
|
||||
@retval true Error
|
||||
|
||||
*/
|
||||
static bool get_quick_record_count(THD *thd, SQL_SELECT *select,
|
||||
TABLE *table,
|
||||
const key_map *keys,ha_rows limit)
|
||||
const key_map *keys,ha_rows limit,
|
||||
ha_rows *quick_count)
|
||||
{
|
||||
int error;
|
||||
quick_select_return error;
|
||||
DBUG_ENTER("get_quick_record_count");
|
||||
uchar buff[STACK_BUFF_ALLOC];
|
||||
if (unlikely(check_stack_overrun(thd, STACK_MIN_SIZE, buff)))
|
||||
DBUG_RETURN(0); // Fatal error flag is set
|
||||
DBUG_RETURN(false); // Fatal error flag is set
|
||||
if (select)
|
||||
{
|
||||
{
|
||||
select->head=table;
|
||||
table->reginfo.impossible_range=0;
|
||||
if (likely((error=
|
||||
select->test_quick_select(thd, *(key_map *)keys,
|
||||
(table_map) 0,
|
||||
limit, 0, FALSE,
|
||||
TRUE, /* remove_where_parts*/
|
||||
FALSE, TRUE)) ==
|
||||
1))
|
||||
error= select->test_quick_select(thd, *(key_map *)keys, (table_map) 0,
|
||||
limit, 0, FALSE,
|
||||
TRUE, /* remove_where_parts*/
|
||||
FALSE, TRUE);
|
||||
|
||||
if (error == SQL_SELECT::OK)
|
||||
{
|
||||
/*
|
||||
opt_range_condition_rows was updated in test_quick_select to be
|
||||
the smallest number of rows in any range.
|
||||
select->quick->records is the number of rows in range with
|
||||
smallest cost.
|
||||
*/
|
||||
DBUG_ASSERT(select->quick->records >=
|
||||
table->opt_range_condition_rows);
|
||||
DBUG_RETURN(table->opt_range_condition_rows);
|
||||
if (select->quick)
|
||||
{
|
||||
/*
|
||||
opt_range_condition_rows was updated in test_quick_select to be
|
||||
the smallest number of rows in any range.
|
||||
select->quick->records is the number of rows in range with
|
||||
smallest cost.
|
||||
*/
|
||||
DBUG_ASSERT(select->quick->records >=
|
||||
table->opt_range_condition_rows);
|
||||
*quick_count= select->quick->records;
|
||||
}
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (unlikely(error == -1))
|
||||
if (error == SQL_SELECT::IMPOSSIBLE_RANGE)
|
||||
{
|
||||
table->reginfo.impossible_range=1;
|
||||
DBUG_RETURN(0);
|
||||
*quick_count= 0;
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (unlikely(error == SQL_SELECT::ERROR))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
DBUG_PRINT("warning",("Couldn't use record count on const keypart"));
|
||||
}
|
||||
DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */
|
||||
*quick_count= HA_POS_ERROR;
|
||||
DBUG_RETURN(false); /* This shouldn't happen */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5484,6 +5527,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
|
||||
/* The following should be optimized to only clear critical things */
|
||||
bzero((void*)stat, sizeof(JOIN_TAB)* table_count);
|
||||
join->top_join_tab_count= table_count;
|
||||
|
||||
/* Initialize POSITION objects */
|
||||
for (i=0 ; i <= table_count ; i++)
|
||||
@@ -6066,11 +6110,10 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
(SORT_INFO*) 0, 1, &error);
|
||||
if (!select)
|
||||
goto error;
|
||||
records= get_quick_record_count(join->thd, select, s->table,
|
||||
&s->const_keys, join->row_limit);
|
||||
if (join->thd->is_error())
|
||||
if (get_quick_record_count(join->thd, select, s->table,
|
||||
&s->const_keys, join->row_limit, &records))
|
||||
{
|
||||
/* get_quick_record_count generated an error */
|
||||
/* There was an error in test_quick_select */
|
||||
delete select;
|
||||
goto error;
|
||||
}
|
||||
@@ -6087,8 +6130,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
join->cond_equal= &((Item_cond_and*) (join->conds))->m_cond_equal;
|
||||
|
||||
s->quick=select->quick;
|
||||
s->needed_reg=select->needed_reg;
|
||||
select->quick=0;
|
||||
s->needed_reg=select->needed_reg;
|
||||
impossible_range= records == 0 && s->table->reginfo.impossible_range;
|
||||
if (optimizer_flag(join->thd, OPTIMIZER_SWITCH_USE_ROWID_FILTER))
|
||||
s->table->init_cost_info_for_usable_range_rowid_filters(join->thd);
|
||||
@@ -14032,15 +14075,18 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
*/
|
||||
if (sel->cond && !sel->cond->fixed())
|
||||
sel->cond->quick_fix_field();
|
||||
quick_select_return res;
|
||||
|
||||
if (sel->test_quick_select(thd, tab->keys,
|
||||
((used_tables & ~ current_map) |
|
||||
OUTER_REF_TABLE_BIT),
|
||||
(join->select_options &
|
||||
OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->lim.get_select_limit()), 0,
|
||||
FALSE, FALSE, FALSE) < 0)
|
||||
if ((res= sel->test_quick_select(thd, tab->keys,
|
||||
((used_tables & ~ current_map) |
|
||||
OUTER_REF_TABLE_BIT),
|
||||
(join->select_options &
|
||||
OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->lim.get_select_limit()),
|
||||
0,
|
||||
FALSE, FALSE, FALSE)) ==
|
||||
SQL_SELECT::IMPOSSIBLE_RANGE)
|
||||
{
|
||||
/*
|
||||
Before reporting "Impossible WHERE" for the whole query
|
||||
@@ -14048,18 +14094,22 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
*/
|
||||
sel->cond=orig_cond;
|
||||
if (!*tab->on_expr_ref ||
|
||||
sel->test_quick_select(thd, tab->keys,
|
||||
used_tables & ~ current_map,
|
||||
(join->select_options &
|
||||
OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->lim.get_select_limit()),0,
|
||||
FALSE, FALSE, FALSE, TRUE) < 0)
|
||||
(res= sel->test_quick_select(thd, tab->keys,
|
||||
used_tables & ~ current_map,
|
||||
(join->select_options &
|
||||
OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->lim.get_select_limit()),
|
||||
0, FALSE, FALSE, FALSE, TRUE)) ==
|
||||
SQL_SELECT::IMPOSSIBLE_RANGE)
|
||||
DBUG_RETURN(1); // Impossible WHERE
|
||||
}
|
||||
else
|
||||
sel->cond=orig_cond;
|
||||
|
||||
if (res == SQL_SELECT::ERROR)
|
||||
DBUG_RETURN(1); /* Some error in one of test_quick_select calls */
|
||||
|
||||
/* Fix for EXPLAIN */
|
||||
if (sel->quick)
|
||||
{
|
||||
@@ -15792,12 +15842,17 @@ bool error_if_full_join(JOIN *join)
|
||||
build_range_rowid_filter()
|
||||
|
||||
Build range rowid filter. This function should only be called if
|
||||
need_to_build_rowid_filter
|
||||
is true
|
||||
need_to_build_rowid_filter is true
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 Error, transaction should be rolled back
|
||||
*/
|
||||
|
||||
void JOIN_TAB::build_range_rowid_filter()
|
||||
bool JOIN_TAB::build_range_rowid_filter()
|
||||
{
|
||||
|
||||
DBUG_ASSERT(need_to_build_rowid_filter && rowid_filter);
|
||||
|
||||
/**
|
||||
@@ -15813,8 +15868,8 @@ void JOIN_TAB::build_range_rowid_filter()
|
||||
Rowid_filter_tracker *rowid_tracker= rowid_filter->get_tracker();
|
||||
table->file->set_time_tracker(rowid_tracker->get_time_tracker());
|
||||
rowid_tracker->start_tracking(join->thd);
|
||||
|
||||
if (rowid_filter->build())
|
||||
Rowid_filter::build_return_code build_rc= rowid_filter->build();
|
||||
if (build_rc != Rowid_filter::SUCCESS)
|
||||
{
|
||||
/* Failed building rowid filter */
|
||||
clear_range_rowid_filter();
|
||||
@@ -15822,9 +15877,11 @@ void JOIN_TAB::build_range_rowid_filter()
|
||||
need_to_build_rowid_filter= false;
|
||||
rowid_tracker->stop_tracking(join->thd);
|
||||
table->file->set_time_tracker(table_tracker);
|
||||
return (build_rc == Rowid_filter::FATAL_ERROR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Clear used rowid filter
|
||||
|
||||
@@ -15898,7 +15955,6 @@ void JOIN_TAB::cleanup()
|
||||
*/
|
||||
table->pos_in_table_list->table= NULL;
|
||||
free_tmp_table(join->thd, table);
|
||||
table= NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -15911,8 +15967,8 @@ void JOIN_TAB::cleanup()
|
||||
multiple times (it may be)
|
||||
*/
|
||||
tmp->table= NULL;
|
||||
table= NULL;
|
||||
}
|
||||
table= NULL;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/*if (table->pos_in_table_list && table->pos_in_table_list->derived)
|
||||
@@ -17275,7 +17331,8 @@ bool check_simple_equality(THD *thd, const Item::Context &ctx,
|
||||
Field *left_field= ((Item_field*) left_item)->field;
|
||||
Field *right_field= ((Item_field*) right_item)->field;
|
||||
|
||||
if (!left_field->eq_def(right_field))
|
||||
if (!left_field->eq_def(right_field) &&
|
||||
!fields_equal_using_narrowing(thd, left_field, right_field))
|
||||
return FALSE;
|
||||
|
||||
/* Search for multiple equalities containing field1 and/or field2 */
|
||||
@@ -23244,6 +23301,7 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
{
|
||||
enum_nested_loop_state rc;
|
||||
JOIN_CACHE *cache= join_tab->cache;
|
||||
int err;
|
||||
DBUG_ENTER("sub_select_cache");
|
||||
|
||||
/*
|
||||
@@ -23269,7 +23327,7 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
}
|
||||
join_tab->jbuf_loops_tracker->on_scan_init();
|
||||
|
||||
if (!test_if_use_dynamic_range_scan(join_tab))
|
||||
if (!(err= test_if_use_dynamic_range_scan(join_tab)))
|
||||
{
|
||||
if (!cache->put_record())
|
||||
DBUG_RETURN(NESTED_LOOP_OK);
|
||||
@@ -23281,6 +23339,10 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
rc= cache->join_records(FALSE);
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||
|
||||
/*
|
||||
TODO: Check whether we really need the call below and we can't do
|
||||
without it. If it's not the case remove it.
|
||||
@@ -23463,7 +23525,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
|
||||
{
|
||||
if (unlikely(join_tab->need_to_build_rowid_filter))
|
||||
{
|
||||
join_tab->build_range_rowid_filter();
|
||||
if (join_tab->build_range_rowid_filter())
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||
/*
|
||||
We have to check join_tab->rowid_filter again as the above
|
||||
function may have cleared it in case of errors.
|
||||
@@ -24401,8 +24464,18 @@ join_read_prev_same(READ_RECORD *info)
|
||||
static int
|
||||
join_init_quick_read_record(JOIN_TAB *tab)
|
||||
{
|
||||
if (test_if_quick_select(tab) == -1)
|
||||
return -1; /* No possible records */
|
||||
quick_select_return res= test_if_quick_select(tab);
|
||||
|
||||
if (res == SQL_SELECT::ERROR)
|
||||
return 1; /* Fatal error */
|
||||
|
||||
if (res == SQL_SELECT::IMPOSSIBLE_RANGE)
|
||||
return -1; /* No possible records */
|
||||
|
||||
/*
|
||||
Proceed to read rows. If we've created a quick select, use it, otherwise
|
||||
do a full scan.
|
||||
*/
|
||||
return join_init_read_record(tab);
|
||||
}
|
||||
|
||||
@@ -24414,7 +24487,13 @@ int read_first_record_seq(JOIN_TAB *tab)
|
||||
return tab->read_record.read_record();
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
/*
|
||||
@brief
|
||||
Create a new (dynamic) quick select.
|
||||
*/
|
||||
|
||||
static quick_select_return
|
||||
test_if_quick_select(JOIN_TAB *tab)
|
||||
{
|
||||
DBUG_EXECUTE_IF("show_explain_probe_test_if_quick_select",
|
||||
@@ -24431,11 +24510,11 @@ test_if_quick_select(JOIN_TAB *tab)
|
||||
if (tab->table->file->inited != handler::NONE)
|
||||
tab->table->file->ha_index_or_rnd_end();
|
||||
|
||||
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,
|
||||
/* no warnings */ TRUE);
|
||||
quick_select_return res;
|
||||
res= tab->select->test_quick_select(tab->join->thd, tab->keys,
|
||||
(table_map) 0, HA_POS_ERROR, 0,
|
||||
FALSE, /*remove where parts*/FALSE,
|
||||
FALSE, /* no warnings */ TRUE);
|
||||
if (tab->explain_plan && tab->explain_plan->range_checked_fer)
|
||||
tab->explain_plan->range_checked_fer->collect_data(tab->select->quick);
|
||||
|
||||
@@ -24443,10 +24522,29 @@ test_if_quick_select(JOIN_TAB *tab)
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab)
|
||||
/*
|
||||
@return
|
||||
1 - Yes, use dynamically built range
|
||||
0 - No, don't use dynamic range (but there's no error)
|
||||
-1 - Fatal error
|
||||
*/
|
||||
|
||||
static
|
||||
int test_if_use_dynamic_range_scan(JOIN_TAB *join_tab)
|
||||
{
|
||||
return (join_tab->use_quick == 2 && test_if_quick_select(join_tab) > 0);
|
||||
if (unlikely(join_tab->use_quick == 2))
|
||||
{
|
||||
quick_select_return res= test_if_quick_select(join_tab);
|
||||
if (res == SQL_SELECT::ERROR)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
/* Both OK and IMPOSSIBLE_RANGE go here */
|
||||
return join_tab->select->quick ? 1 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24468,7 +24566,10 @@ int join_init_read_record(JOIN_TAB *tab)
|
||||
}
|
||||
|
||||
if (tab->need_to_build_rowid_filter)
|
||||
tab->build_range_rowid_filter();
|
||||
{
|
||||
if (tab->build_range_rowid_filter())
|
||||
return 1; /* Fatal error */
|
||||
}
|
||||
|
||||
if (tab->filesort && tab->sort_table()) // Sort table.
|
||||
return 1;
|
||||
@@ -26293,7 +26394,8 @@ void compute_part_of_sort_key_for_equals(JOIN *join, TABLE *table,
|
||||
|
||||
The index must cover all fields in <order>, or it will not be considered.
|
||||
|
||||
@param no_changes No changes will be made to the query plan.
|
||||
@param no_changes No changes will be made to the query plan.
|
||||
@param fatal_error OUT A fatal error occurred
|
||||
|
||||
@todo
|
||||
- sergeyp: Results of all index merge selects actually are ordered
|
||||
@@ -26307,7 +26409,7 @@ void compute_part_of_sort_key_for_equals(JOIN *join, TABLE *table,
|
||||
|
||||
static bool
|
||||
test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
bool no_changes, const key_map *map)
|
||||
bool no_changes, const key_map *map, bool *fatal_error)
|
||||
{
|
||||
int ref_key;
|
||||
uint UNINIT_VAR(ref_key_parts);
|
||||
@@ -26321,11 +26423,25 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
bool orig_cond_saved= false;
|
||||
int best_key= -1;
|
||||
bool changed_key= false;
|
||||
THD *thd= tab->join->thd;
|
||||
Json_writer_object trace_wrapper(thd);
|
||||
Json_writer_array trace_arr(thd, "test_if_skip_sort_order");
|
||||
DBUG_ENTER("test_if_skip_sort_order");
|
||||
|
||||
*fatal_error= false;
|
||||
/* Check that we are always called with first non-const table */
|
||||
DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables);
|
||||
|
||||
/* Sorting a single row can always be skipped */
|
||||
if (tab->type == JT_EQ_REF ||
|
||||
tab->type == JT_CONST ||
|
||||
tab->type == JT_SYSTEM)
|
||||
{
|
||||
Json_writer_object trace_skip(thd);
|
||||
trace_skip.add("skipped", "single row access method");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/*
|
||||
Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
|
||||
been taken into account.
|
||||
@@ -26460,7 +26576,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
*/
|
||||
key_map new_ref_key_map;
|
||||
COND *save_cond;
|
||||
bool res;
|
||||
quick_select_return res;
|
||||
new_ref_key_map.clear_all(); // Force the creation of quick select
|
||||
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
|
||||
|
||||
@@ -26475,13 +26591,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
HA_POS_ERROR :
|
||||
tab->join->unit->
|
||||
lim.get_select_limit(),
|
||||
TRUE, TRUE, FALSE, FALSE) <= 0;
|
||||
if (res)
|
||||
TRUE, TRUE, FALSE, FALSE);
|
||||
// if we cannot use quick select
|
||||
if (res != SQL_SELECT::OK || !tab->select->quick)
|
||||
{
|
||||
if (res == SQL_SELECT::ERROR)
|
||||
*fatal_error= true;
|
||||
select->cond= save_cond;
|
||||
goto use_filesort;
|
||||
}
|
||||
DBUG_ASSERT(tab->select->quick);
|
||||
tab->type= JT_RANGE;
|
||||
tab->ref.key= -1;
|
||||
tab->ref.key_parts= 0;
|
||||
@@ -26572,11 +26690,17 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
cond_saved= true;
|
||||
}
|
||||
|
||||
select->test_quick_select(join->thd, tmp_map, 0,
|
||||
join->select_options & OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->lim.get_select_limit(),
|
||||
TRUE, FALSE, FALSE, FALSE);
|
||||
quick_select_return res;
|
||||
res = select->test_quick_select(join->thd, tmp_map, 0,
|
||||
join->select_options & OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->lim.get_select_limit(),
|
||||
TRUE, FALSE, FALSE, FALSE);
|
||||
if (res == SQL_SELECT::ERROR)
|
||||
{
|
||||
*fatal_error= true;
|
||||
goto use_filesort;
|
||||
}
|
||||
|
||||
if (cond_saved)
|
||||
select->cond= saved_cond;
|
||||
@@ -27415,12 +27539,15 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
|
||||
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
|
||||
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
|
||||
bool result= 0;
|
||||
key_part_map map= 1;
|
||||
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
for (store_key **copy=ref->key_copy ; *copy ; copy++)
|
||||
for (store_key **copy=ref->key_copy ; *copy ; copy++, map <<= 1)
|
||||
{
|
||||
while (map & ref->const_ref_part_map) // skip const ref parts
|
||||
map <<= 1; // no store_key objects for them
|
||||
if ((*copy)->copy(thd) & 1 ||
|
||||
(ref->null_rejecting && (*copy)->null_key))
|
||||
((ref->null_rejecting & map) && (*copy)->null_key))
|
||||
{
|
||||
result= 1;
|
||||
break;
|
||||
|
Reference in New Issue
Block a user