diff options
author | Sergei Golubchik <sergii@pisem.net> | 2015-01-19 14:18:44 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2015-01-19 14:18:44 +0100 |
commit | 47c844f236fc7e9f6065ba4332facea6b51fe26e (patch) | |
tree | 7a4a70cf84dca76777696a8636b7f2a091b30c3d | |
parent | ce0ed977d51e4621fbb241ea7f231ee35db48b39 (diff) | |
download | mariadb-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.result | 16 | ||||
-rw-r--r-- | mysql-test/t/select_found.test | 20 | ||||
-rw-r--r-- | sql/filesort.cc | 13 | ||||
-rw-r--r-- | sql/sql_select.cc | 18 | ||||
-rw-r--r-- | sql/sql_select.h | 1 |
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 |