List:Commits« Previous MessageNext Message »
From:Pekka Nousiainen Date:June 24 2011 4:08pm
Subject:bzr push into mysql-5.1-telco-7.0-wl4124-new1 branch (pekka.nousiainen:4404
to 4405)
View as plain text  
 4405 Pekka Nousiainen	2011-06-24 [merge]
      merge telco-7.0 to wl4124-new1

    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/t/ctype_cp932_binlog_stm.test
      sql/ha_ndb_index_stat.cc
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      storage/ndb/include/mgmapi/mgmapi.h
      storage/ndb/include/mgmapi/ndb_logevent.h
      storage/ndb/include/ndb_types.h.in
      storage/ndb/src/CMakeLists.txt
      storage/ndb/src/common/debugger/CMakeLists.txt
      storage/ndb/src/common/debugger/signaldata/CMakeLists.txt
      storage/ndb/src/common/logger/CMakeLists.txt
      storage/ndb/src/common/mgmcommon/CMakeLists.txt
      storage/ndb/src/common/portlib/CMakeLists.txt
      storage/ndb/src/common/transporter/CMakeLists.txt
      storage/ndb/src/common/transporter/TransporterRegistry.cpp
      storage/ndb/src/common/util/CMakeLists.txt
      storage/ndb/src/kernel/CMakeLists.txt
      storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
      storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
      storage/ndb/src/mgmapi/CMakeLists.txt
      storage/ndb/src/mgmapi/mgmapi.cpp
      storage/ndb/src/mgmsrv/CMakeLists.txt
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.hpp
      storage/ndb/src/ndbapi/CMakeLists.txt
      storage/ndb/src/ndbapi/ClusterMgr.cpp
      storage/ndb/test/ndbapi/testBasic.cpp
      storage/ndb/test/ndbapi/testMgmd.cpp
      storage/ndb/tools/ndb_dump_frm_data.cpp
 4404 Pekka Nousiainen	2011-06-21 [merge]
      merge telco-7.0 to wl4124-new1

    added:
      mysql-test/suite/ndb/r/ndb_alter_table_online_multi.result
      mysql-test/suite/ndb/r/ndb_select_count.result
      mysql-test/suite/ndb/t/ndb_alter_table_online_multi.test
      mysql-test/suite/ndb/t/ndb_select_count.test
    modified:
      mysql-test/suite/ndb/r/ndb_alter_table_online.result
      mysql-test/suite/ndb/r/ndb_index_ordered.result
      mysql-test/suite/ndb/r/ndb_multi.result
      mysql-test/suite/ndb/t/ndb_alter_table_online.test
      mysql-test/suite/ndb/t/ndb_index_ordered.test
      mysql-test/suite/ndb/t/ndb_multi.test
      sql/ha_ndbcluster.cc
      storage/ndb/src/ndbapi/NdbQueryBuilder.hpp
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
      storage/ndb/src/ndbapi/NdbQueryOperation.hpp
      storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp
=== modified file 'mysql-test/suite/ndb/r/ndb_condition_pushdown.result'
--- a/mysql-test/suite/ndb/r/ndb_condition_pushdown.result	2011-04-08 13:59:44 +0000
+++ b/mysql-test/suite/ndb/r/ndb_condition_pushdown.result	2011-06-23 12:19:32 +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
@@ -2201,8 +2201,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	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))
 explain extended
@@ -2212,7 +2212,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	
+1	SIMPLE	tx	ALL	PRIMARY	NULL	NULL	NULL	2	100.00	
 1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	8	test.tx.a,test.tx.b	1	100.00	
 1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	8	test.tx.c,test.tx.d	1	100.00	
 1	SIMPLE	t4	eq_ref	PRIMARY	PRIMARY	8	test.tx.d,test.t2.c	1	100.00	
@@ -2231,8 +2231,8 @@ Warnings:
 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	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))
 explain extended
@@ -2256,7 +2256,7 @@ 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	50.00	Using where
+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
@@ -2266,7 +2266,7 @@ 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	50.00	Using where with pushed condition: (`test`.`subq`.`i` = 3)
+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)))

=== modified file 'mysql-test/suite/ndb/r/ndb_index_unique.result'
--- a/mysql-test/suite/ndb/r/ndb_index_unique.result	2011-02-28 10:42:04 +0000
+++ b/mysql-test/suite/ndb/r/ndb_index_unique.result	2011-06-23 12:19:32 +0000
@@ -185,7 +185,7 @@ set @old_ecpd = @@session.engine_conditi
 set engine_condition_pushdown = true;
 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

=== 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 'mysql-test/t/ctype_cp932_binlog_stm.test'
--- a/mysql-test/t/ctype_cp932_binlog_stm.test	2010-12-09 17:12:41 +0000
+++ b/mysql-test/t/ctype_cp932_binlog_stm.test	2011-06-21 15:03:03 +0000
@@ -34,7 +34,7 @@ delimiter ;|
 # the log's contents) that caused the server crash.
 
 -- disable_query_log
-call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'read error', data_len: 66125, event_type: 116");
+call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'read error', data_len: 66126, event_type: 116");
 -- enable_query_log
 
 --error 1220

=== modified file 'sql/ha_ndb_index_stat.cc'
--- a/sql/ha_ndb_index_stat.cc	2011-06-16 11:36:45 +0000
+++ b/sql/ha_ndb_index_stat.cc	2011-06-22 07:37:51 +0000
@@ -70,7 +70,7 @@ struct Ndb_index_stat {
   int lt_old;     /* for info only */
   struct Ndb_index_stat *list_next;
   struct Ndb_index_stat *list_prev;
-  struct st_ndbcluster_share *share;
+  struct NDB_SHARE *share;
   Ndb_index_stat();
 };
 
@@ -1585,20 +1585,20 @@ ndb_index_stat_thread_func(void *arg __a
   /*
     wait for mysql server to start
   */
-  pthread_mutex_lock(&LOCK_server_started);
+  mysql_mutex_lock(&LOCK_server_started);
   while (!mysqld_server_started)
   {
     set_timespec(abstime, 1);
-    pthread_cond_timedwait(&COND_server_started, &LOCK_server_started,
-	                       &abstime);
+    mysql_cond_timedwait(&COND_server_started, &LOCK_server_started,
+	                 &abstime);
     if (ndbcluster_terminating)
     {
-      pthread_mutex_unlock(&LOCK_server_started);
+      mysql_mutex_unlock(&LOCK_server_started);
       pthread_mutex_lock(&LOCK_ndb_index_stat_thread);
       goto ndb_index_stat_thread_end;
     }
   }
-  pthread_mutex_unlock(&LOCK_server_started);
+  mysql_mutex_unlock(&LOCK_server_started);
 
   /*
     Wait for cluster to start
@@ -1650,10 +1650,8 @@ ndb_index_stat_thread_func(void *arg __a
       goto ndb_index_stat_thread_end;
     pthread_mutex_unlock(&LOCK_ndb_index_stat_thread);
 
-    pthread_mutex_lock(&LOCK_global_system_variables);
     /* const bool enable_ok_new= THDVAR(NULL, index_stat_enable); */
     const bool enable_ok_new= ndb_index_stat_get_enable(NULL);
-    pthread_mutex_unlock(&LOCK_global_system_variables);
 
     Ndb_index_stat_proc pr;
     pr.ndb= thd_ndb->ndb;

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-06-20 12:34:27 +0000
+++ b/sql/ha_ndbcluster.cc	2011-06-23 12:19:32 +0000
@@ -265,7 +265,8 @@ static MYSQL_THDVAR_UINT(
 */
 bool ndb_index_stat_get_enable(THD *thd)
 {
-  return THDVAR(thd, index_stat_enable);
+  const bool value = THDVAR(thd, index_stat_enable);
+  return value;
 }
 
 /*
@@ -404,6 +405,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,
@@ -6058,27 +6062,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 */
@@ -6640,7 +6667,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)
   {
@@ -6686,6 +6724,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)
 {
   /*
@@ -6719,45 +6808,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
   {
@@ -6767,7 +6822,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)
@@ -7139,6 +7194,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;
@@ -11049,7 +11123,7 @@ static int ndbcluster_init(void *p)
   if (pthread_create(&tmp2, &connection_attrib, ndb_index_stat_thread_func, 0))
   {
     DBUG_PRINT("error", ("Could not create ndb index statistics thread"));
-    hash_free(&ndbcluster_open_tables);
+    my_hash_free(&ndbcluster_open_tables);
     pthread_mutex_destroy(&ndbcluster_mutex);
     pthread_mutex_destroy(&LOCK_ndb_index_stat_thread);
     pthread_cond_destroy(&COND_ndb_index_stat_thread);
@@ -11070,7 +11144,7 @@ static int ndbcluster_init(void *p)
   if (!ndb_index_stat_thread_running)
   {
     DBUG_PRINT("error", ("ndb index statistics thread exited prematurely"));
-    hash_free(&ndbcluster_open_tables);
+    my_hash_free(&ndbcluster_open_tables);
     pthread_mutex_destroy(&ndbcluster_mutex);
     pthread_mutex_destroy(&LOCK_ndb_index_stat_thread);
     pthread_cond_destroy(&COND_ndb_index_stat_thread);
@@ -12312,8 +12386,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))
     {
@@ -12325,25 +12413,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;
@@ -12363,6 +12451,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-16 18:16:01 +0000
+++ b/sql/ha_ndbcluster.h	2011-06-23 12:19:32 +0000
@@ -45,7 +45,6 @@ class NdbIndexScanOperation;
 class NdbBlob;
 class NdbIndexStat;
 class NdbEventOperation;
-class NdbInterpretedCode;
 class ha_ndbcluster_cond;
 class Ndb_event_data;
 
@@ -171,7 +170,7 @@ typedef int (* prepare_detect_func) (str
                                      const uchar* old_data,
                                      const uchar* new_data,
                                      const MY_BITMAP* write_set,
-                                     NdbInterpretedCode* code);
+                                     class NdbInterpretedCode* code);
 
 struct st_conflict_fn_def
 {
@@ -191,7 +190,7 @@ enum enum_conflict_cause
 
 /* NdbOperation custom data which points out handler and record. */
 struct Ndb_exceptions_data {
-  struct st_ndbcluster_share *share;
+  struct NDB_SHARE* share;
   const NdbRecord* key_rec;
   const uchar* row;
   enum_conflicting_op_type op_type;
@@ -230,7 +229,7 @@ struct Ndb_statistics {
   Uint64 fragment_extent_free_space;
 };
 
-typedef struct st_ndbcluster_share {
+struct NDB_SHARE {
   NDB_SHARE_STATE state;
   MEM_ROOT mem_root;
   THR_LOCK lock;
@@ -257,7 +256,7 @@ typedef struct st_ndbcluster_share {
   char *old_names; // for rename table
   MY_BITMAP *subscriber_bitmap;
   NdbEventOperation *new_op;
-} NDB_SHARE;
+};
 
 inline
 NDB_SHARE_STATE
@@ -845,7 +844,7 @@ private:
                              key_range *max_key,
                              ha_rows *rows_out);
   int ndb_index_stat_set_rpk(uint inx);
-  int ndb_index_stat_wait(Ndb_index_stat *st,
+  int ndb_index_stat_wait(struct Ndb_index_stat *st,
                           uint sample_version);
   int ndb_index_stat_query(uint inx,
                            const key_range *min_key,
@@ -986,6 +985,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/include/mgmapi/mgmapi.h'
--- a/storage/ndb/include/mgmapi/mgmapi.h	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi.h	2011-06-21 13:10:37 +0000
@@ -206,11 +206,13 @@ extern "C" {
     NDB_MGM_NODE_STATUS_SINGLEUSER    = 7,
     /** Resume mode*/
     NDB_MGM_NODE_STATUS_RESUME        = 8,
+    /** Node is connected */
+    NDB_MGM_NODE_STATUS_CONNECTED     = 9,
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
     /** Min valid value*/
     NDB_MGM_NODE_STATUS_MIN           = 0,
     /** Max valid value*/
-    NDB_MGM_NODE_STATUS_MAX           = 8
+    NDB_MGM_NODE_STATUS_MAX           = 9
 #endif
   };
 

=== modified file 'storage/ndb/include/mgmapi/ndb_logevent.h'
--- a/storage/ndb/include/mgmapi/ndb_logevent.h	2011-04-09 15:48:21 +0000
+++ b/storage/ndb/include/mgmapi/ndb_logevent.h	2011-06-22 08:04:19 +0000
@@ -371,6 +371,7 @@ extern "C" {
     unsigned version;
   };
   struct ndb_logevent_STTORRYRecieved {
+    unsigned unused;
   };
   struct ndb_logevent_StartPhaseCompleted {
     unsigned phase;
@@ -407,6 +408,7 @@ extern "C" {
     unsigned extra;
   };
   struct ndb_logevent_NDBStopAborted {
+    unsigned _unused;
   };
   struct ndb_logevent_StartREDOLog {
     unsigned node;
@@ -436,8 +438,10 @@ extern "C" {
   
   /* NODERESTART */
   struct ndb_logevent_NR_CopyDict {
+    unsigned _unused;
   };
   struct ndb_logevent_NR_CopyDistr {
+    unsigned _unused;
   };
   struct ndb_logevent_NR_CopyFragsStarted {
     unsigned dest_node;
@@ -475,10 +479,13 @@ extern "C" {
     /* TODO */
   };
   struct ndb_logevent_GCP_TakeoverStarted {
+    unsigned _unused;
   };
   struct ndb_logevent_GCP_TakeoverCompleted {
+    unsigned _unused;
   };
   struct ndb_logevent_LCP_TakeoverStarted {
+    unsigned _unused;
   };
   struct ndb_logevent_LCP_TakeoverCompleted {
     unsigned state;
@@ -561,6 +568,7 @@ extern "C" {
   };
   struct ndb_logevent_WarningEvent {
     /* TODO */
+    unsigned _unused;
   };
 
   /* INFO */
@@ -572,6 +580,7 @@ extern "C" {
   };
   struct ndb_logevent_InfoEvent {
     /* TODO */
+    unsigned _unused;
   };
   struct ndb_logevent_EventBufferStatus {
     unsigned usage;
@@ -722,21 +731,21 @@ extern "C" {
     unsigned objectid;
     unsigned version;
     unsigned type;
-    unsigned node; // Node create object
+    unsigned node; /* Node create object */
   };
 
   struct ndb_logevent_AlterSchemaObject {
     unsigned objectid;
     unsigned version;
     unsigned type;
-    unsigned node; // Node create object
+    unsigned node; /* Node create object */
   };
 
   struct ndb_logevent_DropSchemaObject {
     unsigned objectid;
     unsigned version;
     unsigned type;
-    unsigned node; // Node create object
+    unsigned node; /* Node create object */
   };
 
   struct ndb_logevent_StartReadLCP {

=== modified file 'storage/ndb/include/ndb_types.h.in'
--- a/storage/ndb/include/ndb_types.h.in	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/include/ndb_types.h.in	2011-06-22 08:04:19 +0000
@@ -47,15 +47,15 @@ typedef unsigned int   Uint32;
 
 #ifndef INT_MIN64
 #define INT_MIN64       (~0x7FFFFFFFFFFFFFFFLL)
-#endif // !INT_MIN64
+#endif /* !INT_MIN64 */
 
 #ifndef INT_MAX64
 #define INT_MAX64       0x7FFFFFFFFFFFFFFFLL
-#endif // !INT_MAX64
+#endif /* !INT_MAX64 */
 
 #ifndef UINT_MAX64
 #define UINT_MAX64      0xFFFFFFFFFFFFFFFFLL
-#endif // !UINT_MAX64
+#endif /* !UINT_MAX64 */
 
 typedef unsigned int UintR;
 

=== modified file 'storage/ndb/src/CMakeLists.txt'
--- a/storage/ndb/src/CMakeLists.txt	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/CMakeLists.txt	2011-06-20 08:31:14 +0000
@@ -32,7 +32,7 @@ SET(NDBCLIENT_LIBS
                 ndbtrace
                 ndbsignaldata
                 ndbmgmapi
-                ndbmgmsrv
+                ndbmgmcommon
                 ndblogger
                 ndbportlib
                 ndbgeneral

=== modified file 'storage/ndb/src/common/debugger/CMakeLists.txt'
--- a/storage/ndb/src/common/debugger/CMakeLists.txt	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/common/debugger/CMakeLists.txt	2011-06-21 14:05:31 +0000
@@ -18,7 +18,7 @@ ADD_SUBDIRECTORY(signaldata)
 
 INCLUDE(${CMAKE_SOURCE_DIR}/storage/ndb/config/type_kernel.cmake)
 
-ADD_LIBRARY(ndbtrace STATIC
+ADD_CONVENIENCE_LIBRARY(ndbtrace
             SignalLoggerManager.cpp
             DebuggerNames.cpp
             BlockNames.cpp
@@ -26,4 +26,4 @@ ADD_LIBRARY(ndbtrace STATIC
             ${NDB_SOURCE_DIR}/src/kernel/error/ndbd_exit_codes.c
 )
 
-TARGET_LINK_LIBRARIES(ndbtrace ndblogger ndbgeneral)
+TARGET_LINK_LIBRARIES(ndbtrace ndbsignaldata ndblogger ndbgeneral)

=== modified file 'storage/ndb/src/common/debugger/signaldata/CMakeLists.txt'
--- a/storage/ndb/src/common/debugger/signaldata/CMakeLists.txt	2011-05-23 15:46:53 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/CMakeLists.txt	2011-06-21 13:58:00 +0000
@@ -13,7 +13,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-ADD_LIBRARY(ndbsignaldata STATIC
+ADD_CONVENIENCE_LIBRARY(ndbsignaldata
         AlterIndxImpl.cpp BuildIndxImpl.cpp BuildIndx.cpp
         CreateIndxImpl.cpp CreateTab.cpp
         CreateTable.cpp CreateTrigImpl.cpp #DihSwitchReplicaReq.cpp

=== modified file 'storage/ndb/src/common/logger/CMakeLists.txt'
--- a/storage/ndb/src/common/logger/CMakeLists.txt	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/common/logger/CMakeLists.txt	2011-06-21 13:58:00 +0000
@@ -13,7 +13,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-ADD_LIBRARY(ndblogger STATIC
+ADD_CONVENIENCE_LIBRARY(ndblogger
             Logger.cpp
             LogHandlerList.cpp
             LogHandler.cpp

=== modified file 'storage/ndb/src/common/mgmcommon/CMakeLists.txt'
--- a/storage/ndb/src/common/mgmcommon/CMakeLists.txt	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/common/mgmcommon/CMakeLists.txt	2011-06-21 14:07:12 +0000
@@ -18,7 +18,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
                     ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmsrv)
 INCLUDE(${CMAKE_SOURCE_DIR}/storage/ndb/config/type_mgmapiclient.cmake)
 
-ADD_LIBRARY(ndbmgmsrv STATIC
-            ConfigRetriever.cpp
-            IPCConfig.cpp)
+ADD_CONVENIENCE_LIBRARY(ndbmgmcommon
+  ConfigRetriever.cpp
+  IPCConfig.cpp)
 

=== modified file 'storage/ndb/src/common/portlib/CMakeLists.txt'
--- a/storage/ndb/src/common/portlib/CMakeLists.txt	2011-05-25 06:52:33 +0000
+++ b/storage/ndb/src/common/portlib/CMakeLists.txt	2011-06-22 06:19:13 +0000
@@ -22,7 +22,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
 IF(WIN32)
   SET(EXTRA_SRC ${CMAKE_SOURCE_DIR}/sql/nt_servc.cc)
 ENDIF(WIN32)
-ADD_LIBRARY(ndbportlib STATIC
+ADD_CONVENIENCE_LIBRARY(ndbportlib
             NdbCondition.c NdbMutex.c ndb_socket.cpp
             NdbEnv.c NdbThread.c NdbHost.c NdbTCP.cpp
             NdbMem.c NdbConfig.c NdbTick.c NdbDir.cpp

=== modified file 'storage/ndb/src/common/transporter/CMakeLists.txt'
--- a/storage/ndb/src/common/transporter/CMakeLists.txt	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/common/transporter/CMakeLists.txt	2011-06-21 13:58:00 +0000
@@ -22,7 +22,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
                     ${CMAKE_SOURCE_DIR}/storage/ndb/include/transporter
                     ${NDB_SCI_INCLUDES})
 
-ADD_LIBRARY(ndbtransport STATIC
+ADD_CONVENIENCE_LIBRARY(ndbtransport
             Transporter.cpp TCP_Transporter.cpp Loopback_Transporter.cpp
             TransporterRegistry.cpp Packer.cpp)
 

=== modified file 'storage/ndb/src/common/transporter/TransporterRegistry.cpp'
--- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp	2011-06-01 07:40:49 +0000
+++ b/storage/ndb/src/common/transporter/TransporterRegistry.cpp	2011-06-15 13:24:40 +0000
@@ -1002,7 +1002,7 @@ TransporterRegistry::pollReceive(Uint32
     {
       for (int i = 0; i < num_socket_events; i++)
       {
-        Uint32 trpid = m_epoll_events[i].data.u32;
+        const Uint32 trpid = m_epoll_events[i].data.u32;
 #ifdef ERROR_INSERT
         if (m_blocked.get(trpid))
         {
@@ -1011,7 +1011,7 @@ TransporterRegistry::pollReceive(Uint32
           continue;
         }
 #endif
-        mask.set(m_epoll_events[i].data.u32);
+        mask.set(trpid);
       }
     }
     else if (num_socket_events < 0)

=== modified file 'storage/ndb/src/common/util/CMakeLists.txt'
--- a/storage/ndb/src/common/util/CMakeLists.txt	2011-05-09 15:35:25 +0000
+++ b/storage/ndb/src/common/util/CMakeLists.txt	2011-06-21 13:58:00 +0000
@@ -25,7 +25,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOUR
                     ${CMAKE_SOURCE_DIR}/storage/ndb/include/logger)
 
 ADD_DEFINITIONS(-DNO_DUMMY_DECL)
-ADD_LIBRARY(ndbgeneral STATIC
+ADD_CONVENIENCE_LIBRARY(ndbgeneral
             ndbzio.c
             File.cpp
             md5_hash.cpp

=== modified file 'storage/ndb/src/kernel/CMakeLists.txt'
--- a/storage/ndb/src/kernel/CMakeLists.txt	2011-02-23 19:28:26 +0000
+++ b/storage/ndb/src/kernel/CMakeLists.txt	2011-06-20 08:31:14 +0000
@@ -42,7 +42,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOUR
 )
 
 SET(NDBD_LIBS ndbblocks ndbkernel ndberror ndbtransport
-    ndbtrace ndbsignaldata ndblogger ndbmgmsrv ndbmgmapi
+    ndbtrace ndbsignaldata ndblogger ndbmgmcommon ndbmgmapi
     ndbportlib ndbgeneral dbug mysys strings
 )
 

=== 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/qmgr/QmgrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2011-06-13 06:14:32 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2011-06-21 13:10:37 +0000
@@ -3728,6 +3728,7 @@ Qmgr::execAPI_VERSION_REQ(Signal * signa
   else
   {
     conf->version =  0;
+    conf->mysql_version =  0;
     conf->inet_addr= 0;
   }
   conf->nodeId = nodeId;

=== modified file 'storage/ndb/src/mgmapi/CMakeLists.txt'
--- a/storage/ndb/src/mgmapi/CMakeLists.txt	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/mgmapi/CMakeLists.txt	2011-06-21 13:58:00 +0000
@@ -20,7 +20,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
                     ${CMAKE_SOURCE_DIR}/storage/ndb/mgmsrv
 )
 ADD_DEFINITIONS(-DNDB_MGMAPI)
-ADD_LIBRARY(ndbmgmapi STATIC
+ADD_CONVENIENCE_LIBRARY(ndbmgmapi
             mgmapi.cpp
             mgmapi_error.c
             ndb_logevent.cpp

=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp	2011-03-28 09:01:03 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp	2011-06-21 13:10:37 +0000
@@ -934,7 +934,10 @@ static struct ndb_mgm_status_atoi status
   { "STARTED", NDB_MGM_NODE_STATUS_STARTED },
   { "SHUTTING_DOWN", NDB_MGM_NODE_STATUS_SHUTTING_DOWN },
   { "RESTARTING", NDB_MGM_NODE_STATUS_RESTARTING },
-  { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER }
+  { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER },
+  { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER },
+  { "RESUME", NDB_MGM_NODE_STATUS_RESUME },
+  { "CONNECTED", NDB_MGM_NODE_STATUS_CONNECTED }
 };
 
 const int no_of_status_values = (sizeof(status_values) / 

=== modified file 'storage/ndb/src/mgmsrv/CMakeLists.txt'
--- a/storage/ndb/src/mgmsrv/CMakeLists.txt	2011-02-03 14:20:36 +0000
+++ b/storage/ndb/src/mgmsrv/CMakeLists.txt	2011-06-21 13:58:00 +0000
@@ -18,7 +18,7 @@ INCLUDE_DIRECTORIES(
   ${NDB_SOURCE_DIR}/src/ndbapi
   ${NDB_SOURCE_DIR}/src/mgmclient)
 
-ADD_LIBRARY(ndbconf
+ADD_CONVENIENCE_LIBRARY(ndbconf
                Config.cpp
                ConfigInfo.cpp
                InitConfigFileParser.cpp

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-06-01 07:40:49 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-06-22 08:57:03 +0000
@@ -42,7 +42,6 @@
 #include <signaldata/SchemaTrans.hpp>
 #include <signaldata/CreateNodegroup.hpp>
 #include <signaldata/DropNodegroup.hpp>
-#include <signaldata/DbinfoScan.hpp>
 #include <signaldata/Sync.hpp>
 #include <NdbSleep.h>
 #include <portlib/NdbDir.hpp>
@@ -835,59 +834,34 @@ MgmtSrvr::start(int nodeId)
  * Version handling
  *****************************************************************************/
 
-int 
-MgmtSrvr::versionNode(int nodeId, Uint32 &version, Uint32& mysql_version,
-		      const char **address)
-{
-  version= 0;
-  mysql_version = 0;
-  if (getOwnNodeId() == nodeId)
-  {
-    /**
-     * If we're inquiring about our own node id,
-     * We know what version we are (version implies connected for mgm)
-     * but would like to find out from elsewhere what address they're using
-     * to connect to us. This means that secondary mgm servers
-     * can list ip addresses for mgm servers.
-     *
-     * If we don't get an address (i.e. no db nodes),
-     * we get the address from the configuration.
-     */
-    sendVersionReq(nodeId, version, mysql_version, address);
-    version= NDB_VERSION;
-    mysql_version = NDB_MYSQL_VERSION_D;
-    if(!*address)
-    {
-      Guard g(m_local_config_mutex);
-      ConfigIter iter(m_local_config, CFG_SECTION_NODE);
-      unsigned tmp= 0;
-      for(iter.first();iter.valid();iter.next())
-      {
-	if(iter.get(CFG_NODE_ID, &tmp)) require(false);
-	if((unsigned)nodeId!=tmp)
-	  continue;
-	if(iter.get(CFG_NODE_HOST, address)) require(false);
-	break;
-      }
-    }
+void
+MgmtSrvr::status_api(int nodeId,
+                     ndb_mgm_node_status& node_status,
+                     Uint32& version, Uint32& mysql_version,
+                     const char **address)
+{
+  assert(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API);
+  assert(version == 0 && mysql_version == 0);
+
+  if (sendVersionReq(nodeId, version, mysql_version, address) != 0)
+  {
+    // Couldn't get version from any NDB node.
+    assert(version == 0);
+    node_status = NDB_MGM_NODE_STATUS_UNKNOWN;
+    return;
   }
-  else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
+
+  if (version)
   {
-    trp_node node = getNodeInfo(nodeId);
-    if(node.is_connected())
-    {
-      version= node.m_info.m_version;
-      mysql_version = node.m_info.m_mysql_version;
-    }
-    *address= get_connect_address(nodeId);
+    assert(mysql_version);
+    node_status = NDB_MGM_NODE_STATUS_CONNECTED;
   }
-  else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
-	   getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
+  else
   {
-    return sendVersionReq(nodeId, version, mysql_version, address);
+    assert(mysql_version == 0);
+    node_status = NDB_MGM_NODE_STATUS_NO_CONTACT;
   }
-
-  return 0;
+  return;
 }
 
 
@@ -907,8 +881,8 @@ MgmtSrvr::sendVersionReq(int v_nodeId,
   ssig.set(ss, TestOrd::TraceAPI, QMGR,
            GSN_API_VERSION_REQ, ApiVersionReq::SignalLength);
 
-  NodeId nodeId;
-  int do_send = 1;
+  NodeId nodeId = 0;
+  bool do_send = true;
   while(true)
   {
     if (do_send)
@@ -924,7 +898,7 @@ MgmtSrvr::sendVersionReq(int v_nodeId,
         return SEND_OR_RECEIVE_FAILED;
       }
 
-      do_send = 0;
+      do_send = false;
     }
 
     SimpleSignal *signal = ss.waitFor();
@@ -951,7 +925,7 @@ MgmtSrvr::sendVersionReq(int v_nodeId,
       const NFCompleteRep * const rep =
 	CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
       if (rep->failedNodeId == nodeId)
-	do_send = 1; // retry with other node
+	do_send = true; // retry with other node
       continue;
     }
 
@@ -959,7 +933,7 @@ MgmtSrvr::sendVersionReq(int v_nodeId,
       const NodeFailRep * const rep =
 	CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
       if (NdbNodeBitmask::get(rep->theNodes,nodeId))
-	do_send = 1; // retry with other node
+	do_send = true; // retry with other node
       continue;
     }
     case GSN_API_REGCONF:
@@ -1486,11 +1460,11 @@ int MgmtSrvr::shutdownMGM(int *stopCount
     error= sendStopMgmd(nodeId, abort, true, false,
                         false, false);
     if (error == 0)
-      *stopCount++;
+      (*stopCount)++;
   }
 
   *stopSelf= 1;
-  *stopCount++;
+  (*stopCount)++;
 
   return 0;
 }
@@ -1898,6 +1872,75 @@ MgmtSrvr::updateStatus()
   theFacade->ext_forceHB();
 }
 
+
+void
+MgmtSrvr::status_mgmd(NodeId node_id,
+                      ndb_mgm_node_status& node_status,
+                      Uint32& version, Uint32& mysql_version,
+                      const char **address)
+{
+  assert(getNodeType(node_id) == NDB_MGM_NODE_TYPE_MGM);
+
+  if (node_id == getOwnNodeId())
+  {
+    /*
+      Special case to get version of own node
+      - version and mysql_version is hardcoded
+      - address should be the address seen from ndbd(if it's connected)
+        else use HostName from config
+    */
+    Uint32 tmp_version = 0, tmp_mysql_version = 0;
+    sendVersionReq(node_id, tmp_version, tmp_mysql_version, address);
+    // Check that the version returned is equal to compiled in version
+    assert(tmp_version == 0 ||
+           (tmp_version == NDB_VERSION &&
+            tmp_mysql_version == NDB_MYSQL_VERSION_D));
+
+    version = NDB_VERSION;
+    mysql_version = NDB_MYSQL_VERSION_D;
+    if(!*address)
+    {
+      // No address returned from ndbd -> get HostName from config
+      Guard g(m_local_config_mutex);
+      ConfigIter iter(m_local_config, CFG_SECTION_NODE);
+      require(iter.find(CFG_NODE_ID, node_id) == 0);
+      require(iter.get(CFG_NODE_HOST, address) == 0);
+
+      /*
+        Try to convert HostName to numerical ip address
+        (to get same output as if ndbd had replied)
+      */
+      struct in_addr addr;
+      if (Ndb_getInAddr(&addr, *address) == 0)
+        *address = inet_ntoa(addr);
+    }
+
+    node_status = NDB_MGM_NODE_STATUS_CONNECTED;
+    return;
+  }
+
+  /*
+    MGM nodes are connected directly to all other MGM
+    node(s), return status as seen by ClusterMgr
+  */
+  const trp_node node = getNodeInfo(node_id);
+  if(node.is_connected())
+  {
+    version = node.m_info.m_version;
+    mysql_version = node.m_info.m_mysql_version;
+    node_status = NDB_MGM_NODE_STATUS_CONNECTED;
+    *address= get_connect_address(node_id);
+  }
+  else
+  {
+    version = 0;
+    mysql_version = 0;
+    node_status = NDB_MGM_NODE_STATUS_NO_CONTACT;
+  }
+
+  return;
+}
+
 int 
 MgmtSrvr::status(int nodeId, 
                  ndb_mgm_node_status * _status, 
@@ -1910,24 +1953,38 @@ MgmtSrvr::status(int nodeId,
 		 Uint32 * connectCount,
 		 const char **address)
 {
-  if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
-      getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
-    versionNode(nodeId, *version, *mysql_version, address);
-  } else {
-    *address= get_connect_address(nodeId);
+  switch(getNodeType(nodeId)){
+  case NDB_MGM_NODE_TYPE_API:
+    status_api(nodeId, *_status, *version, *mysql_version, address);
+    return 0;
+    break;
+
+  case NDB_MGM_NODE_TYPE_MGM:
+    status_mgmd(nodeId, *_status, *version, *mysql_version, address);
+    return 0;
+    break;
+
+  case NDB_MGM_NODE_TYPE_NDB:
+    break;
+
+  default:
+    abort();
+    break;
   }
 
   const trp_node node = getNodeInfo(nodeId);
+  assert(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB &&
+         node.m_info.getType() == NodeInfo::DB);
 
   if(!node.is_connected()){
     * _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
     return 0;
   }
-  
-  if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
-    * version = node.m_info.m_version;
-    * mysql_version = node.m_info.m_mysql_version;
-  }
+
+  * version = node.m_info.m_version;
+  * mysql_version = node.m_info.m_mysql_version;
+
+  *address= get_connect_address(nodeId);
 
   * dynamic = node.m_state.dynamicId;
   * nodegroup = node.m_state.nodeGroup;
@@ -2792,9 +2849,10 @@ MgmtSrvr::getNodeType(NodeId nodeId) con
 
 const char *MgmtSrvr::get_connect_address(Uint32 node_id)
 {
-  if (m_connect_address[node_id].s_addr == 0 &&
-      theFacade &&
-      getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB) 
+  if (theFacade &&
+      m_connect_address[node_id].s_addr == 0 &&
+      (getNodeType(node_id) == NDB_MGM_NODE_TYPE_MGM ||
+       getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB))
   {
     const trp_node &node= getNodeInfo(node_id);
     if (node.is_connected())

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2011-06-01 07:40:49 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2011-06-21 13:10:37 +0000
@@ -364,8 +364,14 @@ public:
 private:
   int guess_master_node(SignalSender&);
 
-  int versionNode(int nodeId, Uint32 &version,
-                  Uint32 &mysql_version, const char **address);
+  void status_api(int nodeId,
+                  ndb_mgm_node_status& node_status,
+                  Uint32& version, Uint32& mysql_version,
+                  const char **address);
+  void status_mgmd(NodeId node_id,
+                   ndb_mgm_node_status& node_status,
+                   Uint32& version, Uint32& mysql_version,
+                   const char **address);
 
   int sendVersionReq(int processId, Uint32 &version,
                      Uint32& mysql_version, const char **address);

=== modified file 'storage/ndb/src/ndbapi/CMakeLists.txt'
--- a/storage/ndb/src/ndbapi/CMakeLists.txt	2011-06-14 10:42:04 +0000
+++ b/storage/ndb/src/ndbapi/CMakeLists.txt	2011-06-21 14:12:16 +0000
@@ -17,7 +17,7 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_SOURCE_DIR}
   ${NDB_SOURCE_DIR}/src/mgmapi)
 
-ADD_LIBRARY(ndbapi STATIC
+ADD_CONVENIENCE_LIBRARY(ndbapi
             NdbEventOperation.cpp
             NdbEventOperationImpl.cpp
             NdbIndexStat.cpp

=== modified file 'storage/ndb/src/ndbapi/ClusterMgr.cpp'
--- a/storage/ndb/src/ndbapi/ClusterMgr.cpp	2011-02-03 14:20:36 +0000
+++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp	2011-06-21 13:10:37 +0000
@@ -651,6 +651,9 @@ ClusterMgr::execAPI_REGREQ(const Uint32
 
   if(node.m_info.m_version != apiRegReq->version){
     node.m_info.m_version = apiRegReq->version;
+    node.m_info.m_mysql_version = apiRegReq->mysql_version;
+    if (node.m_info.m_version < NDBD_SPLIT_VERSION)
+      node.m_info.m_mysql_version = 0;
 
     if (getMajor(node.m_info.m_version) < getMajor(NDB_VERSION) ||
 	getMinor(node.m_info.m_version) < getMinor(NDB_VERSION)) {

=== modified file 'storage/ndb/test/ndbapi/testBasic.cpp'
--- a/storage/ndb/test/ndbapi/testBasic.cpp	2011-05-25 13:19:02 +0000
+++ b/storage/ndb/test/ndbapi/testBasic.cpp	2011-06-20 07:17:57 +0000
@@ -3027,14 +3027,14 @@ static RefreshScenario refreshTests[] =
 
 enum OpTypes
 {
-  READ_C,
-  READ_S,
-  READ_E,
-  INSERT,
-  UPDATE,
-  WRITE,
-  DELETE,
-  LAST
+  OP_READ_C,
+  OP_READ_S,
+  OP_READ_E,
+  OP_INSERT,
+  OP_UPDATE,
+  OP_WRITE,
+  OP_DELETE,
+  OP_LAST
 };
 
 const char* opTypeNames[] =
@@ -3133,9 +3133,9 @@ runRefreshLocking(NDBT_Context* ctx, NDB
     {
       /* Now try ops from another transaction */
       HugoOperations hugoOps(*ctx->getTab());
-      Uint32 ot = READ_C;
+      Uint32 ot = OP_READ_C;
 
-      while (ot < LAST)
+      while (ot < OP_LAST)
       {
         if (hugoOps.startTransaction(ndb) != 0)
         {
@@ -3147,34 +3147,34 @@ runRefreshLocking(NDBT_Context* ctx, NDB
         int res = 0;
         switch (ot)
         {
-        case READ_C:
+        case OP_READ_C:
           res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_CommittedRead);
           break;
-        case READ_S:
+        case OP_READ_S:
           res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_Read);
           break;
-        case READ_E:
+        case OP_READ_E:
           res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_Exclusive);
           break;
-        case INSERT:
+        case OP_INSERT:
           res = hugoOps.pkInsertRecord(ndb, 0);
           break;
-        case UPDATE:
+        case OP_UPDATE:
           res = hugoOps.pkUpdateRecord(ndb, 0);
           break;
-        case WRITE:
+        case OP_WRITE:
           res = hugoOps.pkWriteRecord(ndb, 0);
           break;
-        case DELETE:
+        case OP_DELETE:
           res = hugoOps.pkDeleteRecord(ndb, 0);
           break;
-        case LAST:
+        case OP_LAST:
           abort();
         }
 
         hugoOps.execute_Commit(ndb);
 
-        if ((ot == READ_C) && (scenario.preExist))
+        if ((ot == OP_READ_C) && (scenario.preExist))
         {
           if (hugoOps.getNdbError().code == 0)
           {

=== modified file 'storage/ndb/test/ndbapi/testMgmd.cpp'
--- a/storage/ndb/test/ndbapi/testMgmd.cpp	2011-02-03 14:20:36 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp	2011-06-21 13:10:37 +0000
@@ -934,6 +934,171 @@ runBug56844(NDBT_Context* ctx, NDBT_Step
   return NDBT_OK;
 }
 
+static bool
+get_status(const char* connectstring,
+           Properties& status)
+{
+  NdbMgmd ndbmgmd;
+  if (!ndbmgmd.connect(connectstring))
+    return false;
+
+  Properties args;
+  if (!ndbmgmd.call("get status", args,
+                    "node status", status, NULL, true))
+  {
+    g_err << "fetch_mgmd_status: mgmd.call failed" << endl;
+    return false;
+  }
+  return true;
+}
+
+static bool
+value_equal(Properties& status,
+            int nodeid, const char* name,
+            const char* expected_value)
+{
+  const char* value;
+  BaseString key;
+  key.assfmt("node.%d.%s", nodeid, name);
+  if (!status.get(key.c_str(), &value))
+  {
+    g_err << "value_equal: no value found for '" << name
+          << "." << nodeid << "'" << endl;
+    return false;
+  }
+
+  if (strcmp(value, expected_value))
+  {
+    g_err << "value_equal: found unexpected value: '" << value
+          << "', expected: '" << expected_value << "'" <<endl;
+    return false;
+  }
+  g_info << "'" << value << "'=='" << expected_value << "'" << endl;
+  return true;
+}
+
+#include <ndb_version.h>
+
+int runTestBug12352191(NDBT_Context* ctx, NDBT_Step* step)
+{
+  BaseString version;
+  version.assfmt("%u", NDB_VERSION_D);
+  BaseString mysql_version;
+  mysql_version.assfmt("%u", NDB_MYSQL_VERSION_D);
+  BaseString address("127.0.0.1");
+
+  NDBT_Workingdir wd("test_mgmd"); // temporary working directory
+
+  g_err << "** Create config.ini" << endl;
+  Properties config = ConfigFactory::create(2);
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config.ini",
+                                             NULL).c_str()));
+
+  MgmdProcessList mgmds;
+  const int nodeid1 = 1;
+  Mgmd* mgmd1 = new Mgmd(nodeid1);
+  mgmds.push_back(mgmd1);
+
+  const int nodeid2 = 2;
+  Mgmd* mgmd2 = new Mgmd(nodeid2);
+  mgmds.push_back(mgmd2);
+
+  // Start first mgmd
+  CHECK(mgmd1->start_from_config_ini(wd.path()));
+  CHECK(mgmd1->connect(config));
+
+  Properties status1;
+  CHECK(get_status(mgmd1->connectstring(config).c_str(), status1));
+  //status1.print();
+  // Check status for own mgm node, always CONNECTED
+  CHECK(value_equal(status1, nodeid1, "type", "MGM"));
+  CHECK(value_equal(status1, nodeid1, "status", "CONNECTED"));
+  CHECK(value_equal(status1, nodeid1, "version", version.c_str()));
+  CHECK(value_equal(status1, nodeid1, "mysql_version", mysql_version.c_str()));
+  CHECK(value_equal(status1, nodeid1, "address", address.c_str()));
+  CHECK(value_equal(status1, nodeid1, "startphase", "0"));
+  CHECK(value_equal(status1, nodeid1, "dynamic_id", "0"));
+  CHECK(value_equal(status1, nodeid1, "node_group", "0"));
+  CHECK(value_equal(status1, nodeid1, "connect_count", "0"));
+
+  // Check status for other mgm node
+  // not started yet -> NO_CONTACT, no address, no versions
+  CHECK(value_equal(status1, nodeid2, "type", "MGM"));
+  CHECK(value_equal(status1, nodeid2, "status", "NO_CONTACT"));
+  CHECK(value_equal(status1, nodeid2, "version", "0"));
+  CHECK(value_equal(status1, nodeid2, "mysql_version", "0"));
+  CHECK(value_equal(status1, nodeid2, "address", ""));
+  CHECK(value_equal(status1, nodeid2, "startphase", "0"));
+  CHECK(value_equal(status1, nodeid2, "dynamic_id", "0"));
+  CHECK(value_equal(status1, nodeid2, "node_group", "0"));
+  CHECK(value_equal(status1, nodeid2, "connect_count", "0"));
+
+  // Start second mgmd
+  CHECK(mgmd2->start_from_config_ini(wd.path()));
+  CHECK(mgmd2->connect(config));
+
+  // wait for confirmed config
+  for (unsigned i = 0; i < mgmds.size(); i++)
+    CHECK(mgmds[i]->wait_confirmed_config());
+
+  Properties status2;
+  CHECK(get_status(mgmd2->connectstring(config).c_str(), status2));
+  //status2.print();
+  // Check status for own mgm node, always CONNECTED
+  CHECK(value_equal(status2, nodeid2, "type", "MGM"));
+  CHECK(value_equal(status2, nodeid2, "status", "CONNECTED"));
+  CHECK(value_equal(status2, nodeid2, "version", version.c_str()));
+  CHECK(value_equal(status2, nodeid2, "mysql_version", mysql_version.c_str()));
+  CHECK(value_equal(status2, nodeid2, "address", address.c_str()));
+  CHECK(value_equal(status2, nodeid2, "startphase", "0"));
+  CHECK(value_equal(status2, nodeid2, "dynamic_id", "0"));
+  CHECK(value_equal(status2, nodeid2, "node_group", "0"));
+  CHECK(value_equal(status2, nodeid2, "connect_count", "0"));
+
+  // Check status for other mgm node
+  // both started now -> CONNECTED, address and versions filled in
+  CHECK(value_equal(status2, nodeid1, "type", "MGM"));
+  CHECK(value_equal(status2, nodeid1, "status", "CONNECTED"));
+  CHECK(value_equal(status2, nodeid1, "version", version.c_str()));
+  CHECK(value_equal(status2, nodeid1, "mysql_version", mysql_version.c_str()));
+  CHECK(value_equal(status2, nodeid1, "address", address.c_str()));
+  CHECK(value_equal(status2, nodeid1, "startphase", "0"));
+  CHECK(value_equal(status2, nodeid1, "dynamic_id", "0"));
+  CHECK(value_equal(status2, nodeid1, "node_group", "0"));
+  CHECK(value_equal(status2, nodeid1, "connect_count", "0"));
+
+  Properties status3;
+  CHECK(get_status(mgmd1->connectstring(config).c_str(), status3));
+  //status3.print();
+  // Check status for own mgm node, always CONNECTED
+  CHECK(value_equal(status3, nodeid1, "type", "MGM"));
+  CHECK(value_equal(status3, nodeid1, "status", "CONNECTED"));
+  CHECK(value_equal(status3, nodeid1, "version", version.c_str()));
+  CHECK(value_equal(status3, nodeid1, "mysql_version", mysql_version.c_str()));
+  CHECK(value_equal(status3, nodeid1, "address", address.c_str()));
+  CHECK(value_equal(status3, nodeid1, "startphase", "0"));
+  CHECK(value_equal(status3, nodeid1, "dynamic_id", "0"));
+  CHECK(value_equal(status3, nodeid1, "node_group", "0"));
+  CHECK(value_equal(status3, nodeid1, "connect_count", "0"));
+
+  // Check status for other mgm node
+  // both started now -> CONNECTED, address and versions filled in
+  CHECK(value_equal(status3, nodeid2, "type", "MGM"));
+  CHECK(value_equal(status3, nodeid2, "status", "CONNECTED"));
+  CHECK(value_equal(status3, nodeid2, "version", version.c_str()));
+  CHECK(value_equal(status3, nodeid2, "mysql_version", mysql_version.c_str()));
+  CHECK(value_equal(status3, nodeid2, "address", address.c_str()));
+  CHECK(value_equal(status3, nodeid2, "startphase", "0"));
+  CHECK(value_equal(status3, nodeid2, "dynamic_id", "0"));
+  CHECK(value_equal(status3, nodeid2, "node_group", "0"));
+  CHECK(value_equal(status3, nodeid2, "connect_count", "0"));
+
+  return NDBT_OK;
+
+}
+
 NDBT_TESTSUITE(testMgmd);
 DRIVER(DummyDriver); /* turn off use of NdbApi */
 
@@ -981,6 +1146,11 @@ TESTCASE("Bug56844",
 {
   INITIALIZER(runBug56844);
 }
+TESTCASE("Bug12352191",
+         "Test mgmd status for other mgmd")
+{
+  INITIALIZER(runTestBug12352191);
+}
 
 NDBT_TESTSUITE_END(testMgmd);
 

=== modified file 'storage/ndb/tools/ndb_dump_frm_data.cpp'
--- a/storage/ndb/tools/ndb_dump_frm_data.cpp	2011-06-14 10:42:04 +0000
+++ b/storage/ndb/tools/ndb_dump_frm_data.cpp	2011-06-22 07:57:40 +0000
@@ -20,7 +20,6 @@
 #include <NdbApi.hpp>
 #include <NDBT.hpp>
 
-// UNUSED static int oi = 1000;
 static struct my_option
 my_long_options[] =
 {

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.0-wl4124-new1 branch (pekka.nousiainen:4404to 4405) Pekka Nousiainen25 Jun