=== modified file 'mysql-test/suite/ndb/r/ndb_bulk_delete.result'
--- a/mysql-test/suite/ndb/r/ndb_bulk_delete.result	2007-11-15 17:39:43 +0000
+++ b/mysql-test/suite/ndb/r/ndb_bulk_delete.result	2008-09-24 14:44:11 +0000
@@ -18,6 +18,33 @@
 # 1 - delete the row + commit the transaction
 
 delete from t1 where a in (1,7, 90, 100, 130);
-@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
-1
+affected rows: 5
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
+# expected result 1 roundtrips
+# 0 - info call
+# 0 - read the rows 
+# 0 - delete the rows 
+# 1 - commit
+# affected = 0
+
+delete from t1 where a=1000;
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
+# expected result 1 roundtrips
+# 0 - info call
+# 0 - read the rows 
+# 0 - delete the rows 
+# 1 - commit
+# affected = 0
+
+delete from t1 where a in (1000, 1001, 1002, 1003, 1004);
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
 drop table t1;
+affected rows: 0

=== modified file 'mysql-test/suite/ndb/r/ndb_update_no_read.result'
--- a/mysql-test/suite/ndb/r/ndb_update_no_read.result	2007-12-25 15:14:17 +0000
+++ b/mysql-test/suite/ndb/r/ndb_update_no_read.result	2008-09-24 14:44:11 +0000
@@ -232,3 +232,148 @@
 affected rows: 0
 drop table t1;
 affected rows: 0
+create table t1 (a int primary key,
+b varchar(4))
+engine=ndb;
+affected rows: 0
+insert into t1 values (1, '1'), (2, '2'), (3, '3');
+affected rows: 3
+info: Records: 3  Duplicates: 0  Warnings: 0
+
+# expected result 1 roundtrip
+# 0 - info call
+# 0 - read the row
+# 0 - update the row
+# 1 - update+commit the row
+# Rows matched=changed=affected=1
+
+update t1 set b='two' where a=2;
+affected rows: 1
+info: Rows matched: 1  Changed: 1  Warnings: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
+
+# expected result 1 roundtrip
+# 0 - info call
+# 0 - read the row
+# 0 - update the row
+# 1 - update+commit the row
+# Rows matched=changed=affected=0
+
+update t1 set b='lots' where a=2000;
+affected rows: 0
+info: Rows matched: 0  Changed: 0  Warnings: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
+
+# expected result 1 roundtrip
+# 0 - info call
+# 0 - read the row
+# 0 - update the row
+# 1 - update+commit the row
+# Rows matched=changed=affected=1
+# 1 warning
+
+update t1 set b='one plus one' where a=2;
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+affected rows: 1
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
+
+# expected result 1 roundtrip
+# 0 - info call
+# 0 - read the row
+# 0 - update the row
+# 1 - update+commit the row
+# Rows matched=changed=affected=0
+# 1 warning
+
+update t1 set b='two thousand' where a=2000;
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+1
+affected rows: 1
+
+# expected result 2 roundtrips
+# 0 - info call
+# 0 - read the row
+# 1 - update the row
+# 1 - commit
+# Rows matched=changed=affected=1
+
+begin;
+affected rows: 0
+update t1 set b='two' where a=2;
+affected rows: 1
+info: Rows matched: 1  Changed: 1  Warnings: 0
+commit;
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+2
+affected rows: 1
+
+# expected result 2 roundtrips
+# 0 - info call
+# 0 - read the row
+# 1 - update the row
+# 1 - commit
+# Rows matched=changed=affected=0
+
+begin;
+affected rows: 0
+update t1 set b='lots' where a=2000;
+affected rows: 0
+info: Rows matched: 0  Changed: 0  Warnings: 0
+commit;
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+2
+affected rows: 1
+
+# expected result 2 roundtrips
+# 0 - info call
+# 0 - read the row
+# 1 - update the row
+# 1 - commit
+# Rows matched=changed=affected=1
+1 warning
+
+begin;
+affected rows: 0
+update t1 set b='one plus one' where a=2;
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+affected rows: 1
+commit;
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+2
+affected rows: 1
+
+# expected result 2 roundtrips
+# 0 - info call
+# 0 - read the row
+# 1 - update the row
+# 1 - commit
+# Rows matched=changed=affected=0
+# 1 warning
+
+begin;
+affected rows: 0
+update t1 set b='two thousand' where a=2000;
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+affected rows: 0
+commit;
+affected rows: 0
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+2
+affected rows: 1
+drop table t1;
+affected rows: 0

=== modified file 'mysql-test/suite/ndb/t/ndb_bulk_delete.test'
--- a/mysql-test/suite/ndb/t/ndb_bulk_delete.test	2007-11-29 10:29:35 +0000
+++ b/mysql-test/suite/ndb/t/ndb_bulk_delete.test	2008-09-24 14:44:11 +0000
@@ -19,6 +19,8 @@
 insert into t1 select a+64 from t1;
 insert into t1 select a+128 from t1;
 
+--enable_info
+
 --echo
 --echo # test: simple delete of multiple pk's
 --echo # expected result 1 roundtrips
@@ -31,5 +33,30 @@
 delete from t1 where a in (1,7, 90, 100, 130);
 --source include/ndb_execute_count.inc
 
+# Test delete with non existant pk
+# Bug 37153
+--echo # expected result 1 roundtrips
+--echo # 0 - info call
+--echo # 0 - read the rows 
+--echo # 0 - delete the rows 
+--echo # 1 - commit
+--echo # affected = 0
+--echo
+--source include/ndb_init_execute_count.inc
+delete from t1 where a=1000;
+--source include/ndb_execute_count.inc
+
+--echo # expected result 1 roundtrips
+--echo # 0 - info call
+--echo # 0 - read the rows 
+--echo # 0 - delete the rows 
+--echo # 1 - commit
+--echo # affected = 0
+--echo
+--source include/ndb_init_execute_count.inc
+delete from t1 where a in (1000, 1001, 1002, 1003, 1004);
+--source include/ndb_execute_count.inc
+
+
 # cleanup
 drop table t1;

=== modified file 'mysql-test/suite/ndb/t/ndb_update_no_read.test'
--- a/mysql-test/suite/ndb/t/ndb_update_no_read.test	2008-05-07 06:37:11 +0000
+++ b/mysql-test/suite/ndb/t/ndb_update_no_read.test	2008-09-24 14:44:11 +0000
@@ -196,3 +196,135 @@
 
 drop table t1;
 
+#Bug 37153 Ndb cluster reports affected rows incorrectly
+create table t1 (a int primary key,
+                 b varchar(4))
+engine=ndb;
+# Show warning and count info
+--enable_info 
+
+insert into t1 values (1, '1'), (2, '2'), (3, '3');
+
+# Autocommit, successful update
+--echo
+--echo # expected result 1 roundtrip
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 0 - update the row
+--echo # 1 - update+commit the row
+--echo # Rows matched=changed=affected=1
+--echo 
+--source include/ndb_init_execute_count.inc
+update t1 set b='two' where a=2;
+--source include/ndb_execute_count.inc
+
+
+# Autocommit, unsuccessful update
+--echo
+--echo # expected result 1 roundtrip
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 0 - update the row
+--echo # 1 - update+commit the row
+--echo # Rows matched=changed=affected=0
+--echo 
+--source include/ndb_init_execute_count.inc
+update t1 set b='lots' where a=2000;
+--source include/ndb_execute_count.inc
+
+# Autocommit, successful update + warning
+--echo
+--echo # expected result 1 roundtrip
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 0 - update the row
+--echo # 1 - update+commit the row
+--echo # Rows matched=changed=affected=1
+--echo # 1 warning
+--echo 
+--source include/ndb_init_execute_count.inc
+update t1 set b='one plus one' where a=2;
+--source include/ndb_execute_count.inc
+
+
+# Autocommit, unsuccessful update + warning
+--echo
+--echo # expected result 1 roundtrip
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 0 - update the row
+--echo # 1 - update+commit the row
+--echo # Rows matched=changed=affected=0
+--echo # 1 warning
+--echo 
+--source include/ndb_init_execute_count.inc
+update t1 set b='two thousand' where a=2000;
+--source include/ndb_execute_count.inc
+
+
+# No autocommit, successful update
+--echo
+--echo # expected result 2 roundtrips
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 1 - update the row
+--echo # 1 - commit
+--echo # Rows matched=changed=affected=1
+--echo 
+--source include/ndb_init_execute_count.inc
+begin;
+update t1 set b='two' where a=2;
+commit;
+--source include/ndb_execute_count.inc
+
+
+# No autocommit, unsuccessful update
+--echo
+--echo # expected result 2 roundtrips
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 1 - update the row
+--echo # 1 - commit
+--echo # Rows matched=changed=affected=0
+--echo 
+--source include/ndb_init_execute_count.inc
+begin;
+update t1 set b='lots' where a=2000;
+commit;
+--source include/ndb_execute_count.inc
+
+
+# No autocommit, successful update + warning
+--echo
+--echo # expected result 2 roundtrips
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 1 - update the row
+--echo # 1 - commit
+--echo # Rows matched=changed=affected=1
+--echo 1 warning
+--echo 
+--source include/ndb_init_execute_count.inc
+begin;
+update t1 set b='one plus one' where a=2;
+commit;
+--source include/ndb_execute_count.inc
+
+
+# No autocommit, unsuccessful update + warning
+--echo
+--echo # expected result 2 roundtrips
+--echo # 0 - info call
+--echo # 0 - read the row
+--echo # 1 - update the row
+--echo # 1 - commit
+--echo # Rows matched=changed=affected=0
+--echo # 1 warning
+--echo 
+--source include/ndb_init_execute_count.inc
+begin;
+update t1 set b='two thousand' where a=2000;
+commit;
+--source include/ndb_execute_count.inc
+
+drop table t1;

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2008-09-21 09:47:14 +0000
+++ b/sql/ha_ndbcluster.cc	2008-09-24 15:01:01 +0000
@@ -5652,14 +5652,50 @@
     if (thd_ndb->m_handler &&
         thd_ndb->m_handler->m_read_before_write_removal_possible)
     {
+      /* Autocommit with read-before-write removal
+       * Some operations in this autocommitted statement have not
+       * yet been executed
+       * They will be executed here as part of commit, and the results
+       * (rowcount, message) sent back to the client will then be modified 
+       * according to how the execution went.
+       * This saves a single roundtrip in the autocommit case
+       */
       uint ignore_count= 0;
       res= execute_commit(thd_ndb, trans, thd->variables.ndb_force_send,
                           TRUE, &ignore_count);
       if (!res && ignore_count)
+      {
+        DBUG_PRINT("info", ("AutoCommit + RBW removal, ignore_count=%u",
+                            ignore_count));
+        /* We have some rows to ignore, modify recorded results,
+         * regenerate result message as required.
+         */
+        thd->row_count_func-= ignore_count;
+
+        ha_rows affected= 0;
+        char buff[ STRING_BUFFER_USUAL_SIZE ];
+        const char* msg= NULL;
         if (thd->lex->sql_command == SQLCOM_DELETE)
-          thd_ndb->m_handler->m_rows_deleted-= ignore_count;
+          affected= (thd_ndb->m_handler->m_rows_deleted-= ignore_count);
         else
-          thd_ndb->m_handler->m_rows_updated-= ignore_count;
+        {
+          DBUG_PRINT("info", ("Update : message was %s", 
+                              thd->main_da.message()));
+          affected= (thd_ndb->m_handler->m_rows_updated-= ignore_count);
+          /* For update in this scenario, we set found and changed to be 
+           * the same as affected
+           * Regenerate the update message
+           */
+          sprintf(buff, ER(ER_UPDATE_INFO), (ulong)affected, (ulong)affected,
+                  (ulong) thd->cuted_fields);
+          msg= buff;
+          DBUG_PRINT("info", ("Update : message changed to %s",
+                              msg));
+        }
+
+        /* Modify execution result + optionally message */
+        thd->main_da.modify_affected_rows(affected, msg);
+      }
     }
     else
       res= execute_commit(thd_ndb, trans, thd->variables.ndb_force_send, FALSE);

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2008-09-01 12:28:57 +0000
+++ b/sql/sql_class.cc	2008-09-24 14:44:11 +0000
@@ -490,6 +490,24 @@
   m_status= DA_ERROR;
 }
 
+/**
+ * modify_affected_rows
+ * Modify the number of affected rows, and optionally the 
+ * message in the Diagnostics area
+ */
+void
+Diagnostics_area::modify_affected_rows(ha_rows new_affected_rows,
+                                       const char* new_message)
+{
+  DBUG_ASSERT(is_set());
+  DBUG_ASSERT(m_status == DA_OK);
+  DBUG_ASSERT(can_overwrite_status);
+
+  m_affected_rows= new_affected_rows;
+  if (new_message)
+    strmake(m_message, new_message, sizeof(m_message) - 1);
+}
+
 
 /**
   Mark the diagnostics area as 'DISABLED'.

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2008-09-02 16:31:03 +0000
+++ b/sql/sql_class.h	2008-09-24 14:44:11 +0000
@@ -1081,6 +1081,9 @@
   void set_eof_status(THD *thd);
   void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg);
 
+  /* Modify affected rows count and optionally message */
+  void modify_affected_rows(ha_rows new_affected_rows, const char *new_message= 0);
+
   void disable_status();
 
   void reset_diagnostics_area();



