diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index f62fd662a5d..270f248ea9c 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2299,8 +2299,7 @@ Handler_read_next 0 FLUSH STATUS; DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1) > 10000; -Warnings: -Error 1242 Subquery returns more than 1 row +ERROR 21000: Subquery returns more than 1 row SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 8 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index edac68a88d6..db9f0613d7f 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -2680,4 +2680,24 @@ t1 CREATE TABLE `t1` ( KEY `c` (`c`(10)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +drop table if exists t1, t2; +Warnings: +Note 1051 Unknown table 't1' +Note 1051 Unknown table 't2' +create table t1 (a int, b int); +create table t2 like t1; +insert into t1 (a, b) values (1,1), (1,2), (1,3), (1,4), (1,5), +(2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); +insert into t2 select a, max(b) from t1 group by a; +prepare stmt from "delete from t2 where (select (select max(b) from t1 group +by a having a < 2) x from t1) > 10000"; +delete from t2 where (select (select max(b) from t1 group +by a having a < 2) x from t1) > 10000; +ERROR 21000: Subquery returns more than 1 row +execute stmt; +ERROR 21000: Subquery returns more than 1 row +execute stmt; +ERROR 21000: Subquery returns more than 1 row +deallocate prepare stmt; +drop table t1, t2; End of 5.1 tests. diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index cf25b4c61be..9d1e065797d 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -890,6 +890,7 @@ FLUSH STATUS; DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000; SHOW STATUS LIKE 'handler_read__e%'; FLUSH STATUS; +--error ER_SUBQUERY_NO_1_ROW DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1) > 10000; SHOW STATUS LIKE 'handler_read__e%'; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index dea86bdd2fa..c528fddaf93 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -2778,4 +2778,37 @@ execute stmt; show create table t1; drop table t1; +# +# Bug #32030 DELETE does not return an error and deletes rows if error +# evaluating WHERE +# +# Test that there is an error for prepared delete just like for the normal +# one. +# + +drop table if exists t1, t2; +create table t1 (a int, b int); +create table t2 like t1; + +insert into t1 (a, b) values (1,1), (1,2), (1,3), (1,4), (1,5), + (2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6); + +insert into t2 select a, max(b) from t1 group by a; + +prepare stmt from "delete from t2 where (select (select max(b) from t1 group +by a having a < 2) x from t1) > 10000"; + +--error ER_SUBQUERY_NO_1_ROW +delete from t2 where (select (select max(b) from t1 group +by a having a < 2) x from t1) > 10000; +--error ER_SUBQUERY_NO_1_ROW +execute stmt; +--error ER_SUBQUERY_NO_1_ROW +execute stmt; + +deallocate prepare stmt; +drop table t1, t2; + + + --echo End of 5.1 tests. diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 219dc90429b..f183cb3142f 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -35,6 +35,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, READ_RECORD info; bool using_limit=limit != HA_POS_ERROR; bool transactional_table, safe_update, const_cond; + bool const_cond_result; ha_rows deleted= 0; uint usable_index= MAX_KEY; SELECT_LEX *select_lex= &thd->lex->select_lex; @@ -86,6 +87,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, select_lex->no_error= thd->lex->ignore; + const_cond_result= const_cond && (!conds || conds->val_int()); + if (thd->is_error()) + { + /* Error evaluating val_int(). */ + DBUG_RETURN(TRUE); + } /* Test if the user wants to delete all rows and deletion doesn't have any side-effects (because of triggers), so we can use optimized @@ -105,7 +112,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - We should not be binlogging this statement row-based, and - there should be no delete triggers associated with the table. */ - if (!using_limit && const_cond && (!conds || conds->val_int()) && + if (!using_limit && const_cond_result && !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && (thd->lex->sql_command == SQLCOM_TRUNCATE || (!thd->current_stmt_binlog_row_based && @@ -300,7 +307,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, else table->file->unlock_row(); // Row failed selection, release lock on it } - if (thd->killed && !error) + if (thd->killed || thd->is_error()) error= 1; // Aborted if (will_batch && (loc_error= table->file->end_bulk_delete())) {