mirror of
https://github.com/MariaDB/server.git
synced 2025-07-07 06:01:31 +03:00
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.
This commit is contained in:
@ -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
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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()
|
|||||||
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()
|
|||||||
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)),
|
|||||||
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)),
|
|||||||
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,
|
|||||||
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 @@ public:
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user