diff --git a/mysql-test/r/analyze_stmt_orderby.result b/mysql-test/r/analyze_stmt_orderby.result index d2abc1db163..440a55060d4 100644 --- a/mysql-test/r/analyze_stmt_orderby.result +++ b/mysql-test/r/analyze_stmt_orderby.result @@ -363,21 +363,68 @@ ANALYZE } } drop table t2; -drop table t0, t1; # # MDEV-8282: crash in filesort() with simple ordered delete # -create table t1(a int) engine=innodb; -delete from t1 order by a; +create table t3(a int) engine=innodb; +delete from t3 order by a; # EXPLAIN thinks it will use delete_all_rows(): explain -delete from t1 order by a; +delete from t3 order by a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL 1 Deleting all rows # ANALYZE shows that delete_all_rows() didn't work and we deleted rows # one-by-one: analyze -delete from t1 order by a; +delete from t3 order by a; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 0.00 100.00 100.00 Using filesort -drop table t1; +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 0.00 100.00 100.00 Using filesort +drop table t3; +# +# +# +create table t3 (a int, b int); +insert into t3 select a, 123 from t0; +analyze format=json +select distinct max(t3.b) Q from t0, t3 where t0.a=t3.a group by t0.a order by null; +ANALYZE +{ + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "duplicate_removal": { + "temporary_table": { + "table": { + "table_name": "t0", + "access_type": "ALL", + "r_loops": 1, + "rows": 10, + "r_rows": 10, + "r_total_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "t3", + "access_type": "ALL", + "r_loops": 1, + "rows": 10, + "r_rows": 10, + "r_total_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "128Kb", + "join_type": "BNL", + "attached_condition": "(t3.a = t0.a)", + "r_filtered": 10 + } + } + } + } +} +drop table t3; +drop table t0,t1; diff --git a/mysql-test/t/analyze_stmt_orderby.test b/mysql-test/t/analyze_stmt_orderby.test index 1a89091aa32..ab89163defa 100644 --- a/mysql-test/t/analyze_stmt_orderby.test +++ b/mysql-test/t/analyze_stmt_orderby.test @@ -91,22 +91,33 @@ analyze format=json select MAX(b) from t2 where mod(a,2)=0 group by c; drop table t2; -drop table t0, t1; --echo # --echo # MDEV-8282: crash in filesort() with simple ordered delete --echo # -create table t1(a int) engine=innodb; -delete from t1 order by a; +create table t3(a int) engine=innodb; +delete from t3 order by a; --echo # EXPLAIN thinks it will use delete_all_rows(): explain -delete from t1 order by a; +delete from t3 order by a; --echo # ANALYZE shows that delete_all_rows() didn't work and we deleted rows --echo # one-by-one: analyze -delete from t1 order by a; +delete from t3 order by a; -drop table t1; +drop table t3; +--echo # +--echo # +--echo # +create table t3 (a int, b int); +insert into t3 select a, 123 from t0; + +--replace_regex /"r_total_time_ms": [0-9]*[.]?[0-9]*/"r_total_time_ms": "REPLACED"/ /"r_buffer_size": "[^"]+"/"r_buffer_size": "REPLACED"/ +analyze format=json +select distinct max(t3.b) Q from t0, t3 where t0.a=t3.a group by t0.a order by null; + +drop table t3; +drop table t0,t1; diff --git a/sql/sql_analyze_stmt.cc b/sql/sql_analyze_stmt.cc index eae47743b03..da1e970d0b8 100644 --- a/sql/sql_analyze_stmt.cc +++ b/sql/sql_analyze_stmt.cc @@ -113,3 +113,22 @@ void Sort_and_group_tracker::report_tmp_table(TABLE *tbl) cur_action++; } + +void Sort_and_group_tracker::report_duplicate_removal() +{ + DBUG_ASSERT(cur_action < MAX_QEP_ACTIONS); + if (total_actions) + { + /* This is not the first execution. Check if the steps match. */ + if (qep_actions[cur_action] != EXPL_ACTION_REMOVE_DUPS) + varied_executions= true; + } + + if (!varied_executions) + { + qep_actions[cur_action]= EXPL_ACTION_REMOVE_DUPS; + } + + cur_action++; +} + diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h index 9e8191c0947..203948813b1 100644 --- a/sql/sql_analyze_stmt.h +++ b/sql/sql_analyze_stmt.h @@ -398,6 +398,12 @@ public: */ Filesort_tracker *report_sorting(THD *thd); + /* + Report that remove_duplicates() is invoked [on a temp. table]. + We don't collect any statistics on this operation, yet. + */ + void report_duplicate_removal(); + friend class Iterator; /*************** Statistics retrieval interface ***************/ bool had_varied_executions() { return varied_executions; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8a6a7f72915..bb96400edaf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -21179,6 +21179,7 @@ remove_duplicates(JOIN *join, TABLE *table, List &fields, Item *having) THD *thd= join->thd; DBUG_ENTER("remove_duplicates"); + join->explain->ops_tracker.report_duplicate_removal(); table->reginfo.lock_type=TL_WRITE;