summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2015-01-19 14:18:44 +0100
committerSergei Golubchik <sergii@pisem.net>2015-01-19 14:18:44 +0100
commit47c844f236fc7e9f6065ba4332facea6b51fe26e (patch)
tree7a4a70cf84dca76777696a8636b7f2a091b30c3d
parentce0ed977d51e4621fbb241ea7f231ee35db48b39 (diff)
downloadmariadb-git-47c844f236fc7e9f6065ba4332facea6b51fe26e.tar.gz
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.
-rw-r--r--mysql-test/r/select_found.result16
-rw-r--r--mysql-test/t/select_found.test20
-rw-r--r--sql/filesort.cc13
-rw-r--r--sql/sql_select.cc18
-rw-r--r--sql/sql_select.h1
5 files changed, 48 insertions, 20 deletions
diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result
index 04eb2c90d31..92758fa134b 100644
--- a/mysql-test/r/select_found.result
+++ b/mysql-test/r/select_found.result
@@ -332,3 +332,19 @@ select found_rows() as count;
count
2
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;
diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test
index d529dc415e7..88940eaf2b8 100644
--- a/mysql-test/t/select_found.test
+++ b/mysql-test/t/select_found.test
@@ -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;
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;
+
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 509a7f8e9b3..027437fca67 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -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;
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);
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);
buffpek=0;
error= 1;
+ *found_rows= HA_POS_ERROR;
param.init_for_filesort(sortlength(thd, sortorder, s_length,
&multi_byte_charset),
@@ -690,8 +689,7 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
ref_pos= ref_buff;
quick_select=select && select->quick;
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);
if (flag)
ref_pos= &file->ref[0];
@@ -814,14 +812,9 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
if (write_record)
{
+ ++(*found_rows);
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);
idx= pq->num_elements();
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2eb2ddc057e..3912a039b9c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3032,6 +3032,7 @@ void JOIN::exec_inner()
const ha_rows select_limit_arg=
select_options & OPTION_FOUND_ROWS
? 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 "
"curr_join->table_count %d "
@@ -3079,7 +3080,8 @@ void JOIN::exec_inner()
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure);
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. */
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
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)
{
DBUG_PRINT("info", ("filesort NESTED_LOOP_QUERY_LIMIT"));
@@ -18922,8 +18925,9 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/* Join over all rows in table; Return number of found rows */
TABLE *table=jt->table;
- join->select_options ^= OPTION_FOUND_ROWS;
- if (join->filesort_found_rows)
+ join->select_options ^= OPTION_FOUND_ROWS;
+ if (table->sort.record_pointers ||
+ (table->sort.io_cache && my_b_inited(table->sort.io_cache)))
{
/* Using filesort */
join->send_records= table->sort.found_records;
@@ -20754,11 +20758,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
select, filesort_limit, 0,
&examined_rows, &found_rows);
table->sort.found_records= filesort_retval;
- if (found_rows != HA_POS_ERROR)
- {
- tab->records= found_rows; // For SQL_CALC_ROWS
- join->filesort_found_rows= true;
- }
+ tab->records= found_rows; // For SQL_CALC_ROWS
if (quick_created)
{
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 490d8c91a9e..7d53731b558 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1341,7 +1341,6 @@ public:
emb_sjm_nest= NULL;
sjm_lookup_tables= 0;
- filesort_found_rows= false;
exec_saved_explain= false;
/*
The following is needed because JOIN::cleanup(true) may be called for