summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2014-06-26 18:32:18 +0400
committerSergei Petrunia <psergey@askmonty.org>2014-06-26 18:32:18 +0400
commita787edd7e660a00f015ca0a25ded0952085f7451 (patch)
tree6715da05c41c835f5c451b6e65989197880e9356
parent12d6f89b073351169e070355e8db363d0d649749 (diff)
downloadmariadb-git-a787edd7e660a00f015ca0a25ded0952085f7451.tar.gz
MDEV-6395: Make ANALYZE UPDATE/DELETE handle the degenerate query plans.
-rw-r--r--mysql-test/r/analyze_stmt.result20
-rw-r--r--mysql-test/t/analyze_stmt.test17
-rw-r--r--sql/sql_delete.cc37
-rw-r--r--sql/sql_update.cc20
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);