Commit 3712931c authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Fixed bug in ORDER BY ... LIMIT

parent b8a8c5e3
...@@ -50797,6 +50797,9 @@ each individual 4.0.x release. ...@@ -50797,6 +50797,9 @@ each individual 4.0.x release.
@appendixsubsec Changes in release 4.0.5 @appendixsubsec Changes in release 4.0.5
@itemize @itemize
@item @item
Fixed a newly introduced bug that caused @code{ORDER BY ... LIMIT #}
to not return all rows.
@item
Fixed a bug in multi-table deletes when outer join is used on an empty Fixed a bug in multi-table deletes when outer join is used on an empty
table, which get's first to be deleted table, which get's first to be deleted
@item @item
...@@ -111,7 +111,8 @@ static Item* part_of_refkey(TABLE *form,Field *field); ...@@ -111,7 +111,8 @@ static Item* part_of_refkey(TABLE *form,Field *field);
static uint find_shortest_key(TABLE *table, key_map usable_keys); static uint find_shortest_key(TABLE *table, key_map usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
ha_rows select_limit, bool no_changes); ha_rows select_limit, bool no_changes);
static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit); static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows filesort_limit,
ha_rows select_limit);
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields, static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
Item *having); Item *having);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
...@@ -207,6 +208,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -207,6 +208,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
int error, tmp_error; int error, tmp_error;
bool need_tmp,hidden_group_fields; bool need_tmp,hidden_group_fields;
bool simple_order,simple_group,no_order, skip_sort_order; bool simple_order,simple_group,no_order, skip_sort_order;
ha_rows select_limit;
Item::cond_result cond_value; Item::cond_result cond_value;
SQL_SELECT *select; SQL_SELECT *select;
DYNAMIC_ARRAY keyuse; DYNAMIC_ARRAY keyuse;
...@@ -662,7 +664,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -662,7 +664,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_PRINT("info",("Sorting for group")); DBUG_PRINT("info",("Sorting for group"));
thd->proc_info="Sorting for group"; thd->proc_info="Sorting for group";
if (create_sort_index(&join.join_tab[join.const_tables],group, if (create_sort_index(&join.join_tab[join.const_tables],group,
HA_POS_ERROR) || HA_POS_ERROR, HA_POS_ERROR) ||
make_sum_func_list(&join,all_fields) || make_sum_func_list(&join,all_fields) ||
alloc_group_fields(&join,group)) alloc_group_fields(&join,group))
goto err; goto err;
...@@ -677,7 +679,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -677,7 +679,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_PRINT("info",("Sorting for order")); DBUG_PRINT("info",("Sorting for order"));
thd->proc_info="Sorting for order"; thd->proc_info="Sorting for order";
if (create_sort_index(&join.join_tab[join.const_tables],order, if (create_sort_index(&join.join_tab[join.const_tables],order,
HA_POS_ERROR)) HA_POS_ERROR, HA_POS_ERROR))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
order=0; order=0;
} }
...@@ -778,7 +780,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -778,7 +780,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (group) if (group)
{ {
thd->proc_info="Creating sort index"; thd->proc_info="Creating sort index";
if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || if (create_sort_index(join.join_tab,group,HA_POS_ERROR, HA_POS_ERROR) ||
alloc_group_fields(&join,group)) alloc_group_fields(&join,group))
{ {
free_tmp_table(thd,tmp_table2); /* purecov: inspected */ free_tmp_table(thd,tmp_table2); /* purecov: inspected */
...@@ -872,11 +874,31 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -872,11 +874,31 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_EXECUTE("where",print_where(conds,"having after sort");); DBUG_EXECUTE("where",print_where(conds,"having after sort"););
} }
} }
select_limit= thd->select_limit;
if (having || group || (join.select_options & OPTION_FOUND_ROWS))
select_limit= HA_POS_ERROR;
else
{
/*
We can abort sorting after thd->select_limit rows if we there is no
WHERE clause for any tables after the sorted one.
*/
JOIN_TAB *table= &join.join_tab[join.const_tables+1];
JOIN_TAB *end_table= &join.join_tab[join.tables];
for (; table < end_table ; table++)
{
if (table->select_cond)
{
/* We have to sort all rows */
select_limit= HA_POS_ERROR;
break;
}
}
}
if (create_sort_index(&join.join_tab[join.const_tables], if (create_sort_index(&join.join_tab[join.const_tables],
group ? group : order, group ? group : order,
(having || group || select_limit,
(join.select_options & OPTION_FOUND_ROWS)) ? thd->select_limit))
HA_POS_ERROR : thd->select_limit))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
} }
join.having=having; // Actually a parameter join.having=having; // Actually a parameter
...@@ -5639,7 +5661,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, ...@@ -5639,7 +5661,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*****************************************************************************/ *****************************************************************************/
static int static int
create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) create_sort_index(JOIN_TAB *tab, ORDER *order, ha_rows filesort_limit,
ha_rows select_limit)
{ {
SORT_FIELD *sortorder; SORT_FIELD *sortorder;
uint length; uint length;
...@@ -5684,7 +5707,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) ...@@ -5684,7 +5707,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
if (table->tmp_table) if (table->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count table->file->info(HA_STATUS_VARIABLE); // Get record count
table->found_records=filesort(table,sortorder,length, table->found_records=filesort(table,sortorder,length,
select, 0L, select_limit, &examined_rows); select, 0L, filesort_limit, &examined_rows);
tab->records=table->found_records; // For SQL_CALC_ROWS tab->records=table->found_records; // For SQL_CALC_ROWS
delete select; // filesort did select delete select; // filesort did select
tab->select=0; tab->select=0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment