List:Commits« Previous MessageNext Message »
From:konstantin Date:November 1 2007 11:23pm
Subject:bk commit into 5.1 tree (kostja:1.2613) BUG#32030
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-02 02:23:06+03:00, kostja@bodhi.(none) +5 -0
  A fix for Bug#32030 "DELETE does not return an error and deletes rows if 
  error evaluating WHERE"
  
  DELETE with a subquery in WHERE clause would sometimes ignore subquery
  evaluation error and proceed with deletion.
  
  The fix is to check for an error after evaluation of the WHERE clause
  in DELETE.
  
  The bug is covered by the existing test suite.

  mysql-test/r/group_min_max.result@stripped, 2007-11-02 02:23:01+03:00, kostja@bodhi.(none) +1 -2
    Update the test results to reflect the fix for Bug#32030

  mysql-test/r/ps.result@stripped, 2007-11-02 02:23:01+03:00, kostja@bodhi.(none) +20 -0
    Update test results (Bug#32030)

  mysql-test/t/group_min_max.test@stripped, 2007-11-02 02:23:01+03:00, kostja@bodhi.(none) +1 -0
    Update the test case to reflect the fix for Bug#32030

  mysql-test/t/ps.test@stripped, 2007-11-02 02:23:01+03:00, kostja@bodhi.(none) +33 -0
    Add a test case for Bug#32030

  sql/sql_delete.cc@stripped, 2007-11-02 02:23:01+03:00, kostja@bodhi.(none) +9 -2
    Check for an error before calling send_ok(). Two different places are
    covered because the subquery code has slightly different execution
    paths depending on ps-protocol/old-protocol

diff -Nrup a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
--- a/mysql-test/r/group_min_max.result	2007-10-31 09:53:56 +03:00
+++ b/mysql-test/r/group_min_max.result	2007-11-02 02:23:01 +03:00
@@ -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 -Nrup a/mysql-test/r/ps.result b/mysql-test/r/ps.result
--- a/mysql-test/r/ps.result	2007-08-02 12:22:29 +04:00
+++ b/mysql-test/r/ps.result	2007-11-02 02:23:01 +03:00
@@ -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 -Nrup a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
--- a/mysql-test/t/group_min_max.test	2007-06-25 06:06:04 +04:00
+++ b/mysql-test/t/group_min_max.test	2007-11-02 02:23:01 +03:00
@@ -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 -Nrup a/mysql-test/t/ps.test b/mysql-test/t/ps.test
--- a/mysql-test/t/ps.test	2007-08-29 14:47:25 +04:00
+++ b/mysql-test/t/ps.test	2007-11-02 02:23:01 +03:00
@@ -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 -Nrup a/sql/sql_delete.cc b/sql/sql_delete.cc
--- a/sql/sql_delete.cc	2007-10-30 20:08:12 +03:00
+++ b/sql/sql_delete.cc	2007-11-02 02:23:01 +03:00
@@ -35,6 +35,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   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 *
 
   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 *
       - 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 *
     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()))
   {
Thread
bk commit into 5.1 tree (kostja:1.2613) BUG#32030konstantin2 Nov