Bug#16394084: LOOSE INDEX SCAN WITH QUOTED INT PREDICATE
RETURNS RANDOM DATA MySQL 5.5 specific version of bugfix. When Loose Index Scan Range access is used, MySQL execution needs to copy non-aggregated fields. end_send() checked if this was necessary by checking if join_tab->select->quick had type QS_TYPE_GROUP_MIN_MAX. In this bug, however, MySQL created a sort index to sort the rows read from this range access method. create_sort_index() deletes join_tab->select->quick which makes it impossible to inquire the join_tab if LIS has been used. The fix for MySQL 5.5 is to introduce a variable in JOIN_TAB that stores whether or not LIS has been used. There is no need for this variable in later MySQL versions because the relevant code has been refactored.
This commit is contained in:
parent
57129a3a4b
commit
015c320a75
@ -2713,6 +2713,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
||||
s->const_keys.init();
|
||||
s->checked_keys.init();
|
||||
s->needed_reg.init();
|
||||
s->filesort_used_loose_index_scan= false;
|
||||
s->filesort_used_loose_index_scan_agg_distinct= false;
|
||||
table_vector[i]=s->table=table=tables->table;
|
||||
table->pos_in_table_list= tables;
|
||||
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||
@ -6163,6 +6165,8 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
|
||||
join_tab->read_first_record= join_init_read_record;
|
||||
join_tab->join= this;
|
||||
join_tab->ref.key_parts= 0;
|
||||
join_tab->filesort_used_loose_index_scan= false;
|
||||
join_tab->filesort_used_loose_index_scan_agg_distinct= false;
|
||||
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
|
||||
temp_table->status=0;
|
||||
temp_table->null_row=0;
|
||||
@ -14240,6 +14244,17 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
tablesort_result_cache= table->sort.io_cache;
|
||||
table->sort.io_cache= NULL;
|
||||
|
||||
if (select->quick &&
|
||||
select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
|
||||
{
|
||||
tab->filesort_used_loose_index_scan= true;
|
||||
|
||||
QUICK_GROUP_MIN_MAX_SELECT *minmax_quick=
|
||||
static_cast<QUICK_GROUP_MIN_MAX_SELECT*>(select->quick);
|
||||
if (minmax_quick->is_agg_distinct())
|
||||
tab->filesort_used_loose_index_scan_agg_distinct= true;
|
||||
}
|
||||
|
||||
/*
|
||||
If a quick object was created outside of create_sort_index()
|
||||
that might be reused, then do not call select->cleanup() since
|
||||
|
@ -243,16 +243,40 @@ typedef struct st_join_table {
|
||||
nested_join_map embedding_map;
|
||||
|
||||
void cleanup();
|
||||
/*
|
||||
In cases where filesort reads rows from a table using Loose Index
|
||||
Scan, the fact that LIS was used is lost because
|
||||
create_sort_index() deletes join_tab->select->quick. MySQL needs
|
||||
this information during JOIN::exec().
|
||||
|
||||
This variable is a hack for MySQL 5.5 only. A value of true means
|
||||
that filesort used LIS to read from the table. In MySQL 5.6 and
|
||||
later, join_tab->filesort is a separate structure with it's own
|
||||
select that can be inquired to get the same information. There is
|
||||
no need for this variable in MySQL 5.6 and later.
|
||||
*/
|
||||
bool filesort_used_loose_index_scan;
|
||||
/*
|
||||
Similar hack as for filesort_used_loose_index_scan. Not needed for
|
||||
MySQL 5.6 and later.
|
||||
*/
|
||||
bool filesort_used_loose_index_scan_agg_distinct;
|
||||
inline bool is_using_loose_index_scan()
|
||||
{
|
||||
return (select && select->quick &&
|
||||
(select->quick->get_type() ==
|
||||
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
|
||||
return (filesort_used_loose_index_scan ||
|
||||
(select && select->quick &&
|
||||
(select->quick->get_type() ==
|
||||
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
|
||||
);
|
||||
}
|
||||
bool is_using_agg_loose_index_scan ()
|
||||
{
|
||||
return (is_using_loose_index_scan() &&
|
||||
((QUICK_GROUP_MIN_MAX_SELECT *)select->quick)->is_agg_distinct());
|
||||
return (filesort_used_loose_index_scan_agg_distinct ||
|
||||
(select && select->quick &&
|
||||
(select->quick->get_type() ==
|
||||
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) &&
|
||||
((QUICK_GROUP_MIN_MAX_SELECT *)select->quick)->is_agg_distinct())
|
||||
);
|
||||
}
|
||||
} JOIN_TAB;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user