Commit 47c844f2 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-7219 SQL_CALC_FOUND_ROWS yields wrong result

revert the code in filesort that conditionally updated 'found_rows',
rely on filesort_limit_arg instead.
parent ce0ed977
...@@ -332,3 +332,19 @@ select found_rows() as count; ...@@ -332,3 +332,19 @@ select found_rows() as count;
count count
2 2
drop table t1, t2; drop table t1, t2;
create table t1 (i int, v varchar(64), key (i));
select sql_calc_found_rows * from t1 where i = 0 order by v limit 59,2;
i v
0 foo
0 foo
select found_rows();
found_rows()
75
select sql_calc_found_rows * from t1 ignore index (i) where i = 0 order by v limit 59,2;
i v
0 foo
0 foo
select found_rows();
found_rows()
75
drop table t1;
...@@ -257,3 +257,23 @@ select sql_calc_found_rows 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 ...@@ -257,3 +257,23 @@ select sql_calc_found_rows 1 as res from t1 left join t2 on i1 = i2 where v2 = 5
select found_rows() as count; select found_rows() as count;
drop table t1, t2; drop table t1, t2;
#
# MDEV-7219 SQL_CALC_FOUND_ROWS yields wrong result
#
create table t1 (i int, v varchar(64), key (i));
--disable_query_log
let $1=150;
while ($1)
{
eval insert into t1 values ($1 % 2, 'foo');
dec $1;
}
--enable_query_log
select sql_calc_found_rows * from t1 where i = 0 order by v limit 59,2;
select found_rows();
select sql_calc_found_rows * from t1 ignore index (i) where i = 0 order by v limit 59,2;
select found_rows();
drop table t1;
...@@ -166,8 +166,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ...@@ -166,8 +166,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
TABLE_LIST *tab= table->pos_in_table_list; TABLE_LIST *tab= table->pos_in_table_list;
Item_subselect *subselect= tab ? tab->containing_subselect() : 0; Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
*found_rows= HA_POS_ERROR;
MYSQL_FILESORT_START(table->s->db.str, table->s->table_name.str); MYSQL_FILESORT_START(table->s->db.str, table->s->table_name.str);
DEBUG_SYNC(thd, "filesort_start"); DEBUG_SYNC(thd, "filesort_start");
...@@ -190,6 +188,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ...@@ -190,6 +188,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
my_b_clear(&buffpek_pointers); my_b_clear(&buffpek_pointers);
buffpek=0; buffpek=0;
error= 1; error= 1;
*found_rows= HA_POS_ERROR;
param.init_for_filesort(sortlength(thd, sortorder, s_length, param.init_for_filesort(sortlength(thd, sortorder, s_length,
&multi_byte_charset), &multi_byte_charset),
...@@ -690,7 +689,6 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select, ...@@ -690,7 +689,6 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
ref_pos= ref_buff; ref_pos= ref_buff;
quick_select=select && select->quick; quick_select=select && select->quick;
record=0; record=0;
if (pq) // don't count unless pq is used
*found_rows= 0; *found_rows= 0;
flag= ((file->ha_table_flags() & HA_REC_NOT_IN_SEQ) || quick_select); flag= ((file->ha_table_flags() & HA_REC_NOT_IN_SEQ) || quick_select);
if (flag) if (flag)
...@@ -814,14 +812,9 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select, ...@@ -814,14 +812,9 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
if (write_record) if (write_record)
{ {
++(*found_rows);
if (pq) if (pq)
{ {
/*
only count rows when pq is used - otherwise there might be
other filters *after* the filesort, we don't know the final row
count here
*/
(*found_rows)++;
pq->push(ref_pos); pq->push(ref_pos);
idx= pq->num_elements(); idx= pq->num_elements();
} }
......
...@@ -3032,6 +3032,7 @@ void JOIN::exec_inner() ...@@ -3032,6 +3032,7 @@ void JOIN::exec_inner()
const ha_rows select_limit_arg= const ha_rows select_limit_arg=
select_options & OPTION_FOUND_ROWS select_options & OPTION_FOUND_ROWS
? HA_POS_ERROR : unit->select_limit_cnt; ? HA_POS_ERROR : unit->select_limit_cnt;
curr_join->filesort_found_rows= filesort_limit_arg != HA_POS_ERROR;
DBUG_PRINT("info", ("has_group_by %d " DBUG_PRINT("info", ("has_group_by %d "
"curr_join->table_count %d " "curr_join->table_count %d "
...@@ -3079,7 +3080,8 @@ void JOIN::exec_inner() ...@@ -3079,7 +3080,8 @@ void JOIN::exec_inner()
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure); error= do_select(curr_join, curr_fields_list, NULL, procedure);
thd->limit_found_rows= curr_join->send_records; thd->limit_found_rows= curr_join->send_records;
if (curr_join->order && curr_join->filesort_found_rows) if (curr_join->order && curr_join->sortorder &&
curr_join->filesort_found_rows)
{ {
/* Use info provided by filesort. */ /* Use info provided by filesort. */
DBUG_ASSERT(curr_join->table_count > curr_join->const_tables); DBUG_ASSERT(curr_join->table_count > curr_join->const_tables);
...@@ -18900,7 +18902,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -18900,7 +18902,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
records are read. Because of optimization in some cases it can records are read. Because of optimization in some cases it can
provide only select_limit_cnt+1 records. provide only select_limit_cnt+1 records.
*/ */
if (join->order && join->filesort_found_rows && if (join->order && join->sortorder &&
join->filesort_found_rows &&
join->select_options & OPTION_FOUND_ROWS) join->select_options & OPTION_FOUND_ROWS)
{ {
DBUG_PRINT("info", ("filesort NESTED_LOOP_QUERY_LIMIT")); DBUG_PRINT("info", ("filesort NESTED_LOOP_QUERY_LIMIT"));
...@@ -18923,7 +18926,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -18923,7 +18926,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
TABLE *table=jt->table; TABLE *table=jt->table;
join->select_options ^= OPTION_FOUND_ROWS; join->select_options ^= OPTION_FOUND_ROWS;
if (join->filesort_found_rows) if (table->sort.record_pointers ||
(table->sort.io_cache && my_b_inited(table->sort.io_cache)))
{ {
/* Using filesort */ /* Using filesort */
join->send_records= table->sort.found_records; join->send_records= table->sort.found_records;
...@@ -20754,11 +20758,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, ...@@ -20754,11 +20758,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
select, filesort_limit, 0, select, filesort_limit, 0,
&examined_rows, &found_rows); &examined_rows, &found_rows);
table->sort.found_records= filesort_retval; table->sort.found_records= filesort_retval;
if (found_rows != HA_POS_ERROR)
{
tab->records= found_rows; // For SQL_CALC_ROWS tab->records= found_rows; // For SQL_CALC_ROWS
join->filesort_found_rows= true;
}
if (quick_created) if (quick_created)
{ {
......
...@@ -1341,7 +1341,6 @@ class JOIN :public Sql_alloc ...@@ -1341,7 +1341,6 @@ class JOIN :public Sql_alloc
emb_sjm_nest= NULL; emb_sjm_nest= NULL;
sjm_lookup_tables= 0; sjm_lookup_tables= 0;
filesort_found_rows= false;
exec_saved_explain= false; exec_saved_explain= false;
/* /*
The following is needed because JOIN::cleanup(true) may be called for The following is needed because JOIN::cleanup(true) may be called for
......
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