List:Commits« Previous MessageNext Message »
From:jonas oreland Date:June 28 2011 5:03pm
Subject:bzr push into mysql-5.5-cluster branch (jonas.oreland:3380 to 3382)
View as plain text  
 3382 jonas oreland	2011-06-28 [merge]
      ndb - merge 71 to 55-cluster

    added:
      mysql-test/suite/ndb/r/ndb_row_count.result
      mysql-test/suite/ndb/t/ndb_row_count.test
    modified:
      mysql-test/suite/ndb/r/ndb_condition_pushdown.result
      mysql-test/suite/ndb/r/ndb_index_unique.result
      mysql-test/suite/ndb/r/ndb_join_pushdown.result
      sql/ha_ndb_index_stat.cc
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/AbstractDomainFieldHandlerImpl.java
      storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/Employee.java
      storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringFKOneOne.java
      storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringOid.java
      storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringPKOneOne.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java
      storage/ndb/config/type_JAVA.cmake
      storage/ndb/include/ndbapi/NdbIndexStat.hpp
      storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/ndbapi/NdbIndexStatImpl.cpp
      storage/ndb/src/ndbapi/NdbIndexStatImpl.hpp
      storage/ndb/src/ndbapi/NdbTransaction.cpp
      storage/ndb/test/crund/build.xml
      storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java
      storage/ndb/test/ndbapi/testMgmd.cpp
      storage/ndb/test/ndbapi/testScan.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
 3381 jonas oreland	2011-06-28
      ndb - add reference to ndbapi function to prevent libndbclient.so becoming empty (as CMake doesnt add whole-archive)

    modified:
      storage/ndb/src/dummy.cpp
      storage/ndb/test/ndbapi/CMakeLists.txt
 3380 Jonas Oreland	2011-06-28
      ndb - add dummp.cpp (to give link type) if java/jdk not present

    added:
      storage/ndb/src/dummy.cpp
    modified:
      storage/ndb/src/CMakeLists.txt
=== modified file 'mysql-test/suite/ndb/r/ndb_condition_pushdown.result'
--- a/mysql-test/suite/ndb/r/ndb_condition_pushdown.result	2011-06-23 06:59:40 +0000
+++ b/mysql-test/suite/ndb/r/ndb_condition_pushdown.result	2011-06-28 17:02:13 +0000
@@ -1910,7 +1910,7 @@ insert into NodeAlias VALUES(null, 8 , '
 12:22:26');
 explain select * from NodeAlias where (aliasKey LIKE '491803%');
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	NodeAlias	range	NodeAlias_KeyIndex	NodeAlias_KeyIndex	48	NULL	2	Using where with pushed condition
+1	SIMPLE	NodeAlias	range	NodeAlias_KeyIndex	NodeAlias_KeyIndex	48	NULL	3	Using where with pushed condition
 select * from NodeAlias where (aliasKey LIKE '491803%') order by id;
 id	nodeId	displayName	aliasKey	objectVersion	changed
 7	8	491803%	491803%	0	2008-03-10 12:22:26
@@ -2105,46 +2105,46 @@ pk	x
 set engine_condition_pushdown = on;
 explain select * from t where x <> "aa";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where
 select * from t where x <> "aa";
 pk	x
 0	a
 explain select * from t where "aa" <> x;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where
 select * from t where "aa" <> x;
 pk	x
 0	a
 explain select * from t where x between "" and "bb";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where
 select * from t where x between "" and "bb";
 pk	x
 0	a
 explain select * from t where x not between "" and "bb";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where
 select * from t where x not between "" and "bb";
 pk	x
 explain select * from t where x in ("","aa","b");
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where
 select * from t where x in ("","aa","b");
 pk	x
 explain select * from t where x not in ("","aa","b");
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where
 select * from t where x not in ("","aa","b");
 pk	x
 0	a
 explain select * from t where x like "aa?";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where with pushed condition
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where with pushed condition
 select * from t where x like "aa?";
 pk	x
 explain select * from t where x not like "aa?";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	1	Using where with pushed condition
+1	SIMPLE	t	ALL	NULL	NULL	NULL	NULL	2	Using where with pushed condition
 select * from t where x not like "aa?";
 pk	x
 0	a
@@ -2233,8 +2233,8 @@ primary key (`a`,`b`)
 ) engine = ndb;
 explain extended select * from tx join tx as t2 on tx.c=1 where t2.c=1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	tx	ALL	NULL	NULL	NULL	NULL	0	0.00	Using where with pushed condition: (`test`.`tx`.`c` = 1)
-1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	0	0.00	Using where with pushed condition: (`test`.`t2`.`c` = 1); Using join buffer
+1	SIMPLE	tx	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where with pushed condition: (`test`.`tx`.`c` = 1)
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where with pushed condition: (`test`.`t2`.`c` = 1); Using join buffer
 Warnings:
 Note	1644	Can't push table 't2' as child, 'type' must be a 'ref' access
 Note	1003	select `test`.`tx`.`a` AS `a`,`test`.`tx`.`b` AS `b`,`test`.`tx`.`c` AS `c`,`test`.`tx`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`tx` join `test`.`tx` `t2` where ((`test`.`tx`.`c` = 1) and (`test`.`t2`.`c` = 1))
@@ -2245,7 +2245,7 @@ join tx as t2 on t2.a = tx.a and t2.b =
 join tx as t3 on t3.a = tx.c and t3.b = tx.d
 join tx as t4 on t4.a = t3.b and t4.b = t2.c;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	tx	ALL	PRIMARY	NULL	NULL	NULL	0	0.00	Parent of 4 pushed join@1
+1	SIMPLE	tx	ALL	PRIMARY	NULL	NULL	NULL	2	100.00	Parent of 4 pushed join@1
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	8	test.tx.a,test.tx.b	1	100.00	Child of 'tx' in pushed join@1
 1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	8	test.tx.c,test.tx.d	1	100.00	Child of 'tx' in pushed join@1
 1	SIMPLE	t4	eq_ref	PRIMARY	PRIMARY	8	test.tx.d,test.t2.c	1	100.00	Child of 't2' in pushed join@1
@@ -2266,8 +2266,8 @@ Note	1644	Table 'tx' is not pushable: GR
 Note	1003	select `test`.`t2`.`c` AS `c`,count(distinct `test`.`t2`.`a`) AS `count(distinct t2.a)` from `test`.`tx` join `test`.`tx` `t2` where ((`test`.`tx`.`b` = `test`.`t2`.`d`) and (`test`.`tx`.`a` = `test`.`t2`.`c`) and (`test`.`t2`.`a` = 4)) group by `test`.`t2`.`c`
 explain extended select * from tx join tx as t2 on tx.c=1 where t2.c=1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	tx	ALL	NULL	NULL	NULL	NULL	0	0.00	Using where with pushed condition: (`test`.`tx`.`c` = 1)
-1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	0	0.00	Using where with pushed condition: (`test`.`t2`.`c` = 1); Using join buffer
+1	SIMPLE	tx	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where with pushed condition: (`test`.`tx`.`c` = 1)
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where with pushed condition: (`test`.`t2`.`c` = 1); Using join buffer
 Warnings:
 Note	1644	Can't push table 't2' as child, 'type' must be a 'ref' access
 Note	1003	select `test`.`tx`.`a` AS `a`,`test`.`tx`.`b` AS `b`,`test`.`tx`.`c` AS `c`,`test`.`tx`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`tx` join `test`.`tx` `t2` where ((`test`.`tx`.`c` = 1) and (`test`.`t2`.`c` = 1))
@@ -2285,6 +2285,39 @@ Note	1644	Table 't2' is not pushable: GR
 Note	1644	Table 'tx' is not pushable: GROUP BY cannot be done using index on grouped columns.
 Note	1003	select `test`.`t2`.`c` AS `c`,count(distinct `test`.`t2`.`a`) AS `count(distinct t2.a)` from `test`.`tx` join `test`.`tx` `t2` where ((`test`.`tx`.`b` = `test`.`t2`.`d`) and (`test`.`tx`.`a` = `test`.`t2`.`c`) and (`test`.`t2`.`a` = 4)) group by `test`.`t2`.`c`
 drop table tx;
+set engine_condition_pushdown = on;
+create table t (pk int, i int) engine = ndb;
+insert into t values (1,3), (3,6), (6,9), (9,1);
+create table subq (pk int, i int) engine = ndb;
+insert into subq values (1,3), (3,6), (6,9), (9,1);
+explain extended 
+select * from t where exists
+(select * from t as subq where subq.i=3 and t.i=3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	PRIMARY	t	ALL	NULL	NULL	NULL	NULL	4	100.00	Using where
+2	DEPENDENT SUBQUERY	subq	ALL	NULL	NULL	NULL	NULL	4	100.00	Using where with pushed condition: (`test`.`subq`.`i` = 3)
+Warnings:
+Note	1276	Field or reference 'test.t.i' of SELECT #2 was resolved in SELECT #1
+Note	1003	select `test`.`t`.`pk` AS `pk`,`test`.`t`.`i` AS `i` from `test`.`t` where exists(select 1 from `test`.`t` `subq` where ((`test`.`subq`.`i` = 3) and (`test`.`t`.`i` = 3)))
+explain extended 
+select * from t where exists
+(select * from subq where subq.i=3 and t.i=3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	PRIMARY	t	ALL	NULL	NULL	NULL	NULL	4	100.00	Using where
+2	DEPENDENT SUBQUERY	subq	ALL	NULL	NULL	NULL	NULL	4	100.00	Using where with pushed condition: (`test`.`subq`.`i` = 3)
+Warnings:
+Note	1276	Field or reference 'test.t.i' of SELECT #2 was resolved in SELECT #1
+Note	1003	select `test`.`t`.`pk` AS `pk`,`test`.`t`.`i` AS `i` from `test`.`t` where exists(select 1 from `test`.`subq` where ((`test`.`subq`.`i` = 3) and (`test`.`t`.`i` = 3)))
+select * from t where exists
+(select * from t as subq where subq.i=3 and t.i=3);
+pk	i
+1	3
+select * from t where exists
+(select * from subq where subq.i=3 and t.i=3);
+pk	i
+1	3
+drop table t,subq;
+
 create table t (pk1 int, pk2 int, primary key(pk1,pk2)) engine = ndb;
 insert into t values (1,0), (2,0), (3,0), (4,0);
 set engine_condition_pushdown=1;

=== modified file 'mysql-test/suite/ndb/r/ndb_index_unique.result'
--- a/mysql-test/suite/ndb/r/ndb_index_unique.result	2011-06-27 10:16:18 +0000
+++ b/mysql-test/suite/ndb/r/ndb_index_unique.result	2011-06-28 17:02:13 +0000
@@ -185,7 +185,7 @@ set @old_os = @@session.optimizer_switch
 set optimizer_switch = 'engine_condition_pushdown=on';
 explain select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	range	PRIMARY,b	PRIMARY	4	NULL	2	Using where with pushed condition
+1	SIMPLE	t2	range	PRIMARY,b	b	9	NULL	2	Using where with pushed condition; Using filesort
 select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
 a	b	c
 3	3	NULL

=== modified file 'mysql-test/suite/ndb/r/ndb_join_pushdown.result'
--- a/mysql-test/suite/ndb/r/ndb_join_pushdown.result	2011-06-23 13:44:45 +0000
+++ b/mysql-test/suite/ndb/r/ndb_join_pushdown.result	2011-06-28 17:02:13 +0000
@@ -26,7 +26,7 @@ select *
 from t1
 join t1 as t2 on t2.a = t1.b and t2.b = t1.c;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	16	12.50	Parent of 2 pushed join@1
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	16	100.00	Parent of 2 pushed join@1
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	8	test.t1.b,test.t1.c	1	100.00	Child of 't1' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`))
@@ -2106,7 +2106,7 @@ from t1, t1 as t2
 where t1.a in (1,3,5)
 and t2.a = t1.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	3	66.67	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`t1`.`a` in (1,3,5))
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	3	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`t1`.`a` in (1,3,5))
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Child of 't1' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` in (1,3,5)))
@@ -2129,7 +2129,7 @@ from t1, t1 as t2
 where t1.a in (1,3,5)
 and t2.a = t1.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	3	66.67	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`t1`.`a` in (1,3,5))
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	3	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`t1`.`a` in (1,3,5))
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Child of 't1' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` in (1,3,5)))
@@ -2147,7 +2147,7 @@ where t1.a in (1,3,5)
 and t2.a = t1.b
 order by t1.a desc;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	3	66.67	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`t1`.`a` in (1,3,5))
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	3	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`t1`.`a` in (1,3,5))
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Child of 't1' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` in (1,3,5))) order by `test`.`t1`.`a` desc
@@ -2182,7 +2182,7 @@ insert into t3_hash values (0x3f, 0x1f,
 explain extended
 select * from t3 x, t3 y, t1 where y.a3=x.d3 and y.b3=x.b3 and t1.a = y.d3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	66.67	Parent of 3 pushed join@1
+1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	100.00	Parent of 3 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.d3,test.x.b3	1	100.00	Child of 'x' in pushed join@1
 1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.y.d3	1	100.00	Child of 'y' in pushed join@1
 Warnings:
@@ -2220,7 +2220,7 @@ a3	b3	c3	d3	a3	b3	c3	d3	a3	b3	c3	d3	a3	b
 explain extended
 select straight_join * from t1 x, t1 y where y.a=0x1f and x.b = 0x1f;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	66.67	Using where with pushed condition: (`test`.`x`.`b` = 0x1f)
+1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where with pushed condition: (`test`.`x`.`b` = 0x1f)
 1	SIMPLE	y	const	PRIMARY	PRIMARY	4	const	1	100.00	
 Warnings:
 Note	1709	Can't push table 'y' as child of 'x', their dependency is 'const'
@@ -2360,7 +2360,7 @@ insert into t3_unq values (1003, 0x3f, 0
 explain extended
 select * from t3 x, t3 y where y.a3=x.d3 and y.b3=x.b3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	PRIMARY	NULL	NULL	NULL	3	66.67	Parent of 2 pushed join@1
+1	SIMPLE	x	ALL	PRIMARY	NULL	NULL	NULL	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.b3,test.x.d3	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = `test`.`x`.`b3`) and (`test`.`y`.`a3` = `test`.`x`.`d3`))
@@ -2372,7 +2372,7 @@ a3	b3	c3	d3	a3	b3	c3	d3
 explain extended
 select * from t3_hash x, t3_hash y where y.a3=x.d3 and y.b3=x.b3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	PRIMARY	NULL	NULL	NULL	3	66.67	Parent of 2 pushed join@1
+1	SIMPLE	x	ALL	PRIMARY	NULL	NULL	NULL	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.b3,test.x.d3	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3_hash` `x` join `test`.`t3_hash` `y` where ((`test`.`y`.`b3` = `test`.`x`.`b3`) and (`test`.`y`.`a3` = `test`.`x`.`d3`))
@@ -2384,7 +2384,7 @@ a3	b3	c3	d3	a3	b3	c3	d3
 explain extended
 select * from t3_unq x, t3_unq y where y.a3=x.d3 and y.b3=x.b3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	b3	NULL	NULL	NULL	3	66.67	Parent of 2 pushed join@1
+1	SIMPLE	x	ALL	b3	NULL	NULL	NULL	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	b3	b3	8	test.x.b3,test.x.d3	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`pk` AS `pk`,`test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`pk` AS `pk`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3_unq` `x` join `test`.`t3_unq` `y` where ((`test`.`y`.`b3` = `test`.`x`.`b3`) and (`test`.`y`.`a3` = `test`.`x`.`d3`))
@@ -2441,7 +2441,7 @@ select * from t3 as t1
 left outer join t3 as t2 on t2.d3 = t1.d3
 left outer join t3 as t3 on t3.a3 = t2.d3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	50.00	Parent of 3 pushed join@1
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	100.00	Parent of 3 pushed join@1
 1	SIMPLE	t2	ref	d3	d3	5	test.t1.d3	1	100.00	Child of 't1' in pushed join@1
 1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.d3	1	100.00	Child of 't2' in pushed join@1
 Warnings:
@@ -2539,7 +2539,7 @@ explain extended
 select straight_join * 
 from t3 as x join t3 as y on x.b3 = y.b3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	b3	NULL	NULL	NULL	7	28.57	Parent of 2 pushed join@1
+1	SIMPLE	x	ALL	b3	NULL	NULL	NULL	7	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	ref	b3	b3	4	test.x.b3	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select straight_join `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where (`test`.`y`.`b3` = `test`.`x`.`b3`)
@@ -2937,12 +2937,12 @@ select * from t1, t2, t1 as t3
 where t2.a = t1.b
 and t3.a = t2.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	50.00	
-1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	100.00	
+1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	75.00	Using where; Using join buffer
 1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.b	1	100.00	
 Warnings:
 Note	1709	Table 't2' not in ndb engine, not pushable
-Note	1709	Can't push table 't3' as child of 't1', column 't2.b' is outside scope of pushable join
+Note	1709	Cannot push table 't3' as child of table 't1'. Doing so would prevent using join buffer for table 't2'.
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t1` `t3` where ((`test`.`t3`.`a` = `test`.`t2`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`b`))
 select * from t1, t2, t1 as t3
 where t2.a = t1.b
@@ -2969,7 +2969,7 @@ select t1.a, t1.b, t2.a, t2.b
 from t1, t2
 where t2.a = t1.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	50.00	Parent of 2 pushed join@1
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	100.00	Parent of 2 pushed join@1
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Child of 't1' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`)
@@ -3002,7 +3002,7 @@ select t1.a, t1.b, t2.a, t2.b
 from t1, t2
 where t1.a = t2.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	4	50.00	Parent of 2 pushed join@1
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	4	100.00	Parent of 2 pushed join@1
 1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.b	1	100.00	Child of 't2' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`b`)
@@ -3109,7 +3109,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3="63";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	5	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = '63'))
@@ -3125,7 +3125,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	5	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3141,7 +3141,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	6	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3157,7 +3157,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	6	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3173,7 +3173,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	7	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3189,7 +3189,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	7	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3205,7 +3205,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3221,7 +3221,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = <cache>((60 + 3))) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3237,7 +3237,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	12	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 63) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3253,7 +3253,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	12	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 63) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3269,7 +3269,7 @@ insert into t3 values (0x3f, 0, 3, 0x3f)
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	5	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 1) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3285,7 +3285,7 @@ insert into t3 values (0x3f, 0.50, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where with pushed condition: (`test`.`y`.`b3` = 3.0)
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = 3.0))
@@ -3301,7 +3301,7 @@ insert into t3 values (0x3f, 0.50, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	8	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where with pushed condition: (`test`.`y`.`b3` = 3.0)
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = 3.0))
@@ -3317,7 +3317,7 @@ insert into t3 values (0x3f, 0.50, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	12	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = 3.14))
@@ -3333,7 +3333,7 @@ insert into t3 values (0x3f, 0.50, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	12	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = 3.14))
@@ -3349,7 +3349,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=63;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	9	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = 63))
@@ -3365,7 +3365,7 @@ insert into t3 values (0x3f, 0.50, 3, 0x
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	10	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 3.14) and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3381,7 +3381,7 @@ insert into t3 values (0x3f, '2000-02-29
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='2000-02-28';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	7	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = '2000-02-28') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3397,7 +3397,7 @@ insert into t3 values (0x3f, '2000-02-29
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='2000-02-28 23:59';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	12	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = '2000-02-28 23:59') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3413,7 +3413,7 @@ insert into t3 values (0x3f, '12:59:59',
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='23:59';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	7	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f) and (`test`.`y`.`b3` = 235900))
@@ -3429,7 +3429,7 @@ insert into t3 values (0x3f, 'Doffen', 2
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	20	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where with pushed condition: (`test`.`y`.`b3` = 'Dole')
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 'Dole') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3445,7 +3445,7 @@ insert into t3 values (0x3f, 'Doffen', 2
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	22	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where with pushed condition: (`test`.`y`.`b3` = 'Dole')
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 'Dole') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3461,7 +3461,7 @@ insert into t3 values (0x3f, 'Doffen', 2
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	518	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where with pushed condition: (`test`.`y`.`b3` = 'Dole')
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 'Dole') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3477,7 +3477,7 @@ insert into t3 values (0x3f, 'Doffen', 2
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	20	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 'Dole') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3492,7 +3492,7 @@ insert into t3 values (0x3f, 'Doffen', 2
 explain extended
 select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	2	100.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	4	const	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	22	test.x.d3,const	1	100.00	Child of 'x' in pushed join@1; Using where
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = 'Dole') and (`test`.`y`.`a3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 0x2f))
@@ -3508,7 +3508,7 @@ insert into t3 values (0x3f, 0x1f, 3, 0x
 explain extended
 select * from t3 x, t3 y where y.a3=x.b3 and y.b3="63";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	66.67	
+1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	5	test.x.b3,const	1	100.00	Using where
 Warnings:
 Note	1709	Can't push table 'y' as child, column 'a3' does not have same datatype as ref'ed column 'x.b3'
@@ -3535,7 +3535,7 @@ Dole	47	2	47	Dole	47	2	47
 explain extended
 select * from t3 x, t3 y where x.a3='Dole' and y.a3=x.a3 and y.b3=x.d3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ref	PRIMARY	PRIMARY	18	const	2	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`x`.`a3` = 'Dole')
+1	SIMPLE	x	ref	PRIMARY	PRIMARY	18	const	3	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`x`.`a3` = 'Dole')
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	22	const,test.x.d3	1	100.00	Child of 'x' in pushed join@1; Using where with pushed condition: (`test`.`y`.`a3` = 'Dole')
 Warnings:
 Note	1003	select `test`.`x`.`a3` AS `a3`,`test`.`x`.`b3` AS `b3`,`test`.`x`.`c3` AS `c3`,`test`.`x`.`d3` AS `d3`,`test`.`y`.`a3` AS `a3`,`test`.`y`.`b3` AS `b3`,`test`.`y`.`c3` AS `c3`,`test`.`y`.`d3` AS `d3` from `test`.`t3` `x` join `test`.`t3` `y` where ((`test`.`y`.`b3` = `test`.`x`.`d3`) and (`test`.`x`.`a3` = 'Dole') and (`test`.`y`.`a3` = 'Dole'))
@@ -3552,7 +3552,7 @@ straight_join t1 as t2 on t2.k = t1.b+0
 straight_join t1 as t3 on t3.k = t2.b
 straight_join t1 as t4 on t4.k = t1.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	50.00	Parent of 2 pushed join@1
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	4	100.00	Parent of 2 pushed join@1
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	func	1	100.00	Parent of 2 pushed join@2; Using where
 1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.b	1	100.00	Child of 't2' in pushed join@2
 1	SIMPLE	t4	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Child of 't1' in pushed join@1
@@ -3703,7 +3703,7 @@ insert into t2 values (11, 12);
 insert into t2 values (12, 13);
 explain extended select * from t1, t2 where t1.c = t2.a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	66.67	Parent of 2 pushed join@1
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.c	1	100.00	Child of 't1' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`c`)
@@ -3722,7 +3722,7 @@ a	b	c	a	b
 11	12	12	12	13
 explain extended select * from t2, t1 where t2.b = t1.a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	3	66.67	Parent of 2 pushed join@1
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Parent of 2 pushed join@1
 1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.b	1	100.00	Child of 't2' in pushed join@1
 Warnings:
 Note	1003	select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t2` join `test`.`t1` where (`test`.`t1`.`a` = `test`.`t2`.`b`)
@@ -3830,7 +3830,7 @@ insert into t1 values (2, 3, 4);
 insert into t1 values (3, 4, 5);
 explain extended select * from t1 x, t1 y where x.b=y.a and x.c=4;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	66.67	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`x`.`c` = 4)
+1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`x`.`c` = 4)
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	4	test.x.b	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`a` AS `a`,`test`.`x`.`b` AS `b`,`test`.`x`.`c` AS `c`,`test`.`y`.`a` AS `a`,`test`.`y`.`b` AS `b`,`test`.`y`.`c` AS `c` from `test`.`t1` `x` join `test`.`t1` `y` where ((`test`.`x`.`c` = 4) and (`test`.`y`.`a` = `test`.`x`.`b`))
@@ -4087,7 +4087,7 @@ insert into t1 values (1,2,20,30);
 insert into t1 values (2,3,30,40);
 explain extended select * from t1 as x join t1 as y join t1 as z on x.u=y.pk and y.a=z.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	66.67	Parent of 3 pushed join@1
+1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	3	100.00	Parent of 3 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	4	test.x.u	1	100.00	Child of 'x' in pushed join@1
 1	SIMPLE	z	ref	ix1	ix1	5	test.y.a	1	100.00	Child of 'y' in pushed join@1; Using where
 Warnings:
@@ -4118,7 +4118,7 @@ insert into t1 values (0,-1), (1,-1), (2
 (132,-1), (133,-1), (134,-1), (135,-1), (136,-1), (137,-1), (138,-1), (139,-1);
 explain extended select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	index	NULL	PRIMARY	4	NULL	140	1.43	Parent of 2 pushed join@1
+1	SIMPLE	x	index	NULL	PRIMARY	4	NULL	140	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	eq_ref	PRIMARY	PRIMARY	4	test.x.u	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select `test`.`x`.`pk` AS `pk`,`test`.`x`.`u` AS `u`,`test`.`y`.`pk` AS `pk`,`test`.`y`.`u` AS `u` from `test`.`t1` `x` join `test`.`t1` `y` where (`test`.`y`.`pk` = `test`.`x`.`u`) order by `test`.`x`.`pk`
@@ -4143,7 +4143,7 @@ insert into t1 values (11,11,10,10);
 explain extended select count(*) from t1 as x1 join t1 as x2 join t1 as x3 
 on x1.a=x2.u and x2.a = x3.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	12	16.67	Parent of 3 pushed join@1
+1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	12	100.00	Parent of 3 pushed join@1
 1	SIMPLE	x2	eq_ref	ix2	ix2	4	test.x1.a	1	100.00	Child of 'x1' in pushed join@1
 1	SIMPLE	x3	ref	ix1	ix1	5	test.x2.a	2	100.00	Child of 'x2' in pushed join@1; Using where
 Warnings:
@@ -4167,7 +4167,7 @@ count(*)
 insert into t1 values (12,12,20,10);
 explain extended select count(*) from t1 as x1 left join t1 as x2 on x1.a=x2.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	13	92.31	
+1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	13	100.00	
 1	SIMPLE	x2	ref	ix1	ix1	5	test.x1.a	2	100.00	
 Warnings:
 Note	1709	Can't push table 'x2' as child of 'x1', outer join of scan-child not implemented
@@ -4311,7 +4311,7 @@ Note	1003	select straight_join `test`.`x
 explain extended select straight_join * from t1 as x1 
 right join t1 as x2 on x2.b = x1.a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x2	ALL	NULL	NULL	NULL	NULL	13	92.31	
+1	SIMPLE	x2	ALL	NULL	NULL	NULL	NULL	13	100.00	
 1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	13	100.00	
 Warnings:
 Note	1709	Can't push table 'x1' as child, 'type' must be a 'ref' access
@@ -4596,7 +4596,7 @@ set ndb_join_pushdown=on;
 explain extended
 select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	8	25.00	Parent of 2 pushed join@1
+1	SIMPLE	x	ALL	NULL	NULL	NULL	NULL	8	100.00	Parent of 2 pushed join@1
 1	SIMPLE	y	ref	PRIMARY	PRIMARY	8	test.x.d,test.x.e	1	100.00	Child of 'x' in pushed join@1
 Warnings:
 Note	1003	select straight_join `test`.`x`.`d` AS `d`,`test`.`x`.`e` AS `e`,`test`.`x`.`f` AS `f`,`test`.`x`.`a` AS `a`,`test`.`x`.`b` AS `b`,`test`.`x`.`c` AS `c`,`test`.`y`.`d` AS `d`,`test`.`y`.`e` AS `e`,`test`.`y`.`f` AS `f`,`test`.`y`.`a` AS `a`,`test`.`y`.`b` AS `b`,`test`.`y`.`c` AS `c` from `test`.`t1` `x` join `test`.`t1` `y` where ((`test`.`y`.`b` = `test`.`x`.`e`) and (`test`.`y`.`a` = `test`.`x`.`d`))
@@ -4808,7 +4808,7 @@ join t1 as x2 on x1.a=x2.b
 join t1 as x3 on x2.a=x3.b 
 order by x1.pk limit 70;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x1	index	NULL	PRIMARY	4	NULL	10	20.00	Parent of 3 pushed join@1; Using temporary; Using filesort
+1	SIMPLE	x1	index	NULL	PRIMARY	4	NULL	10	100.00	Parent of 3 pushed join@1; Using temporary; Using filesort
 1	SIMPLE	x2	ref	ix1	ix1	5	test.x1.a	2	100.00	Child of 'x1' in pushed join@1; Using where
 1	SIMPLE	x3	ref	ix1	ix1	5	test.x2.a	2	100.00	Child of 'x2' in pushed join@1; Using where
 Warnings:
@@ -4911,7 +4911,7 @@ on table2.pk =  table3.pk )
 on table1.a =  table4.pk
 where  table2.pk != 6;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	table1	ALL	NULL	NULL	NULL	NULL	6	33.33	Using temporary
+1	SIMPLE	table1	ALL	NULL	NULL	NULL	NULL	6	100.00	Using temporary
 1	SIMPLE	table2	range	PRIMARY	PRIMARY	4	NULL	6	100.00	Parent of 2 pushed join@1; Using where with pushed condition: (`test`.`table2`.`pk` <> 6); Distinct; Using join buffer
 1	SIMPLE	table3	eq_ref	PRIMARY	PRIMARY	4	test.table2.pk	1	100.00	Child of 'table2' in pushed join@1; Distinct
 1	SIMPLE	table4	eq_ref	PRIMARY	PRIMARY	4	test.table1.a	1	100.00	Using where; Distinct
@@ -4953,7 +4953,7 @@ on t1.pk2 = t2.pk1
 where t1.pk1 != 6
 order by t1.pk1 DESC;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	4	50.00	Using where with pushed condition: (`test`.`t1`.`pk1` <> 6)
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	6	66.67	Using where with pushed condition: (`test`.`t1`.`pk1` <> 6)
 1	SIMPLE	t2	ref	PRIMARY	PRIMARY	4	test.t1.pk2	1	100.00	
 Warnings:
 Note	1709	Push of table 't2' as scan-child with ordered indexscan-root 't1' not implemented
@@ -4973,7 +4973,7 @@ explain extended
 select straight_join * from t as a join t as b 
 on a.uq=b.uq or b.uq is null;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	a	ALL	ix1	NULL	NULL	NULL	4	50.00	
+1	SIMPLE	a	ALL	ix1	NULL	NULL	NULL	4	100.00	
 1	SIMPLE	b	ref_or_null	ix1	ix1	5	test.a.uq	2	100.00	Using where
 Warnings:
 Note	1709	Table 'b' is not pushable: This table access method can not be pushed.
@@ -4996,7 +4996,7 @@ select * from t as a left join t as b
 on a.k is null and a.uq=b.uq;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	SIMPLE	b	system	NULL	NULL	NULL	NULL	1	100.00	
-1	SIMPLE	a	ALL	NULL	NULL	NULL	NULL	4	50.00	
+1	SIMPLE	a	ALL	NULL	NULL	NULL	NULL	4	100.00	
 Warnings:
 Note	1709	Table 'b' was optimized away, or const'ified by optimizer
 Note	1003	select `test`.`a`.`k` AS `k`,`test`.`a`.`uq` AS `uq`,NULL AS `k`,NULL AS `uq` from `test`.`t` `a`
@@ -5036,7 +5036,7 @@ aa	bb	x	bb	cc	x	bb	cc	x
 bb	cc	x	cc	dd	x	cc	dd	x
 explain extended select * from tc as x1, tc as x2 where x1.b=x2.a for update;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x1	ALL	uk1	NULL	NULL	NULL	3	66.67	
+1	SIMPLE	x1	ALL	uk1	NULL	NULL	NULL	3	100.00	
 1	SIMPLE	x2	eq_ref	PRIMARY	PRIMARY	12	test.x1.b	1	100.00	
 Warnings:
 Note	1709	Table 'x1' is not pushable: lock modes other than 'read committed' not implemented
@@ -5115,7 +5115,7 @@ left join (t1 as x2
 cross join t1 as x3) 
 on x1.d=x2.a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	8	25.00	
+1	SIMPLE	x1	ALL	NULL	NULL	NULL	NULL	8	100.00	
 1	SIMPLE	x2	ref	PRIMARY	PRIMARY	4	test.x1.d	1	100.00	
 1	SIMPLE	x3	ALL	NULL	NULL	NULL	NULL	8	100.00	
 Warnings:

=== added file 'mysql-test/suite/ndb/r/ndb_row_count.result'
--- a/mysql-test/suite/ndb/r/ndb_row_count.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_row_count.result	2011-06-23 12:19:32 +0000
@@ -0,0 +1,115 @@
+create table t1(
+a int primary key
+) engine=ndbcluster;
+insert into t1 values
+(00),(01),(02),(03),(04),(05),(06),(07),(08),(09),
+(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
+(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),
+(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),
+(40),(41),(42),(43),(44),(45),(46),(47),(48),(49),
+(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),
+(60),(61),(62),(63),(64),(65),(66),(67),(68),(69),
+(70),(71),(72),(73),(74),(75),(76),(77),(78),(79),
+(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+(90),(91),(92),(93),(94),(95),(96),(97),(98),(99);
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+insert into t1 select a+100 from t1;
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	20	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+delete from t1 where a >= 100;
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+begin;
+insert into t1 select a+100 from t1;
+commit;
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	20	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+begin;
+delete from t1 where a >= 100;
+commit;
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+begin;
+insert into t1 select a+100 from t1;
+rollback;
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+begin;
+delete from t1 where a <= 100;
+rollback;
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+insert into t1 select a from t1;
+ERROR 23000: Can't write; duplicate key in table 't1'
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+begin;
+insert into t1 select a from t1;
+ERROR 23000: Can't write; duplicate key in table 't1'
+
+# expected result 0 roundtrips - read stats from share
+explain extended select * from t1 where a < 100;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	10	100.00	Using where with pushed condition: (`test`.`t1`.`a` < 100)
+Warnings:
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 100)
+@ndb_execute_count:=VARIABLE_VALUE-@ndb_init_execute_count
+0
+drop table t1;

=== added file 'mysql-test/suite/ndb/t/ndb_row_count.test'
--- a/mysql-test/suite/ndb/t/ndb_row_count.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_row_count.test	2011-06-23 12:19:32 +0000
@@ -0,0 +1,100 @@
+-- source include/have_ndb.inc
+
+create table t1(
+  a int primary key
+) engine=ndbcluster;
+
+insert into t1 values
+(00),(01),(02),(03),(04),(05),(06),(07),(08),(09),
+(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
+(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),
+(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),
+(40),(41),(42),(43),(44),(45),(46),(47),(48),(49),
+(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),
+(60),(61),(62),(63),(64),(65),(66),(67),(68),(69),
+(70),(71),(72),(73),(74),(75),(76),(77),(78),(79),
+(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+(90),(91),(92),(93),(94),(95),(96),(97),(98),(99);
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+insert into t1 select a+100 from t1;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+delete from t1 where a >= 100;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+begin;
+insert into t1 select a+100 from t1;
+commit;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+begin;
+delete from t1 where a >= 100;
+commit;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+begin;
+insert into t1 select a+100 from t1;
+rollback;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+begin;
+delete from t1 where a <= 100;
+rollback;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+--error ER_DUP_KEY
+insert into t1 select a from t1;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+begin;
+--error ER_DUP_KEY
+insert into t1 select a from t1;
+
+--echo
+--echo # expected result 0 roundtrips - read stats from share
+--source suite/ndb/include/ndb_init_execute_count.inc
+explain extended select * from t1 where a < 100;
+--source suite/ndb/include/ndb_execute_count.inc
+
+drop table t1;

=== modified file 'sql/ha_ndb_index_stat.cc'
--- a/sql/ha_ndb_index_stat.cc	2011-06-22 09:20:53 +0000
+++ b/sql/ha_ndb_index_stat.cc	2011-06-28 17:02:13 +0000
@@ -1084,10 +1084,10 @@ ndb_index_stat_proc_idle(Ndb_index_stat_
   const time_t check_wait=
     st->check_time == 0 ? 0 : st->check_time + check_delay - pr.now;
 
-  DBUG_PRINT("index_stat", ("st %s check wait:%ds force update:%u"
-                            " clean wait:%ds cache clean:%d",
-                            st->id, check_wait, st->force_update,
-                            clean_wait, st->cache_clean));
+  DBUG_PRINT("index_stat", ("st %s check wait:%lds force update:%u"
+                            " clean wait:%lds cache clean:%d",
+                            st->id, (long)check_wait, st->force_update,
+                            (long)clean_wait, st->cache_clean));
 
   if (!st->cache_clean && clean_wait <= 0)
   {

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-06-27 11:30:44 +0000
+++ b/sql/ha_ndbcluster.cc	2011-06-28 17:02:13 +0000
@@ -275,9 +275,7 @@ static MYSQL_THDVAR_BOOL(
 */
 bool ndb_index_stat_get_enable(THD *thd)
 {
-  mysql_mutex_lock(&LOCK_global_system_variables);
   const bool value = THDVAR(thd, index_stat_enable);
-  mysql_mutex_unlock(&LOCK_global_system_variables);
   return value;
 }
 
@@ -432,6 +430,9 @@ HASH ndbcluster_open_tables;
 static uchar *ndbcluster_get_key(NDB_SHARE *share, size_t *length,
                                 my_bool not_used __attribute__((unused)));
 
+static void modify_shared_stats(NDB_SHARE *share,
+                                Ndb_local_table_statistics *local_stat);
+
 static int ndb_get_table_statistics(THD *thd, ha_ndbcluster*, bool, Ndb*,
                                     const NdbRecord *, struct Ndb_statistics *,
                                     bool have_lock= FALSE,
@@ -6560,27 +6561,50 @@ int ha_ndbcluster::info(uint flag)
     if (!thd)
       thd= current_thd;
     DBUG_PRINT("info", ("HA_STATUS_VARIABLE"));
-    if ((flag & HA_STATUS_NO_LOCK) &&
-        !THDVAR(thd, use_exact_count))
-    {
-      if (thd->lex->sql_command != SQLCOM_SHOW_TABLE_STATUS &&
-          thd->lex->sql_command != SQLCOM_SHOW_KEYS)
-      {
-        /*
-          just use whatever stats we have however,
-          optimizer behaves strangely if we return few rows
-        */
-        if (stats.records < 2)
-          stats.records= 2;
-        break;
-      }
-    }
+
     if (!m_table_info)
     {
       if ((my_errno= check_ndb_connection(thd)))
         DBUG_RETURN(my_errno);
     }
-    result= update_stats(thd, 1);
+
+    /*
+      May need to update local copy of statistics in
+      'm_table_info', either directly from datanodes,
+      or from shared (mutex protected) cached copy, if:
+       1) 'use_exact_count' has been set (by config or user).
+       2) HA_STATUS_NO_LOCK -> read from shared cached copy.
+       3) Local copy is invalid.
+    */
+    bool exact_count= THDVAR(thd, use_exact_count);
+    if (exact_count                 ||         // 1)
+        !(flag & HA_STATUS_NO_LOCK) ||         // 2)
+        m_table_info == NULL        ||         // 3)
+        m_table_info->records == ~(ha_rows)0)  // 3)
+    {
+      result= update_stats(thd, (exact_count || !(flag & HA_STATUS_NO_LOCK)));
+      if (result)
+        DBUG_RETURN(result);
+    }
+    /* Read from local statistics, fast and fuzzy, wo/ locks */
+    else
+    {
+      DBUG_ASSERT(m_table_info->records != ~(ha_rows)0);
+      stats.records= m_table_info->records +
+                     m_table_info->no_uncommitted_rows_count;
+    }
+
+    if (thd->lex->sql_command != SQLCOM_SHOW_TABLE_STATUS &&
+        thd->lex->sql_command != SQLCOM_SHOW_KEYS)
+    {
+      /*
+        just use whatever stats we have. However,
+        optimizer interprets the values 0 and 1 as EXACT:
+          -> < 2 should not be returned.
+      */
+      if (stats.records < 2)
+        stats.records= 2;
+    }
     break;
   }
   /* RPK moved to variable part */
@@ -7169,7 +7193,18 @@ int ha_ndbcluster::start_statement(THD *
       there is more than one handler involved, execute deferal
       not possible
     */
+    ha_ndbcluster* handler = thd_ndb->m_handler;
     thd_ndb->m_handler= NULL;
+    if (handler != NULL)
+    {
+      /**
+       * If we initially belived that this could be run
+       *  using execute deferal...but changed out mind
+       *  add handler to thd_ndb->open_tables like it would
+       *  have done "normally"
+       */
+      add_handler_to_open_tables(thd, thd_ndb, handler);
+    }
   }
   if (!trans && table_count == 0)
   {
@@ -7215,6 +7250,57 @@ int ha_ndbcluster::start_statement(THD *
   DBUG_RETURN(0);
 }
 
+int
+ha_ndbcluster::add_handler_to_open_tables(THD *thd,
+                                          Thd_ndb *thd_ndb,
+                                          ha_ndbcluster* handler)
+{
+  DBUG_ENTER("ha_ndbcluster::add_handler_to_open_tables");
+  DBUG_PRINT("info", ("Adding %s", handler->m_share->key));
+
+  /**
+   * thd_ndb->open_tables is only used iff thd_ndb->m_handler is not
+   */
+  DBUG_ASSERT(thd_ndb->m_handler == NULL);
+  const void *key= handler->m_share;
+  HASH_SEARCH_STATE state;
+  THD_NDB_SHARE *thd_ndb_share=
+    (THD_NDB_SHARE*)my_hash_first(&thd_ndb->open_tables,
+                                  (const uchar *)&key, sizeof(key),
+                                  &state);
+  while (thd_ndb_share && thd_ndb_share->key != key)
+  {
+    thd_ndb_share=
+      (THD_NDB_SHARE*)my_hash_next(&thd_ndb->open_tables,
+                                   (const uchar *)&key, sizeof(key),
+                                   &state);
+  }
+  if (thd_ndb_share == 0)
+  {
+    thd_ndb_share= (THD_NDB_SHARE *) alloc_root(&thd->transaction.mem_root,
+                                                sizeof(THD_NDB_SHARE));
+    if (!thd_ndb_share)
+    {
+      mem_alloc_error(sizeof(THD_NDB_SHARE));
+      DBUG_RETURN(1);
+    }
+    thd_ndb_share->key= key;
+    thd_ndb_share->stat.last_count= thd_ndb->count;
+    thd_ndb_share->stat.no_uncommitted_rows_count= 0;
+    thd_ndb_share->stat.records= ~(ha_rows)0;
+    my_hash_insert(&thd_ndb->open_tables, (uchar *)thd_ndb_share);
+  }
+  else if (thd_ndb_share->stat.last_count != thd_ndb->count)
+  {
+    thd_ndb_share->stat.last_count= thd_ndb->count;
+    thd_ndb_share->stat.no_uncommitted_rows_count= 0;
+    thd_ndb_share->stat.records= ~(ha_rows)0;
+  }
+
+  handler->m_table_info= &thd_ndb_share->stat;
+  DBUG_RETURN(0);
+}
+
 int ha_ndbcluster::init_handler_for_statement(THD *thd)
 {
   /*
@@ -7248,45 +7334,11 @@ int ha_ndbcluster::init_handler_for_stat
   }
 #endif
 
-  if (thd_options(thd) & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+  int ret = 0;
+  if (thd_ndb->m_handler == 0)
   {
-    const void *key= m_table;
-    HASH_SEARCH_STATE state;
-    THD_NDB_SHARE *thd_ndb_share=
-      (THD_NDB_SHARE*)my_hash_first(&thd_ndb->open_tables,
-                                    (const uchar *)&key, sizeof(key),
-                                    &state);
-    while (thd_ndb_share && thd_ndb_share->key != key)
-    {
-      thd_ndb_share=
-        (THD_NDB_SHARE*)my_hash_next(&thd_ndb->open_tables,
-                                     (const uchar *)&key, sizeof(key),
-                                     &state);
-    }
-    if (thd_ndb_share == 0)
-    {
-      thd_ndb_share= (THD_NDB_SHARE *) alloc_root(&thd->transaction.mem_root,
-                                                  sizeof(THD_NDB_SHARE));
-      if (!thd_ndb_share)
-      {
-        mem_alloc_error(sizeof(THD_NDB_SHARE));
-        DBUG_RETURN(1);
-      }
-      thd_ndb_share->key= key;
-      thd_ndb_share->stat.last_count= thd_ndb->count;
-      thd_ndb_share->stat.no_uncommitted_rows_count= 0;
-      thd_ndb_share->stat.records= ~(ha_rows)0;
-      my_hash_insert(&thd_ndb->open_tables, (uchar *)thd_ndb_share);
-    }
-    else if (thd_ndb_share->stat.last_count != thd_ndb->count)
-    {
-      thd_ndb_share->stat.last_count= thd_ndb->count;
-      thd_ndb_share->stat.no_uncommitted_rows_count= 0;
-      thd_ndb_share->stat.records= ~(ha_rows)0;
-    }
-    DBUG_PRINT("exit", ("thd_ndb_share: 0x%lx  key: 0x%lx",
-                        (long) thd_ndb_share, (long) key));
-    m_table_info= &thd_ndb_share->stat;
+    DBUG_ASSERT(m_share);
+    ret = add_handler_to_open_tables(thd, thd_ndb, this);
   }
   else
   {
@@ -7296,7 +7348,7 @@ int ha_ndbcluster::init_handler_for_stat
     stat.records= ~(ha_rows)0;
     m_table_info= &stat;
   }
-  DBUG_RETURN(0);
+  DBUG_RETURN(ret);
 }
 
 int ha_ndbcluster::external_lock(THD *thd, int lock_type)
@@ -7671,6 +7723,25 @@ int ndbcluster_commit(handlerton *hton,
     if (res != -1)
       ndbcluster_print_error(res, error_op);
   }
+  else
+  {
+    /* Update shared statistics for tables inserted into / deleted from*/
+    if (thd_ndb->m_handler &&      // Autocommit Txn
+        thd_ndb->m_handler->m_share &&
+        thd_ndb->m_handler->m_table_info)
+    {
+      modify_shared_stats(thd_ndb->m_handler->m_share, thd_ndb->m_handler->m_table_info);
+    }
+
+    /* Manual commit: Update all affected NDB_SHAREs found in 'open_tables' */
+    for (uint i= 0; i<thd_ndb->open_tables.records; i++)
+    {
+      THD_NDB_SHARE *thd_share=
+        (THD_NDB_SHARE*)my_hash_element(&thd_ndb->open_tables, i);
+      modify_shared_stats((NDB_SHARE*)thd_share->key, &thd_share->stat);
+    }
+  }
+
   ndb->closeTransaction(trans);
   thd_ndb->trans= NULL;
   thd_ndb->m_handler= NULL;
@@ -12664,8 +12735,22 @@ int ha_ndbcluster::update_stats(THD *thd
   struct Ndb_statistics stat;
   Thd_ndb *thd_ndb= get_thd_ndb(thd);
   DBUG_ENTER("ha_ndbcluster::update_stats");
-  if (do_read_stat || !m_share)
+  do
   {
+    if (m_share && !do_read_stat)
+    {
+      pthread_mutex_lock(&m_share->mutex);
+      stat= m_share->stat;
+      pthread_mutex_unlock(&m_share->mutex);
+
+      DBUG_ASSERT(stat.row_count != ~(ha_rows)0); // should never be invalid
+
+      /* Accept shared cached statistics if row_count is valid. */
+      if (stat.row_count != ~(ha_rows)0)
+        break;
+    }
+
+    /* Request statistics from datanodes */
     Ndb *ndb= thd_ndb->ndb;
     if (ndb->setDatabaseName(m_dbname))
     {
@@ -12677,25 +12762,25 @@ int ha_ndbcluster::update_stats(THD *thd
     {
       DBUG_RETURN(err);
     }
+
+    /* Update shared statistics with fresh data */
     if (m_share)
     {
       pthread_mutex_lock(&m_share->mutex);
       m_share->stat= stat;
       pthread_mutex_unlock(&m_share->mutex);
     }
+    break;
   }
-  else
+  while(0);
+
+  int no_uncommitted_rows_count= 0;
+  if (m_table_info && !thd_ndb->m_error)
   {
-    pthread_mutex_lock(&m_share->mutex);
-    stat= m_share->stat;
-    pthread_mutex_unlock(&m_share->mutex);
+    m_table_info->records= stat.row_count;
+    m_table_info->last_count= thd_ndb->count;
+    no_uncommitted_rows_count= m_table_info->no_uncommitted_rows_count;
   }
-  struct Ndb_local_table_statistics *local_info= m_table_info;
-  int no_uncommitted_rows_count;
-  if (thd_ndb->m_error || !local_info)
-    no_uncommitted_rows_count= 0;
-  else
-    no_uncommitted_rows_count= local_info->no_uncommitted_rows_count;
   stats.mean_rec_length= stat.row_size;
   stats.data_file_length= stat.fragment_memory;
   stats.records= stat.row_count + no_uncommitted_rows_count;
@@ -12715,6 +12800,35 @@ int ha_ndbcluster::update_stats(THD *thd
   DBUG_RETURN(0);
 }
 
+/**
+  Update 'row_count' in shared table statistcs if any rows where
+  inserted/deleted by the local transaction related to specified
+ 'local_stat'.
+  Should be called when transaction has succesfully commited its changes.
+*/
+static
+void modify_shared_stats(NDB_SHARE *share,
+                         Ndb_local_table_statistics *local_stat)
+{
+  if (local_stat->no_uncommitted_rows_count)
+  {
+    pthread_mutex_lock(&share->mutex);
+    DBUG_ASSERT(share->stat.row_count != ~(ha_rows)0);// should never be invalid
+    if (share->stat.row_count != ~(ha_rows)0)
+    {
+      DBUG_PRINT("info", ("Update row_count for %s, row_count: %lu, with:%d",
+                          share->table_name, (ulong) share->stat.row_count,
+                          local_stat->no_uncommitted_rows_count));
+      share->stat.row_count=
+        ((Int64)share->stat.row_count+local_stat->no_uncommitted_rows_count > 0)
+         ? share->stat.row_count+local_stat->no_uncommitted_rows_count
+         : 0;
+    }
+    pthread_mutex_unlock(&share->mutex);
+    local_stat->no_uncommitted_rows_count= 0;
+  }
+}
+
 /* If part_id contains a legal partition id, ndbstat returns the
    partition-statistics pertaining to that partition only.
    Otherwise, it returns the table-statistics,

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-06-27 10:16:18 +0000
+++ b/sql/ha_ndbcluster.h	2011-06-28 17:02:13 +0000
@@ -781,6 +781,7 @@ private:
 
   int update_stats(THD *thd, bool do_read_stat, bool have_lock= FALSE,
                    uint part_id= ~(uint)0);
+  int add_handler_to_open_tables(THD*, Thd_ndb*, ha_ndbcluster* handler);
 };
 
 int ndbcluster_discover(THD* thd, const char* dbname, const char* name,

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/AbstractDomainFieldHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/AbstractDomainFieldHandlerImpl.java	2011-06-20 23:34:36 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/AbstractDomainFieldHandlerImpl.java	2011-06-24 20:58:44 +0000
@@ -1279,7 +1279,7 @@ public abstract class AbstractDomainFiel
 
     };
 
-    protected static ObjectOperationHandler objectOperationHandlerInt = new ObjectOperationHandler() {
+    protected abstract static class ObjectOperationHandlerInt implements ObjectOperationHandler {
 
         public boolean isPrimitive() {
             return true;
@@ -1301,17 +1301,6 @@ public abstract class AbstractDomainFiel
             op.setInt(fmd.storeColumn, (Integer) value);
         }
 
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
-            if (logger.isDetailEnabled()) {
-                logger.detail("Column " + fmd.columnName + " set to value " + handler.getInt(fmd.fieldNumber));
-            }
-            op.setInt(fmd.storeColumn, handler.getInt(fmd.fieldNumber));
-        }
-
-        public String handler() {
-            return "primitive int";
-        }
-
         public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
             int value = rs.getInt(fmd.storeColumn);
             if (logger.isDetailEnabled()) {
@@ -1339,14 +1328,49 @@ public abstract class AbstractDomainFiel
             return true;
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getInt(index);
+        }
+
+    };
+
+    protected static ObjectOperationHandler objectOperationHandlerInt = new ObjectOperationHandlerInt() {
+
+        public String handler() {
+            return "primitive int";
+        }
+
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
+            if (logger.isDetailEnabled()) {
+                logger.detail("Column " + fmd.columnName + " set to value " + handler.getInt(fmd.fieldNumber));
+            }
+            op.setInt(fmd.storeColumn, handler.getInt(fmd.fieldNumber));
+        }
+
         public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
                 PartitionKey partitionKey, ValueHandler keyValueHandler) {
             throw new ClusterJFatalInternalException(
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
-        public Object getValue(QueryExecutionContext context, String index) {
-            return context.getInt(index);
+    };
+
+    protected static ObjectOperationHandler objectOperationHandlerKeyInt = new ObjectOperationHandlerInt() {
+
+        public String handler() {
+            return "primitive key int";
+        }
+
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
+            if (logger.isDetailEnabled()) {
+                logger.detail("Key field " + fmd.name + " set equal to value " + handler.getInt(fmd.getFieldNumber()));
+            }
+            op.equalInt(fmd.storeColumn, handler.getInt(fmd.fieldNumber));
+        }
+
+        public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
+                PartitionKey partitionKey, ValueHandler keyValueHandler) {
+            partitionKey.addIntKey(fmd.storeColumn, keyValueHandler.getInt(fmd.fieldNumber));
         }
 
     };
@@ -1635,14 +1659,13 @@ public abstract class AbstractDomainFiel
 
     };
 
-    protected static ObjectOperationHandler objectOperationHandlerKeyInt = new ObjectOperationHandler() {
+    protected static ObjectOperationHandler objectOperationHandlerKeyString = new ObjectOperationHandler() {
 
         public boolean isPrimitive() {
-            return true;
+            return false;
         }
 
         public void objectInitializeJavaDefaultValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler) {
-            handler.setInt(fmd.fieldNumber, 0);
         }
 
         public void operationGetValue(AbstractDomainFieldHandlerImpl fmd, Operation op) {
@@ -1650,44 +1673,38 @@ public abstract class AbstractDomainFiel
         }
 
         public Object getDefaultValueFor(AbstractDomainFieldHandlerImpl fmd, String columnDefaultValue) {
-            return (Integer) (columnDefaultValue == null ? Integer.valueOf(0) : Integer.valueOf(columnDefaultValue));
+            return (String) (columnDefaultValue == null ? "" : columnDefaultValue);
         }
 
         public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
-            op.setInt(fmd.storeColumn, (Integer) value);
+            op.setString(fmd.storeColumn, (String) value);
         }
 
         public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
-            if (logger.isDetailEnabled()) {
-                logger.detail("Key field " + fmd.name + " set equal to value " + handler.getInt(fmd.getFieldNumber()));
-            }
-            op.equalInt(fmd.storeColumn, handler.getInt(fmd.fieldNumber));
+            op.equalString(fmd.storeColumn, handler.getString(fmd.fieldNumber));
         }
 
         public String handler() {
-            return "key int";
+            return "key String";
         }
 
         public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
-        if (logger.isDetailEnabled()) {
-            logger.detail("field " + fmd.name + " set to value " + rs.getInt(fmd.storeColumn));
-        }
-            handler.setInt(fmd.fieldNumber, rs.getInt(fmd.storeColumn));
+            handler.setString(fmd.fieldNumber, rs.getString(fmd.storeColumn));
         }
 
         public void operationSetBounds(AbstractDomainFieldHandlerImpl fmd, Object value, IndexScanOperation.BoundType type, IndexScanOperation op) {
-            op.setBoundInt(fmd.storeColumn, type, (Integer) value);
+            op.setBoundString(fmd.storeColumn, type, (String) value);
         }
 
         public void filterCompareValue(AbstractDomainFieldHandlerImpl fmd, Object value, ScanFilter.BinaryCondition condition, ScanFilter filter) {
-            filter.cmpInt(condition, fmd.storeColumn, ((Integer) value).intValue());
+            filter.cmpString(condition, fmd.storeColumn, (String)value);
         }
 
         public void operationEqual(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
             if (logger.isDetailEnabled()) {
-                logger.detail("Column " + fmd.columnName + " set to value " + value);
+                logger.detail("setString.setEqual " + fmd.columnName + " to value " + value);
             }
-            op.equalInt(fmd.storeColumn, ((Integer) value).intValue());
+            op.equalString(fmd.storeColumn, (String)value);
         }
 
         public boolean isValidIndexType(AbstractDomainFieldHandlerImpl fmd, boolean hashNotOrdered) {
@@ -1696,15 +1713,16 @@ public abstract class AbstractDomainFiel
 
         public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
                 PartitionKey partitionKey, ValueHandler keyValueHandler) {
-            partitionKey.addIntKey(fmd.storeColumn, keyValueHandler.getInt(fmd.fieldNumber));
+            partitionKey.addStringKey(fmd.storeColumn, keyValueHandler.getString(fmd.fieldNumber));
         }
 
         public Object getValue(QueryExecutionContext context, String index) {
-            return context.getInt(index);
+            return context.getString(index);
         }
 
     };
-    protected static ObjectOperationHandler objectOperationHandlerKeyLong = new ObjectOperationHandler() {
+
+    public abstract static class ObjectOperationHandlerLong implements ObjectOperationHandler {
 
         public boolean isPrimitive() {
             return true;
@@ -1723,18 +1741,7 @@ public abstract class AbstractDomainFiel
         }
 
         public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
-            op.setLong(fmd.storeColumn, (Long) value);
-        }
-
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
-            if (logger.isDetailEnabled()) {
-                logger.detail("Column " + fmd.columnName + " set to value " + handler.getLong(fmd.fieldNumber));
-            }
-            op.equalLong(fmd.storeColumn, handler.getLong(fmd.fieldNumber));
-        }
-
-        public String handler() {
-            return "key long";
+            op.setLong(fmd.storeColumn, ((Number) value).longValue());
         }
 
         public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
@@ -1742,7 +1749,7 @@ public abstract class AbstractDomainFiel
         }
 
         public void operationSetBounds(AbstractDomainFieldHandlerImpl fmd, Object value, IndexScanOperation.BoundType type, IndexScanOperation op) {
-            op.setBoundLong(fmd.storeColumn, type, (Long) value);
+            op.setBoundLong(fmd.storeColumn, type, ((Number) value).longValue());
         }
 
         public void filterCompareValue(AbstractDomainFieldHandlerImpl fmd, Object value, ScanFilter.BinaryCondition condition, ScanFilter filter) {
@@ -1760,147 +1767,52 @@ public abstract class AbstractDomainFiel
             return true;
         }
 
-        public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
-                PartitionKey partitionKey, ValueHandler keyValueHandler) {
-            partitionKey.addLongKey(fmd.storeColumn, keyValueHandler.getLong(fmd.fieldNumber));
-        }
-
         public Object getValue(QueryExecutionContext context, String index) {
             return context.getLong(index);
         }
 
-    };
-    protected static ObjectOperationHandler objectOperationHandlerKeyString = new ObjectOperationHandler() {
-
-        public boolean isPrimitive() {
-            return false;
-        }
-
-        public void objectInitializeJavaDefaultValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler) {
-        }
-
-        public void operationGetValue(AbstractDomainFieldHandlerImpl fmd, Operation op) {
-            op.getValue(fmd.storeColumn);
-        }
-
-        public Object getDefaultValueFor(AbstractDomainFieldHandlerImpl fmd, String columnDefaultValue) {
-            return (String) (columnDefaultValue == null ? "" : columnDefaultValue);
-        }
-
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
-            op.setString(fmd.storeColumn, (String) value);
-        }
+    }
 
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
-            op.equalString(fmd.storeColumn, handler.getString(fmd.fieldNumber));
-        }
+    protected static ObjectOperationHandler objectOperationHandlerLong = new ObjectOperationHandlerLong() {
 
         public String handler() {
-            return "key String";
-        }
-
-        public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
-            handler.setString(fmd.fieldNumber, rs.getString(fmd.storeColumn));
-        }
-
-        public void operationSetBounds(AbstractDomainFieldHandlerImpl fmd, Object value, IndexScanOperation.BoundType type, IndexScanOperation op) {
-            op.setBoundString(fmd.storeColumn, type, (String) value);
-        }
-
-        public void filterCompareValue(AbstractDomainFieldHandlerImpl fmd, Object value, ScanFilter.BinaryCondition condition, ScanFilter filter) {
-            filter.cmpString(condition, fmd.storeColumn, (String)value);
+            return "primitive long";
         }
 
-        public void operationEqual(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
             if (logger.isDetailEnabled()) {
-                logger.detail("setString.setEqual " + fmd.columnName + " to value " + value);
+                logger.detail("Column " + fmd.columnName + " set to value " + handler.getLong(fmd.fieldNumber));
             }
-            op.equalString(fmd.storeColumn, (String)value);
-        }
-
-        public boolean isValidIndexType(AbstractDomainFieldHandlerImpl fmd, boolean hashNotOrdered) {
-            return true;
+            op.setLong(fmd.storeColumn, handler.getLong(fmd.fieldNumber));
         }
 
         public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
                 PartitionKey partitionKey, ValueHandler keyValueHandler) {
-            partitionKey.addStringKey(fmd.storeColumn, keyValueHandler.getString(fmd.fieldNumber));
-        }
-
-        public Object getValue(QueryExecutionContext context, String index) {
-            return context.getString(index);
+            throw new ClusterJFatalInternalException(
+                    local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
     };
 
-    protected static ObjectOperationHandler objectOperationHandlerLong = new ObjectOperationHandler() {
-
-        public boolean isPrimitive() {
-            return true;
-        }
-
-        public void objectInitializeJavaDefaultValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler) {
-            handler.setLong(fmd.fieldNumber, 0L);
-        }
-
-        public void operationGetValue(AbstractDomainFieldHandlerImpl fmd, Operation op) {
-            op.getValue(fmd.storeColumn);
-        }
+    protected static ObjectOperationHandler objectOperationHandlerKeyLong = new ObjectOperationHandlerLong() {
 
-        public Object getDefaultValueFor(AbstractDomainFieldHandlerImpl fmd, String columnDefaultValue) {
-            return (Long) (columnDefaultValue == null ? Long.valueOf(0) : Long.valueOf(columnDefaultValue));
-        }
-
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
-            op.setLong(fmd.storeColumn, ((Number) value).longValue());
+        public String handler() {
+            return "key primitive long";
         }
 
         public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
             if (logger.isDetailEnabled()) {
                 logger.detail("Column " + fmd.columnName + " set to value " + handler.getLong(fmd.fieldNumber));
             }
-            op.setLong(fmd.storeColumn, handler.getLong(fmd.fieldNumber));
-        }
-
-        public String handler() {
-            return "primitive long";
-        }
-
-        public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
-            handler.setLong(fmd.fieldNumber, rs.getLong(fmd.storeColumn));
-        }
-
-        public void operationSetBounds(AbstractDomainFieldHandlerImpl fmd, Object value, IndexScanOperation.BoundType type, IndexScanOperation op) {
-            op.setBoundLong(fmd.storeColumn, type, ((Number) value).longValue());
-        }
-
-        public void filterCompareValue(AbstractDomainFieldHandlerImpl fmd, Object value, ScanFilter.BinaryCondition condition, ScanFilter filter) {
-            filter.cmpLong(condition, fmd.storeColumn, ((Number) value).longValue());
-        }
-
-        public void operationEqual(AbstractDomainFieldHandlerImpl fmd, Object value, Operation op) {
-            if (logger.isDetailEnabled()) {
-                logger.detail("setLong.setEqual " + fmd.columnName + " to value " + value);
-            }
-            op.equalLong(fmd.storeColumn, ((Number) value).longValue());
-        }
-
-        public boolean isValidIndexType(AbstractDomainFieldHandlerImpl fmd, boolean hashNotOrdered) {
-            return true;
+            op.equalLong(fmd.storeColumn, handler.getLong(fmd.fieldNumber));
         }
 
         public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
                 PartitionKey partitionKey, ValueHandler keyValueHandler) {
-            throw new ClusterJFatalInternalException(
-                    local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
-        }
-
-        public Object getValue(QueryExecutionContext context, String index) {
-            return context.getLong(index);
+            partitionKey.addLongKey(fmd.storeColumn, keyValueHandler.getLong(fmd.fieldNumber));
         }
 
     };
-
     protected static ObjectOperationHandler objectOperationHandlerObjectByte = new ObjectOperationHandler() {
 
         public boolean isPrimitive() {
@@ -2099,8 +2011,8 @@ public abstract class AbstractDomainFiel
 
     };
 
-    protected static ObjectOperationHandler objectOperationHandlerObjectInteger = new ObjectOperationHandler() {
-
+    protected abstract static class ObjectOperationHandlerInteger implements ObjectOperationHandler {
+        
         public boolean isPrimitive() {
             return false;
         }
@@ -2120,18 +2032,6 @@ public abstract class AbstractDomainFiel
             op.setInt(fmd.storeColumn, (Integer) value);
         }
 
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
-            if (handler.isNull(fmd.fieldNumber)) {
-                op.setNull(fmd.storeColumn);
-            } else {
-                op.setInt(fmd.storeColumn, handler.getObjectInt(fmd.fieldNumber));
-            }
-        }
-
-        public String handler() {
-            return "object Integer";
-        }
-
         public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
             handler.setObjectInt(fmd.fieldNumber, rs.getObjectInteger(fmd.storeColumn));
         }
@@ -2155,19 +2055,56 @@ public abstract class AbstractDomainFiel
             return true;
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getInt(index);
+        }
+
+    }
+
+    protected static ObjectOperationHandler objectOperationHandlerObjectInteger = new ObjectOperationHandlerInteger() {
+
+        public String handler() {
+            return "object Integer";
+        }
+
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
+            if (handler.isNull(fmd.fieldNumber)) {
+                op.setNull(fmd.storeColumn);
+            } else {
+                op.setInt(fmd.storeColumn, handler.getObjectInt(fmd.fieldNumber));
+            }
+        }
+
         public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
                 PartitionKey partitionKey, ValueHandler keyValueHandler) {
             throw new ClusterJFatalInternalException(
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
-        public Object getValue(QueryExecutionContext context, String index) {
-            return context.getInt(index);
+    };
+
+    protected static ObjectOperationHandler objectOperationHandlerKeyObjectInteger = new ObjectOperationHandlerInteger() {
+
+        public String handler() {
+            return "key object Integer";
+        }
+
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
+            if (handler.isNull(fmd.fieldNumber)) {
+                op.setNull(fmd.storeColumn);
+            } else {
+                op.equalInt(fmd.storeColumn, handler.getObjectInt(fmd.fieldNumber));
+            }
+        }
+
+        public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
+                PartitionKey partitionKey, ValueHandler keyValueHandler) {
+            partitionKey.addIntKey(fmd.storeColumn, keyValueHandler.getObjectInt(fmd.fieldNumber));
         }
 
     };
 
-    protected static ObjectOperationHandler objectOperationHandlerObjectLong = new ObjectOperationHandler() {
+    public abstract static class ObjectOperationHandlerObjectLong implements ObjectOperationHandler {
 
         public boolean isPrimitive() {
             return false;
@@ -2188,18 +2125,6 @@ public abstract class AbstractDomainFiel
             op.setLong(fmd.storeColumn, ((Number) value).longValue());
         }
 
-        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
-            if (handler.isNull(fmd.fieldNumber)) {
-                op.setNull(fmd.storeColumn);
-            } else {
-                op.setLong(fmd.storeColumn, handler.getObjectLong(fmd.fieldNumber));
-            }
-        }
-
-        public String handler() {
-            return "object Long";
-        }
-
         public void objectSetValue(AbstractDomainFieldHandlerImpl fmd, ResultData rs, ValueHandler handler) {
             handler.setObjectLong(fmd.fieldNumber, rs.getObjectLong(fmd.storeColumn));
         }
@@ -2223,14 +2148,51 @@ public abstract class AbstractDomainFiel
             return true;
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getLong(index);
+        }
+
+    }
+
+    protected static ObjectOperationHandler objectOperationHandlerObjectLong = new ObjectOperationHandlerObjectLong() {
+
+        public String handler() {
+            return "object Long";
+        }
+
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
+            if (handler.isNull(fmd.fieldNumber)) {
+                op.setNull(fmd.storeColumn);
+            } else {
+                op.setLong(fmd.storeColumn, handler.getObjectLong(fmd.fieldNumber));
+            }
+        }
+
         public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
                 PartitionKey partitionKey, ValueHandler keyValueHandler) {
             throw new ClusterJFatalInternalException(
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
-        public Object getValue(QueryExecutionContext context, String index) {
-            return context.getLong(index);
+    };
+
+    protected static ObjectOperationHandler objectOperationHandlerKeyObjectLong = new ObjectOperationHandlerObjectLong() {
+
+        public String handler() {
+            return "key object Long";
+        }
+
+        public void operationSetValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler, Operation op) {
+            if (handler.isNull(fmd.fieldNumber)) {
+                op.setNull(fmd.storeColumn);
+            } else {
+                op.equalLong(fmd.storeColumn, handler.getObjectLong(fmd.fieldNumber));
+            }
+        }
+
+        public void partitionKeySetPart(AbstractDomainFieldHandlerImpl fmd,
+                PartitionKey partitionKey, ValueHandler keyValueHandler) {
+            partitionKey.addLongKey(fmd.storeColumn, keyValueHandler.getObjectLong(fmd.fieldNumber));
         }
 
     };

=== modified file 'storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/Employee.java'
--- a/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/Employee.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/Employee.java	2011-06-24 20:58:44 +0000
@@ -28,7 +28,7 @@ import javax.persistence.Table;
 public class Employee implements IdBase, Serializable {
 
     @Id
-    private int id;
+    private Integer id;
     private String name;
     private int magic;
     private Integer age;

=== modified file 'storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringFKOneOne.java'
--- a/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringFKOneOne.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringFKOneOne.java	2011-06-24 20:58:44 +0000
@@ -49,7 +49,7 @@ public class LongIntStringFKOneOne exten
 
     @javax.persistence.Id
     @javax.persistence.Column(name="longpk")
-    private long longpk;
+    private Long longpk;
 
     @javax.persistence.Id
     @javax.persistence.Column(name="intpk")
@@ -74,11 +74,11 @@ public class LongIntStringFKOneOne exten
     public LongIntStringFKOneOne() {
     }
 
-    public long getLongpk() {
+    public Long getLongpk() {
         return longpk;
     }
 
-    public void setLongpk(long value) {
+    public void setLongpk(Long value) {
         longpk = value;
     }
 
@@ -131,8 +131,6 @@ public class LongIntStringFKOneOne exten
         result.append(stringpk);
         result.append("\"]: ");
         result.append(stringvalue);
-        result.append(" -> (");
-        result.append((longIntStringPKOneOne==null)?"null":longIntStringPKOneOne.toString());
         result.append(").");
         return result.toString();
     }

=== modified file 'storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringOid.java'
--- a/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringOid.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringOid.java	2011-06-24 20:58:44 +0000
@@ -27,7 +27,7 @@ import java.io.Serializable;
  */
 public class LongIntStringOid extends LongIntStringConstants implements Serializable {
 
-    public long longpk;
+    public Long longpk;
 
     public int intpk;
 
@@ -50,14 +50,14 @@ public class LongIntStringOid extends Lo
         if (obj == null || !this.getClass().equals(obj.getClass()))
             return false;
         LongIntStringOid o = (LongIntStringOid)obj;
-        return (this.longpk == o.longpk
+        return (this.longpk.equals(o.longpk)
                 && this.intpk == o.intpk
                 && this.stringpk.equals(o.stringpk));
     }
 
     @Override
     public int hashCode() {
-        return stringpk.hashCode() + (int)intpk + (int)longpk;
+        return stringpk.hashCode() + (int)intpk + longpk.intValue();
     }
 
     @Override

=== modified file 'storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringPKOneOne.java'
--- a/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringPKOneOne.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-jpatest/src/main/java/com/mysql/clusterj/jpatest/model/LongIntStringPKOneOne.java	2011-06-24 20:58:44 +0000
@@ -41,7 +41,7 @@ public class LongIntStringPKOneOne exten
 
     @javax.persistence.Id
     @javax.persistence.Column(name="longpk")
-    private long longpk;
+    private Long longpk;
 
     @javax.persistence.Id
     @javax.persistence.Column(name="intpk")
@@ -60,11 +60,11 @@ public class LongIntStringPKOneOne exten
     public LongIntStringPKOneOne() {
     }
 
-    public long getLongpk() {
+    public Long getLongpk() {
         return longpk;
     }
 
-    public void setLongpk(long value) {
+    public void setLongpk(Long value) {
         longpk = value;
     }
 

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java	2011-06-20 23:34:36 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java	2011-06-24 20:58:44 +0000
@@ -226,14 +226,18 @@ public class NdbOpenJPADomainFieldHandle
                 oidField = getFieldForOidClass(this, domainTypeHandler.getOidClass(), name);
                 indexNames.add("PRIMARY");
                 switch (javaType) {
-                    case JavaTypes.INT: 
-                    case JavaTypes.INT_OBJ: 
+                    case JavaTypes.INT:
                         this.objectOperationHandlerDelegate = objectOperationHandlerKeyInt;
                         break;
+                    case JavaTypes.INT_OBJ: 
+                        this.objectOperationHandlerDelegate = objectOperationHandlerKeyObjectInteger;
+                        break;
                     case JavaTypes.LONG:
-                    case JavaTypes.LONG_OBJ: 
                         this.objectOperationHandlerDelegate = objectOperationHandlerKeyLong;
                         break;
+                    case JavaTypes.LONG_OBJ: 
+                        this.objectOperationHandlerDelegate = objectOperationHandlerKeyObjectLong;
+                        break;
                    case JavaTypes.STRING: this.objectOperationHandlerDelegate =
                         objectOperationHandlerKeyString;
                         break;

=== modified file 'storage/ndb/config/type_JAVA.cmake'
--- a/storage/ndb/config/type_JAVA.cmake	2011-06-22 09:23:35 +0000
+++ b/storage/ndb/config/type_JAVA.cmake	2011-06-27 15:07:36 +0000
@@ -130,9 +130,10 @@ MACRO(CREATE_JAR)
   SET(separator) # Empty separator to start with
   SET(classpath_str)
   FOREACH(item ${ARG_CLASSPATH})
-    SET(classpath_str ${classpath_str}${separator}${item})
+    SET(classpath_str "${classpath_str}${separator}${item}")
     IF (WIN32)
-      SET(separator ";")
+      # Quote the semicolon since it's cmakes list separator
+      SET(separator "\;")
     ELSE()
       SET(separator ":")
     ENDIF()

=== modified file 'storage/ndb/include/ndbapi/NdbIndexStat.hpp'
--- a/storage/ndb/include/ndbapi/NdbIndexStat.hpp	2011-06-07 10:03:02 +0000
+++ b/storage/ndb/include/ndbapi/NdbIndexStat.hpp	2011-06-28 16:13:49 +0000
@@ -334,9 +334,9 @@ public:
   struct Mem {
     Mem();
     virtual ~Mem();
-    virtual void* mem_alloc(size_t size) = 0;
+    virtual void* mem_alloc(UintPtr size) = 0;
     virtual void mem_free(void* ptr) = 0;
-    virtual size_t mem_used() const = 0;
+    virtual UintPtr mem_used() const = 0;
   };
 
   /*

=== modified file 'storage/ndb/src/dummy.cpp'
--- a/storage/ndb/src/dummy.cpp	2011-06-28 13:12:15 +0000
+++ b/storage/ndb/src/dummy.cpp	2011-06-28 16:26:30 +0000
@@ -0,0 +1,8 @@
+#include "../include/ndbapi/NdbApi.hpp"
+
+typedef void (Ndb_cluster_connection::* fptr)(const char*);
+
+fptr functions[] = {
+  (fptr)&Ndb_cluster_connection::set_name,
+  0
+};

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp	2011-05-04 11:45:33 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp	2011-06-24 12:01:37 +0000
@@ -532,7 +532,7 @@ public:
 
   struct ScanIndexData
   {
-    Uint16 m_frags_not_complete;
+    Uint16 m_frags_complete;
     Uint16 m_frags_outstanding;
     Uint32 m_rows_received;  // #execTRANSID_AI
     Uint32 m_rows_expecting; // Sum(ScanFragConf)

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp	2011-06-16 08:37:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp	2011-06-24 12:01:37 +0000
@@ -4449,7 +4449,7 @@ Dbspj::parseScanIndex(Build_context& ctx
     ScanIndexData& data = treeNodePtr.p->m_scanindex_data;
     data.m_fragments.init();
     data.m_frags_outstanding = 0;
-    data.m_frags_not_complete = 0;
+    data.m_frags_complete = 0;
     data.m_batch_chunks = 0;
 
     err = parseDA(ctx, requestPtr, treeNodePtr,
@@ -4679,6 +4679,7 @@ Dbspj::execDIH_SCAN_TAB_CONF(Signal* sig
       }
     }
   }
+  data.m_frags_complete = data.m_fragCount;
 
   if (!pruned)
   {
@@ -4966,7 +4967,8 @@ Dbspj::scanIndex_parent_batch_complete(S
   data.m_rows_received = 0;
   data.m_rows_expecting = 0;
   ndbassert(data.m_frags_outstanding == 0);
-  ndbassert(data.m_frags_not_complete == 0);
+  ndbassert(data.m_frags_complete == data.m_fragCount);
+  data.m_frags_complete = 0;
 
   Ptr<ScanFragHandle> fragPtr;
   {
@@ -4975,32 +4977,33 @@ Dbspj::scanIndex_parent_batch_complete(S
 
     if ((treeNodePtr.p->m_bits & TreeNode::T_PRUNE_PATTERN) == 0)
     {
-      if (fragPtr.p->m_rangePtrI != RNIL)
+      if (fragPtr.p->m_rangePtrI == RNIL)
       {
-        // No pruning, so we must scan all fragments.
+        // No keys found
         jam();
-        data.m_frags_not_complete = data.m_fragCount;
+        data.m_frags_complete = data.m_fragCount;
       }
     }
     else
     {
       while(!fragPtr.isNull())
       {
-        if (fragPtr.p->m_rangePtrI != RNIL)
+        if (fragPtr.p->m_rangePtrI == RNIL)
         {
           jam();
           /**
            * This is a pruned scan, so we must scan those fragments that
            * some distribution key hashed to.
            */
-          data.m_frags_not_complete++;
+          fragPtr.p->m_state = ScanFragHandle::SFH_COMPLETE;
+          data.m_frags_complete++;
         }
         list.next(fragPtr);
       }
     }
   }
 
-  if (data.m_frags_not_complete == 0)
+  if (data.m_frags_complete == data.m_fragCount)
   {
     jam();
     /**
@@ -5058,7 +5061,7 @@ Dbspj::scanIndex_send(Signal* signal,
   if (treeNodePtr.p->m_bits & TreeNode::T_SCAN_PARALLEL)
   {
     jam();
-    cnt = data.m_frags_not_complete;
+    cnt = data.m_fragCount - data.m_frags_complete;
     ndbrequire(cnt > 0);
 
     bs_rows /= cnt;
@@ -5194,7 +5197,8 @@ Dbspj::scanIndex_send(Signal* signal,
 
   if (treeNodePtr.p->m_bits & TreeNode::T_SCAN_PARALLEL)
   {
-    ndbrequire(data.m_frags_outstanding == data.m_frags_not_complete);
+    ndbrequire(data.m_frags_outstanding == 
+               data.m_fragCount - data.m_frags_complete);
   }
   else
   {
@@ -5295,10 +5299,10 @@ Dbspj::scanIndex_execSCAN_FRAGCONF(Signa
   {
     jam();
     fragPtr.p->m_state = ScanFragHandle::SFH_COMPLETE;
-    ndbrequire(data.m_frags_not_complete>0);
-    data.m_frags_not_complete--;
+    ndbrequire(data.m_frags_complete < data.m_fragCount);
+    data.m_frags_complete++;
 
-    if (data.m_frags_not_complete == 0)
+    if (data.m_frags_complete == data.m_fragCount)
     {
       jam();
       ndbrequire(requestPtr.p->m_cnt_active);
@@ -5355,12 +5359,12 @@ Dbspj::scanIndex_execSCAN_FRAGREF(Signal
   fragPtr.p->m_state = ScanFragHandle::SFH_COMPLETE;
 
   ScanIndexData& data = treeNodePtr.p->m_scanindex_data;
-  ndbrequire(data.m_frags_not_complete > 0);
-  data.m_frags_not_complete--;
+  ndbrequire(data.m_frags_complete < data.m_fragCount);
+  data.m_frags_complete++;
   ndbrequire(data.m_frags_outstanding > 0);
   data.m_frags_outstanding--;
 
-  if (data.m_frags_not_complete == 0)
+  if (data.m_frags_complete == data.m_fragCount)
   {
     jam();
     ndbrequire(requestPtr.p->m_cnt_active);
@@ -5391,8 +5395,8 @@ Dbspj::scanIndex_execSCAN_NEXTREQ(Signal
   data.m_rows_expecting = 0;
   ndbassert(data.m_frags_outstanding == 0);
 
-  ndbrequire(data.m_frags_not_complete>0);
-  Uint32 cnt = data.m_frags_not_complete;
+  ndbrequire(data.m_frags_complete < data.m_fragCount);
+  Uint32 cnt = data.m_fragCount - data.m_frags_complete;
   if ((treeNodePtr.p->m_bits & TreeNode::T_SCAN_PARALLEL) == 0)
   {
     jam();
@@ -5581,7 +5585,7 @@ Dbspj::scanIndex_execNODE_FAILREP(Signal
   Ptr<ScanFragHandle> fragPtr;
 
   Uint32 save0 = data.m_frags_outstanding;
-  Uint32 save1 = data.m_frags_not_complete;
+  Uint32 save1 = data.m_frags_complete;
 
   for (list.first(fragPtr); !fragPtr.isNull(); list.next(fragPtr))
   {
@@ -5597,8 +5601,8 @@ Dbspj::scanIndex_execNODE_FAILREP(Signal
     switch(fragPtr.p->m_state){
     case ScanFragHandle::SFH_NOT_STARTED:
       jam();
-      ndbrequire(data.m_frags_not_complete > 0);
-      data.m_frags_not_complete--;
+      ndbrequire(data.m_frags_complete < data.m_fragCount);
+      data.m_frags_complete++;
       // fall through
     case ScanFragHandle::SFH_COMPLETE:
       jam();
@@ -5618,8 +5622,8 @@ Dbspj::scanIndex_execNODE_FAILREP(Signal
     case ScanFragHandle::SFH_WAIT_NEXTREQ:
       jam();
       sum++;
-      ndbrequire(data.m_frags_not_complete > 0);
-      data.m_frags_not_complete--;
+      ndbrequire(data.m_frags_complete < data.m_fragCount);
+      data.m_frags_complete++;
       break;
     }
     fragPtr.p->m_ref = 0;
@@ -5633,7 +5637,8 @@ Dbspj::scanIndex_execNODE_FAILREP(Signal
     requestPtr.p->m_outstanding--;
   }
 
-  if (save1 != 0 && data.m_frags_not_complete == 0)
+  if (save1 != data.m_fragCount
+      && data.m_frags_complete == data.m_fragCount)
   {
     jam();
     ndbrequire(requestPtr.p->m_cnt_active);

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2011-05-26 15:04:45 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2011-06-28 17:02:13 +0000
@@ -978,10 +978,10 @@ ArrayPool<TupTriggerData> c_triggerPool;
       subscriptionDeleteTriggers(triggerPool),
       subscriptionUpdateTriggers(triggerPool),
       constraintUpdateTriggers(triggerPool),
-      tuxCustomTriggers(triggerPool),
       deferredInsertTriggers(triggerPool),
       deferredDeleteTriggers(triggerPool),
-      deferredUpdateTriggers(triggerPool)
+      deferredUpdateTriggers(triggerPool),
+      tuxCustomTriggers(triggerPool)
       {}
     
     Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask;

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-06-22 09:32:00 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-06-27 07:00:44 +0000
@@ -1081,10 +1081,6 @@ MgmtSrvr::sendall_STOP_REQ(NodeBitmask &
         else
           failed++;
       }
-      else
-      {
-        failed++;
-      }
     }
   }
 

=== modified file 'storage/ndb/src/ndbapi/NdbIndexStatImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbIndexStatImpl.cpp	2011-06-16 18:16:01 +0000
+++ b/storage/ndb/src/ndbapi/NdbIndexStatImpl.cpp	2011-06-28 16:13:49 +0000
@@ -2257,7 +2257,7 @@ NdbIndexStatImpl::MemDefault::~MemDefaul
 }
 
 void*
-NdbIndexStatImpl::MemDefault::mem_alloc(size_t size)
+NdbIndexStatImpl::MemDefault::mem_alloc(UintPtr size)
 {
   if (size == 0 || size % 4 != 0)
   {
@@ -2290,7 +2290,7 @@ NdbIndexStatImpl::MemDefault::mem_free(v
   }
 }
 
-size_t
+UintPtr
 NdbIndexStatImpl::MemDefault::mem_used() const
 {
   return m_used;

=== modified file 'storage/ndb/src/ndbapi/NdbIndexStatImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbIndexStatImpl.hpp	2011-06-12 16:54:32 +0000
+++ b/storage/ndb/src/ndbapi/NdbIndexStatImpl.hpp	2011-06-28 16:13:49 +0000
@@ -281,9 +281,9 @@ public:
 
   // default memory allocator
   struct MemDefault : public Mem {
-    virtual void* mem_alloc(size_t bytes);
+    virtual void* mem_alloc(UintPtr bytes);
     virtual void mem_free(void* p);
-    virtual size_t mem_used() const;
+    virtual UintPtr mem_used() const;
     MemDefault();
     virtual ~MemDefault();
   private:

=== modified file 'storage/ndb/src/ndbapi/NdbTransaction.cpp'
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp	2011-05-26 15:04:45 +0000
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp	2011-06-28 17:02:13 +0000
@@ -937,7 +937,10 @@ int NdbTransaction::refresh()
       scan_op != 0; scan_op = (NdbIndexScanOperation *) scan_op->theNext)
   {
     NdbTransaction* scan_trans = scan_op->theNdbCon;
-    scan_trans->sendTC_HBREP();
+    if (scan_trans)
+    {
+      scan_trans->sendTC_HBREP();
+    }
   }
   return sendTC_HBREP();
 }

=== modified file 'storage/ndb/test/crund/build.xml'
--- a/storage/ndb/test/crund/build.xml	2011-06-09 21:09:40 +0000
+++ b/storage/ndb/test/crund/build.xml	2011-06-24 22:48:05 +0000
@@ -631,7 +631,7 @@
   </target>
 
   <!-- runs the benchmark against Cluster/J -->
-  <target name="run.clusterj" depends="set.run,set.paths.clusterj.run">
+  <target name="run.clusterj" depends="set.run,compile.clusterj,set.paths.clusterj.run">
     <echo message="using:" />
     <echo message="  ndbjtie.libdir: ${ndbjtie.libdir}" />
     <echo message="  classpath.clusterj.run: ${toString:classpath.clusterj.run}" />

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java	2011-06-07 14:12:24 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java	2011-06-24 22:48:05 +0000
@@ -157,40 +157,60 @@ public class ClusterjLoad extends CrundD
         out.print("initializing operations ...");
         out.flush();
 
+        for (CrundDriver.XMode m : xMode) {
+            // inner classes can only refer to a constant
+            final CrundDriver.XMode mode = m;
+
         ops.add(
-            new ClusterjOp("insA") {
+            new ClusterjOp("insA_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         final IA o = session.newInstance(IA.class);
                         assert o != null;
                         o.setId(i);
                         session.persist(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("insB0") {
+            new ClusterjOp("insB0_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         final IB0 o = session.newInstance(IB0.class);
                         assert o != null;
                         o.setId(i);
                         o.setCvarbinary_def(null);
                         session.persist(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("setAByPK") {
+            new ClusterjOp("setAByPK_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
-                    for (int i = 0; i < nOps; i++) {
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
+                   for (int i = 0; i < nOps; i++) {
                         // blind update
                         final IA o = session.newInstance(IA.class);
                         o.setId(i);
@@ -200,15 +220,22 @@ public class ClusterjLoad extends CrundD
                         o.setCfloat((float)i);
                         o.setCdouble((double)i);
                         session.updatePersistent(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
                     }
-                    commitTransaction();
+                   if (mode != CrundDriver.XMode.INDY) {
+                       commitTransaction();
+                   }
                 }
             });
 
         ops.add(
-            new ClusterjOp("setB0ByPK") {
+            new ClusterjOp("setB0ByPK_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         // blind update
                         final IB0 o = session.newInstance(IB0.class);
@@ -219,40 +246,87 @@ public class ClusterjLoad extends CrundD
                         o.setCfloat((float)i);
                         o.setCdouble((double)i);
                         session.updatePersistent(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("getAByPK") {
+            new ClusterjOp("getAByPK_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
-                    for (int i = 0; i < nOps; i++) {
-                        final IA o = session.find(IA.class, i);
-                        assert o != null;
-                        final int id = o.getId();
-                        verify(id == i);
-                        final int j = checkFields(o);
-                        verify(j == id);
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
+                    if (mode != CrundDriver.XMode.BULK) {
+                        for (int i = 0; i < nOps; i++) {
+                            final IA o = session.find(IA.class, i);
+                            assert o != null;
+                            final int id = o.getId();
+                            verify(id == i);
+                            final int j = checkFields(o);
+                            verify(j == id);
+                        }
+                    } else {
+                        IA[] objs = new IA[nOps];
+                        for (int i = 0; i < nOps; ++i) {
+                            final IA o = session.newInstance(IA.class, i);
+                            objs[i] =o;
+                        }
+                        session.load(objs);
+                        session.flush();
+                        for (int i = 0; i < nOps; ++i) {
+                            IA o = objs[i];
+                            final int id = o.getId();
+                            verify(id == i);
+                            final int j = checkFields(o);
+                            verify (j == id);
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("getB0ByPK") {
+            new ClusterjOp("getB0ByPK_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
-                    for (int i = 0; i < nOps; i++) {
-                        final IB0 o = session.find(IB0.class, i);
-                        assert o != null;
-                        final int id = o.getId();
-                        verify(id == i);
-                        final int j = checkFields(o);
-                        verify(j == id);
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
+                    if (mode != CrundDriver.XMode.BULK) {
+                        for (int i = 0; i < nOps; i++) {
+                            final IB0 o = session.find(IB0.class, i);
+                            assert o != null;
+                            final int id = o.getId();
+                            verify(id == i);
+                            final int j = checkFields(o);
+                            verify(j == id);
+                        }
+                    } else {
+                        IB0[] objs = new IB0[nOps];
+                        for (int i = 0; i < nOps; ++i) {
+                            final IB0 o = session.newInstance(IB0.class, i);
+                            objs[i] =o;
+                        }
+                        session.load(objs);
+                        session.flush();
+                        for (int i = 0; i < nOps; ++i) {
+                            IB0 o = objs[i];
+                            final int id = o.getId();
+                            verify(id == i);
+                            final int j = checkFields(o);
+                            verify (j == id);
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
@@ -261,9 +335,11 @@ public class ClusterjLoad extends CrundD
             assert l == b.length;
 
             ops.add(
-                new ClusterjOp("setVarbinary" + l) {
+                new ClusterjOp("setVarbinary" + l + "_" + mode.toString().toLowerCase()) {
                     public void run(int nOps) {
-                        beginTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            beginTransaction();
+                        }
                         for (int i = 0; i < nOps; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -271,28 +347,41 @@ public class ClusterjLoad extends CrundD
                             assert o != null;
                             o.setCvarbinary_def(b);
                             session.updatePersistent(o);
+                            if (mode == CrundDriver.XMode.EACH) {
+                                session.flush();
+                            }
+                        }
+                        if (mode != CrundDriver.XMode.INDY) {
+                            commitTransaction();
                         }
-                        commitTransaction();
                     }
                 });
 
             ops.add(
-                new ClusterjOp("getVarbinary" + l) {
+                new ClusterjOp("getVarbinary" + l + "_" + mode.toString().toLowerCase()) {
+
+                    // TODO implement BULK using session.load
                     public void run(int nOps) {
-                        beginTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            beginTransaction();
+                        }
                         for (int i = 0; i < nOps; i++) {
                             final IB0 o = session.find(IB0.class, i);
                             assert o != null;
                             verify(Arrays.equals(b, o.getCvarbinary_def()));
                         }
-                        commitTransaction();
-                    }
+                        if (mode != CrundDriver.XMode.INDY) {
+                            commitTransaction();
+                        }
+                   }
                 });
 
             ops.add(
-                new ClusterjOp("clearVarbinary" + l) {
+                new ClusterjOp("clearVarbinary" + l + "_" + mode.toString().toLowerCase()) {
                     public void run(int nOps) {
-                        beginTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            beginTransaction();
+                        }
                         for (int i = 0; i < nOps; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -300,8 +389,13 @@ public class ClusterjLoad extends CrundD
                             assert o != null;
                             o.setCvarbinary_def(null);
                             session.updatePersistent(o);
+                            if (mode == CrundDriver.XMode.EACH) {
+                                session.flush();
+                            }
+                        }
+                        if (mode != CrundDriver.XMode.INDY) {
+                            commitTransaction();
                         }
-                        commitTransaction();
                     }
                 });
         }
@@ -311,9 +405,11 @@ public class ClusterjLoad extends CrundD
             assert l == s.length();
 
             ops.add(
-                new ClusterjOp("setVarchar" + l) {
+                new ClusterjOp("setVarchar" + l + "_" + mode.toString().toLowerCase()) {
                     public void run(int nOps) {
-                        beginTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            beginTransaction();
+                        }
                         for (int i = 0; i < nOps; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -321,28 +417,41 @@ public class ClusterjLoad extends CrundD
                             assert o != null;
                             o.setCvarchar_def(s);
                             session.updatePersistent(o);
+                            if (mode == CrundDriver.XMode.EACH) {
+                                session.flush();
+                            }
+                        }
+                        if (mode != CrundDriver.XMode.INDY) {
+                            commitTransaction();
                         }
-                        commitTransaction();
                     }
                 });
 
             ops.add(
-                new ClusterjOp("getVarchar" + l) {
+                new ClusterjOp("getVarchar" + l + "_" + mode.toString().toLowerCase()) {
+
+                    // TODO implement BULK using session.load
                     public void run(int nOps) {
-                        beginTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            beginTransaction();
+                        }
                         for (int i = 0; i < nOps; i++) {
                             final IB0 o = session.find(IB0.class, i);
                             assert o != null;
                             verify(s.equals(o.getCvarchar_def()));
                         }
-                        commitTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            commitTransaction();
+                        }
                     }
                 });
 
             ops.add(
-                new ClusterjOp("clearVarchar" + l) {
+                new ClusterjOp("clearVarchar" + l + "_" + mode.toString().toLowerCase()) {
                     public void run(int nOps) {
-                        beginTransaction();
+                        if (mode != CrundDriver.XMode.INDY) {
+                            beginTransaction();
+                        }
                         for (int i = 0; i < nOps; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -350,16 +459,23 @@ public class ClusterjLoad extends CrundD
                             assert o != null;
                             o.setCvarchar_def(null);
                             session.updatePersistent(o);
+                            if (mode == CrundDriver.XMode.EACH) {
+                                session.flush();
+                            }
+                        }
+                        if (mode != CrundDriver.XMode.INDY) {
+                            commitTransaction();
                         }
-                        commitTransaction();
                     }
                 });
         }
 
         ops.add(
-            new ClusterjOp("setB0->A") {
+            new ClusterjOp("setB0->A_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         // blind update
                         final IB0 b0 = session.newInstance(IB0.class);
@@ -368,15 +484,22 @@ public class ClusterjLoad extends CrundD
                         final int aId = i % nOps;
                         b0.setAid(aId);
                         session.updatePersistent(b0);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("navB0->A") {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         final IB0 b0 = session.find(IB0.class, i);
                         assert b0 != null;
@@ -388,7 +511,9 @@ public class ClusterjLoad extends CrundD
                         final int j = checkFields(a);
                         verify(j == id);
                     }
-                    commitTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
+                    }
                 }
             });
 
@@ -406,7 +531,9 @@ public class ClusterjLoad extends CrundD
                 }
 
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     // QueryBuilder is the sessionFactory for queries
                     final QueryBuilder builder
                         = session.getQueryBuilder();
@@ -433,14 +560,18 @@ public class ClusterjLoad extends CrundD
                             verify(j == id);
                         }
                     }
-                    commitTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
+                    }
                 }
             });
 
         ops.add(
             new ClusterjOp("nullB0->A") {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         // blind update
                         final IB0 b0 = session.newInstance(IB0.class);
@@ -448,45 +579,66 @@ public class ClusterjLoad extends CrundD
                         assert b0 != null;
                         b0.setAid(0);
                         session.updatePersistent(b0);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("delB0ByPK") {
+            new ClusterjOp("delB0ByPK_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         // blind delete
                         final IB0 o = session.newInstance(IB0.class);
                         assert o != null;
                         o.setId(i);
                         session.remove(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("delAByPK") {
+            new ClusterjOp("delAByPK_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         // blind delete
                         final IA o = session.newInstance(IA.class);
                         assert o != null;
                         o.setId(i);
                         session.remove(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("insA_attr") {
+            new ClusterjOp("insAattr_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         final IA o = session.newInstance(IA.class);
                         assert o != null;
@@ -496,15 +648,22 @@ public class ClusterjLoad extends CrundD
                         o.setCfloat((float)-i);
                         o.setCdouble((double)-i);
                         session.persist(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("insB0_attr") {
+            new ClusterjOp("insB0attr_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     for (int i = 0; i < nOps; i++) {
                         final IB0 o = session.newInstance(IB0.class);
                         assert o != null;
@@ -515,31 +674,45 @@ public class ClusterjLoad extends CrundD
                         o.setCdouble((double)-i);
                         o.setCvarbinary_def(null);
                         session.persist(o);
+                        if (mode == CrundDriver.XMode.EACH) {
+                            session.flush();
+                        }
+                    }
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
                     }
-                    commitTransaction();
                 }
             });
 
         ops.add(
-            new ClusterjOp("delAllB0") {
+            new ClusterjOp("delAllB0_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     int del = session.deletePersistentAll(IB0.class);
                     assert del == nOps;
-                    commitTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
+                    }
                 }
             });
 
         ops.add(
-            new ClusterjOp("delAllA") {
+            new ClusterjOp("delAllA_" + mode.toString().toLowerCase()) {
                 public void run(int nOps) {
-                    beginTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        beginTransaction();
+                    }
                     int del = session.deletePersistentAll(IA.class);
                     assert del == nOps;
-                    commitTransaction();
+                    if (mode != CrundDriver.XMode.INDY) {
+                        commitTransaction();
+                    }
                 }
             });
 
+        }
         // prepare queries
         for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((ClusterjOp)i.next()).init();

=== modified file 'storage/ndb/test/ndbapi/CMakeLists.txt'
--- a/storage/ndb/test/ndbapi/CMakeLists.txt	2011-04-10 17:32:41 +0000
+++ b/storage/ndb/test/ndbapi/CMakeLists.txt	2011-06-28 16:26:30 +0000
@@ -36,12 +36,9 @@ ADD_EXECUTABLE(testDataBuffers testDataB
 ADD_EXECUTABLE(testDict testDict.cpp)
 ADD_EXECUTABLE(testIndex testIndex.cpp)
 ADD_EXECUTABLE(testMgm testMgm.cpp)
-TARGET_LINK_LIBRARIES(testMgm ndbconf)
 ADD_EXECUTABLE(testNdbApi testNdbApi.cpp)
 ADD_EXECUTABLE(testNodeRestart testNodeRestart.cpp)
-TARGET_LINK_LIBRARIES(testNodeRestart ndbclient)
 ADD_EXECUTABLE(testOIBasic testOIBasic.cpp)
-TARGET_LINK_LIBRARIES(testOIBasic ndbclient)
 ADD_EXECUTABLE(testOperations testOperations.cpp)
 ADD_EXECUTABLE(testRestartGci testRestartGci.cpp)
 ADD_EXECUTABLE(testScan testScan.cpp ScanFunctions.hpp)

=== modified file 'storage/ndb/test/ndbapi/testMgmd.cpp'
--- a/storage/ndb/test/ndbapi/testMgmd.cpp	2011-06-21 13:50:33 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp	2011-06-27 07:00:44 +0000
@@ -280,6 +280,8 @@ public:
 
   }
 
+  NdbMgmHandle handle() { return m_mgmd_client.handle(); }
+
 private:
 
   bool get_section_string(const Properties& config,
@@ -1099,6 +1101,55 @@ int runTestBug12352191(NDBT_Context* ctx
 
 }
 
+int
+runBug61607(NDBT_Context* ctx, NDBT_Step* step)
+{
+  NDBT_Workingdir wd("test_mgmd"); // temporary working directory
+
+  // Create config.ini
+  const int cnt_mgmd = 1;
+  Properties config = ConfigFactory::create(cnt_mgmd);
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config.ini",
+                                             NULL).c_str()));
+  // Start ndb_mgmd(s)
+  MgmdProcessList mgmds;
+  for (int i = 1; i <= cnt_mgmd; i++)
+  {
+    Mgmd* mgmd = new Mgmd(i);
+    mgmds.push_back(mgmd);
+    CHECK(mgmd->start_from_config_ini(wd.path()));
+  }
+
+  // Connect the ndb_mgmd(s)
+  for (unsigned i = 0; i < mgmds.size(); i++)
+    CHECK(mgmds[i]->connect(config));
+
+  // wait for confirmed config
+  for (unsigned i = 0; i < mgmds.size(); i++)
+    CHECK(mgmds[i]->wait_confirmed_config());
+
+  // Check binary config files created
+  CHECK(file_exists(path(wd.path(),
+                         "ndb_1_config.bin.1",
+                         NULL).c_str()));
+
+  int no_of_nodes = 0;
+  int * node_ids = 0;
+  int initialstart = 0;
+  int nostart = 0;
+  int abort = 0;
+  int force = 0;
+  int need_disconnect = 0;
+  int res = ndb_mgm_restart4(mgmds[0]->handle(), no_of_nodes, node_ids,
+                             initialstart, nostart, abort, force,
+                             &need_disconnect);
+
+
+  return res == 0 ? NDBT_OK : NDBT_FAILED;
+}
+
 NDBT_TESTSUITE(testMgmd);
 DRIVER(DummyDriver); /* turn off use of NdbApi */
 
@@ -1151,6 +1202,10 @@ TESTCASE("Bug12352191",
 {
   INITIALIZER(runTestBug12352191);
 }
+TESTCASE("Bug61607", "")
+{
+  INITIALIZER(runBug61607);
+}
 
 NDBT_TESTSUITE_END(testMgmd);
 

=== modified file 'storage/ndb/test/ndbapi/testScan.cpp'
--- a/storage/ndb/test/ndbapi/testScan.cpp	2011-04-07 07:22:49 +0000
+++ b/storage/ndb/test/ndbapi/testScan.cpp	2011-06-28 08:47:18 +0000
@@ -1424,6 +1424,86 @@ runBug54945(NDBT_Context* ctx, NDBT_Step
   return NDBT_OK;
 }
 
+int
+runCloseRefresh(NDBT_Context* ctx, NDBT_Step* step)
+{
+  Ndb * pNdb = GETNDB(step);
+
+  const Uint32 codeWords= 1;
+  Uint32 codeSpace[ codeWords ];
+  NdbInterpretedCode code(NULL, // Table is irrelevant
+                          &codeSpace[0],
+                          codeWords);
+  if ((code.interpret_exit_last_row() != 0) ||
+      (code.finalise() != 0))
+  {
+    ERR(code.getNdbError());
+    return NDBT_FAILED;
+  }
+
+  const NdbDictionary::Table*  pTab = ctx->getTab();
+  NdbTransaction* pTrans = pNdb->startTransaction();
+  NdbScanOperation* pOp = pTrans->getNdbScanOperation(pTab->getName());
+  if (pOp == NULL)
+  {
+    ERR(pTrans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if (pOp->readTuples(NdbOperation::LM_CommittedRead) != 0)
+  {
+    ERR(pTrans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if (pOp->setInterpretedCode(&code) == -1 )
+  {
+    ERR(pTrans->getNdbError());
+    pNdb->closeTransaction(pTrans);
+    return NDBT_FAILED;
+  }
+
+  if (pOp->getValue(NdbDictionary::Column::ROW_COUNT) == 0)
+  {
+    ERR(pTrans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  pTrans->execute(NdbTransaction::NoCommit);
+  pOp->close(); // close this
+
+  pOp = pTrans->getNdbScanOperation(pTab->getName());
+  if (pOp == NULL)
+  {
+    ERR(pTrans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if (pOp->readTuples(NdbOperation::LM_CommittedRead) != 0)
+  {
+    ERR(pTrans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if (pOp->setInterpretedCode(&code) == -1 )
+  {
+    ERR(pTrans->getNdbError());
+    pNdb->closeTransaction(pTrans);
+    return NDBT_FAILED;
+  }
+
+  if (pOp->getValue(NdbDictionary::Column::ROW_COUNT) == 0)
+  {
+    ERR(pTrans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  pTrans->execute(NdbTransaction::NoCommit);
+  pTrans->refresh();
+  pTrans->close();
+  return NDBT_OK;
+}
+
 #define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
 
 int
@@ -2066,6 +2146,10 @@ TESTCASE("Bug42559", "")
   FINALIZER(finalizeBug42559);
   FINALIZER(runClearTable);
 }
+TESTCASE("CloseRefresh", "")
+{
+  INITIALIZER(runCloseRefresh);
+}
 TESTCASE("Bug54945", "")
 {
   INITIALIZER(runBug54945);

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2011-06-23 06:59:40 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2011-06-28 17:02:13 +0000
@@ -517,6 +517,10 @@ args: -n NoCloseTransaction T6 D1 D2
 
 max-time: 500
 cmd: testScan
+args: -n CloseRefresh T1
+
+max-time: 500
+cmd: testScan
 args: -n CheckInactivityTimeOut T6 D1 D2 
 
 max-time: 500

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-cluster branch (jonas.oreland:3380 to 3382) jonas oreland29 Jun