List:Commits« Previous MessageNext Message »
From:marc.alff Date:August 16 2006 5:51am
Subject:bk commit into 5.0 tree (malff:1.2236) BUG#12713
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of marcsql. When marcsql 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, 2006-08-15 22:51:11-07:00, malff@weblab.(none) +46 -0
  Bug#12713 (Error in a stored function called from a SELECT doesn't cause
      ROLLBACK of statem)
  
  Investigating this bug in depth revealed several issues.
  As a result, the following was done:
  
  1)
  The usage of "if (transactional_table)" before calling
  ha_autocommit_or_rollback is flawed, as only 1 table is considered,
  which breaks integrity for statements involving many tables with a
  mix of transactional and non transactional engines.
  
  The serie of tests t/engine_mix_<xxx>_<yyy>.test has been written
  to cover this area.
  
  Existing calls to ha_commit_or_rollback() have been adjusted.
  
  2)
  Executing these tests also exposed some limitations in the BDB and NDB
  engines, for which the handlerton call backs have been fixed.
  
  3)
  After a very carefull investigation, the list of statements that can
  modify transactional data has been identified, and documented in
  mysql_execute_command (See the comments there).
  
  4)
  All the statements that can cause side effects have been fixed to
  properly call ha_commit_or_rollback().
  
  5)
  While doing 4), a flaw has been found for the DO command.
  The code has been fixed and the related tests cases adjusted.
  Also, a flaw in multi updates has been fixed.
  
  6)
  A serie of tests t/autocommit_<xxx>.test has been written
  to verify that statement crollback *and* transaction rollback
  occur properly.
  
  7)
  All the new tests have been organized in a manner consistent
  with the test reorganization performed recently in 5.1 for falcon.
  
  8)
  Two unrelated issues have been found and documented for NDB,
  the tests written with the expected output (unverified),
  and disabled in t/disable.def

  mysql-test/include/autocommit_common.inc@stripped, 2006-08-15 19:28:18-07:00, malff@weblab.(none) +257 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/include/autocommit_common.inc@stripped, 2006-08-15 19:28:18-07:00, malff@weblab.(none) +0 -0

  mysql-test/include/engine_mix_common.inc@stripped, 2006-08-15 19:23:20-07:00, malff@weblab.(none) +130 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/include/engine_mix_common.inc@stripped, 2006-08-15 19:23:20-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/autocommit_bdb.result@stripped, 2006-08-15 19:26:56-07:00, malff@weblab.(none) +273 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/r/autocommit_bdb.result@stripped, 2006-08-15 19:26:56-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/autocommit_innodb.result@stripped, 2006-08-15 19:27:14-07:00, malff@weblab.(none) +273 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/r/autocommit_innodb.result@stripped, 2006-08-15 19:27:14-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/autocommit_ndb.result@stripped, 2006-08-15 19:27:31-07:00, malff@weblab.(none) +273 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/r/autocommit_ndb.result@stripped, 2006-08-15 19:27:31-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_bdb_innodb.result@stripped, 2006-08-15 19:16:44-07:00, malff@weblab.(none) +87 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_bdb_innodb.result@stripped, 2006-08-15 19:16:44-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_bdb_myisam.result@stripped, 2006-08-15 19:18:29-07:00, malff@weblab.(none) +113 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_bdb_myisam.result@stripped, 2006-08-15 19:18:29-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_bdb_ndb.result@stripped, 2006-08-15 19:17:01-07:00, malff@weblab.(none) +87 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_bdb_ndb.result@stripped, 2006-08-15 19:17:01-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_innodb_bdb.result@stripped, 2006-08-15 19:18:44-07:00, malff@weblab.(none) +87 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_innodb_bdb.result@stripped, 2006-08-15 19:18:44-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_innodb_myisam.result@stripped, 2006-08-15 19:19:01-07:00, malff@weblab.(none) +113 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_innodb_myisam.result@stripped, 2006-08-15 19:19:01-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_innodb_ndb.result@stripped, 2006-08-15 19:17:53-07:00, malff@weblab.(none) +87 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_innodb_ndb.result@stripped, 2006-08-15 19:17:53-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_myisam_bdb.result@stripped, 2006-08-15 19:19:17-07:00, malff@weblab.(none) +91 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_myisam_bdb.result@stripped, 2006-08-15 19:19:17-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_myisam_innodb.result@stripped, 2006-08-15 19:19:48-07:00, malff@weblab.(none) +91 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_myisam_innodb.result@stripped, 2006-08-15 19:19:48-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_myisam_ndb.result@stripped, 2006-08-15 19:18:09-07:00, malff@weblab.(none) +91 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_myisam_ndb.result@stripped, 2006-08-15 19:18:09-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_ndb_bdb.result@stripped, 2006-08-15 19:21:29-07:00, malff@weblab.(none) +87 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_ndb_bdb.result@stripped, 2006-08-15 19:21:29-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_ndb_innodb.result@stripped, 2006-08-15 19:21:44-07:00, malff@weblab.(none) +87 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_ndb_innodb.result@stripped, 2006-08-15 19:21:44-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/engine_mix_ndb_myisam.result@stripped, 2006-08-15 19:22:02-07:00, malff@weblab.(none) +113 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/r/engine_mix_ndb_myisam.result@stripped, 2006-08-15 19:22:02-07:00, malff@weblab.(none) +0 -0

  mysql-test/r/rpl_sp.result@stripped, 2006-08-15 19:06:03-07:00, malff@weblab.(none) +1 -2
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    The DO command now reports errors, adjusted the tests accordingly.

  mysql-test/r/subselect.result@stripped, 2006-08-15 19:07:41-07:00, malff@weblab.(none) +1 -2
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    The DO command now reports errors, adjusted the tests accordingly.

  mysql-test/t/autocommit_bdb.test@stripped, 2006-08-15 19:25:30-07:00, malff@weblab.(none) +6 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/t/autocommit_bdb.test@stripped, 2006-08-15 19:25:30-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/autocommit_innodb.test@stripped, 2006-08-15 19:25:42-07:00, malff@weblab.(none) +6 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/t/autocommit_innodb.test@stripped, 2006-08-15 19:25:42-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/autocommit_ndb.test@stripped, 2006-08-15 19:25:55-07:00, malff@weblab.(none) +6 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (autocommit or rollback of statements with side effects)
    

  mysql-test/t/autocommit_ndb.test@stripped, 2006-08-15 19:25:55-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/disabled.def@stripped, 2006-08-15 21:16:47-07:00, malff@weblab.(none) +3 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Disabled new tests case written for NDB, as they exposed unrelated issues.

  mysql-test/t/engine_mix_bdb_innodb.test@stripped, 2006-08-15 19:12:17-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_bdb_innodb.test@stripped, 2006-08-15 19:12:17-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_bdb_myisam.test@stripped, 2006-08-15 19:12:00-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_bdb_myisam.test@stripped, 2006-08-15 19:12:00-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_bdb_ndb.test@stripped, 2006-08-15 19:12:35-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_bdb_ndb.test@stripped, 2006-08-15 19:12:35-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_innodb_bdb.test@stripped, 2006-08-15 19:12:51-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_innodb_bdb.test@stripped, 2006-08-15 19:12:51-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_innodb_myisam.test@stripped, 2006-08-15 19:13:04-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_innodb_myisam.test@stripped, 2006-08-15 19:13:04-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_innodb_ndb.test@stripped, 2006-08-15 19:13:23-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_innodb_ndb.test@stripped, 2006-08-15 19:13:23-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_myisam_bdb.test@stripped, 2006-08-15 19:14:11-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_myisam_bdb.test@stripped, 2006-08-15 19:14:11-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_myisam_innodb.test@stripped, 2006-08-15 19:14:26-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_myisam_innodb.test@stripped, 2006-08-15 19:14:26-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_myisam_ndb.test@stripped, 2006-08-15 19:14:45-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_myisam_ndb.test@stripped, 2006-08-15 19:14:45-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_ndb_bdb.test@stripped, 2006-08-15 19:15:00-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_ndb_bdb.test@stripped, 2006-08-15 19:15:00-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_ndb_innodb.test@stripped, 2006-08-15 19:15:20-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_ndb_innodb.test@stripped, 2006-08-15 19:15:20-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/engine_mix_ndb_myisam.test@stripped, 2006-08-15 19:15:50-07:00, malff@weblab.(none) +8 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    New test cases (transactions accross multiple storage engines)
    

  mysql-test/t/engine_mix_ndb_myisam.test@stripped, 2006-08-15 19:15:50-07:00, malff@weblab.(none) +0 -0

  mysql-test/t/rpl_sp.test@stripped, 2006-08-15 19:06:58-07:00, malff@weblab.(none) +2 -1
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    The DO command now reports errors, adjusted the tests accordingly.

  mysql-test/t/subselect.test@stripped, 2006-08-15 19:08:20-07:00, malff@weblab.(none) +2 -1
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    The DO command now reports errors, adjusted the tests accordingly.

  sql/ha_berkeley.cc@stripped, 2006-08-15 19:30:56-07:00, malff@weblab.(none) +23 -6
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback crash, for transactions accross multiple engines.

  sql/ha_ndbcluster.cc@stripped, 2006-08-15 19:32:59-07:00, malff@weblab.(none) +48 -46
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback crash, for transactions accross multiple engines.
    (Changed the DBUG_ASSERT to an if statement, indented the code)

  sql/sql_delete.cc@stripped, 2006-08-15 19:59:04-07:00, malff@weblab.(none) +7 -3
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback, for transactions accross multiple engines.

  sql/sql_do.cc@stripped, 2006-08-15 19:02:52-07:00, malff@weblab.(none) +16 -3
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed the DO command to:
    - report errors
    - be aware of transactions, and properly commit or rollback changes

  sql/sql_insert.cc@stripped, 2006-08-15 19:59:29-07:00, malff@weblab.(none) +2 -2
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback, for transactions accross multiple engines.

  sql/sql_load.cc@stripped, 2006-08-15 22:07:06-07:00, malff@weblab.(none) +1 -0
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback, for transactions accross multiple engines.
    Fixed a logic flaw for autocommit that failed

  sql/sql_load.cc@stripped, 2006-08-15 21:10:09-07:00, malff@weblab.(none) +2 -5
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback, for transactions accross multiple engines.
    Fixed a logic flaw for autocommit that failed

  sql/sql_parse.cc@stripped, 2006-08-15 21:12:38-07:00, malff@weblab.(none) +212 -2
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Improved transactional integrity for all the statements that modify data.
    Documented in details the results of reverse engineering / analysis.

  sql/sql_select.cc@stripped, 2006-08-15 20:13:23-07:00, malff@weblab.(none) +1 -1
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed err, used without being initialized.

  sql/sql_update.cc@stripped, 2006-08-15 20:05:37-07:00, malff@weblab.(none) +13 -10
    Bug#12713 (Error in a stored function called from a SELECT doesn't cause
        ROLLBACK of statem)
    
    Fixed commit/rollback, for transactions accross multiple engines.
    Fixed error handling for mysql_multi_update

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	malff
# Host:	weblab.(none)
# Root:	/home/marcsql/TREE/mysql-5.0-12713

--- 1.161/sql/ha_berkeley.cc	2006-08-15 22:51:16 -07:00
+++ 1.162/sql/ha_berkeley.cc	2006-08-15 22:51:16 -07:00
@@ -254,12 +254,21 @@ bool berkeley_flush_logs()
 
 static int berkeley_commit(THD *thd, bool all)
 {
+  int error=0;
   DBUG_ENTER("berkeley_commit");
   DBUG_PRINT("trans",("ending transaction %s", all ? "all" : "stmt"));
   berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
-  DB_TXN **txn= all ? &trx->all : &trx->stmt;
-  int error=txn_commit(*txn,0);
-  *txn=0;
+
+  if (trx)
+  {
+    DB_TXN **txn= all ? &trx->all : &trx->stmt;
+    if (*txn)
+    {
+      error=txn_commit(*txn,0);
+      *txn=0;
+    }
+  }
+
 #ifndef DBUG_OFF
   if (error)
     DBUG_PRINT("error",("error: %d",error));
@@ -269,12 +278,20 @@ static int berkeley_commit(THD *thd, boo
 
 static int berkeley_rollback(THD *thd, bool all)
 {
+  int error=0;
   DBUG_ENTER("berkeley_rollback");
   DBUG_PRINT("trans",("aborting transaction %s", all ? "all" : "stmt"));
   berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
-  DB_TXN **txn= all ? &trx->all : &trx->stmt;
-  int error=txn_abort(*txn);
-  *txn=0;
+
+  if (trx)
+  {
+    DB_TXN **txn= all ? &trx->all : &trx->stmt;
+    if (*txn)
+    {
+      error=txn_abort(*txn);
+      *txn=0;
+    }
+  }
   DBUG_RETURN(error);
 }
 

--- 1.176/sql/sql_delete.cc	2006-08-15 22:51:16 -07:00
+++ 1.177/sql/sql_delete.cc	2006-08-15 22:51:16 -07:00
@@ -39,6 +39,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   ha_rows	deleted;
   uint usable_index= MAX_KEY;
   SELECT_LEX   *select_lex= &thd->lex->select_lex;
+  int           tx_error= 0;
   DBUG_ENTER("mysql_delete");
 
   if (open_and_lock_tables(thd, table_list))
@@ -298,10 +299,13 @@ cleanup:
       thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
   }
   free_underlaid_joins(thd, select_lex);
-  if (transactional_table)
+
+  /* WARNING: error == 0 *is* an error */
+  /* On success, error == -1 */
+  tx_error= (error >= 0) ? 1 : 0;
+  if (ha_autocommit_or_rollback(thd, tx_error))
   {
-    if (ha_autocommit_or_rollback(thd,error >= 0))
-      error=1;
+    error= 1;
   }
 
   if (thd->lock)

--- 1.197/sql/sql_insert.cc	2006-08-15 22:51:16 -07:00
+++ 1.198/sql/sql_insert.cc	2006-08-15 22:51:16 -07:00
@@ -651,8 +651,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
           thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
       }
     }
-    if (transactional_table)
-      error=ha_autocommit_or_rollback(thd,error);
+
+    error= ha_autocommit_or_rollback(thd, error);
 
     if (thd->lock)
     {

--- 1.96/sql/sql_load.cc	2006-08-15 22:51:16 -07:00
+++ 1.98/sql/sql_load.cc	2006-08-15 22:51:16 -07:00
@@ -406,11 +406,10 @@ bool mysql_load(THD *thd,sql_exchange *e
   */
   query_cache_invalidate3(thd, table_list, 0);
 
+  error= ha_autocommit_or_rollback(thd, error);
+
   if (error)
   {
-    if (transactional_table)
-      ha_autocommit_or_rollback(thd,error);
-
     if (read_file_from_client)
       while (!read_info.next_line())
 	;
@@ -477,8 +476,7 @@ bool mysql_load(THD *thd,sql_exchange *e
 					 ignore, transactional_table);
   }
 #endif /*!EMBEDDED_LIBRARY*/
-  if (transactional_table)
-    error=ha_autocommit_or_rollback(thd,error);
+  error= ha_autocommit_or_rollback(thd, error);
 
 err:
   if (thd->lock)

--- 1.563/sql/sql_parse.cc	2006-08-15 22:51:16 -07:00
+++ 1.564/sql/sql_parse.cc	2006-08-15 22:51:16 -07:00
@@ -2397,6 +2397,183 @@ static void reset_one_shot_variables(THD
     global read lock when it succeeds. This needs to be released by
     start_waiting_global_read_lock() after the operation.
 
+    Note on ha_autocommit_or_rollback() and transactional integrity
+    ===============================================================
+
+    The following statements do manipulate transactions explicitly:
+    - SQLCOM_HA_OPEN
+    - SQLCOM_HA_CLOSE
+    - SQLCOM_HA_READ
+    - SQLCOM_BEGIN
+    - SQLCOM_COMMIT
+    - SQLCOM_ROLLBACK
+    - SQLCOM_RELEASE_SAVEPOINT
+    - SQLCOM_ROLLBACK_TO_SAVEPOINT
+    - SQLCOM_SAVEPOINT
+    - SQLCOM_XA_START
+    - SQLCOM_XA_END
+    - SQLCOM_XA_PREPARE
+    - SQLCOM_XA_COMMIT
+    - SQLCOM_XA_ROLLBACK
+    - SQLCOM_XA_RECOVER
+    - SQLCOM_UNLOCK_TABLES
+    - SQLCOM_LOCK_TABLES
+    For these statements, ha_autocommit_or_rollback should *not* be called.
+    See http://dev.mysql.com/doc/refman/5.1/en/transactional-commands.html
+
+    The following statements do manipulate transactions implicitly:
+    - Data Definition
+      - SQLCOM_CREATE_TABLE
+      - SQLCOM_CREATE_INDEX
+      - SQLCOM_ALTER_TABLE
+      - SQLCOM_RENAME_TABLE
+      - SQLCOM_DROP_TABLE
+      - SQLCOM_DROP_INDEX
+      - SQLCOM_CREATE_DB
+      - SQLCOM_DROP_DB
+      - SQLCOM_ALTER_DB
+      - SQLCOM_CREATE_PROCEDURE
+      - SQLCOM_CREATE_SPFUNCTION
+      - SQLCOM_ALTER_PROCEDURE
+      - SQLCOM_ALTER_FUNCTION
+      - SQLCOM_DROP_PROCEDURE
+      - SQLCOM_DROP_FUNCTION
+      - SQLCOM_CREATE_VIEW
+      - SQLCOM_DROP_VIEW
+      - SQLCOM_CREATE_TRIGGER
+      - SQLCOM_DROP_TRIGGER
+
+    - Data Administration
+      - SQLCOM_CREATE_USER  (FIXME: why ?)
+      - SQLCOM_DROP_USER    (FIXME: why ?)
+      - SQLCOM_RENAME_USER  (FIXME: why ?)
+
+      - SQLCOM_TRUNCATE
+
+    These statements are implemented using code that is not transaction aware,
+    (all the Data Definition Statements manipulate files .frm and other files
+    directly in 5.0 for example)
+    As a result, the implementation for these commands commits the current
+    transaction first, then performs the DDL manipulation.
+    There is no point in calling ha_autocommit_or_rollback(), since the
+    code is *not* transaction-aware (for example, rollback may not be clean
+    and may leave .frm files around).
+
+    LATER: Once the implementation of the DDL statements is transaction-aware,
+    - explicit calls to end_active_trans() should be removed,
+    - a call to ha_autocommit_or_rollback() should be added.
+    See http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html
+
+    The following statements:
+    - SQLCOM_PURGE
+    - SQLCOM_PURGE_BEFORE
+    - SQLCOM_RESET (REFRESH_MASTER)
+    - SQLCOM_SHOW_BINLOG_EVENTS
+    - SQLCOM_SHOW_BINLOGS
+    - SQLCOM_SHOW_MASTER_STAT
+    - SQLCOM_SHOW_SLAVE_HOSTS
+    - SQLCOM_CHANGE_MASTER
+    - SQLCOM_LOAD_MASTER_DATA
+    - SQLCOM_LOAD_MASTER_TABLE
+    - SQLCOM_RESET (REFRESH_SLAVE)
+    - SQLCOM_SHOW_SLAVE_STAT
+    - SQLCOM_SLAVE_START
+    - SQLCOM_SLAVE_STOP
+    are used for replication.
+    No call to ha_autocommit_or_rollback() is needed.
+
+    The following statements:
+    - SQLCOM_PREPARE
+    - SQLCOM_DEALLOCATE_PREPARE
+    - SQLCOM_EMPTY_QUERY
+    - SQLCOM_HELP
+    - SQLCOM_SHOW_WARNS
+    - SQLCOM_SHOW_ERRORS
+    - SQLCOM_ASSIGN_TO_KEYCACHE
+    - SQLCOM_PRELOAD_KEYS
+    - SQLCOM_SHOW_NDBCLUSTER_STATUS
+    - SQLCOM_SHOW_INNODB_STATUS
+    - SQLCOM_SHOW_MUTEX_STATUS
+    - SQLCOM_SHOW_PROCESSLIST
+    - SQLCOM_SHOW_STORAGE_ENGINES
+    - SQLCOM_SHOW_PRIVILEGES
+    - SQLCOM_SHOW_COLUMN_TYPES
+    - SQLCOM_SHOW_LOGS
+    - SQLCOM_SHOW_CREATE_DB
+    - SQLCOM_KILL
+    - SQLCOM_SHOW_GRANTS
+    - SQLCOM_SHOW_CREATE_PROC
+    - SQLCOM_SHOW_CREATE_FUNC
+    - SQLCOM_SHOW_PROC_CODE
+    - SQLCOM_SHOW_FUNC_CODE
+    - SQLCOM_SET_OPTION
+    are known to have no possible side effect on the transactional data.
+    No ha_autocommit_or_rollback() is needed, nor in some cases is desirable
+    (for very low level server state inspection like SQLCOM_SHOW_MUTEX_STATUS).
+
+    The following statements can directly or indirectly modify data,
+    so ha_autocommit_or_rollback() *must* be called for these.
+    Note that indirect manipulation of data is due to side effects,
+    when invoking a stored function, a stored procedure or a trigger.
+    - SQLCOM_SELECT and derivatives
+      - SQLCOM_SHOW_DATABASES
+      - SQLCOM_SHOW_TABLES
+      - SQLCOM_SHOW_TRIGGERS
+      - SQLCOM_SHOW_TABLE_STATUS
+      - SQLCOM_SHOW_OPEN_TABLES
+      - SQLCOM_SHOW_FIELDS
+      - SQLCOM_SHOW_STATUS
+      - SQLCOM_SHOW_VARIABLES
+      - SQLCOM_SHOW_CHARSETS
+      - SQLCOM_SHOW_COLLATIONS
+      - SQLCOM_SHOW_STATUS_PROC
+      - SQLCOM_SHOW_STATUS_FUNC
+    - SQLCOM_EXECUTE
+    - SQLCOM_DO
+    - SQLCOM_UPDATE
+    - SQLCOM_UPDATE_MULTI
+    - SQLCOM_REPLACE
+    - SQLCOM_INSERT
+    - SQLCOM_REPLACE_SELECT
+    - SQLCOM_INSERT_SELECT
+    - SQLCOM_DELETE
+    - SQLCOM_DELETE_MULTI
+    - SQLCOM_LOAD
+    - SQLCOM_CALL
+
+    The following commands:
+    - SQLCOM_REVOKE_ALL
+    - SQLCOM_REVOKE
+    - SQLCOM_GRANT
+    *do* modify data, but in the system tables which are not (as of 5.0)
+    transactional. A call to ha_autocommit_or_rollback() would generate
+    spurious warnings in case of rollback, and should be avoided for now.
+    TODO: Once the system tables are transactional, revise the implementation
+    of these commands.
+
+    The following commands:
+    - SQLCOM_ANALYZE
+    - SQLCOM_BACKUP_TABLE
+    - SQLCOM_CHECKSUM
+    - SQLCOM_OPTIMIZE
+    - SQLCOM_RESTORE_TABLE
+    - SQLCOM_REPAIR
+    are used for data maintenance and administration.
+    No call to ha_autocommit_or_rollback() is needed.
+    See http://dev.mysql.com/doc/refman/5.1/en/table-maintenance-sql.html
+
+    Note that the relative order of code that :
+    - lock tables with storage engines
+    - open / execute / closes cursors, read / write with storage engines
+    - calls ha_autocommit_or_rollback()
+    - unlock tables with storage engines
+    - respond with send_ok(thd) / send_eof(thd) to the client
+    has to be *strictly* respected, otherwise disastrous side effects
+    will occur.
+    As a result, the place where in practice ha_autocommit_or_rollback()
+    is called varies greatly between commands, to comply with the constrainst
+    of the original design.
+
   RETURN
     FALSE       OK
     TRUE        Error
@@ -2571,6 +2748,7 @@ mysql_execute_command(THD *thd)
           goto error;
 	query_cache_store_query(thd, all_tables);
 	res= handle_select(thd, lex, result, 0);
+        res= ha_autocommit_or_rollback(thd, res);
         if (result != lex->result)
           delete result;
       }
@@ -2585,6 +2763,11 @@ mysql_execute_command(THD *thd)
   case SQLCOM_EXECUTE:
   {
     mysql_sql_stmt_execute(thd);
+    /*
+      mysql_sql_stmt_execute() does recursively call
+      mysql_execute_command(), which performs the commit/rollback
+      for the prepared statement.
+    */
     break;
   }
   case SQLCOM_DEALLOCATE_PREPARE:
@@ -3279,9 +3462,18 @@ end_with_restore_list:
                                (ORDER *) select_lex->order_list.first,
                                unit->select_limit_cnt,
                                lex->duplicates, lex->ignore));
-    /* mysql_update return 2 if we need to switch to multi-update */
+    /*
+     mysql_update return 2 if we need to switch to multi-update.
+     Note that in this case, mysql_update() did no processing,
+     and that the current statement transaction is still opened.
+     It will be commited/rollbacked by the MULTI-UPDATE code below.
+     TODO: refactor this code.
+     */
     if (result != 2)
+    {
       break;
+    }
+    /* FALL THOUGH */
   case SQLCOM_UPDATE_MULTI:
   {
     DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -3336,6 +3528,7 @@ end_with_restore_list:
                             select_lex->where,
                             select_lex->options,
                             lex->duplicates, lex->ignore, unit, select_lex);
+    res= ha_autocommit_or_rollback(thd, res);
     break;
   }
   case SQLCOM_REPLACE:
@@ -3357,6 +3550,7 @@ end_with_restore_list:
     res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
 		      lex->update_list, lex->value_list,
                       lex->duplicates, lex->ignore);
+    /* ha_autocommit_or_rollback() performed by mysql_insert() */
     if (first_table->view && !first_table->contain_auto_increment)
       thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
     break;
@@ -3400,6 +3594,7 @@ end_with_restore_list:
                                              lex->duplicates, lex->ignore)))
       {
 	res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
+        res= ha_autocommit_or_rollback(thd, res);
         /*
           Invalidate the table in the query cache if something changed
           after unlocking when changes become visible.
@@ -3464,6 +3659,7 @@ end_with_restore_list:
                        &select_lex->order_list,
                        unit->select_limit_cnt, select_lex->options,
                        FALSE);
+    /* ha_autocommit_or_rollback() performed by mysql_delete() */
     break;
   }
   case SQLCOM_DELETE_MULTI:
@@ -3510,6 +3706,7 @@ end_with_restore_list:
 			SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
                         OPTION_SETUP_TABLES_DONE,
 			result, unit, select_lex);
+      res= ha_autocommit_or_rollback(thd, res);
       delete result;
     }
     else
@@ -3615,6 +3812,7 @@ end_with_restore_list:
     res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
                     lex->update_list, lex->value_list, lex->duplicates,
                     lex->ignore, (bool) lex->local_file);
+    /* ha_autocommit_or_rollback() performed by mysql_load() */
     break;
   }
 
@@ -3882,7 +4080,9 @@ end_with_restore_list:
     if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
-    if (!(res = mysql_revoke_all(thd, lex->users_list)))
+    res= mysql_revoke_all(thd, lex->users_list);
+    /* LATER: res= ha_autocommit_or_rollback(thd, res); */
+    if (!res)
     {
       if (mysql_bin_log.is_open())
       {
@@ -3953,6 +4153,7 @@ end_with_restore_list:
                                  lex->type == TYPE_ENUM_PROCEDURE, 
                                  lex->users_list, grants,
                                  lex->sql_command == SQLCOM_REVOKE, 0);
+        /* LATER: res= ha_autocommit_or_rollback(thd, res); */
       }
       else
       {
@@ -3964,6 +4165,7 @@ end_with_restore_list:
         res= mysql_table_grant(thd, all_tables, lex->users_list,
 			       lex->columns, lex->grant,
 			       lex->sql_command == SQLCOM_REVOKE);
+        /* LATER: res= ha_autocommit_or_rollback(thd, res); */
       }
       if (!res && mysql_bin_log.is_open())
       {
@@ -3981,8 +4183,11 @@ end_with_restore_list:
         goto error;
       }
       else
+      {
 	res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
 			  lex->sql_command == SQLCOM_REVOKE);
+        /* LATER: res= ha_autocommit_or_rollback(thd, res); */
+      }
       if (!res)
       {
 	if (mysql_bin_log.is_open())
@@ -4474,6 +4679,11 @@ end_with_restore_list:
           So just execute the statement.
         */
 	res= sp->execute_procedure(thd, &lex->value_list);
+        /*
+          sp_head::execute_statement() does recursively call
+          mysql_execute_command(), which performs the commit/rollback
+          for the statements inside the procedure.
+        */
 	/*
           If warnings have been cleared, we have to clear total_warn_count
           too, otherwise the clients get confused.

--- 1.439/sql/sql_select.cc	2006-08-15 22:51:16 -07:00
+++ 1.440/sql/sql_select.cc	2006-08-15 22:51:16 -07:00
@@ -1914,7 +1914,7 @@ mysql_select(THD *thd, Item ***rref_poin
 	     select_result *result, SELECT_LEX_UNIT *unit,
 	     SELECT_LEX *select_lex)
 {
-  bool err;
+  bool err= FALSE;
   bool free_join= 1;
   DBUG_ENTER("mysql_select");
 

--- 1.194/sql/sql_update.cc	2006-08-15 22:51:16 -07:00
+++ 1.195/sql/sql_update.cc	2006-08-15 22:51:16 -07:00
@@ -137,6 +137,7 @@ int mysql_update(THD *thd,
   READ_RECORD	info;
   SELECT_LEX    *select_lex= &thd->lex->select_lex;
   bool need_reopen;
+  int tx_error= 0;
   DBUG_ENTER("mysql_update");
 
   LINT_INIT(timestamp_query_id);
@@ -548,10 +549,13 @@ int mysql_update(THD *thd,
       thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
   }
   free_underlaid_joins(thd, select_lex);
-  if (transactional_table)
+
+  /* WARNING: error == 0 *is* an error */
+  /* On success, error == -1 */
+  tx_error= (error >= 0) ? 1 : 0;
+  if (ha_autocommit_or_rollback(thd, tx_error))
   {
-    if (ha_autocommit_or_rollback(thd, error >= 0))
-      error=1;
+    error= 1;
   }
 
   if (thd->lock)
@@ -899,6 +903,8 @@ bool mysql_multi_update(THD *thd,
                         enum enum_duplicates handle_duplicates, bool ignore,
                         SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
 {
+  int error= 0;
+  bool brc= FALSE;
   multi_update *result;
   DBUG_ENTER("mysql_multi_update");
 
@@ -914,7 +920,7 @@ bool mysql_multi_update(THD *thd,
                                MODE_STRICT_ALL_TABLES));
 
   List<Item> total_list;
-  (void) mysql_select(thd, &select_lex->ref_pointer_array,
+  error= mysql_select(thd, &select_lex->ref_pointer_array,
                       table_list, select_lex->with_wild,
                       total_list,
                       conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
@@ -924,7 +930,8 @@ bool mysql_multi_update(THD *thd,
                       result, unit, select_lex);
   delete result;
   thd->abort_on_warning= 0;
-  DBUG_RETURN(FALSE);
+  brc= (error ? TRUE : FALSE);
+  DBUG_RETURN(brc);
 }
 
 
@@ -1546,11 +1553,7 @@ bool multi_update::send_eof()
       thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
   }
 
-  if (transactional_tables)
-  {
-    if (ha_autocommit_or_rollback(thd, local_error != 0))
-      local_error=1;
-  }
+  local_error= ha_autocommit_or_rollback(thd, local_error);
 
   if (local_error > 0) // if the above log write did not fail ...
   {

--- 1.153/mysql-test/r/subselect.result	2006-08-15 22:51:16 -07:00
+++ 1.154/mysql-test/r/subselect.result	2006-08-15 22:51:16 -07:00
@@ -1600,8 +1600,7 @@ insert into t1 values (2);
 set sort_buffer_size = (select s1 from t1);
 ERROR 21000: Subquery returns more than 1 row
 do (select * from t1);
-Warnings:
-Error	1242	Subquery returns more than 1 row
+ERROR 21000: Subquery returns more than 1 row
 drop table t1;
 create table t1 (s1 char);
 insert into t1 values ('e');

--- 1.124/mysql-test/t/subselect.test	2006-08-15 22:51:16 -07:00
+++ 1.125/mysql-test/t/subselect.test	2006-08-15 22:51:16 -07:00
@@ -971,8 +971,9 @@ DROP TABLE t1,t2;
 create table t1 (s1 int);
 insert into t1 values (1);
 insert into t1 values (2);
--- error 1242
+-- error ER_SUBQUERY_NO_1_ROW
 set sort_buffer_size = (select s1 from t1);
+-- error ER_SUBQUERY_NO_1_ROW
 do (select * from t1);
 drop table t1;
 

--- 1.18/mysql-test/r/rpl_sp.result	2006-08-15 22:51:16 -07:00
+++ 1.19/mysql-test/r/rpl_sp.result	2006-08-15 22:51:16 -07:00
@@ -240,8 +240,7 @@ insert into t2 values(x),(x);
 return 10;
 end|
 do fn1(100);
-Warnings:
-Error	1062	Duplicate entry '100' for key 1
+ERROR 23000: Duplicate entry '100' for key 1
 select fn1(20);
 ERROR 23000: Duplicate entry '20' for key 1
 select * from t2;

--- 1.13/mysql-test/t/rpl_sp.test	2006-08-15 22:51:16 -07:00
+++ 1.14/mysql-test/t/rpl_sp.test	2006-08-15 22:51:16 -07:00
@@ -303,9 +303,10 @@ end|
 
 delimiter ;|
 
+--error ER_DUP_ENTRY
 do fn1(100);
 
---error 1062
+--error ER_DUP_ENTRY
 select fn1(20);
 
 select * from t2;

--- 1.32/mysql-test/t/disabled.def	2006-08-15 22:51:16 -07:00
+++ 1.33/mysql-test/t/disabled.def	2006-08-15 22:51:16 -07:00
@@ -12,3 +12,6 @@
 
 ndb_load        : Bug#17233
 lowercase_fs_off : Bug#21419
+engine_mix_bdb_ndb : Bug#21590
+engine_mix_myisam_ndb : Bug#21590
+autocommit_ndb : Bug#21667

--- 1.273/sql/ha_ndbcluster.cc	2006-08-15 22:51:16 -07:00
+++ 1.274/sql/ha_ndbcluster.cc	2006-08-15 22:51:16 -07:00
@@ -3765,36 +3765,37 @@ int ndbcluster_commit(THD *thd, bool all
   DBUG_PRINT("transaction",("%s",
                             trans == thd_ndb->stmt ?
                             "stmt" : "all"));
-  DBUG_ASSERT(ndb && trans);
-
-  if (execute_commit(thd,trans) != 0)
-  {
-    const NdbError err= trans->getNdbError();
-    const NdbOperation *error_op= trans->getNdbErrorOperation();
-    ERR_PRINT(err);
-    res= ndb_to_mysql_error(&err);
-    if (res != -1)
-      ndbcluster_print_error(res, error_op);
-  }
-  ndb->closeTransaction(trans);
-
-  if (all)
-    thd_ndb->all= NULL;
-  else
-    thd_ndb->stmt= NULL;
-
-  /* Clear commit_count for tables changed by transaction */
-  NDB_SHARE* share;
-  List_iterator_fast<NDB_SHARE> it(thd_ndb->changed_tables);
-  while ((share= it++))
+  if (ndb && trans)
   {
-    pthread_mutex_lock(&share->mutex);
-    DBUG_PRINT("info", ("Invalidate commit_count for %s, share->commit_count: %d ", share->table_name, share->commit_count));
-    share->commit_count= 0;
-    share->commit_count_lock++;
-    pthread_mutex_unlock(&share->mutex);
+    if (execute_commit(thd,trans) != 0)
+    {
+      const NdbError err= trans->getNdbError();
+      const NdbOperation *error_op= trans->getNdbErrorOperation();
+      ERR_PRINT(err);
+      res= ndb_to_mysql_error(&err);
+      if (res != -1)
+        ndbcluster_print_error(res, error_op);
+    }
+    ndb->closeTransaction(trans);
+
+    if (all)
+      thd_ndb->all= NULL;
+    else
+      thd_ndb->stmt= NULL;
+
+    /* Clear commit_count for tables changed by transaction */
+    NDB_SHARE* share;
+    List_iterator_fast<NDB_SHARE> it(thd_ndb->changed_tables);
+    while ((share= it++))
+    {
+      pthread_mutex_lock(&share->mutex);
+      DBUG_PRINT("info", ("Invalidate commit_count for %s, share->commit_count: %d ", share->table_name, share->commit_count));
+      share->commit_count= 0;
+      share->commit_count_lock++;
+      pthread_mutex_unlock(&share->mutex);
+    }
+    thd_ndb->changed_tables.empty();
   }
-  thd_ndb->changed_tables.empty();
 
   DBUG_RETURN(res);
 }
@@ -3815,26 +3816,27 @@ int ndbcluster_rollback(THD *thd, bool a
   DBUG_PRINT("transaction",("%s",
                             trans == thd_ndb->stmt ? 
                             "stmt" : "all"));
-  DBUG_ASSERT(ndb && trans);
-
-  if (trans->execute(NdbTransaction::Rollback) != 0)
+  if (ndb && trans)
   {
-    const NdbError err= trans->getNdbError();
-    const NdbOperation *error_op= trans->getNdbErrorOperation();
-    ERR_PRINT(err);     
-    res= ndb_to_mysql_error(&err);
-    if (res != -1) 
-      ndbcluster_print_error(res, error_op);
-  }
-  ndb->closeTransaction(trans);
+    if (trans->execute(NdbTransaction::Rollback) != 0)
+    {
+      const NdbError err= trans->getNdbError();
+      const NdbOperation *error_op= trans->getNdbErrorOperation();
+      ERR_PRINT(err);     
+      res= ndb_to_mysql_error(&err);
+      if (res != -1) 
+        ndbcluster_print_error(res, error_op);
+    }
+    ndb->closeTransaction(trans);
+
+    if (all)
+      thd_ndb->all= NULL;
+    else
+      thd_ndb->stmt= NULL;
 
-  if (all)
-    thd_ndb->all= NULL;
-  else
-    thd_ndb->stmt= NULL;
-
-  /* Clear list of tables changed by transaction */
-  thd_ndb->changed_tables.empty();
+    /* Clear list of tables changed by transaction */
+    thd_ndb->changed_tables.empty();
+  }
 
   DBUG_RETURN(res);
 }
--- New file ---
+++ mysql-test/include/autocommit_common.inc	06/08/15 19:28:18

## Bug#12713 (Error in a stored function called from a SELECT doesn't cause
##    ROLLBACK of statem)

##
## Pre-Requisites :
## - $engine_type should be set
##

set autocommit=1;

--disable_warnings
drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop function if exists f2;
drop procedure if exists p1;
--enable_warnings

eval create table t1 (a int) engine = $engine_type;
eval create table t2 (a int unique) engine = $engine_type;
eval create table t3 (a int) engine = $engine_type;

insert into t1 (a) values (1), (2);
insert into t3 (a) values (1), (2);

delimiter //;

## Cause a failure every time
create function f2(x int) returns int
begin
  insert into t2 (a) values (x);
  insert into t2 (a) values (x);
  return x;
end//

create procedure p1 ()
begin
  insert into t2 (a) values (24);
  insert into t2 (a) values (24);
end//

delimiter ;//

set autocommit=0;

## In each case, statement rollback is expected
## for transactional engines, the rollback should be properly executed
## for non transactional engines, the rollback may cause warnings

insert into t2 (a) values (1001);
--error ER_DUP_ENTRY
insert into t1 (a) values (f2(1));
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1002);
--error ER_DUP_ENTRY
insert into t3 (a) select f2(2) from t1;
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1003);
--error ER_DUP_ENTRY
update t1 set a= a + f2(3);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1004);
--error ER_DUP_ENTRY
update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1005);
--error ER_DUP_ENTRY
delete from t1 where (a = f2(5));
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1006);
--error ER_DUP_ENTRY
delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1007);
--error ER_DUP_ENTRY
replace t1 values (f2(7));
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1008);
--error ER_DUP_ENTRY
replace into t3 (a) select f2(8) from t1;
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1009);
--error ER_DUP_ENTRY
select f2(9) from t1 ;
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1010);
--error ER_DUP_ENTRY
show databases where (f2(10) = 10);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1011);
--error ER_DUP_ENTRY
show tables where (f2(11) = 11);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1012);
--error ER_DUP_ENTRY
show triggers where (f2(12) = 12);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1013);
--error ER_DUP_ENTRY
show table status where (f2(13) = 13);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1014);
--error ER_DUP_ENTRY
show open tables where (f2(14) = 14);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1015);
--error ER_DUP_ENTRY
show columns in mysql.proc where (f2(15) = 15);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1016);
--error ER_DUP_ENTRY
show status where (f2(16) = 16);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1017);
--error ER_DUP_ENTRY
show variables where (f2(17) = 17);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1018);
--error ER_DUP_ENTRY
show charset where (f2(18) = 18);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1019);
--error ER_DUP_ENTRY
show collation where (f2(19) = 19);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1020);
--error ER_DUP_ENTRY
show procedure status where (f2(20) = 20);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1021);
--error ER_DUP_ENTRY
show function status where (f2(21) = 21);
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1022);
prepare stmt from "insert into t1 (a) values (f2(22))";
--error ER_DUP_ENTRY
execute stmt;
select * from t2;
rollback;
select * from t2;
commit;

insert into t2 (a) values (1023);
--error ER_DUP_ENTRY
do (f2(23));
select * from t2;
rollback;
select * from t2;
commit;

## Please note :
## This will insert a record 1024 in t1 (statement commit)
## This will insert a record 24 in t1 (statement commit)
## then will rollback the second insert only (24) (statement rollback)
## then will rollback the complete transaction (transaction rollback)

insert into t2 (a) values (1024);
--error ER_DUP_ENTRY
call p1();
select * from t2;
rollback;
select * from t2;
commit;

set autocommit=1;

drop table t1;
drop table t2;
drop table t3;
drop function f2;
drop procedure p1;


--- New file ---
+++ mysql-test/include/engine_mix_common.inc	06/08/15 19:23:20

## Bug#12713 (Error in a stored function called from a SELECT doesn't cause
##    ROLLBACK of statem)

##
## Pre-Requisites :
## - $engine_type_1 should be set
## - $engine_type_2 should be set
##

set autocommit=1;

--disable_warnings
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
--enable_warnings

eval create table t1 (a int) engine = $engine_type_1;
eval create table t2 (a int unique) engine = $engine_type_2;

insert into t1 (a) values (1), (2);

delimiter //;

## Cause a failure every time
create function f2_hard(x int) returns int
begin
  insert into t2 (a) values (x);
  insert into t2 (a) values (x);
  return x;
end//

## May or may not fail
## the second parameter is not used ...
## ... but the optimizer does not know that.
create function f2_soft(x int, y int) returns int
begin
  insert into t2 (a) values (x);
  return x;
end//
delimiter ;//

set autocommit=0;

## In each case, statement rollback is expected
## for transactional engines, the rollback should be properly executed
## for non transactional engines, the rollback may cause warnings

## Causing failures in engine_2 only

--error ER_DUP_ENTRY
insert into t1 (a) values (f2_hard(1));
select * from t2;
rollback;
select * from t2;
commit;

--error ER_DUP_ENTRY
update t1 set a= a + f2_hard(2);
select * from t2;
rollback;
select * from t2;
commit;

--error ER_DUP_ENTRY
delete from t1 where (a = f2_hard(3));
select * from t2;
rollback;
select * from t2;
commit;

--error ER_DUP_ENTRY
select f2_hard(4) from t1 ;
select * from t2;
rollback;
select * from t2;
commit;

## Causing engine_2 to have pending transactions,
## then engine_1 to have pending transactions,
## then failures in engine_2
## The extras 'delete from t2' are to cleanup after non transactional engines.

delete from t2;
commit;

--error ER_DUP_ENTRY
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
select * from t2;
rollback;
select * from t2;
commit;
delete from t2;
commit;

--error ER_DUP_ENTRY
update t1 set a= a + f2_soft(2, a);
select * from t2;
rollback;
select * from t2;
commit;
delete from t2;
commit;

## This one needs adjustment (in the test)
## --error ER_DUP_ENTRY
## delete from t1 where ((a + 3) = (a + f2_soft(3, a)));
## select * from t2;
## rollback;
## select * from t2;
## commit;
## delete from t2;
## commit;

--error ER_DUP_ENTRY
select f2_soft(4, a) from t1 ;
select * from t2;
rollback;
select * from t2;
commit;
delete from t2;
commit;

set autocommit=1;

drop table t1, t2;
drop function f2_hard;
drop function f2_soft;


--- New file ---
+++ mysql-test/r/autocommit_bdb.result	06/08/15 19:26:56
set autocommit=1;
drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop function if exists f2;
drop procedure if exists p1;
create table t1 (a int) engine = BerkeleyDB;
create table t2 (a int unique) engine = BerkeleyDB;
create table t3 (a int) engine = BerkeleyDB;
insert into t1 (a) values (1), (2);
insert into t3 (a) values (1), (2);
create function f2(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create procedure p1 ()
begin
insert into t2 (a) values (24);
insert into t2 (a) values (24);
end//
set autocommit=0;
insert into t2 (a) values (1001);
insert into t1 (a) values (f2(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1001
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1002);
insert into t3 (a) select f2(2) from t1;
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
1002
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1003);
update t1 set a= a + f2(3);
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
1003
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1004);
update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
1004
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
insert into t2 (a) values (1005);
delete from t1 where (a = f2(5));
ERROR 23000: Duplicate entry '5' for key 1
select * from t2;
a
1005
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1006);
delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
ERROR 23000: Duplicate entry '6' for key 1
select * from t2;
a
1006
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1007);
replace t1 values (f2(7));
ERROR 23000: Duplicate entry '7' for key 1
select * from t2;
a
1007
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1008);
replace into t3 (a) select f2(8) from t1;
ERROR 23000: Duplicate entry '8' for key 1
select * from t2;
a
1008
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1009);
select f2(9) from t1 ;
ERROR 23000: Duplicate entry '9' for key 1
select * from t2;
a
1009
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1010);
show databases where (f2(10) = 10);
ERROR 23000: Duplicate entry '10' for key 1
select * from t2;
a
1010
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1011);
show tables where (f2(11) = 11);
ERROR 23000: Duplicate entry '11' for key 1
select * from t2;
a
1011
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1012);
show triggers where (f2(12) = 12);
ERROR 23000: Duplicate entry '12' for key 1
select * from t2;
a
1012
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1013);
show table status where (f2(13) = 13);
ERROR 23000: Duplicate entry '13' for key 1
select * from t2;
a
1013
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1014);
show open tables where (f2(14) = 14);
ERROR 23000: Duplicate entry '14' for key 1
select * from t2;
a
1014
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1015);
show columns in mysql.proc where (f2(15) = 15);
ERROR 23000: Duplicate entry '15' for key 1
select * from t2;
a
1015
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1016);
show status where (f2(16) = 16);
ERROR 23000: Duplicate entry '16' for key 1
select * from t2;
a
1016
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1017);
show variables where (f2(17) = 17);
ERROR 23000: Duplicate entry '17' for key 1
select * from t2;
a
1017
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1018);
show charset where (f2(18) = 18);
ERROR 23000: Duplicate entry '18' for key 1
select * from t2;
a
1018
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1019);
show collation where (f2(19) = 19);
ERROR 23000: Duplicate entry '19' for key 1
select * from t2;
a
1019
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1020);
show procedure status where (f2(20) = 20);
ERROR 23000: Duplicate entry '20' for key 1
select * from t2;
a
1020
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1021);
show function status where (f2(21) = 21);
ERROR 23000: Duplicate entry '21' for key 1
select * from t2;
a
1021
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1022);
prepare stmt from "insert into t1 (a) values (f2(22))";
execute stmt;
ERROR 23000: Duplicate entry '22' for key 1
select * from t2;
a
1022
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1023);
do (f2(23));
ERROR 23000: Duplicate entry '23' for key 1
select * from t2;
a
1023
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1024);
call p1();
ERROR 23000: Duplicate entry '24' for key 1
select * from t2;
a
24
1024
rollback;
select * from t2;
a
commit;
set autocommit=1;
drop table t1;
drop table t2;
drop table t3;
drop function f2;
drop procedure p1;

--- New file ---
+++ mysql-test/r/autocommit_innodb.result	06/08/15 19:27:14
set autocommit=1;
drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop function if exists f2;
drop procedure if exists p1;
create table t1 (a int) engine = InnoDB;
create table t2 (a int unique) engine = InnoDB;
create table t3 (a int) engine = InnoDB;
insert into t1 (a) values (1), (2);
insert into t3 (a) values (1), (2);
create function f2(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create procedure p1 ()
begin
insert into t2 (a) values (24);
insert into t2 (a) values (24);
end//
set autocommit=0;
insert into t2 (a) values (1001);
insert into t1 (a) values (f2(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1001
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1002);
insert into t3 (a) select f2(2) from t1;
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
1002
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1003);
update t1 set a= a + f2(3);
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
1003
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1004);
update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
1004
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
insert into t2 (a) values (1005);
delete from t1 where (a = f2(5));
ERROR 23000: Duplicate entry '5' for key 1
select * from t2;
a
1005
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1006);
delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
ERROR 23000: Duplicate entry '6' for key 1
select * from t2;
a
1006
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1007);
replace t1 values (f2(7));
ERROR 23000: Duplicate entry '7' for key 1
select * from t2;
a
1007
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1008);
replace into t3 (a) select f2(8) from t1;
ERROR 23000: Duplicate entry '8' for key 1
select * from t2;
a
1008
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1009);
select f2(9) from t1 ;
ERROR 23000: Duplicate entry '9' for key 1
select * from t2;
a
1009
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1010);
show databases where (f2(10) = 10);
ERROR 23000: Duplicate entry '10' for key 1
select * from t2;
a
1010
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1011);
show tables where (f2(11) = 11);
ERROR 23000: Duplicate entry '11' for key 1
select * from t2;
a
1011
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1012);
show triggers where (f2(12) = 12);
ERROR 23000: Duplicate entry '12' for key 1
select * from t2;
a
1012
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1013);
show table status where (f2(13) = 13);
ERROR 23000: Duplicate entry '13' for key 1
select * from t2;
a
1013
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1014);
show open tables where (f2(14) = 14);
ERROR 23000: Duplicate entry '14' for key 1
select * from t2;
a
1014
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1015);
show columns in mysql.proc where (f2(15) = 15);
ERROR 23000: Duplicate entry '15' for key 1
select * from t2;
a
1015
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1016);
show status where (f2(16) = 16);
ERROR 23000: Duplicate entry '16' for key 1
select * from t2;
a
1016
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1017);
show variables where (f2(17) = 17);
ERROR 23000: Duplicate entry '17' for key 1
select * from t2;
a
1017
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1018);
show charset where (f2(18) = 18);
ERROR 23000: Duplicate entry '18' for key 1
select * from t2;
a
1018
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1019);
show collation where (f2(19) = 19);
ERROR 23000: Duplicate entry '19' for key 1
select * from t2;
a
1019
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1020);
show procedure status where (f2(20) = 20);
ERROR 23000: Duplicate entry '20' for key 1
select * from t2;
a
1020
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1021);
show function status where (f2(21) = 21);
ERROR 23000: Duplicate entry '21' for key 1
select * from t2;
a
1021
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1022);
prepare stmt from "insert into t1 (a) values (f2(22))";
execute stmt;
ERROR 23000: Duplicate entry '22' for key 1
select * from t2;
a
1022
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1023);
do (f2(23));
ERROR 23000: Duplicate entry '23' for key 1
select * from t2;
a
1023
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1024);
call p1();
ERROR 23000: Duplicate entry '24' for key 1
select * from t2;
a
24
1024
rollback;
select * from t2;
a
commit;
set autocommit=1;
drop table t1;
drop table t2;
drop table t3;
drop function f2;
drop procedure p1;

--- New file ---
+++ mysql-test/r/autocommit_ndb.result	06/08/15 19:27:31
set autocommit=1;
drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop function if exists f2;
drop procedure if exists p1;
create table t1 (a int) engine = ndbcluster;
create table t2 (a int unique) engine = ndbcluster;
create table t3 (a int) engine = ndbcluster;
insert into t1 (a) values (1), (2);
insert into t3 (a) values (1), (2);
create function f2(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create procedure p1 ()
begin
insert into t2 (a) values (24);
insert into t2 (a) values (24);
end//
set autocommit=0;
insert into t2 (a) values (1001);
insert into t1 (a) values (f2(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1001
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1002);
insert into t3 (a) select f2(2) from t1;
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
1002
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1003);
update t1 set a= a + f2(3);
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
1003
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1004);
update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
1004
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
insert into t2 (a) values (1005);
delete from t1 where (a = f2(5));
ERROR 23000: Duplicate entry '5' for key 1
select * from t2;
a
1005
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1006);
delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
ERROR 23000: Duplicate entry '6' for key 1
select * from t2;
a
1006
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1007);
replace t1 values (f2(7));
ERROR 23000: Duplicate entry '7' for key 1
select * from t2;
a
1007
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1008);
replace into t3 (a) select f2(8) from t1;
ERROR 23000: Duplicate entry '8' for key 1
select * from t2;
a
1008
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1009);
select f2(9) from t1 ;
ERROR 23000: Duplicate entry '9' for key 1
select * from t2;
a
1009
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1010);
show databases where (f2(10) = 10);
ERROR 23000: Duplicate entry '10' for key 1
select * from t2;
a
1010
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1011);
show tables where (f2(11) = 11);
ERROR 23000: Duplicate entry '11' for key 1
select * from t2;
a
1011
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1012);
show triggers where (f2(12) = 12);
ERROR 23000: Duplicate entry '12' for key 1
select * from t2;
a
1012
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1013);
show table status where (f2(13) = 13);
ERROR 23000: Duplicate entry '13' for key 1
select * from t2;
a
1013
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1014);
show open tables where (f2(14) = 14);
ERROR 23000: Duplicate entry '14' for key 1
select * from t2;
a
1014
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1015);
show columns in mysql.proc where (f2(15) = 15);
ERROR 23000: Duplicate entry '15' for key 1
select * from t2;
a
1015
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1016);
show status where (f2(16) = 16);
ERROR 23000: Duplicate entry '16' for key 1
select * from t2;
a
1016
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1017);
show variables where (f2(17) = 17);
ERROR 23000: Duplicate entry '17' for key 1
select * from t2;
a
1017
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1018);
show charset where (f2(18) = 18);
ERROR 23000: Duplicate entry '18' for key 1
select * from t2;
a
1018
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1019);
show collation where (f2(19) = 19);
ERROR 23000: Duplicate entry '19' for key 1
select * from t2;
a
1019
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1020);
show procedure status where (f2(20) = 20);
ERROR 23000: Duplicate entry '20' for key 1
select * from t2;
a
1020
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1021);
show function status where (f2(21) = 21);
ERROR 23000: Duplicate entry '21' for key 1
select * from t2;
a
1021
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1022);
prepare stmt from "insert into t1 (a) values (f2(22))";
execute stmt;
ERROR 23000: Duplicate entry '22' for key 1
select * from t2;
a
1022
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1023);
do (f2(23));
ERROR 23000: Duplicate entry '23' for key 1
select * from t2;
a
1023
rollback;
select * from t2;
a
commit;
insert into t2 (a) values (1024);
call p1();
ERROR 23000: Duplicate entry '24' for key 1
select * from t2;
a
24
1024
rollback;
select * from t2;
a
commit;
set autocommit=1;
drop table t1;
drop table t2;
drop table t3;
drop function f2;
drop procedure p1;

--- New file ---
+++ mysql-test/r/engine_mix_bdb_innodb.result	06/08/15 19:16:44
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = BerkeleyDB;
create table t2 (a int unique) engine = InnoDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_bdb_myisam.result	06/08/15 19:18:29
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = BerkeleyDB;
create table t2 (a int unique) engine = MyISAM;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1
rollback;
select * from t2;
a
1
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
1
2
rollback;
select * from t2;
a
1
2
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
1
2
3
rollback;
select * from t2;
a
1
2
3
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
1
2
3
4
rollback;
select * from t2;
a
1
2
3
4
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1
rollback;
select * from t2;
a
1
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
2
rollback;
select * from t2;
a
2
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
4
rollback;
select * from t2;
a
4
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_bdb_ndb.result	06/08/15 19:17:01
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = BerkeleyDB;
create table t2 (a int unique) engine = ndbcluster;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_innodb_bdb.result	06/08/15 19:18:44
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = InnoDB;
create table t2 (a int unique) engine = BerkeleyDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_innodb_myisam.result	06/08/15 19:19:01
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = InnoDB;
create table t2 (a int unique) engine = MyISAM;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1
rollback;
select * from t2;
a
1
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
1
2
rollback;
select * from t2;
a
1
2
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
1
2
3
rollback;
select * from t2;
a
1
2
3
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
1
2
3
4
rollback;
select * from t2;
a
1
2
3
4
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1
rollback;
select * from t2;
a
1
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
2
rollback;
select * from t2;
a
2
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
4
rollback;
select * from t2;
a
4
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_innodb_ndb.result	06/08/15 19:17:53
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = ndbcluster;
create table t2 (a int unique) engine = InnoDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_myisam_bdb.result	06/08/15 19:19:17
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = MyISAM;
create table t2 (a int unique) engine = BerkeleyDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_myisam_innodb.result	06/08/15 19:19:48
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = MyISAM;
create table t2 (a int unique) engine = InnoDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_myisam_ndb.result	06/08/15 19:18:09
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = MyISAM;
create table t2 (a int unique) engine = ndbcluster;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
Warnings:
Warning	1196	Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_ndb_bdb.result	06/08/15 19:21:29
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = ndbcluster;
create table t2 (a int unique) engine = BerkeleyDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_ndb_innodb.result	06/08/15 19:21:44
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = ndbcluster;
create table t2 (a int unique) engine = InnoDB;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
rollback;
select * from t2;
a
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/r/engine_mix_ndb_myisam.result	06/08/15 19:22:02
set autocommit=1;
drop table if exists t1, t2;
drop function if exists f2_hard;
drop function if exists f2_soft;
create table t1 (a int) engine = ndbcluster;
create table t2 (a int unique) engine = MyISAM;
insert into t1 (a) values (1), (2);
create function f2_hard(x int) returns int
begin
insert into t2 (a) values (x);
insert into t2 (a) values (x);
return x;
end//
create function f2_soft(x int, y int) returns int
begin
insert into t2 (a) values (x);
return x;
end//
set autocommit=0;
insert into t1 (a) values (f2_hard(1));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1
rollback;
select * from t2;
a
1
commit;
update t1 set a= a + f2_hard(2);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
1
2
rollback;
select * from t2;
a
1
2
commit;
delete from t1 where (a = f2_hard(3));
ERROR 23000: Duplicate entry '3' for key 1
select * from t2;
a
1
2
3
rollback;
select * from t2;
a
1
2
3
commit;
select f2_hard(4) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
1
2
3
4
rollback;
select * from t2;
a
1
2
3
4
commit;
delete from t2;
commit;
insert into t1 (a) values (f2_soft(1, 2)), (f2_soft(1, 3));
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
a
1
rollback;
select * from t2;
a
1
commit;
delete from t2;
commit;
update t1 set a= a + f2_soft(2, a);
ERROR 23000: Duplicate entry '2' for key 1
select * from t2;
a
2
rollback;
select * from t2;
a
2
commit;
delete from t2;
commit;
select f2_soft(4, a) from t1 ;
ERROR 23000: Duplicate entry '4' for key 1
select * from t2;
a
4
rollback;
select * from t2;
a
4
commit;
delete from t2;
commit;
set autocommit=1;
drop table t1, t2;
drop function f2_hard;
drop function f2_soft;

--- New file ---
+++ mysql-test/t/autocommit_bdb.test	06/08/15 19:25:30
-- source include/have_bdb.inc

let $engine_type = BerkeleyDB;

-- source include/autocommit_common.inc


--- New file ---
+++ mysql-test/t/autocommit_innodb.test	06/08/15 19:25:42
-- source include/have_innodb.inc

let $engine_type = InnoDB;

-- source include/autocommit_common.inc


--- New file ---
+++ mysql-test/t/autocommit_ndb.test	06/08/15 19:25:55
-- source include/have_ndb.inc

let $engine_type = ndbcluster;

-- source include/autocommit_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_bdb_innodb.test	06/08/15 19:12:17
-- source include/have_bdb.inc
-- source include/have_innodb.inc

let $engine_type_1 = BerkeleyDB;
let $engine_type_2 = InnoDB;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_bdb_myisam.test	06/08/15 19:12:00
-- source include/have_bdb.inc
## -- source include/have_myisam.inc

let $engine_type_1 = BerkeleyDB;
let $engine_type_2 = MyISAM;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_bdb_ndb.test	06/08/15 19:12:35
-- source include/have_bdb.inc
-- source include/have_ndb.inc

let $engine_type_1 = BerkeleyDB;
let $engine_type_2 = ndbcluster;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_innodb_bdb.test	06/08/15 19:12:51
-- source include/have_innodb.inc
-- source include/have_bdb.inc

let $engine_type_1 = InnoDB;
let $engine_type_2 = BerkeleyDB;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_innodb_myisam.test	06/08/15 19:13:04
-- source include/have_innodb.inc
## -- source include/have_myisam.inc

let $engine_type_1 = InnoDB;
let $engine_type_2 = MyISAM;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_innodb_ndb.test	06/08/15 19:13:23
-- source include/have_innodb.inc
-- source include/have_ndb.inc

let $engine_type_2 = InnoDB;
let $engine_type_1 = ndbcluster;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_myisam_bdb.test	06/08/15 19:14:11
## -- source include/have_myisam.inc
-- source include/have_bdb.inc

let $engine_type_1 = MyISAM;
let $engine_type_2 = BerkeleyDB;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_myisam_innodb.test	06/08/15 19:14:26
## -- source include/have_myisam.inc
-- source include/have_innodb.inc

let $engine_type_1 = MyISAM;
let $engine_type_2 = InnoDB;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_myisam_ndb.test	06/08/15 19:14:45
## -- source include/have_myisam.inc
-- source include/have_ndb.inc

let $engine_type_1 = MyISAM;
let $engine_type_2 = ndbcluster;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_ndb_bdb.test	06/08/15 19:15:00
-- source include/have_ndb.inc
-- source include/have_bdb.inc

let $engine_type_1 = ndbcluster;
let $engine_type_2 = BerkeleyDB;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_ndb_innodb.test	06/08/15 19:15:20
-- source include/have_ndb.inc
-- source include/have_innodb.inc

let $engine_type_1 = ndbcluster;
let $engine_type_2 = InnoDB;

-- source include/engine_mix_common.inc


--- New file ---
+++ mysql-test/t/engine_mix_ndb_myisam.test	06/08/15 19:15:50
-- source include/have_ndb.inc
## -- source include/have_myisam.inc

let $engine_type_1 = ndbcluster;
let $engine_type_2 = MyISAM;

-- source include/engine_mix_common.inc



--- 1.11/sql/sql_do.cc	2006-08-15 22:51:16 -07:00
+++ 1.12/sql/sql_do.cc	2006-08-15 22:51:16 -07:00
@@ -21,6 +21,8 @@
 
 bool mysql_do(THD *thd, List<Item> &values)
 {
+  int tx_error= 0;
+  bool result= FALSE;
   List_iterator<Item> li(values);
   Item *value;
   DBUG_ENTER("mysql_do");
@@ -29,7 +31,18 @@ bool mysql_do(THD *thd, List<Item> &valu
   while ((value = li++))
     value->val_int();
   free_underlaid_joins(thd, &thd->lex->select_lex);
-  thd->clear_error(); // DO always is OK
-  send_ok(thd);
-  DBUG_RETURN(FALSE);
+
+  tx_error= thd->net.report_error;
+  tx_error= ha_autocommit_or_rollback(thd, tx_error);
+
+  if (tx_error)
+  {
+    result= TRUE;
+  }
+  else
+  {
+    send_ok(thd);
+    result= FALSE;
+  }
+  DBUG_RETURN(result);
 }
Thread
bk commit into 5.0 tree (malff:1.2236) BUG#12713marc.alff16 Aug