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:
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user