1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-8989 ORDER BY optimizer ignores equality propagation

Restore the fix from the commit 99cd5a9 that was lost in a merge.
This commit is contained in:
Sergei Golubchik
2016-07-01 16:44:17 +02:00
parent 76f492e26d
commit ffac85482b
3 changed files with 36 additions and 9 deletions

View File

@ -137,7 +137,8 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table,
*/
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
Filesort_tracker* tracker)
Filesort_tracker* tracker, JOIN *join,
table_map first_table_bit)
{
int error;
size_t memory_available= thd->variables.sortbuff_size;
@ -154,7 +155,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
DBUG_ENTER("filesort");
if (!(s_length= filesort->make_sortorder(thd)))
if (!(s_length= filesort->make_sortorder(thd, join, first_table_bit)))
DBUG_RETURN(NULL); /* purecov: inspected */
DBUG_EXECUTE("info",TEST_filesort(filesort->sortorder,s_length););
@ -438,7 +439,7 @@ void Filesort::cleanup()
}
uint Filesort::make_sortorder(THD *thd)
uint Filesort::make_sortorder(THD *thd, JOIN *join, table_map first_table_bit)
{
uint count;
SORT_FIELD *sort,*pos;
@ -458,7 +459,30 @@ uint Filesort::make_sortorder(THD *thd)
for (ord= order; ord; ord= ord->next, pos++)
{
Item *item= ord->item[0]->real_item();
Item *first= ord->item[0];
/*
It is possible that the query plan is to read table t1, while the
sort criteria actually has "ORDER BY t2.col" and the WHERE clause has
a multi-equality(t1.col, t2.col, ...).
The optimizer detects such cases (grep for
UseMultipleEqualitiesToRemoveTempTable to see where), but doesn't
perform equality substitution in the order->item. We need to do the
substitution here ourselves.
*/
table_map item_map= first->used_tables();
if (join && (item_map & ~join->const_table_map) &&
!(item_map & first_table_bit) && join->cond_equal &&
first->get_item_equal())
{
/*
Ok, this is the case descibed just above. Get the first element of the
multi-equality.
*/
Item_equal *item_eq= first->get_item_equal();
first= item_eq->get_first(NO_PARTICULAR_TAB, NULL);
}
Item *item= first->real_item();
pos->field= 0; pos->item= 0;
if (item->type() == Item::FIELD_ITEM)
pos->field= ((Item_field*) item)->field;
@ -474,7 +498,7 @@ uint Filesort::make_sortorder(THD *thd)
DBUG_ASSERT(pos->field != NULL || pos->item != NULL);
}
DBUG_RETURN(count);
}
}
/** Read 'count' number of buffer pointers into memory. */

View File

@ -26,6 +26,7 @@ struct TABLE;
class Filesort_tracker;
struct SORT_FIELD;
typedef struct st_order ORDER;
class JOIN;
/**
@ -72,7 +73,7 @@ public:
~Filesort() { cleanup(); }
/* Prepare ORDER BY list for sorting. */
uint make_sortorder(THD *thd);
uint make_sortorder(THD *thd, JOIN *join, table_map first_table_bit);
private:
void cleanup();
@ -152,11 +153,13 @@ public:
{ return filesort_buffer.sort_buffer_size(); }
friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
Filesort_tracker* tracker);
Filesort_tracker* tracker, JOIN *join,
table_map first_table_bit);
};
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
Filesort_tracker* tracker);
Filesort_tracker* tracker, JOIN *join=NULL,
table_map first_table_bit=0);
void change_double_for_sort(double nr,uchar *to);

View File

@ -21427,7 +21427,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort)
if (table->s->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
file_sort= filesort(thd, table, fsort, fsort->tracker);
file_sort= filesort(thd, table, fsort, fsort->tracker, join, tab->table->map);
DBUG_ASSERT(tab->filesort_result == 0);
tab->filesort_result= file_sort;
tab->records= 0;