1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-04 01:23:45 +03:00

MDEV-8989: ORDER BY optimizer ignores equality propagation

Variant #4 of the fix.

Make ORDER BY optimization functions take into account multiple
equalities. This is done in several places:
- remove_const() checks whether we can sort the first table in the
  join, or we need to put rows into temp.table and then sort.
- test_if_order_by_key() checks whether there are indexes that
  can be used to produce the required ordering
- make_unireg_sortorder() constructs sort criteria for filesort.
This commit is contained in:
Sergei Petrunia
2016-05-23 21:15:01 +03:00
parent 9c9747fed3
commit 99cd5a962c
13 changed files with 414 additions and 21 deletions

View File

@ -607,7 +607,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort
1 SIMPLE t3 ref period period 4 test.t1.period 4181
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
id select_type table type possible_keys key key_len ref rows Extra

View File

@ -2987,3 +2987,144 @@ EXPLAIN SELECT id1 FROM t2 WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref id_23_date,id_234_date id_23_date 2 const,const 3 Using where
drop table t1,t2;
#
# MDEV-8989: ORDER BY optimizer ignores equality propagation
#
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(a int);
insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
create table t2 (
pk int primary key,
a int, b int,
filler char(200),
key(a)
);
insert into t2 select a, 1000-a, 1000-a, repeat('abc-',50) from t1 where a<200 limit 200;
create table t3 (
pk int primary key,
a int, b int,
filler char(200),
key(a)
);
insert into t3 select a, 1000-a, 1000-a, repeat('abc-',50) from t1;
insert into t3 select a+1000, 1000+a, 1000+a, repeat('abc-',50) from t1;
# The optimizer produces an order of 't2,t3' for this join
#
# Case #1 (from the bug report):
# Q1 can take advantage of t2.a to resolve ORDER BY limit w/o sorting
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index a a 5 NULL 5 Using where
1 SIMPLE t3 ref a a 5 test.t2.a 1
#
# This is Q2 which used to have "Using temporary; using filesort" but
# has the same query plan as Q1:
#
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index a a 5 NULL 5 Using where
1 SIMPLE t3 ref a a 5 test.t2.a 1
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 5;
pk a b pk a b
199 801 801 199 801 801
198 802 802 198 802 802
197 803 803 197 803 803
196 804 804 196 804 804
195 805 805 195 805 805
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 5;
pk a b pk a b
199 801 801 199 801 801
198 802 802 198 802 802
197 803 803 197 803 803
196 804 804 196 804 804
195 805 805 195 805 805
#
# Case #2: here, only "Using temporary" is removed. "Using filesort" remains.
#
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 25;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 200 Using where; Using filesort
1 SIMPLE t3 ref a a 5 test.t2.a 1
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 25;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 200 Using where; Using filesort
1 SIMPLE t3 ref a a 5 test.t2.a 1
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 25;
pk a b pk a b
199 801 801 199 801 801
198 802 802 198 802 802
197 803 803 197 803 803
196 804 804 196 804 804
195 805 805 195 805 805
194 806 806 194 806 806
193 807 807 193 807 807
192 808 808 192 808 808
191 809 809 191 809 809
190 810 810 190 810 810
189 811 811 189 811 811
188 812 812 188 812 812
187 813 813 187 813 813
186 814 814 186 814 814
185 815 815 185 815 815
184 816 816 184 816 816
183 817 817 183 817 817
182 818 818 182 818 818
181 819 819 181 819 819
180 820 820 180 820 820
179 821 821 179 821 821
178 822 822 178 822 822
177 823 823 177 823 823
176 824 824 176 824 824
175 825 825 175 825 825
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 25;
pk a b pk a b
199 801 801 199 801 801
198 802 802 198 802 802
197 803 803 197 803 803
196 804 804 196 804 804
195 805 805 195 805 805
194 806 806 194 806 806
193 807 807 193 807 807
192 808 808 192 808 808
191 809 809 191 809 809
190 810 810 190 810 810
189 811 811 189 811 811
188 812 812 188 812 812
187 813 813 187 813 813
186 814 814 186 814 814
185 815 815 185 815 815
184 816 816 184 816 816
183 817 817 183 817 817
182 818 818 182 818 818
181 819 819 181 819 819
180 820 820 180 820 820
179 821 821 179 821 821
178 822 822 178 822 822
177 823 823 177 823 823
176 824 824 176 824 824
175 825 825 175 825 825
#
# Case #3: single table access (the code that decides whether we need
# "Using temporary" is not invoked)
#
explain select * from t3 where b=a order by a limit 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 index NULL a 5 NULL 10 Using where
# This must not use filesort. The query plan should be like the query above:
explain select * from t3 where b=a order by b limit 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 index NULL a 5 NULL 10 Using where
drop table t0,t1,t2,t3;

View File

@ -603,7 +603,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort
1 SIMPLE t3 ref period period 4 test.t1.period 4181
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
id select_type table type possible_keys key key_len ref rows Extra

View File

@ -606,7 +606,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort
1 SIMPLE t3 ref period period 4 test.t1.period 4181
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
id select_type table type possible_keys key key_len ref rows Extra

View File

@ -606,7 +606,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort
1 SIMPLE t3 ref period period 4 test.t1.period 4181
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
id select_type table type possible_keys key key_len ref rows Extra

View File

@ -610,7 +610,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort
1 SIMPLE t3 ref period period 4 test.t1.period 4181
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
id select_type table type possible_keys key key_len ref rows Extra

View File

@ -607,7 +607,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort
1 SIMPLE t3 ref period period 4 test.t1.period 4181
explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
id select_type table type possible_keys key key_len ref rows Extra

View File

@ -1997,3 +1997,81 @@ EXPLAIN SELECT id1 FROM t2 WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4;
drop table t1,t2;
--echo #
--echo # MDEV-8989: ORDER BY optimizer ignores equality propagation
--echo #
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(a int);
insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
create table t2 (
pk int primary key,
a int, b int,
filler char(200),
key(a)
);
insert into t2 select a, 1000-a, 1000-a, repeat('abc-',50) from t1 where a<200 limit 200;
create table t3 (
pk int primary key,
a int, b int,
filler char(200),
key(a)
);
insert into t3 select a, 1000-a, 1000-a, repeat('abc-',50) from t1;
insert into t3 select a+1000, 1000+a, 1000+a, repeat('abc-',50) from t1;
--echo # The optimizer produces an order of 't2,t3' for this join
--echo #
--echo # Case #1 (from the bug report):
--echo # Q1 can take advantage of t2.a to resolve ORDER BY limit w/o sorting
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 5;
--echo #
--echo # This is Q2 which used to have "Using temporary; using filesort" but
--echo # has the same query plan as Q1:
--echo #
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 5;
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 5;
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 5;
--echo #
--echo # Case #2: here, only "Using temporary" is removed. "Using filesort" remains.
--echo #
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 25;
explain
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 25;
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t2.a limit 25;
select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b
from t2, t3 where t2.a=t3.a order by t3.a limit 25;
--echo #
--echo # Case #3: single table access (the code that decides whether we need
--echo # "Using temporary" is not invoked)
--echo #
explain select * from t3 where b=a order by a limit 10;
--echo # This must not use filesort. The query plan should be like the query above:
explain select * from t3 where b=a order by b limit 10;
drop table t0,t1,t2,t3;

View File

@ -499,7 +499,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
Filesort_tracker *fs_tracker=
thd->lex->explain->get_upd_del_plan()->filesort_tracker;
if (!(sortorder= make_unireg_sortorder(thd, order, &length, NULL)) ||
if (!(sortorder= make_unireg_sortorder(thd, NULL, 0, order, &length, NULL)) ||
(table->sort.found_records= filesort(thd, table, sortorder, length,
select, HA_POS_ERROR,
true,

View File

@ -12327,10 +12327,56 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue;
}
/*
UseMultipleEqualitiesToRemoveTempTable:
Can use multiple-equalities here to check that ORDER BY columns
can be used without tmp. table.
*/
bool can_subst_to_first_table= false;
if (first_is_base_table &&
order->item[0]->real_item()->type() == Item::FIELD_ITEM &&
join->cond_equal)
{
table_map first_table_bit=
join->join_tab[join->const_tables].table->map;
Item *item= order->item[0];
/*
We are using Context_identity below. This means only do
substitution when equality means
*/
Item *res= item->propagate_equal_fields(join->thd,
Value_source::
Context_identity(),
join->cond_equal);
if (res != item)
{
/* Substituted to a constant */
can_subst_to_first_table= true;
}
else
{
Item_equal *item_eq= item->get_item_equal();
if (item_eq)
{
Item *first= item_eq->get_first(NO_PARTICULAR_TAB, NULL);
if (first->const_item() || first->used_tables() ==
first_table_bit)
{
can_subst_to_first_table= true;
}
}
}
}
if (!can_subst_to_first_table)
{
*simple_order=0; // Must do a temp table to sort
}
}
}
}
/* Remove ORDER BY entries that we have seen before */
for (tmp_order= first_order;
tmp_order != order;
@ -20327,6 +20373,8 @@ part_of_refkey(TABLE *table,Field *field)
/**
Test if one can use the key to resolve ORDER BY.
@param join if not NULL, can use the join's top-level
multiple-equalities.
@param order Sort order
@param table Table to sort
@param idx Index to check
@ -20349,7 +20397,8 @@ part_of_refkey(TABLE *table,Field *field)
-1 Reverse key can be used
*/
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
static int test_if_order_by_key(JOIN *join,
ORDER *order, TABLE *table, uint idx,
uint *used_key_parts= NULL)
{
KEY_PART_INFO *key_part,*key_part_end;
@ -20372,7 +20421,8 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
for (; order ; order=order->next, const_key_parts>>=1)
{
Field *field=((Item_field*) (*order->item)->real_item())->field;
Item_field *item_field= ((Item_field*) (*order->item)->real_item());
Field *field= item_field->field;
int flag;
/*
@ -20414,6 +20464,17 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
DBUG_RETURN(0);
}
if (key_part->field != field)
{
/*
Check if there is a multiple equality that allows to infer that field
and key_part->field are equal
(see also: compute_part_of_sort_key_for_equals)
*/
if (item_field->item_equal &&
item_field->item_equal->contains(key_part->field))
field= key_part->field;
}
if (key_part->field != field || !field->part_of_sortkey.is_set(idx))
DBUG_RETURN(0);
@ -20541,7 +20602,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
table->key_info[nr].user_defined_key_parts >= ref_key_parts &&
is_subkey(table->key_info[nr].key_part, ref_key_part,
ref_key_part_end) &&
test_if_order_by_key(order, table, nr))
test_if_order_by_key(NULL, order, table, nr))
{
min_length= table->key_info[nr].key_length;
best= nr;
@ -20680,6 +20741,68 @@ find_field_in_item_list (Field *field, void *data)
}
/*
Fill *col_keys with a union of Field::part_of_sortkey of all fields
that belong to 'table' and are equal to 'item_field'.
*/
void compute_part_of_sort_key_for_equals(JOIN *join, TABLE *table,
Item_field *item_field,
key_map *col_keys)
{
col_keys->clear_all();
col_keys->merge(item_field->field->part_of_sortkey);
Item_equal *item_eq= NULL;
if (item_field->item_equal)
{
/*
The item_field is from ORDER structure, but it already has an item_equal
pointer set (UseMultipleEqualitiesToRemoveTempTable code have set it)
*/
item_eq= item_field->item_equal;
}
else
{
/*
Walk through join's muliple equalities and find the one that contains
item_field.
*/
if (!join->cond_equal)
return;
table_map needed_tbl_map= item_field->used_tables() | table->map;
List_iterator<Item_equal> li(join->cond_equal->current_level);
Item_equal *cur_item_eq;
while ((cur_item_eq= li++))
{
if ((cur_item_eq->used_tables() & needed_tbl_map) &&
cur_item_eq->contains(item_field->field))
{
item_eq= cur_item_eq;
item_field->item_equal= item_eq; // Save the pointer to our Item_equal.
break;
}
}
}
if (item_eq)
{
Item_equal_fields_iterator it(*item_eq);
Item *item;
/* Loop through other members that belong to table table */
while ((item= it++))
{
if (item->type() == Item::FIELD_ITEM &&
((Item_field*)item)->field->table == table)
{
col_keys->merge(((Item_field*)item)->field->part_of_sortkey);
}
}
}
}
/**
Test if we can skip the ORDER BY by using an index.
@ -20736,7 +20859,27 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
usable_keys.clear_all();
DBUG_RETURN(0);
}
usable_keys.intersect(((Item_field*) item)->field->part_of_sortkey);
/*
Take multiple-equalities into account. Suppose we have
ORDER BY col1, col10
and there are
multiple-equal(col1, col2, col3),
multiple-equal(col10, col11).
Then,
- when item=col1, we find the set of indexes that cover one of {col1,
col2, col3}
- when item=col10, we find the set of indexes that cover one of {col10,
col11}
And we compute an intersection of these sets to find set of indexes that
cover all ORDER BY components.
*/
key_map col_keys;
compute_part_of_sort_key_for_equals(tab->join, table, (Item_field*)item,
&col_keys);
usable_keys.intersect(col_keys);
if (usable_keys.is_clear_all())
goto use_filesort; // No usable keys
}
@ -20894,7 +21037,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
/* Check if we get the rows in requested sorted order by using the key */
if (usable_keys.is_set(ref_key) &&
(order_direction= test_if_order_by_key(order,table,ref_key,
(order_direction= test_if_order_by_key(tab->join, order,table,ref_key,
&used_key_parts)))
goto check_reverse_order;
}
@ -21274,8 +21417,11 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
for (ORDER *ord= join->order; ord; ord= ord->next)
length++;
if (!(join->sortorder=
make_unireg_sortorder(thd, order, &length, join->sortorder)))
make_unireg_sortorder(thd, join, tab->table->map, order, &length,
join->sortorder)))
{
goto err; /* purecov: inspected */
}
table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_WME | MY_ZEROFILL|
@ -21693,7 +21839,9 @@ err:
}
SORT_FIELD *make_unireg_sortorder(THD *thd, ORDER *order, uint *length,
SORT_FIELD *make_unireg_sortorder(THD *thd, JOIN *join,
table_map first_table_bit,
ORDER *order, uint *length,
SORT_FIELD *sortorder)
{
uint count;
@ -21713,7 +21861,30 @@ SORT_FIELD *make_unireg_sortorder(THD *thd, ORDER *order, uint *length,
for (;order;order=order->next,pos++)
{
Item *const item= order->item[0], *const real_item= item->real_item();
Item *first= order->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 *const item= first, *const real_item= item->real_item();
pos->field= 0; pos->item= 0;
if (real_item->type() == Item::FIELD_ITEM)
{
@ -25581,7 +25752,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
uint used_key_parts= 0;
if (keys.is_set(nr) &&
(direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
(direction= test_if_order_by_key(join, order, table, nr,
&used_key_parts)))
{
/*
At this point we are sure that ref_key is a non-ordering
@ -25824,7 +25996,7 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
}
uint used_key_parts;
switch (test_if_order_by_key(order, table, select->quick->index,
switch (test_if_order_by_key(NULL, order, table, select->quick->index,
&used_key_parts)) {
case 1: // desired order
*need_sort= FALSE;

View File

@ -1821,7 +1821,9 @@ bool error_if_full_join(JOIN *join);
int report_error(TABLE *table, int error);
int safe_index_read(JOIN_TAB *tab);
int get_quick_record(SQL_SELECT *select);
SORT_FIELD * make_unireg_sortorder(THD *thd, ORDER *order, uint *length,
SORT_FIELD *make_unireg_sortorder(THD *thd, JOIN *join,
table_map first_table_map,
ORDER *order, uint *length,
SORT_FIELD *sortorder);
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
List<Item> &fields, List <Item> &all_fields, ORDER *order);

View File

@ -9472,7 +9472,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
&tables, fields, all_fields, order) ||
!(sortorder= make_unireg_sortorder(thd, order, &length, NULL)) ||
!(sortorder= make_unireg_sortorder(thd, NULL, 0, order, &length, NULL)) ||
(from->sort.found_records= filesort(thd, from, sortorder, length,
NULL, HA_POS_ERROR,
true,

View File

@ -567,7 +567,7 @@ int mysql_update(THD *thd,
Filesort_tracker *fs_tracker=
thd->lex->explain->get_upd_del_plan()->filesort_tracker;
if (!(sortorder=make_unireg_sortorder(thd, order, &length, NULL)) ||
if (!(sortorder=make_unireg_sortorder(thd, NULL, 0, order, &length, NULL)) ||
(table->sort.found_records= filesort(thd, table, sortorder, length,
select, limit,
true,