diff options
-rw-r--r-- | mysql-test/r/analyze_stmt.result | 20 | ||||
-rw-r--r-- | mysql-test/t/analyze_stmt.test | 17 | ||||
-rw-r--r-- | sql/sql_delete.cc | 37 | ||||
-rw-r--r-- | sql/sql_update.cc | 20 |
4 files changed, 67 insertions, 27 deletions
diff --git a/mysql-test/r/analyze_stmt.result b/mysql-test/r/analyze_stmt.result index 6f9bdb11fc1..7a18dc836e0 100644 --- a/mysql-test/r/analyze_stmt.result +++ b/mysql-test/r/analyze_stmt.result @@ -214,4 +214,22 @@ analyze update t2,t1 set t2.i=5 where t2.a=t1.a; ERROR 42S22: Unknown column 't2.a' in 'where clause' analyze delete t1 from t2,t1 where t2.a=t1.a; ERROR 42S22: Unknown column 't2.a' in 'where clause' -drop table t1,t2; +drop table t1, t2; +# +# MDEV-6395: ANALYZE UPDATE/DELETE with impossible where does not produce any output +# +create table t1 (a int, b int, key(a)); +insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5); +analyze delete from t1 where 1 > 2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +analyze delete from t1 where a > 30 and a < 10; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +analyze update t1 set b=12345 where 1 > 2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +analyze update t1 set b=12345 where a > 30 and a < 10; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +drop table t1; diff --git a/mysql-test/t/analyze_stmt.test b/mysql-test/t/analyze_stmt.test index d310ab2a3fb..67a7456a473 100644 --- a/mysql-test/t/analyze_stmt.test +++ b/mysql-test/t/analyze_stmt.test @@ -1,5 +1,5 @@ # -# Tests for "ANALYZE $statement" feature (PostgreSQL's analog is called EXPLAIN ANALYZE) +# Tests for "ANALYZE $statement" feature # --disable_warnings drop table if exists t0,t1,t2,t3; @@ -169,5 +169,18 @@ analyze update t2,t1 set t2.i=5 where t2.a=t1.a; --error ER_BAD_FIELD_ERROR analyze delete t1 from t2,t1 where t2.a=t1.a; -drop table t1,t2; +drop table t1, t2; +--echo # +--echo # MDEV-6395: ANALYZE UPDATE/DELETE with impossible where does not produce any output +--echo # +create table t1 (a int, b int, key(a)); +insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5); + +analyze delete from t1 where 1 > 2; +analyze delete from t1 where a > 30 and a < 10; + +analyze update t1 set b=12345 where 1 > 2; +analyze update t1 set b=12345 where a > 30 and a < 10; + +drop table t1; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8e776d7281c..d149d09949f 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -281,7 +281,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, setup_order(thd, select_lex->ref_pointer_array, &tables, fields, all_fields, order)) { - delete select; free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(TRUE); } @@ -332,8 +331,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, DBUG_PRINT("debug", ("Trying to use delete_all_rows()")); query_plan.set_delete_all_rows(maybe_deleted); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; if (!(error=table->file->ha_delete_all_rows())) { @@ -362,8 +361,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { limit= 0; query_plan.set_impossible_where(); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; } } @@ -373,8 +372,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, select_lex); query_plan.set_no_partitions(); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; my_ok(thd, 0); DBUG_RETURN(0); @@ -393,8 +392,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if ((select && select->check_quick(thd, safe_update, limit)) || !limit) { query_plan.set_impossible_where(); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; delete select; free_underlaid_joins(thd, select_lex); @@ -458,7 +457,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - otherwise, execute the query plan */ if (thd->lex->describe) - goto exit_without_my_ok; + goto produce_explain_and_leave; query_plan.save_explain_data(thd->lex->explain); @@ -634,6 +633,7 @@ cleanup: } delete select; + select= NULL; transactional_table= table->file->has_transactions(); if (!transactional_table && deleted > 0) @@ -669,12 +669,11 @@ cleanup: } } DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); - free_underlaid_joins(thd, select_lex); + if (thd->lex->analyze_stmt) - { - error= thd->lex->explain->send_explain(thd); - } - else + goto emit_explain_and_leave; + + free_underlaid_joins(thd, select_lex); if (error < 0 || (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) { @@ -687,8 +686,14 @@ cleanup: DBUG_RETURN(error >= 0 || thd->is_error()); /* Special exits */ -exit_without_my_ok: +produce_explain_and_leave: + /* + We come here for various "degenerate" query plans: impossible WHERE, + no-partitions-used, impossible-range, etc. + */ query_plan.save_explain_data(thd->lex->explain); + +emit_explain_and_leave: int err2= thd->lex->explain->send_explain(thd); delete select; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b9277adb15a..44d3784becf 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -382,8 +382,8 @@ int mysql_update(THD *thd, { limit= 0; // Impossible WHERE query_plan.set_impossible_where(); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; } } @@ -404,8 +404,8 @@ int mysql_update(THD *thd, free_underlaid_joins(thd, select_lex); query_plan.set_no_partitions(); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; my_ok(thd); // No matching records DBUG_RETURN(0); @@ -420,8 +420,8 @@ int mysql_update(THD *thd, (select && select->check_quick(thd, safe_update, limit))) { query_plan.set_impossible_where(); - if (thd->lex->describe) - goto exit_without_my_ok; + if (thd->lex->describe || thd->lex->analyze_stmt) + goto produce_explain_and_leave; delete select; free_underlaid_joins(thd, select_lex); @@ -516,7 +516,7 @@ int mysql_update(THD *thd, - otherwise, execute the query plan */ if (thd->lex->describe) - goto exit_without_my_ok; + goto produce_explain_and_leave; query_plan.save_explain_data(thd->lex->explain); DBUG_EXECUTE_IF("show_explain_probe_update_exec_start", @@ -1029,7 +1029,11 @@ err: thd->abort_on_warning= 0; DBUG_RETURN(1); -exit_without_my_ok: +produce_explain_and_leave: + /* + We come here for various "degenerate" query plans: impossible WHERE, + no-partitions-used, impossible-range, etc. + */ query_plan.save_explain_data(thd->lex->explain); int err2= thd->lex->explain->send_explain(thd); |