=== modified file 'BUILD/compile-ndb-autotest'
--- a/BUILD/compile-ndb-autotest	2006-08-02 07:08:21 +0000
+++ b/BUILD/compile-ndb-autotest	2008-06-24 10:53:41 +0000
@@ -15,5 +15,6 @@
 fi
 
 extra_flags="$extra_flags $max_cflags -g"
+extra_configs="$extra_configs $NDB_AUTOTEST_CONFIGURE_OPTIONS"
 
 . "$path/FINISH.sh"

=== modified file 'mysql-test/suite/binlog/r/binlog_multi_engine.result'
--- a/mysql-test/suite/binlog/r/binlog_multi_engine.result	2008-03-28 12:16:41 +0000
+++ b/mysql-test/suite/binlog/r/binlog_multi_engine.result	2008-06-19 07:18:42 +0000
@@ -27,11 +27,6 @@
 master-bin.000001	#	Query	#	#	use `test`; UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f
 master-bin.000001	#	Query	#	#	use `test`; UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c
 master-bin.000001	#	Query	#	#	use `test`; COMMIT
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t1n)
-master-bin.000001	#	Table_map	#	#	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Query	#	#	COMMIT
 master-bin.000001	#	Query	#	#	use `test`; TRUNCATE t1m
 master-bin.000001	#	Query	#	#	use `test`; TRUNCATE t1b
 master-bin.000001	#	Query	#	#	use `test`; TRUNCATE t1n

=== added file 'mysql-test/suite/ndb/r/ndb_hidden_pk.result'
--- a/mysql-test/suite/ndb/r/ndb_hidden_pk.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_hidden_pk.result	2008-06-26 09:35:14 +0000
@@ -0,0 +1,265 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+attr1 INT
+) ENGINE=ndbcluster;
+insert into t1 values (0), (1), (2), (3), (4), (1), (1), (1), (2), (2), (2), (3), (3), (3), (NULL), (NULL), (NULL);
+select * from t1 order by attr1;
+attr1
+NULL
+NULL
+NULL
+0
+1
+1
+1
+1
+2
+2
+2
+2
+3
+3
+3
+3
+4
+select * from t1 where attr1 = 1;
+attr1
+1
+1
+1
+1
+select * from t1 where attr1 IS NULL;
+attr1
+NULL
+NULL
+NULL
+select * from t1 where attr1 = 4;
+attr1
+4
+select * from t1 where attr1 = 1000;
+attr1
+update t1 set attr1=7 where attr1=4;
+select * from t1 order by attr1;
+attr1
+NULL
+NULL
+NULL
+0
+1
+1
+1
+1
+2
+2
+2
+2
+3
+3
+3
+3
+7
+update t1 set attr1=10 where attr1=1;
+select * from t1 order by attr1;
+attr1
+NULL
+NULL
+NULL
+0
+2
+2
+2
+2
+3
+3
+3
+3
+7
+10
+10
+10
+10
+update t1 set attr1=20 where attr1 IS NULL;
+select * from t1 order by attr1;
+attr1
+0
+2
+2
+2
+2
+3
+3
+3
+3
+7
+10
+10
+10
+10
+20
+20
+20
+update t1 set attr1=NULL where attr1=20;
+select * from t1 order by attr1;
+attr1
+NULL
+NULL
+NULL
+0
+2
+2
+2
+2
+3
+3
+3
+3
+7
+10
+10
+10
+10
+delete from t1 where attr1=0;
+select * from t1 order by attr1;
+attr1
+NULL
+NULL
+NULL
+2
+2
+2
+2
+3
+3
+3
+3
+7
+10
+10
+10
+10
+delete from t1 where attr1 IS NULL;
+select * from t1 order by attr1;
+attr1
+2
+2
+2
+2
+3
+3
+3
+3
+7
+10
+10
+10
+10
+drop table t1;
+CREATE TABLE t1 (
+b blob
+) ENGINE=ndbcluster;
+Warnings:
+Error	1478	Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK'
+insert into t1 values (NULL), (NULL), ('Something'), (''), (REPEAT('Lots', 2000));
+select * from t1 order by b;
+b
+NULL
+NULL
+
+LotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLots!
 LotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLots!
 LotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLo!
 tsLotsLo
tsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLot!
 sLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLot!
 sLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsL!
 otsLotsL
otsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLo!
 tsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLo!
 tsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLots!
 LotsLots
LotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsL!
 otsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLotsLots
+Something
+select * from t1 where b IS NULL;
+b
+NULL
+NULL
+select * from t1 where b='Something';
+b
+Something
+select count(*) from t1 where b=REPEAT('Lots', 2000);
+count(*)
+1
+select * from t1 where b='Imaginary';
+b
+drop table t1;
+CREATE TABLE t1 (
+a int,
+b int, 
+UNIQUE(a)
+) ENGINE=NDBCLUSTER;
+insert into t1 values (NULL, NULL), (NULL, NULL), (NULL, 1), (1, 1), (2, 2), (3, 3);
+select * from t1 order by a, b;
+a	b
+NULL	NULL
+NULL	NULL
+NULL	1
+1	1
+2	2
+3	3
+select * from t1 where a IS NULL order by b;
+a	b
+NULL	NULL
+NULL	NULL
+NULL	1
+select * from t1 where a=2;
+a	b
+2	2
+select * from t1 where a=10;
+a	b
+update t1 set b=12 where a=12;
+select * from t1 order by a, b;
+a	b
+NULL	NULL
+NULL	NULL
+NULL	1
+1	1
+2	2
+3	3
+update t1 set b=4 where a=3;
+select * from t1 order by a, b;
+a	b
+NULL	NULL
+NULL	NULL
+NULL	1
+1	1
+2	2
+3	4
+update t1 set b=2 where a=1;
+select * from t1 order by a, b;
+a	b
+NULL	NULL
+NULL	NULL
+NULL	1
+1	2
+2	2
+3	4
+update t1 set b=14 where a IS NULL;
+select * from t1 order by a,b;
+a	b
+NULL	14
+NULL	14
+NULL	14
+1	2
+2	2
+3	4
+delete from t1 where a = 999;
+select * from t1 order by a, b;
+a	b
+NULL	14
+NULL	14
+NULL	14
+1	2
+2	2
+3	4
+delete from t1 where a=3;
+select * from t1 order by a, b;
+a	b
+NULL	14
+NULL	14
+NULL	14
+1	2
+2	2
+delete from t1 where a IS NULL;
+select * from t1 order by a, b;
+a	b
+1	2
+2	2
+drop table t1;

=== added file 'mysql-test/suite/ndb/t/ndb_hidden_pk.test'
--- a/mysql-test/suite/ndb/t/ndb_hidden_pk.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_hidden_pk.test	2008-06-26 09:35:14 +0000
@@ -0,0 +1,142 @@
+-- source include/have_ndb.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+#
+# ndb_hidden_pk.test
+# Test use of tables with hidden primary key
+#
+
+# Bag of nullable ints
+CREATE TABLE t1 (
+  attr1 INT
+) ENGINE=ndbcluster;
+
+insert into t1 values (0), (1), (2), (3), (4), (1), (1), (1), (2), (2), (2), (3), (3), (3), (NULL), (NULL), (NULL);
+
+# all
+select * from t1 order by attr1;
+
+# many
+select * from t1 where attr1 = 1;
+
+# many NULLs
+select * from t1 where attr1 IS NULL;
+
+# one
+select * from t1 where attr1 = 4;
+
+# none
+select * from t1 where attr1 = 1000;
+
+# Single value update
+update t1 set attr1=7 where attr1=4;
+select * from t1 order by attr1;
+
+
+# Multi value update
+update t1 set attr1=10 where attr1=1;
+select * from t1 order by attr1;
+
+# Multi NULL value update
+update t1 set attr1=20 where attr1 IS NULL;
+select * from t1 order by attr1;
+
+# Put them back...
+update t1 set attr1=NULL where attr1=20;
+select * from t1 order by attr1;
+
+# Single value delete
+delete from t1 where attr1=0;
+select * from t1 order by attr1;
+
+
+# Multi value delete
+delete from t1 where attr1 IS NULL;
+select * from t1 order by attr1;
+
+
+drop table t1;
+
+
+# Hidden primary key and blob only
+CREATE TABLE t1 (
+  b blob
+) ENGINE=ndbcluster;
+
+insert into t1 values (NULL), (NULL), ('Something'), (''), (REPEAT('Lots', 2000));
+
+# all
+select * from t1 order by b;
+
+# many null
+select * from t1 where b IS NULL;
+
+# one
+select * from t1 where b='Something';
+
+# large
+select count(*) from t1 where b=REPEAT('Lots', 2000);
+
+# none
+select * from t1 where b='Imaginary';
+
+drop table t1;
+
+
+# Unique index instead of PK
+#
+CREATE TABLE t1 (
+  a int,
+  b int, 
+  UNIQUE(a)
+) ENGINE=NDBCLUSTER;
+
+
+insert into t1 values (NULL, NULL), (NULL, NULL), (NULL, 1), (1, 1), (2, 2), (3, 3);
+
+# select all
+select * from t1 order by a, b;
+
+# select many null
+select * from t1 where a IS NULL order by b;
+
+# select one
+select * from t1 where a=2;
+
+# select none
+select * from t1 where a=10;
+
+# update none
+update t1 set b=12 where a=12;
+select * from t1 order by a, b;
+
+# update one
+update t1 set b=4 where a=3;
+select * from t1 order by a, b;
+
+# update many
+update t1 set b=2 where a=1;
+select * from t1 order by a, b;
+
+# update many null
+update t1 set b=14 where a IS NULL;
+select * from t1 order by a,b;
+
+# Bug # 37516 had problems with delete via unique index
+# on table with hidden PK
+# delete none
+delete from t1 where a = 999;
+select * from t1 order by a, b;
+
+# delete one
+delete from t1 where a=3;
+select * from t1 order by a, b;
+
+# delete many null
+delete from t1 where a IS NULL;
+select * from t1 order by a, b;
+
+drop table t1;

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result	2008-03-25 18:03:33 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result	2008-06-19 07:18:42 +0000
@@ -24,9 +24,4 @@
 master-bin.000001	#	Query	#	#	use `test`; UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f
 master-bin.000001	#	Query	#	#	use `test`; UPDATE t3, t2 SET e = 2, b = 3 WHERE f = c
 master-bin.000001	#	Query	#	#	use `test`; COMMIT
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t3)
-master-bin.000001	#	Table_map	#	#	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Query	#	#	COMMIT
 DROP TABLE t1, t2, t3;

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result	2008-02-25 13:50:20 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result	2008-06-19 07:18:42 +0000
@@ -13,22 +13,12 @@
 Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	1	#	BEGIN
-master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest.t1)
-master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Query	1	#	COMMIT
 reset master;
 use mysqltest;
 insert into t2 values (1,1);
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 master-bin1.000001	#	Query	102	#	BEGIN
-master-bin1.000001	#	Table_map	102	#	table_id: # (mysqltest.t1)
-master-bin1.000001	#	Table_map	102	#	table_id: # (mysql.ndb_apply_status)
-master-bin1.000001	#	Write_rows	102	#	table_id: # flags: STMT_END_F
-master-bin1.000001	#	Query	102	#	COMMIT
-master-bin1.000001	#	Query	102	#	BEGIN
 master-bin1.000001	#	Table_map	102	#	table_id: # (mysqltest.t2)
 master-bin1.000001	#	Table_map	102	#	table_id: # (mysql.ndb_apply_status)
 master-bin1.000001	#	Write_rows	102	#	table_id: #

=== added file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result	2008-06-18 15:03:43 +0000
@@ -0,0 +1,101 @@
+drop table if exists t1;
+#
+# create a table with some data with and without binlogging
+#
+create table t1 (a int key, b int) engine ndb;
+insert into t1 values (1,1);
+@the_backup_id:=backup_id
+<the_backup_id>
+#
+# extra table to be used to ensure data has arrived to binlog
+create table t2 (a int key, b int) engine ndb;
+#
+# reset and restore schema
+drop table t1;
+reset master;
+show tables;
+Tables_in_test
+t2
+t1
+#
+# restore and _no_ binlog
+#
+# check the binlog, should be empty
+# extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (1,1);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+#
+# reset and restore schema again
+drop table t1;
+reset master;
+show tables;
+Tables_in_test
+t2
+t1
+#
+# restore and  binlog should now happen
+#
+# check the binlog, should contain data
+# extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (2,2);
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.t1)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+drop table t1, t2;
+#
+# Now more complex using "BANK schema" including restore of log
+#
+CREATE DATABASE IF NOT EXISTS BANK;
+DROP DATABASE BANK;
+CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin;
+USE BANK;
+CREATE TABLE GL ( TIME BIGINT UNSIGNED NOT NULL,
+ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+BALANCE INT UNSIGNED NOT NULL,
+DEPOSIT_COUNT INT UNSIGNED NOT NULL,
+DEPOSIT_SUM INT UNSIGNED NOT NULL,
+WITHDRAWAL_COUNT INT UNSIGNED NOT NULL,
+WITHDRAWAL_SUM INT UNSIGNED NOT NULL,
+PURGED INT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (TIME,ACCOUNT_TYPE))
+ENGINE = NDB;
+CREATE TABLE ACCOUNT ( ACCOUNT_ID INT UNSIGNED NOT NULL,
+OWNER INT UNSIGNED NOT NULL,
+BALANCE INT UNSIGNED NOT NULL,
+ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (ACCOUNT_ID))
+ENGINE = NDB;
+CREATE TABLE TRANSACTION ( TRANSACTION_ID BIGINT UNSIGNED NOT NULL,
+ACCOUNT INT UNSIGNED NOT NULL,
+ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+OTHER_ACCOUNT INT UNSIGNED NOT NULL,
+TRANSACTION_TYPE INT UNSIGNED NOT NULL,
+TIME BIGINT UNSIGNED NOT NULL,
+AMOUNT INT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (TRANSACTION_ID,ACCOUNT))
+ENGINE = NDB;
+CREATE TABLE SYSTEM_VALUES ( SYSTEM_VALUES_ID INT UNSIGNED NOT NULL,
+VALUE BIGINT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (SYSTEM_VALUES_ID))
+ENGINE = NDB;
+CREATE TABLE ACCOUNT_TYPE ( ACCOUNT_TYPE_ID INT UNSIGNED NOT NULL,
+DESCRIPTION CHAR(64) NOT NULL,
+PRIMARY KEY USING HASH (ACCOUNT_TYPE_ID))
+ENGINE = NDB;
+#
+# reset, restore and  binlog should _not_ happen
+reset master;
+select count(*) from TRANSACTION;
+count(*)
+3444
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+DROP DATABASE BANK;

=== added file 'mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test'
--- a/mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test	2008-06-18 15:03:43 +0000
@@ -0,0 +1,126 @@
+-- source include/have_ndb.inc
+-- source include/have_binlog_format_mixed_or_row.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--echo #
+--echo # create a table with some data with and without binlogging
+--echo #
+create table t1 (a int key, b int) engine ndb;
+insert into t1 values (1,1);
+
+# backup and drop data
+--disable_query_log
+--source include/ndb_backup.inc
+--enable_query_log
+
+--echo #
+--echo # extra table to be used to ensure data has arrived to binlog
+create table t2 (a int key, b int) engine ndb;
+
+--echo #
+--echo # reset and restore schema
+drop table t1;
+reset master;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+show tables;
+
+--echo #
+--echo # restore and _no_ binlog
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b $the_backup_id -n 1 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b $the_backup_id -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+
+--echo #
+--echo # check the binlog, should be empty
+--echo # extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (1,1);
+--source include/show_binlog_events2.inc
+
+--echo #
+--echo # reset and restore schema again
+drop table t1;
+reset master;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+show tables;
+
+--echo #
+--echo # restore and  binlog should now happen
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+
+--echo #
+--echo # check the binlog, should contain data
+--echo # extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (2,2);
+--source include/show_binlog_events2.inc
+
+drop table t1, t2;
+
+
+
+--echo #
+--echo # Now more complex using "BANK schema" including restore of log
+--echo #
+--disable_warnings
+CREATE DATABASE IF NOT EXISTS BANK;
+DROP DATABASE BANK;
+--enable_warnings
+CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin;
+
+#
+# These tables should correspond to the table definitions in
+# storage/ndb/test/src/NDBT_Tables.cpp
+#
+USE BANK;
+CREATE TABLE GL ( TIME BIGINT UNSIGNED NOT NULL,
+                  ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+                  BALANCE INT UNSIGNED NOT NULL,
+                  DEPOSIT_COUNT INT UNSIGNED NOT NULL,
+                  DEPOSIT_SUM INT UNSIGNED NOT NULL,
+                  WITHDRAWAL_COUNT INT UNSIGNED NOT NULL,
+                  WITHDRAWAL_SUM INT UNSIGNED NOT NULL,
+                  PURGED INT UNSIGNED NOT NULL,
+                  PRIMARY KEY USING HASH (TIME,ACCOUNT_TYPE))
+   ENGINE = NDB;
+
+CREATE TABLE ACCOUNT ( ACCOUNT_ID INT UNSIGNED NOT NULL,
+                       OWNER INT UNSIGNED NOT NULL,
+                       BALANCE INT UNSIGNED NOT NULL,
+                       ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+                       PRIMARY KEY USING HASH (ACCOUNT_ID))
+   ENGINE = NDB;
+
+CREATE TABLE TRANSACTION ( TRANSACTION_ID BIGINT UNSIGNED NOT NULL,
+                           ACCOUNT INT UNSIGNED NOT NULL,
+                           ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+                           OTHER_ACCOUNT INT UNSIGNED NOT NULL,
+                           TRANSACTION_TYPE INT UNSIGNED NOT NULL,
+                           TIME BIGINT UNSIGNED NOT NULL,
+                           AMOUNT INT UNSIGNED NOT NULL,
+                           PRIMARY KEY USING HASH (TRANSACTION_ID,ACCOUNT))
+   ENGINE = NDB;
+
+CREATE TABLE SYSTEM_VALUES ( SYSTEM_VALUES_ID INT UNSIGNED NOT NULL,
+                             VALUE BIGINT UNSIGNED NOT NULL,
+                             PRIMARY KEY USING HASH (SYSTEM_VALUES_ID))
+   ENGINE = NDB;
+
+CREATE TABLE ACCOUNT_TYPE ( ACCOUNT_TYPE_ID INT UNSIGNED NOT NULL,
+                            DESCRIPTION CHAR(64) NOT NULL,
+                            PRIMARY KEY USING HASH (ACCOUNT_TYPE_ID))
+   ENGINE = NDB;
+
+--echo #
+--echo # reset, restore and  binlog should _not_ happen
+reset master;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b 1 -n 1 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
+
+select count(*) from TRANSACTION;
+--source include/show_binlog_events2.inc
+
+DROP DATABASE BANK;

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2008-06-17 07:32:16 +0000
+++ b/sql/ha_ndbcluster.cc	2008-07-01 07:53:42 +0000
@@ -3650,29 +3650,30 @@
                                             bool use_active_index)
 {
   DBUG_ENTER("setup_key_ref_for_ndb_record");
-  if (table_share->primary_key != MAX_KEY)
-  {
-    if (use_active_index)
-    {
-      /*
-        Using unique key and getting read before write removal
-        optimisation working. Use key_rec according to this
-        unique index instead of primary key index
-      */
-      *key_rec= m_index[active_index].ndb_unique_record_row;
-    }
-    else
-      *key_rec= m_index[table_share->primary_key].ndb_unique_record_row;
-    *key_row= record;
-    DBUG_VOID_RETURN;
+  if (use_active_index)
+  {
+    /* Use unique key to access table */
+    DBUG_PRINT("info", ("Using unique index (%u)", active_index));
+    *key_rec= m_index[active_index].ndb_unique_record_row;
+    *key_row= record;
+  }
+  else if (table_share->primary_key != MAX_KEY)
+  {
+    /* Use primary key to access table */
+    DBUG_PRINT("info", ("Using primary key"));
+    *key_rec= m_index[table_share->primary_key].ndb_unique_record_row;
+    *key_row= record;
   }
   else
   {
     /* Use hidden primary key previously read into m_ref. */
+    DBUG_PRINT("info", ("Using hidden primary key (%llu)", m_ref));
+    /* Can't use hidden pk if we didn't read it first */
+    DBUG_ASSERT(m_read_before_write_removal_used == false);
     *key_rec= m_ndb_hidden_key_record;
     *key_row= (const uchar *)(&m_ref);
-    DBUG_VOID_RETURN;
   }
+  DBUG_VOID_RETURN;
 }
 
 
@@ -10441,6 +10442,8 @@
         ppartitionId=&partitionId;
       }
 
+      DBUG_PRINT("info", ("Generating Pk/Unique key read for range %u",
+                          i));
       if (!(op= pk_unique_index_read_key(active_index,
                                          r->start_key.key,
                                          row_buf, lm,
@@ -10461,6 +10464,8 @@
     const NdbOperation* rangeOp= lastOp ? lastOp->next() : 
       trans->getFirstDefinedOperation();
     
+    DBUG_PRINT("info", ("Executing reads"));
+
     if (execute_no_commit_ie(m_thd_ndb, trans) == 0)
     {
       m_multi_range_result_ptr= buffer->buffer;

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2008-06-17 07:32:16 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2008-06-25 13:06:41 +0000
@@ -4530,7 +4530,8 @@
 static int
 ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp,
                                     ndb_binlog_index_row **rows,
-                                    injector::transaction &trans)
+                                    injector::transaction &trans,
+                                    unsigned &trans_row_count)
 {
   Ndb_event_data *event_data= (Ndb_event_data *) pOp->getCustomData();
   TABLE *table= event_data->table;
@@ -4627,6 +4628,7 @@
   {
   case NDBEVENT::TE_INSERT:
     row->n_inserts++;
+    trans_row_count++;
     DBUG_PRINT("info", ("INSERT INTO %s.%s",
                         table->s->db.str, table->s->table_name.str));
     {
@@ -4649,6 +4651,7 @@
     break;
   case NDBEVENT::TE_DELETE:
     row->n_deletes++;
+    trans_row_count++;
     DBUG_PRINT("info",("DELETE FROM %s.%s",
                        table->s->db.str, table->s->table_name.str));
     {
@@ -4689,6 +4692,7 @@
     break;
   case NDBEVENT::TE_UPDATE:
     row->n_updates++;
+    trans_row_count++;
     DBUG_PRINT("info", ("UPDATE %s.%s",
                         table->s->db.str, table->s->table_name.str));
     {
@@ -5331,6 +5335,7 @@
         bzero((char*)&_row, sizeof(_row));
         thd->variables.character_set_client= &my_charset_latin1;
         injector::transaction trans;
+        unsigned trans_row_count= 0;
         // pass table map before epoch
         {
           Uint32 iter= 0;
@@ -5497,7 +5502,7 @@
 #endif
           if ((unsigned) pOp->getEventType() <
               (unsigned) NDBEVENT::TE_FIRST_NON_DATA_EVENT)
-            ndb_binlog_thread_handle_data_event(i_ndb, pOp, &rows, trans);
+            ndb_binlog_thread_handle_data_event(i_ndb, pOp, &rows, trans, trans_row_count);
           else
           {
             // set injector_ndb database/schema from table internal name
@@ -5540,9 +5545,20 @@
         write_timer.stop();
 #endif
 
-        if (trans.good())
+        while (trans.good())
         {
-          //DBUG_ASSERT(row.n_inserts || row.n_updates || row.n_deletes);
+          if (trans_row_count == 0)
+          {
+            /* nothing to commit, rollback instead */
+            if (int r= trans.rollback())
+            {
+              sql_print_error("NDB Binlog: "
+                              "Error during ROLLBACK of GCI %u/%u. Error: %d",
+                              uint(gci >> 32), uint(gci), r);
+              /* TODO: Further handling? */
+            }
+            break;
+          }
           thd->proc_info= "Committing events to binlog";
           injector::transaction::binlog_pos start= trans.start_pos();
           if (int r= trans.commit())
@@ -5564,6 +5580,7 @@
             do_check_ndb_binlog_index= 0;
           }
           ndb_latest_applied_binlog_epoch= gci;
+          break;
         }
         ndb_latest_handled_binlog_epoch= gci;
 

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2008-02-19 11:43:01 +0000
+++ b/sql/rpl_injector.cc	2008-06-18 12:53:42 +0000
@@ -86,6 +86,14 @@
    DBUG_RETURN(0);
 }
 
+int injector::transaction::rollback()
+{
+   DBUG_ENTER("injector::transaction::rollback()");
+   ha_autocommit_or_rollback(m_thd, 1 /* error to get rollback */);
+   end_trans(m_thd, ROLLBACK);
+   DBUG_RETURN(0);
+}
+
 int injector::transaction::use_table(server_id_type sid, table tbl)
 {
   DBUG_ENTER("injector::transaction::use_table");

=== modified file 'sql/rpl_injector.h'
--- a/sql/rpl_injector.h	2007-05-10 09:59:39 +0000
+++ b/sql/rpl_injector.h	2008-06-18 12:53:42 +0000
@@ -210,6 +210,14 @@
       int commit();
 
       /*
+        Rollback a transaction.
+
+        This member function will clean up after a sequence of *_row calls by,
+        for example, releasing resource and unlocking files.
+      */
+      int rollback();
+
+      /*
         Get the position for the start of the transaction.
 
         Returns the position in the binary log of the first event in this

=== modified file 'storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp	2008-06-17 07:32:16 +0000
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp	2008-06-25 13:06:41 +0000
@@ -1958,14 +1958,14 @@
   Uint64 stop_gci = m_latest_complete_GCI;
 
   Uint64 start_gci = array[minpos];
-  g_eventLogger->info("complete_outof_order_gcis from: %u/%u to: %u/%u",
-                      Uint32(start_gci >> 32), Uint32(start_gci),
-                      Uint32(stop_gci >> 32), Uint32(stop_gci));
+  g_eventLogger->info("complete_outof_order_gcis from: %u/%u(%u) to: %u/%u(%u)",
+                      Uint32(start_gci >> 32), Uint32(start_gci), minpos,
+                      Uint32(stop_gci >> 32), Uint32(stop_gci), maxpos);
 
   assert(start_gci <= stop_gci);
   do
   {
-    Uint64 start_gci = array[minpos];
+    start_gci = array[minpos];
     Gci_container* bucket = find_bucket(start_gci);
     assert(bucket);
     assert(maxpos == m_max_gci_index);
@@ -1979,10 +1979,10 @@
 
 #ifdef VM_TRACE
     ndbout_c("complete_outof_order_gcis - completing %u/%u rows: %u",
-             Uint32(start_gci), Uint32(start_gci), bucket->m_data.m_count);
+             Uint32(start_gci >> 32), Uint32(start_gci), bucket->m_data.m_count);
 #else
     ndbout_c("complete_outof_order_gcis - completing %u/%u",
-             Uint32(start_gci), Uint32(start_gci));
+             Uint32(start_gci >> 32), Uint32(start_gci));
 #endif
     
     complete_bucket(bucket);

=== modified file 'storage/ndb/test/include/NDBT_Test.hpp'
--- a/storage/ndb/test/include/NDBT_Test.hpp	2008-03-03 11:12:37 +0000
+++ b/storage/ndb/test/include/NDBT_Test.hpp	2008-06-23 12:37:22 +0000
@@ -50,7 +50,7 @@
   // Get arguments
   int getNumRecords() const;
   int getNumLoops() const;
-  char * getRemoteMgm() const;
+
   // Common place to store state between 
   // steps, for example information from one step to the 
   // verifier about how many records have been inserted
@@ -84,7 +84,6 @@
 
   void setTab(const NdbDictionary::Table*);
   void addTab(const NdbDictionary::Table*);
-  void setRemoteMgm(char * mgm);
 
   /**
    * Get no of steps running/completed
@@ -114,7 +113,6 @@
   int records;
   int loops;
   bool stopped;
-  char * remote_mgm;
   Properties props;
   NdbMutex* propertyMutexPtr;
   NdbCondition* propertyCondPtr;

=== removed file 'storage/ndb/test/include/NdbGrep.hpp'
--- a/storage/ndb/test/include/NdbGrep.hpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/test/include/NdbGrep.hpp	1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
-/* Copyright (C) 2003 MySQL AB
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-#ifndef NDBT_GREP_HPP
-#define NDBT_GREP_HPP
-
-#include <mgmapi.h>
-#include <Vector.hpp>
-#include "NdbConfig.hpp"
-#include <NdbRestarter.hpp>
-#include <NDBT.hpp>
-#include <NDBT_Test.hpp>
-class NdbGrep : public NdbConfig {
-public:
-  NdbGrep(int _own_id, const char* _addr = 0) 
-    : NdbConfig(_own_id, _addr) {};
-
-  int start();
-  int stop();
-  int query();
-
-
-  int verify(NDBT_Context* ctx);
-
-
-  int NFMaster(NdbRestarter& _restarter);
-  int NFMasterAsSlave(NdbRestarter& _restarter);
-  int NFSlave(NdbRestarter& _restarter);
-  int NF(NdbRestarter& _restarter, int *NFDuringGrep_codes, const int sz, bool onMaster);
-
-  int FailMaster(NdbRestarter& _restarter);
-  int FailMasterAsSlave(NdbRestarter& _restarter);
-  int FailSlave(NdbRestarter& _restarter);
-  int Fail(NdbRestarter& _restarter, int *Fail_codes, const int sz, bool onMaster);
-
-private:
-  
-};
-
-#endif

=== added file 'storage/ndb/test/include/NdbMgmd.hpp'
--- a/storage/ndb/test/include/NdbMgmd.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/include/NdbMgmd.hpp	2008-06-23 12:37:22 +0000
@@ -0,0 +1,39 @@
+/* Copyright (C) 2003 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef NDB_MGMD_HPP
+#define NDB_MGMD_HPP
+
+#include <BaseString.hpp>
+
+
+class NdbMgmd {
+  BaseString m_connect_str;
+public:
+  NdbMgmd() :
+    m_connect_str(getenv("NDB_CONNECTSTRING"))
+    {
+      if (!m_connect_str.length()){
+        fprintf(stderr, "Could not init NdbConnectCtring");
+        abort();
+      }
+    }
+
+  const char* getConnectString() const {
+    return m_connect_str.c_str();
+  }
+};
+
+#endif

=== modified file 'storage/ndb/test/ndbapi/Makefile.am'
--- a/storage/ndb/test/ndbapi/Makefile.am	2008-07-01 12:35:34 +0000
+++ b/storage/ndb/test/ndbapi/Makefile.am	2008-07-01 15:01:50 +0000
@@ -33,6 +33,7 @@
 testIndex \
 testLimits \
 testMgm \
+testSingleUserMode \
 testNdbApi \
 testNodeRestart \
 testUpgrade \
@@ -86,6 +87,7 @@
 testIndex_SOURCES = testIndex.cpp
 testLimits_SOURCES = testLimits.cpp
 testMgm_SOURCES = testMgm.cpp
+testSingleUserMode_SOURCES = testSingleUserMode.cpp
 testNdbApi_SOURCES = testNdbApi.cpp
 testNodeRestart_SOURCES = testNodeRestart.cpp
 testUpgrade_SOURCES = testUpgrade.cpp

=== modified file 'storage/ndb/test/ndbapi/testInterpreter.cpp'
--- a/storage/ndb/test/ndbapi/testInterpreter.cpp	2008-05-23 09:07:58 +0000
+++ b/storage/ndb/test/ndbapi/testInterpreter.cpp	2008-06-18 14:55:21 +0000
@@ -206,8 +206,9 @@
   // Load 64-bit constant into register 1 and
   // write from register 1 to 32-bit column KOL2
   const Uint64 reg_val = 0x0102030405060708ULL;
-
-  const Uint32* reg_ptr32 = (const Uint32*)&reg_val;
+  Uint32 reg_ptr32[2];
+  memcpy(reg_ptr32+0, (Uint8*)&reg_val, sizeof(Uint32));
+  memcpy(reg_ptr32+1, ((Uint8*)&reg_val)+4, sizeof(Uint32));
   if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) {
     g_err << "runTestBug19537: platform is LITTLE endian" << endl;
   } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) {

=== modified file 'storage/ndb/test/ndbapi/testMgm.cpp'
--- a/storage/ndb/test/ndbapi/testMgm.cpp	2007-06-13 12:54:00 +0000
+++ b/storage/ndb/test/ndbapi/testMgm.cpp	2008-06-23 12:52:49 +0000
@@ -15,170 +15,28 @@
 
 #include <NDBT.hpp>
 #include <NDBT_Test.hpp>
-#include <HugoTransactions.hpp>
-#include <UtilTransactions.hpp>
-#include <NdbRestarter.hpp>
-#include <Vector.hpp>
-#include <random.h>
+#include "NdbMgmd.hpp"
 #include <mgmapi.h>
 #include <mgmapi_debug.h>
-#include <ndb_logevent.h>
 #include <InputStream.hpp>
 #include <signaldata/EventReport.hpp>
 
-int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
-
-  int records = ctx->getNumRecords();
-  HugoTransactions hugoTrans(*ctx->getTab());
-  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
-    return NDBT_FAILED;
-  }
-  return NDBT_OK;
-}
-
-int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
-  int records = ctx->getNumRecords();
-  
-  UtilTransactions utilTrans(*ctx->getTab());
-  if (utilTrans.clearTable2(GETNDB(step),  records) != 0){
-    return NDBT_FAILED;
-  }
-  return NDBT_OK;
-}
-
-
-int create_index_on_pk(Ndb* pNdb, const char* tabName){
-  int result  = NDBT_OK;
-
-  const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb(pNdb,
-								     tabName);
-
-  // Create index      
-  const char* idxName = "IDX_ON_PK";
-  ndbout << "Create: " <<idxName << "( ";
-  NdbDictionary::Index pIdx(idxName);
-  pIdx.setTable(tabName);
-  pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
-  for (int c = 0; c< tab->getNoOfPrimaryKeys(); c++){    
-    pIdx.addIndexColumn(tab->getPrimaryKey(c));
-    ndbout << tab->getPrimaryKey(c)<<" ";
-  }
-  
-  ndbout << ") ";
-  if (pNdb->getDictionary()->createIndex(pIdx) != 0){
-    ndbout << "FAILED!" << endl;
-    const NdbError err = pNdb->getDictionary()->getNdbError();
-    ERR(err);
-    result = NDBT_FAILED;
-  } else {
-    ndbout << "OK!" << endl;
-  }
-  return result;
-}
-
-int drop_index_on_pk(Ndb* pNdb, const char* tabName){
-  int result = NDBT_OK;
-  const char* idxName = "IDX_ON_PK";
-  ndbout << "Drop: " << idxName;
-  if (pNdb->getDictionary()->dropIndex(idxName, tabName) != 0){
-    ndbout << "FAILED!" << endl;
-    const NdbError err = pNdb->getDictionary()->getNdbError();
-    ERR(err);
-    result = NDBT_FAILED;
-  } else {
-    ndbout << "OK!" << endl;
-  }
-  return result;
-}
-
-
-#define CHECK(b) if (!(b)) { \
-  g_err << "ERR: "<< step->getName() \
-         << " failed on line " << __LINE__ << endl; \
-  result = NDBT_FAILED; \
-  continue; } 
-
-int runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step){
-  int result = NDBT_OK;
-  int loops = ctx->getNumLoops();
-  int records = ctx->getNumRecords();
-  Ndb* pNdb = GETNDB(step);
-  NdbRestarter restarter;
-  char tabName[255];
-  strncpy(tabName, ctx->getTab()->getName(), 255);
-  ndbout << "tabName="<<tabName<<endl;
-  
-  int i = 0;
-  int count;
-  HugoTransactions hugoTrans(*ctx->getTab());
-  UtilTransactions utilTrans(*ctx->getTab());
-  while (i<loops && result == NDBT_OK) {
-    g_info << i << ": ";
-    int timeout = 120;
-    // Test that the single user mode api can do everything     
-    CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
-    CHECK(restarter.waitClusterSingleUser(timeout) == 0); 
-    CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
-    CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
-    CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
-    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
-    CHECK(count == records);
-    CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
-    CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0);
-    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
-    CHECK(count == (records/2));
-    CHECK(utilTrans.clearTable(pNdb, records/2) == 0);
-    CHECK(restarter.exitSingleUserMode() == 0);
-    CHECK(restarter.waitClusterStarted(timeout) == 0); 
-
-    // Test create index in single user mode
-    CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
-    CHECK(restarter.waitClusterSingleUser(timeout) == 0); 
-    CHECK(create_index_on_pk(pNdb, tabName) == 0);
-    CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
-    CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
-    CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
-    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
-    CHECK(count == records);
-    CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
-    CHECK(drop_index_on_pk(pNdb, tabName) == 0);	  
-    CHECK(restarter.exitSingleUserMode() == 0);
-    CHECK(restarter.waitClusterStarted(timeout) == 0); 
-
-    // Test recreate index in single user mode
-    CHECK(create_index_on_pk(pNdb, tabName) == 0);
-    CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
-    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
-    CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
-    CHECK(restarter.waitClusterSingleUser(timeout) == 0); 
-    CHECK(drop_index_on_pk(pNdb, tabName) == 0);	
-    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
-    CHECK(create_index_on_pk(pNdb, tabName) == 0);
-    CHECK(restarter.exitSingleUserMode() == 0);
-    CHECK(restarter.waitClusterStarted(timeout) == 0); 
-    CHECK(drop_index_on_pk(pNdb, tabName) == 0);
-
-    CHECK(utilTrans.clearTable(GETNDB(step),  records) == 0);
-
-    ndbout << "Restarting cluster" << endl;
-    CHECK(restarter.restartAll() == 0);
-    CHECK(restarter.waitClusterStarted(timeout) == 0);
-    CHECK(pNdb->waitUntilReady(timeout) == 0);
-
-    i++;
-
-  }
-  return result;
-}
+/*
+  Tests that only need the mgmd(s) started
+
+  Start ndb_mgmd and set NDB_CONNECTSTRING pointing
+  to that/those ndb_mgmd(s), then run testMgm
+ */
+
 
 int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   Uint64 session_id= 0;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
   ndb_mgm_connect(h,0,0,0);
   int s= ndb_mgm_get_fd(h);
   session_id= ndb_mgm_get_session_id(h);
@@ -191,7 +49,7 @@
   int slen= sizeof(struct NdbMgmSession);
 
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
   ndb_mgm_connect(h,0,0,0);
 
   NdbSleep_SecSleep(1);
@@ -214,15 +72,12 @@
 
 int runTestApiConnectTimeout(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   int result= NDBT_FAILED;
-  int cc= 0;
-  int mgmd_nodeid= 0;
-  ndb_mgm_reply reply;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   ndbout << "TEST connect timeout" << endl;
 
@@ -246,7 +101,7 @@
   else
     goto done;
 
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   ndbout << "TEST connect timeout" << endl;
 
@@ -284,7 +139,7 @@
 
 int runTestApiTimeoutBasic(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   int result= NDBT_FAILED;
   int cc= 0;
   int mgmd_nodeid= 0;
@@ -292,7 +147,7 @@
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   ndbout << "TEST timout check_connection" << endl;
   int errs[] = { 1, 2, 3, -1};
@@ -404,14 +259,13 @@
 
 int runTestApiGetStatusTimeout(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   int result= NDBT_OK;
-  int cc= 0;
   int mgmd_nodeid= 0;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   int errs[] = { 0, 5, 6, 7, 8, 9, -1 };
 
@@ -492,13 +346,13 @@
 
 int runTestMgmApiGetConfigTimeout(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   int result= NDBT_OK;
   int mgmd_nodeid= 0;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   int errs[] = { 0, 1, 2, 3, -1 };
 
@@ -572,13 +426,13 @@
 
 int runTestMgmApiEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   int result= NDBT_OK;
   int mgmd_nodeid= 0;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   int errs[] = { 10000, 0, -1 };
 
@@ -682,13 +536,13 @@
 
 int runTestMgmApiStructEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
 {
-  char *mgm= ctx->getRemoteMgm();
+  NdbMgmd mgmd;
   int result= NDBT_OK;
   int mgmd_nodeid= 0;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
-  ndb_mgm_set_connectstring(h, mgm);
+  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
 
   int errs[] = { 10000, 0, -1 };
 
@@ -788,11 +642,6 @@
 }
 
 NDBT_TESTSUITE(testMgm);
-TESTCASE("SingleUserMode", 
-	 "Test single user mode"){
-  INITIALIZER(runTestSingleUserMode);
-  FINALIZER(runClearTable);
-}
 TESTCASE("ApiSessionFailure",
 	 "Test failures in MGMAPI session"){
   INITIALIZER(runTestApiSession);
@@ -832,7 +681,6 @@
 
 int main(int argc, const char** argv){
   ndb_init();
-  myRandom48Init(NdbTick_CurrentMillisecond());
   return testMgm.execute(argc, argv);
 }
 

=== added file 'storage/ndb/test/ndbapi/testSingleUserMode.cpp'
--- a/storage/ndb/test/ndbapi/testSingleUserMode.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/ndbapi/testSingleUserMode.cpp	2008-06-23 12:52:49 +0000
@@ -0,0 +1,181 @@
+/* Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include <NDBT.hpp>
+#include <NDBT_Test.hpp>
+#include <HugoTransactions.hpp>
+#include <UtilTransactions.hpp>
+#include <NdbRestarter.hpp>
+
+
+int
+runClearTable(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int records = ctx->getNumRecords();
+
+  UtilTransactions utilTrans(*ctx->getTab());
+  if (utilTrans.clearTable2(GETNDB(step),  records) != 0){
+    return NDBT_FAILED;
+  }
+  return NDBT_OK;
+}
+
+
+int
+create_index_on_pk(Ndb* pNdb, const char* tabName)
+{
+  int result  = NDBT_OK;
+
+  const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb(pNdb,
+								     tabName);
+  // Create index
+  const char* idxName = "IDX_ON_PK";
+  ndbout << "Create: " <<idxName << "( ";
+  NdbDictionary::Index pIdx(idxName);
+  pIdx.setTable(tabName);
+  pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
+  for (int c = 0; c< tab->getNoOfPrimaryKeys(); c++){
+    pIdx.addIndexColumn(tab->getPrimaryKey(c));
+    ndbout << tab->getPrimaryKey(c)<<" ";
+  }
+
+  ndbout << ") ";
+  if (pNdb->getDictionary()->createIndex(pIdx) != 0){
+    ndbout << "FAILED!" << endl;
+    const NdbError err = pNdb->getDictionary()->getNdbError();
+    ERR(err);
+    result = NDBT_FAILED;
+  } else {
+    ndbout << "OK!" << endl;
+  }
+  return result;
+}
+
+
+int
+drop_index_on_pk(Ndb* pNdb, const char* tabName)
+{
+  int result = NDBT_OK;
+  const char* idxName = "IDX_ON_PK";
+  ndbout << "Drop: " << idxName;
+  if (pNdb->getDictionary()->dropIndex(idxName, tabName) != 0){
+    ndbout << "FAILED!" << endl;
+    const NdbError err = pNdb->getDictionary()->getNdbError();
+    ERR(err);
+    result = NDBT_FAILED;
+  } else {
+    ndbout << "OK!" << endl;
+  }
+  return result;
+}
+
+
+#define CHECK(b) if (!(b)) { \
+  g_err << "ERR: "<< step->getName() \
+         << " failed on line " << __LINE__ << endl; \
+  result = NDBT_FAILED; \
+  continue; }
+
+
+int
+runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int result = NDBT_OK;
+  int loops = ctx->getNumLoops();
+  int records = ctx->getNumRecords();
+  Ndb* pNdb = GETNDB(step);
+  NdbRestarter restarter;
+  char tabName[255];
+  strncpy(tabName, ctx->getTab()->getName(), 255);
+  ndbout << "tabName="<<tabName<<endl;
+
+  int i = 0;
+  int count;
+  HugoTransactions hugoTrans(*ctx->getTab());
+  UtilTransactions utilTrans(*ctx->getTab());
+  while (i<loops && result == NDBT_OK) {
+    g_info << i << ": ";
+    int timeout = 120;
+    // Test that the single user mode api can do everything
+    CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
+    CHECK(restarter.waitClusterSingleUser(timeout) == 0);
+    CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
+    CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
+    CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
+    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
+    CHECK(count == records);
+    CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
+    CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0);
+    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
+    CHECK(count == (records/2));
+    CHECK(utilTrans.clearTable(pNdb, records/2) == 0);
+    CHECK(restarter.exitSingleUserMode() == 0);
+    CHECK(restarter.waitClusterStarted(timeout) == 0);
+
+    // Test create index in single user mode
+    CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
+    CHECK(restarter.waitClusterSingleUser(timeout) == 0);
+    CHECK(create_index_on_pk(pNdb, tabName) == 0);
+    CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
+    CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
+    CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
+    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
+    CHECK(count == records);
+    CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
+    CHECK(drop_index_on_pk(pNdb, tabName) == 0);
+    CHECK(restarter.exitSingleUserMode() == 0);
+    CHECK(restarter.waitClusterStarted(timeout) == 0);
+
+    // Test recreate index in single user mode
+    CHECK(create_index_on_pk(pNdb, tabName) == 0);
+    CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
+    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
+    CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
+    CHECK(restarter.waitClusterSingleUser(timeout) == 0);
+    CHECK(drop_index_on_pk(pNdb, tabName) == 0);
+    CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
+    CHECK(create_index_on_pk(pNdb, tabName) == 0);
+    CHECK(restarter.exitSingleUserMode() == 0);
+    CHECK(restarter.waitClusterStarted(timeout) == 0);
+    CHECK(drop_index_on_pk(pNdb, tabName) == 0);
+
+    CHECK(utilTrans.clearTable(GETNDB(step),  records) == 0);
+
+    ndbout << "Restarting cluster" << endl;
+    CHECK(restarter.restartAll() == 0);
+    CHECK(restarter.waitClusterStarted(timeout) == 0);
+    CHECK(pNdb->waitUntilReady(timeout) == 0);
+
+    i++;
+
+  }
+  return result;
+}
+
+
+NDBT_TESTSUITE(testSingleUserMode);
+TESTCASE("SingleUserMode",
+	 "Test single user mode"){
+  INITIALIZER(runTestSingleUserMode);
+  FINALIZER(runClearTable);
+}
+NDBT_TESTSUITE_END(testSingleUserMode);
+
+
+int main(int argc, const char** argv){
+  ndb_init();
+  return testSingleUserMode.execute(argc, argv);
+}
+

=== modified file 'storage/ndb/test/ndbapi/testSystemRestart.cpp'
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp	2008-03-25 15:47:07 +0000
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp	2008-06-18 21:25:50 +0000
@@ -1271,7 +1271,7 @@
   NdbRestarter restarter;
   const Uint32 nodeCount = restarter.getNumDbNodes();
 
-  if (nodeCount < 2)
+  if (nodeCount < 4)
     return NDBT_OK;
 
   int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT, 0 };

=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp	2008-06-17 08:54:54 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp	2008-06-18 21:25:50 +0000
@@ -1806,7 +1806,6 @@
   int records = ctx->getNumRecords();
   HugoTransactions hugoTrans(*ctx->getTab());
   
-  if(ctx->getPropertyWait("LastGCI", ~(Uint32)0))
   if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
   {
     g_err << "FAIL " << __LINE__ << endl;

=== modified file 'storage/ndb/test/run-test/Makefile.am'
--- a/storage/ndb/test/run-test/Makefile.am	2008-04-25 06:32:23 +0000
+++ b/storage/ndb/test/run-test/Makefile.am	2008-06-25 13:06:41 +0000
@@ -23,10 +23,11 @@
 test_PROGRAMS = atrt
 test_DATA=daily-basic-tests.txt daily-devel-tests.txt 16node-tests.txt \
           conf-ndbmaster.cnf \
-          conf-dl145a.cnf test-tests.txt conf-test.cnf db.sql
+          conf-fimafeng08.cnf conf-dl145a.cnf test-tests.txt conf-test.cnf db.sql
+#          conf-dl145a.cnf test-tests.txt conf-test.cnf db.sql
 
 test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \
-          atrt-clear-result.sh autotest-run.sh
+          autotest-run.sh
 
 atrt_SOURCES = main.cpp setup.cpp files.cpp db.cpp command.cpp
 

=== removed file 'storage/ndb/test/run-test/atrt-clear-result.sh'
--- a/storage/ndb/test/run-test/atrt-clear-result.sh	2005-04-27 01:19:54 +0000
+++ b/storage/ndb/test/run-test/atrt-clear-result.sh	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-set -e
-rm -rf result

=== modified file 'storage/ndb/test/run-test/autotest-boot.sh'
--- a/storage/ndb/test/run-test/autotest-boot.sh	2008-06-08 05:21:05 +0000
+++ b/storage/ndb/test/run-test/autotest-boot.sh	2008-06-24 14:08:39 +0000
@@ -13,7 +13,12 @@
 VERSION="autotest-boot.sh version 1.00"
 
 DATE=`date '+%Y-%m-%d'`
-HOST=`hostname -s`
+if [ `uname -s` != "SunOS" ]
+then
+  HOST=`hostname -s`
+else
+  HOST=`hostname`
+fi
 export DATE HOST
 
 set -e

=== modified file 'storage/ndb/test/run-test/autotest-run.sh'
--- a/storage/ndb/test/run-test/autotest-run.sh	2007-08-31 14:55:59 +0000
+++ b/storage/ndb/test/run-test/autotest-run.sh	2008-06-24 14:04:54 +0000
@@ -13,7 +13,12 @@
 VERSION="autotest-run.sh version 1.00"
 
 DATE=`date '+%Y-%m-%d'`
-HOST=`hostname -s`
+if [ `uname -s` != "SunOS" ]
+then
+  HOST=`hostname -s`
+else
+  HOST=`hostname`
+fi
 export DATE HOST
 
 set -e

=== added file 'storage/ndb/test/run-test/conf-fimafeng08.cnf'
--- a/storage/ndb/test/run-test/conf-fimafeng08.cnf	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/run-test/conf-fimafeng08.cnf	2008-06-24 14:08:39 +0000
@@ -0,0 +1,28 @@
+[atrt]
+basedir = CHOOSE_dir
+baseport = 14000
+clusters = .2node
+
+[ndb_mgmd]
+
+[mysqld]
+skip-innodb
+skip-bdb
+
+[cluster_config.2node]
+ndb_mgmd = CHOOSE_host1
+ndbd = CHOOSE_host2,CHOOSE_host3
+ndbapi= CHOOSE_host1,CHOOSE_host1,CHOOSE_host1
+
+NoOfReplicas = 2
+IndexMemory = 100M 
+DataMemory = 300M
+BackupMemory = 64M
+MaxNoOfConcurrentScans = 100
+MaxNoOfSavedMessages= 1000
+SendBufferMemory = 2M
+NoOfFragmentLogFiles = 4
+FragmentLogFileSize = 64M
+CompressedLCP=1
+CompressedBackup=1
+ODirect=1

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2008-07-01 12:35:34 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2008-07-01 15:01:50 +0000
@@ -467,10 +467,6 @@
 
 max-time: 500
 cmd: testScan
-args: -n ScanRestart T1 D1 D2 
-
-max-time: 500
-cmd: testScan
 args: -l 100 -n Scan-bug8262 T6 D1 D2
 
 max-time: 500
@@ -1106,7 +1102,7 @@
 cmd: test_event
 args: -l 1 -n SubscribeNR T1
 
-max-time: 300
+max-time: 600
 cmd: testNodeRestart
 args: -n Bug34702 T1
 

=== modified file 'storage/ndb/test/run-test/daily-devel-tests.txt'
--- a/storage/ndb/test/run-test/daily-devel-tests.txt	2008-03-25 15:52:57 +0000
+++ b/storage/ndb/test/run-test/daily-devel-tests.txt	2008-06-23 12:52:49 +0000
@@ -26,7 +26,7 @@
 # MGMAPI AND MGSRV
 #
 max-time: 1800
-cmd: testMgm
+cmd: testSingleUserMode
 args: -n SingleUserMode T1 
 
 #

=== modified file 'storage/ndb/test/run-test/main.cpp'
--- a/storage/ndb/test/run-test/main.cpp	2008-05-27 19:57:28 +0000
+++ b/storage/ndb/test/run-test/main.cpp	2008-06-23 16:14:43 +0000
@@ -33,7 +33,6 @@
 static const char progname[] = "ndb_atrt";
 static const char * g_gather_progname = "atrt-gather-result.sh";
 static const char * g_analyze_progname = "atrt-analyze-result.sh";
-static const char * g_clear_progname = "atrt-clear-result.sh";
 static const char * g_setup_progname = "atrt-setup.sh";
 
 static const char * g_log_filename = 0;
@@ -182,13 +181,13 @@
   if (!configure(g_config, g_do_setup))
     goto end;
   
-  g_logger.info("Setting up directories");
+  g_logger.info("Setting up directories...");
   if (!setup_directories(g_config, g_do_setup))
     goto end;
 
   if (g_do_setup)
   {
-    g_logger.info("Setting up files");
+    g_logger.info("Setting up files...");
     if (!setup_files(g_config, g_do_setup, g_do_sshx))
       goto end;
   }
@@ -226,7 +225,7 @@
     goto end;
   }
  
-  g_logger.info("Connecting to hosts");
+  g_logger.info("Connecting to hosts...");
   if(!connect_hosts(g_config))
     goto end;
 
@@ -264,7 +263,7 @@
      * Do we need to restart ndb
      */
     if(restart){
-      g_logger.info("(Re)starting server processes");
+      g_logger.info("(Re)starting server processes...");
       if(!stop_processes(g_config, ~0))
 	goto end;
 
@@ -444,7 +443,9 @@
     mycnf.append("my.cnf");
     if (lstat(mycnf.c_str(), &sbuf) != 0)
     {
-      g_logger.error("Unable to stat %s", mycnf.c_str());
+      g_logger.error("Could not find out which config file to use! "
+                     "Pass it as last argument to atrt: 'atrt <config file>' "
+                     "(default: '%s')", mycnf.c_str());
       return false;
     }
   }
@@ -592,6 +593,10 @@
       return false;
     }
   }
+  else {
+    g_logger.info("No test case file given with -f <test file>, "
+                  "running in interactive mode from stdin");
+  }
   
   if (g_do_setup == 0)
   {
@@ -601,7 +606,9 @@
     tmp.append("my.cnf");
     if (lstat(tmp.c_str(), &sbuf) != 0)
     {
-      g_logger.error("Unable to stat %s", tmp.c_str());
+      g_logger.error("Could not find a my.cnf file in the basedir '%s', "
+                     "you probably need to configure it with "
+                     "'atrt --configure=1 <config_file>'", g_basedir);
       return false;
     }
 
@@ -1019,7 +1026,10 @@
   Properties p;
   int elements = 0;
   char buf[1024];
+
   while(!feof(file)){
+    if (file == stdin)
+      printf("atrt> ");
     if(!fgets(buf, 1024, file))
       break;
 
@@ -1092,13 +1102,13 @@
 
 bool
 setup_test_case(atrt_config& config, const atrt_testcase& tc){
-  g_logger.debug("system(%s)", g_clear_progname);
-  const int r1 = system(g_clear_progname);
-  if(r1 != 0){
-    g_logger.critical("Failed to clear result");
+
+  if (!remove_dir("result", true))
+  {
+    g_logger.critical("setup_test_case: Failed to clear result");
     return false;
   }
-  
+
   size_t i = 0;
   for(; i<config.m_processes.size(); i++)
   {
@@ -1163,10 +1173,9 @@
 
 bool
 setup_hosts(atrt_config& config){
-  g_logger.debug("system(%s)", g_clear_progname);
-  const int r1 = system(g_clear_progname);
-  if(r1 != 0){
-    g_logger.critical("Failed to clear result");
+  if (!remove_dir("result", true))
+  {
+    g_logger.critical("setup_hosts: Failed to clear result");
     return false;
   }
 

=== modified file 'storage/ndb/test/run-test/test-tests.txt'
--- a/storage/ndb/test/run-test/test-tests.txt	2007-02-13 01:38:54 +0000
+++ b/storage/ndb/test/run-test/test-tests.txt	2008-06-23 12:52:49 +0000
@@ -3,7 +3,7 @@
 args: -n PkRead T1
 
 max-time: 1800
-cmd: testMgm
+cmd: testSingleUserMode
 args: -n SingleUserMode T1 
 
 #

=== modified file 'storage/ndb/test/src/Makefile.am'
--- a/storage/ndb/test/src/Makefile.am	2008-02-21 14:33:19 +0000
+++ b/storage/ndb/test/src/Makefile.am	2008-06-23 12:38:11 +0000
@@ -22,7 +22,7 @@
 	HugoOperations.cpp HugoTransactions.cpp \
 	HugoAsynchTransactions.cpp UtilTransactions.cpp \
 	NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp \
-	NdbBackup.cpp  NdbConfig.cpp NdbGrep.cpp NDBT_Table.cpp \
+	NdbBackup.cpp  NdbConfig.cpp NDBT_Table.cpp \
 	NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c AtrtClient.cpp \
 	CpcClient.cpp NdbMixRestarter.cpp NDBT_Thread.cpp DbUtil.cpp
 

=== modified file 'storage/ndb/test/src/NDBT_Test.cpp'
--- a/storage/ndb/test/src/NDBT_Test.cpp	2007-11-23 12:51:00 +0000
+++ b/storage/ndb/test/src/NDBT_Test.cpp	2008-06-23 12:37:22 +0000
@@ -36,19 +36,10 @@
   records = 1;
   loops = 1;
   stopped = false;
-  remote_mgm ="";
   propertyMutexPtr = NdbMutex_Create();
   propertyCondPtr = NdbCondition_Create();
 }
 
- 
-char * NDBT_Context::getRemoteMgm() const {
-  return remote_mgm;
-} 
-void NDBT_Context::setRemoteMgm(char * mgm) {
-  remote_mgm = strdup(mgm);
-} 
-
 
 NDBT_Context::~NDBT_Context(){
   NdbCondition_Destroy(propertyCondPtr);
@@ -893,8 +884,6 @@
 	
       ctx->setNumRecords(records);
       ctx->setNumLoops(loops);
-      if(remote_mgm != NULL)
-	ctx->setRemoteMgm(remote_mgm);
       ctx->setSuite(this);
       
       const NdbDictionary::Table** tables= ctx->getTables();
@@ -987,8 +976,6 @@
       ctx->setTab(ptab);
       ctx->setNumRecords(records);
       ctx->setNumLoops(loops);
-      if(remote_mgm != NULL)
-        ctx->setRemoteMgm(remote_mgm);
       ctx->setSuite(this);
     
       result = tests[t]->execute(ctx);
@@ -1090,8 +1077,6 @@
     ctx->setTab(pTab2);
     ctx->setNumRecords(records);
     ctx->setNumLoops(loops);
-    if(remote_mgm != NULL)
-      ctx->setRemoteMgm(remote_mgm);
     ctx->setSuite(this);
     
     result = tests[t]->execute(ctx);
@@ -1188,7 +1173,6 @@
 static int opt_records;
 static int opt_loops;
 static int opt_timer;
-static char * opt_remote_mgm = NULL;
 static char * opt_testname = NULL;
 static int opt_verbose;
 static int opt_seed = 0;
@@ -1219,10 +1203,6 @@
   { "testname", 'n', "Name of test to run",
     (uchar **) &opt_testname, (uchar **) &opt_testname, 0,
     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-  { "remote_mgm", 'm',
-    "host:port to mgmsrv of remote cluster",
-    (uchar **) &opt_remote_mgm, (uchar **) &opt_remote_mgm, 0,
-    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
   { "timer", 't', "Print execution time",
     (uchar **) &opt_timer, (uchar **) &opt_timer, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
@@ -1309,7 +1289,6 @@
   else 
     setOutputLevel(0); // Show only g_err ?
 
-  remote_mgm = opt_remote_mgm;
   records = opt_records;
   loops = opt_loops;
   timer = opt_timer;

=== removed file 'storage/ndb/test/src/NdbGrep.cpp'
--- a/storage/ndb/test/src/NdbGrep.cpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/test/src/NdbGrep.cpp	1970-01-01 00:00:00 +0000
@@ -1,332 +0,0 @@
-/* Copyright (C) 2003 MySQL AB
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-#include <signaldata/DumpStateOrd.hpp>
-#include <NdbGrep.hpp>
-#include <NdbOut.hpp>
-#include <NDBT_Output.hpp>
-#include <NdbConfig.h>
-#include <ConfigRetriever.hpp>
-#include <ndb_version.h>
-#include <NDBT.hpp>
-#include <NdbSleep.h>
-#include <random.h>
-#include <NdbTick.h>
-
-#define CHECK(b, m) { int _xx = b; if (!(_xx)) { \
-  ndbout << "ERR: "<< m \
-           << "   " << "File: " << __FILE__ \
-           << " (Line: " << __LINE__ << ")" << "- " << _xx << endl; \
-  return NDBT_FAILED; } }
-
-
-int 
-NdbGrep::start(){
-
-  return 1;
-}
-
-int 
-NdbGrep::stop(){
-
-  return 1;
-}
-
-
-int 
-NdbGrep::query(){
-
-  return 1;
-}
-
-
-int 
-NdbGrep::verify(NDBT_Context * ctx){
-  
-  if (!isConnected())
-    return -1;
-
-  char cheat_table[255];
-  BaseString::snprintf(cheat_table, 255, "TEST_DB/def/%s",ctx->getTab()->getName());
-
-  char buf[255];
-  BaseString::snprintf(buf, 255, "testGrepVerify -c \"nodeid=%d;host=%s\" -t %s -r %d", 
-	   4,  //cheat. Hardcoded nodeid....
-	   ctx->getRemoteMgm(),
-	   cheat_table,
-	   ctx->getNumRecords());
-  
-
-  ndbout << "buf: "<< buf <<endl;
-  int res = system(buf);  
-
-  ndbout << "res: " << res << endl;
-
-  return res;
-  
-
-  
-
-}
-
-
-// Master failure
-int
-NFDuringGrepM_codes[] = {
-  10003,
-  10004,
-  10005,
-  10007,
-  10008,
-  10009,
-  10010,
-  10012,
-  10013
-};
-
-// Slave failure
-int
-NFDuringGrepS_codes[] = {
-  10014,
-  10015,
-  10016,
-  10017,
-  10018,
-  10020
-};
-
-// Master takeover etc...
-int
-NFDuringGrepSL_codes[] = {
-  10001,
-  10002,
-  10021
-};
-
-int 
-NdbGrep::NFMaster(NdbRestarter& _restarter){
-  const int sz = sizeof(NFDuringGrepM_codes)/sizeof(NFDuringGrepM_codes[0]);
-  return NF(_restarter, NFDuringGrepM_codes, sz, true);
-}
-
-int 
-NdbGrep::NFMasterAsSlave(NdbRestarter& _restarter){
-  const int sz = sizeof(NFDuringGrepS_codes)/sizeof(NFDuringGrepS_codes[0]);
-  return NF(_restarter, NFDuringGrepS_codes, sz, true);
-}
-
-int 
-NdbGrep::NFSlave(NdbRestarter& _restarter){
-  const int sz = sizeof(NFDuringGrepS_codes)/sizeof(NFDuringGrepS_codes[0]);
-  return NF(_restarter, NFDuringGrepS_codes, sz, false);
-}
-
-int 
-NdbGrep::NF(NdbRestarter& _restarter, int *NFDuringGrep_codes, const int sz, bool onMaster){
-  {
-    int nodeId = _restarter.getMasterNodeId();
-
-    CHECK(_restarter.restartOneDbNode(nodeId, false, true, true) == 0,
-	  "Could not restart node "<< nodeId);
-    
-    CHECK(_restarter.waitNodesNoStart(&nodeId, 1) == 0,
-	  "waitNodesNoStart failed");
-    
-    CHECK(_restarter.startNodes(&nodeId, 1) == 0,
-	  "failed to start node");
-
-    NdbSleep_SecSleep(10);
-  }
-
-  CHECK(_restarter.waitClusterStarted() == 0,
-	"waitClusterStarted failed");
-
-  int nNodes = _restarter.getNumDbNodes();
-
-  myRandom48Init(NdbTick_CurrentMillisecond());
-
-  for(int i = 0; i<sz; i++){
-
-    int error = NFDuringGrep_codes[i];
-    unsigned int backupId;
-
-    const int masterNodeId = _restarter.getMasterNodeId();
-    CHECK(masterNodeId > 0, "getMasterNodeId failed");
-    int nodeId;
-
-    nodeId = masterNodeId;
-    if (!onMaster) {
-      int randomId;
-      while (nodeId == masterNodeId) {
-	randomId = myRandom48(nNodes);
-	nodeId = _restarter.getDbNodeId(randomId);
-      }
-    }
-
-    g_err << "NdbGrep::NF node = " << nodeId 
-	   << " error code = " << error << " masterNodeId = "
-	   << masterNodeId << endl;
-
-
-    int val = DumpStateOrd::CmvmiSetRestartOnErrorInsert;
-    CHECK(_restarter.dumpStateOneNode(nodeId, &val, 1) == 0,
-	  "failed to set RestartOnErrorInsert");
-    CHECK(_restarter.insertErrorInNode(nodeId, error) == 0,
-	  "failed to set error insert");
-   
-    g_info << "error inserted"  << endl;
-
-    g_info << "starting backup"  << endl;
-    int r = start();
-    g_info << "r = " << r
-	   << " (which should fail) started with id = "  << backupId << endl;
-    if (r == 0) {
-      g_err << "Grep should have failed on error_insertion " << error << endl
-	    << "Master = " << masterNodeId << "Node = " << nodeId << endl;
-    }
-
-    CHECK(_restarter.waitNodesNoStart(&nodeId, 1) == 0,
-	  "waitNodesNoStart failed");
-
-    g_info << "number of nodes running " << _restarter.getNumDbNodes() << endl;
-
-    if (_restarter.getNumDbNodes() != nNodes) {
-      g_err << "Failure: cluster not up" << endl;
-      return NDBT_FAILED;
-    }
-
-    NdbSleep_SecSleep(1);
-
-    g_info << "starting new backup"  << endl;
-    CHECK(start() == 0,
-	  "failed to start backup");
-    g_info << "(which should succeed) started with id = "  << backupId << endl;
-
-    g_info << "starting node"  << endl;
-    CHECK(_restarter.startNodes(&nodeId, 1) == 0,
-	  "failed to start node");
-
-    CHECK(_restarter.waitClusterStarted() == 0,
-	  "waitClusterStarted failed");
-    g_info << "node started"  << endl;
-
-    CHECK(_restarter.insertErrorInNode(nodeId, 10099) == 0,
-	  "failed to set error insert");
-  }
-
-  return NDBT_OK;
-}
-
-int
-FailS_codes[] = {
-  10023,
-  10024,
-  10025,
-  10026,
-  10027,
-  10028,
- 10029,
-  10030,
-  10031
-};
-
-int
-FailM_codes[] = {
-  10023,
-  10024,
-  10025,
-  10026,
-  10027,
-  10028,
-  10029,
-  10030,
-  10031
-};
-
-int 
-NdbGrep::FailMaster(NdbRestarter& _restarter){
-  const int sz = sizeof(FailM_codes)/sizeof(FailM_codes[0]);
-  return Fail(_restarter, FailM_codes, sz, true);
-}
-
-int 
-NdbGrep::FailMasterAsSlave(NdbRestarter& _restarter){
-  const int sz = sizeof(FailS_codes)/sizeof(FailS_codes[0]);
-  return Fail(_restarter, FailS_codes, sz, true);
-}
-
-int 
-NdbGrep::FailSlave(NdbRestarter& _restarter){
-  const int sz = sizeof(FailS_codes)/sizeof(FailS_codes[0]);
-  return Fail(_restarter, FailS_codes, sz, false);
-}
-
-int 
-NdbGrep::Fail(NdbRestarter& _restarter, int *Fail_codes, const int sz, bool onMaster){
-
-  CHECK(_restarter.waitClusterStarted() == 0,
-	"waitClusterStarted failed");
-
-  int nNodes = _restarter.getNumDbNodes();
-
-  myRandom48Init(NdbTick_CurrentMillisecond());
-
-  for(int i = 0; i<sz; i++){
-    int error = Fail_codes[i];
-    unsigned int backupId;
-
-    const int masterNodeId = _restarter.getMasterNodeId();
-    CHECK(masterNodeId > 0, "getMasterNodeId failed");
-    int nodeId;
-
-    nodeId = masterNodeId;
-    if (!onMaster) {
-      int randomId;
-      while (nodeId == masterNodeId) {
-	randomId = myRandom48(nNodes);
-	nodeId = _restarter.getDbNodeId(randomId);
-      }
-    }
-
-    g_err << "NdbGrep::Fail node = " << nodeId 
-	   << " error code = " << error << " masterNodeId = "
-	   << masterNodeId << endl;
-
-    CHECK(_restarter.insertErrorInNode(nodeId, error) == 0,
-	  "failed to set error insert");
-   
-    g_info << "error inserted"  << endl;
-    g_info << "waiting some before starting backup"  << endl;
-
-    g_info << "starting backup"  << endl;
-    int r = start();
-    g_info << "r = " << r
-	   << " (which should fail) started with id = "  << backupId << endl;
-    if (r == 0) {
-      g_err << "Grep should have failed on error_insertion " << error << endl
-	    << "Master = " << masterNodeId << "Node = " << nodeId << endl;
-    }
-
-    CHECK(_restarter.waitClusterStarted() == 0,
-	  "waitClusterStarted failed");
-
-    CHECK(_restarter.insertErrorInNode(nodeId, 10099) == 0,
-	  "failed to set error insert");
-  }
-
-  return NDBT_OK;
-}
-
-

=== modified file 'storage/ndb/tools/restore/consumer_restore.cpp'
--- a/storage/ndb/tools/restore/consumer_restore.cpp	2008-06-02 13:27:27 +0000
+++ b/storage/ndb/tools/restore/consumer_restore.cpp	2008-06-25 13:06:41 +0000
@@ -21,6 +21,8 @@
 #include <ndb_internal.hpp>
 #include <ndb_logevent.h>
 
+#define NDB_ANYVALUE_FOR_NOLOGGING 0xFFFFFFFF
+
 extern my_bool opt_core;
 
 extern FilteredNdbOut err;
@@ -34,6 +36,8 @@
 extern const char * g_connect_string;
 extern BaseString g_options;
 
+extern unsigned int opt_no_binlog;
+
 bool BackupRestore::m_preserve_trailing_spaces = false;
 
 const PromotionRules 
@@ -1536,6 +1540,11 @@
       exitHandler();
     }
 
+    if (opt_no_binlog)
+    {
+      op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
+    }
+
     // Prepare transaction (the transaction is NOT yet sent to NDB)
     cb->n_bytes= n_bytes;
     cb->connection->executeAsynchPrepare(NdbTransaction::Commit,
@@ -1796,6 +1805,10 @@
     } // if
   }
   
+  if (opt_no_binlog)
+  {
+    op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
+  }
   const int ret = trans->execute(NdbTransaction::Commit);
   if (ret != 0)
   {

=== modified file 'storage/ndb/tools/restore/restore_main.cpp'
--- a/storage/ndb/tools/restore/restore_main.cpp	2008-06-09 14:31:19 +0000
+++ b/storage/ndb/tools/restore/restore_main.cpp	2008-06-18 21:19:57 +0000
@@ -56,6 +56,7 @@
 Vector<BaseString> g_databases;
 Vector<BaseString> g_tables;
 NdbRecordPrintFormat g_ndbrecord_print_format;
+unsigned int opt_no_binlog;
 
 NDB_STD_OPTS_VARS;
 
@@ -91,6 +92,7 @@
   OPT_LINES_TERMINATED_BY,
   OPT_APPEND,
   OPT_PROGRESS_FREQUENCY,
+  OPT_NO_BINLOG,
   OPT_VERBOSE
 };
 static const char *opt_fields_enclosed_by= NULL;
@@ -207,6 +209,10 @@
     "Print status uf restore periodically in given seconds", 
     (uchar**) &opt_progress_frequency, (uchar**) &opt_progress_frequency, 0,
     GET_INT, REQUIRED_ARG, 0, 0, 65535, 0, 0, 0 },
+  { "no-binlog", OPT_NO_BINLOG,
+    "If a mysqld is connected and has binary log, do not log the restored data", 
+    (uchar**) &opt_no_binlog, (uchar**) &opt_no_binlog, 0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   { "verbose", OPT_VERBOSE,
     "verbosity", 
     (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0,


