Skip to content

Commit fcff3f9

Browse files
author
Tor Didriksen
committed
Bug#68458 Wrong count from FOUND_ROWS() on MySQL 5.6
Bug#16383173 WRONG COUNT FROM FOUND_ROWS() ON MYSQL 5.6 The handling of SQL_CALC_FOUND_ROWS in combination with "order by with limit" was not specific enough, and could lead to wrong results for FOUND_ROWS() The bug was that we took 'limit_found_rows' from filesort() for cases where filesort() did not produce the final result. Solution: let filesort() tell the execution machinery that a priority queue was in fact used to filter the result.
1 parent ae21683 commit fcff3f9

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

sql/filesort.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ ha_rows filesort(THD *thd, TABLE *table, Filesort *filesort,
280280
}
281281
// For PQ queries (with limit) we initialize all pointers.
282282
table_sort.init_record_pointers();
283+
filesort->using_pq= true;
283284
}
284285
else
285286
{

sql/filesort.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ class Filesort: public Sql_alloc
4444
SQL_SELECT *select;
4545
/** TRUE <=> free select on destruction */
4646
bool own_select;
47+
/** true means we are using Priority Queue for order by with limit. */
48+
bool using_pq;
4749

4850
Filesort(ORDER *order_arg, ha_rows limit_arg, SQL_SELECT *select_arg):
4951
order(order_arg),
5052
limit(limit_arg),
5153
sortorder(NULL),
5254
select(select_arg),
53-
own_select(false)
55+
own_select(false),
56+
using_pq(false)
5457
{
5558
DBUG_ASSERT(order);
5659
};

sql/sql_executor.cc

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,15 @@ do_select(JOIN *join)
933933
}
934934

935935
join->thd->limit_found_rows= join->send_records;
936-
/* Use info provided by filesort. */
936+
/*
937+
Use info provided by filesort for "order by with limit":
938+
939+
When using a Priority Queue, we cannot rely on send_records, but need
940+
to use the rowcount read originally into the join_tab applying the
941+
filesort. There cannot be any post-filtering conditions, nor any
942+
following join_tabs in this case, so this rowcount properly represents
943+
the correct number of qualifying rows.
944+
*/
937945
if (join->order)
938946
{
939947
// Save # of found records prior to cleanup
@@ -950,7 +958,7 @@ do_select(JOIN *join)
950958
sort_tab= join_tab + const_tables;
951959
}
952960
if (sort_tab->filesort &&
953-
sort_tab->filesort->sortorder)
961+
sort_tab->filesort->using_pq)
954962
{
955963
join->thd->limit_found_rows= sort_tab->records;
956964
}
@@ -2773,16 +2781,15 @@ end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
27732781
!join->do_send_rows)
27742782
{
27752783
/*
2776-
If filesort is used for sorting, stop after select_limit_cnt+1
2777-
records are read. Because of optimization in some cases it can
2778-
provide only select_limit_cnt+1 records.
2784+
If we have used Priority Queue for optimizing order by with limit,
2785+
then stop here, there are no more records to consume.
27792786
When this optimization is used, end_send is called on the next
27802787
join_tab.
27812788
*/
27822789
if (join->order &&
27832790
join->select_options & OPTION_FOUND_ROWS &&
27842791
join_tab > join->join_tab &&
2785-
(join_tab - 1)->filesort && (join_tab - 1)->filesort->sortorder)
2792+
(join_tab - 1)->filesort && (join_tab - 1)->filesort->using_pq)
27862793
{
27872794
DBUG_PRINT("info", ("filesort NESTED_LOOP_QUERY_LIMIT"));
27882795
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);

0 commit comments

Comments
 (0)