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,
|
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
||||||
Filesort_tracker* tracker)
|
Filesort_tracker* tracker, JOIN *join,
|
||||||
|
table_map first_table_bit)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
size_t memory_available= thd->variables.sortbuff_size;
|
size_t memory_available= thd->variables.sortbuff_size;
|
||||||
@ -154,7 +155,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
|||||||
|
|
||||||
DBUG_ENTER("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_RETURN(NULL); /* purecov: inspected */
|
||||||
|
|
||||||
DBUG_EXECUTE("info",TEST_filesort(filesort->sortorder,s_length););
|
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;
|
uint count;
|
||||||
SORT_FIELD *sort,*pos;
|
SORT_FIELD *sort,*pos;
|
||||||
@ -458,7 +459,30 @@ uint Filesort::make_sortorder(THD *thd)
|
|||||||
|
|
||||||
for (ord= order; ord; ord= ord->next, pos++)
|
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;
|
pos->field= 0; pos->item= 0;
|
||||||
if (item->type() == Item::FIELD_ITEM)
|
if (item->type() == Item::FIELD_ITEM)
|
||||||
pos->field= ((Item_field*) item)->field;
|
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_ASSERT(pos->field != NULL || pos->item != NULL);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(count);
|
DBUG_RETURN(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Read 'count' number of buffer pointers into memory. */
|
/** Read 'count' number of buffer pointers into memory. */
|
||||||
|
@ -26,6 +26,7 @@ struct TABLE;
|
|||||||
class Filesort_tracker;
|
class Filesort_tracker;
|
||||||
struct SORT_FIELD;
|
struct SORT_FIELD;
|
||||||
typedef struct st_order ORDER;
|
typedef struct st_order ORDER;
|
||||||
|
class JOIN;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +73,7 @@ public:
|
|||||||
|
|
||||||
~Filesort() { cleanup(); }
|
~Filesort() { cleanup(); }
|
||||||
/* Prepare ORDER BY list for sorting. */
|
/* Prepare ORDER BY list for sorting. */
|
||||||
uint make_sortorder(THD *thd);
|
uint make_sortorder(THD *thd, JOIN *join, table_map first_table_bit);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
@ -152,11 +153,13 @@ public:
|
|||||||
{ return filesort_buffer.sort_buffer_size(); }
|
{ return filesort_buffer.sort_buffer_size(); }
|
||||||
|
|
||||||
friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
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,
|
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);
|
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)
|
if (table->s->tmp_table)
|
||||||
table->file->info(HA_STATUS_VARIABLE); // Get record count
|
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);
|
DBUG_ASSERT(tab->filesort_result == 0);
|
||||||
tab->filesort_result= file_sort;
|
tab->filesort_result= file_sort;
|
||||||
tab->records= 0;
|
tab->records= 0;
|
||||||
|
Reference in New Issue
Block a user