List:Commits« Previous MessageNext Message »
From:magnus.blaudd Date:June 22 2011 9:22am
Subject:bzr push into mysql-5.5-cluster branch (magnus.blaudd:3364 to 3367)
View as plain text  
 3367 magnus.blaudd@stripped	2011-06-22 [merge]
      Merge 7.1 -> 5.5-cluster

    modified:
      sql/ha_ndb_index_stat.cc
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      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/mgmapi/CMakeLists.txt
      storage/ndb/src/mgmsrv/CMakeLists.txt
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/ndbapi/CMakeLists.txt
      storage/ndb/src/ndbjtie/mysql/CMakeLists.txt
      storage/ndb/test/ndbapi/testBasic.cpp
      storage/ndb/tools/ndb_dump_frm_data.cpp
 3366 magnus.blaudd@stripped	2011-06-22 [merge]
      Merge 7.1 -> 5.5-cluster

    added:
      mysql-test/suite/ndb/r/ndb_select_count.result
      mysql-test/suite/ndb/t/ndb_select_count.test
    modified:
      sql/ha_ndbcluster.cc
      storage/ndb/include/mgmapi/mgmapi.h
      storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
      storage/ndb/src/mgmapi/mgmapi.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.hpp
      storage/ndb/src/ndbapi/ClusterMgr.cpp
      storage/ndb/src/ndbapi/NdbQueryBuilder.hpp
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
      storage/ndb/src/ndbapi/NdbQueryOperation.hpp
      storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp
      storage/ndb/test/ndbapi/testMgmd.cpp
 3365 magnus.blaudd@stripped	2011-06-22 [merge]
      Merge 7.1 -> 5.5-cluster

    added:
      mysql-test/suite/ndb/r/ndb_alter_table_online_multi.result
      mysql-test/suite/ndb/t/ndb_alter_table_online_multi.test
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/QueryExecutionContext.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/QueryExecutionContextJDBCImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/BatchDeleteQueryAllPrimitivesTest.java
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryMultipleParameterTest.java
      storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryMultipleParameterTest.java
    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/clusterj/clusterj-core/Makefile.am
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/AbstractDomainFieldHandlerImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/CandidateIndexImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ComparativePredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/EqualPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterEqualPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterThanPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessEqualPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessThanPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ParameterImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/DomainFieldHandler.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java
      storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties
      storage/ndb/clusterj/clusterj-jdbc/Makefile.am
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/AbstractResultSetInternalMethods.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/InterceptorImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsUpdateCount.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/SQLExecutor.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/resources/com/mysql/clusterj/jdbc/Bundle.properties
      storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/JDBCQueryTest.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java
      storage/ndb/clusterj/clusterj-test/Makefile.am
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryAllPrimitivesTest.java
      storage/ndb/clusterj/clusterj-tie/pom.xml
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java
 3364 magnus.blaudd@stripped	2011-06-22 [merge]
      Merge 7.1 -> 5.5-cluster

    added:
      sql/ha_ndb_index_stat.cc
      sql/ha_ndb_index_stat.h
      storage/ndb/src/ndbapi/NdbIndexStatFrmData.cpp
      storage/ndb/tools/ndb_dump_frm_data.cpp
    modified:
      mysql-test/suite/ndb/r/ndb_basic.result
      mysql-test/suite/ndb/r/ndb_index_ordered.result
      mysql-test/suite/ndb/t/ndb_basic.test
      mysql-test/suite/ndb/t/ndb_index_ordered.test
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
      sql/ha_ndbcluster_binlog.h
      sql/ndb_share.h
      storage/ndb/CMakeLists.txt
      storage/ndb/include/kernel/ndb_limits.h
      storage/ndb/include/ndb_constants.h
      storage/ndb/src/kernel/blocks/trix/Trix.cpp
      storage/ndb/src/ndbapi/CMakeLists.txt
      storage/ndb/src/ndbapi/Makefile.am
      storage/ndb/src/ndbapi/NdbIndexStatImpl.cpp
      storage/ndb/src/ndbapi/NdbIndexStatImpl.hpp
      storage/ndb/tools/CMakeLists.txt
      storage/ndb/tools/Makefile.am
      storage/ndb/tools/ndb_index_stat.cpp
=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table_online.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2011-04-11 13:36:12 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2011-06-17 10:15:34 +0000
@@ -142,67 +142,6 @@ select name from ndb_show_tables_results
 name
 DROP TABLE t1;
 *******************************
-* basic concurent online alter test
-*******************************
-* With Commit
-*******************************
-CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
-begin;
-update t1 set b = 0 where a = 1;
-update t1 set b = 1 where a = 2;
-delete from t1      where a = 3;
-insert into t1 values (5,5),(6,6);
-update t1 set b = 0 where a = 6;
-ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
-Warnings:
-Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
-Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
-Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
-update t1 set b = 0 where a = 2;
-update t1 set b = 0 where a = 4;
-update t1 set b = 0 where a = 5;
-insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
-commit;
-SELECT * FROM t1 ORDER BY a;
-a	b	c	d	e
-1	0	NULL	NULL	NULL
-2	0	NULL	NULL	NULL
-4	0	NULL	NULL	NULL
-5	0	NULL	NULL	NULL
-6	0	NULL	NULL	NULL
-7	0	NULL	NULL	NULL
-8	0	8	8	8
-DROP TABLE t1;
-*******************************
-* basic concurent online alter test
-*******************************
-* With Rollback
-*******************************
-CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
-begin;
-update t1 set b = 0 where a = 1;
-update t1 set b = 1 where a = 2;
-delete from t1      where a = 3;
-insert into t1 values (5,5),(6,6);
-update t1 set b = 0 where a = 6;
-ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
-Warnings:
-Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
-Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
-Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
-update t1 set b = 0 where a = 2;
-update t1 set b = 0 where a = 4;
-update t1 set b = 0 where a = 5;
-insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
-rollback;
-SELECT * FROM t1 ORDER BY a;
-a	b	c	d	e
-1	1	NULL	NULL	NULL
-2	2	NULL	NULL	NULL
-3	3	NULL	NULL	NULL
-4	4	NULL	NULL	NULL
-DROP TABLE t1;
-*******************************
 * The following ALTER operations are not supported on-line
 *******************************
 * Not supported Test#1

=== added file 'mysql-test/suite/ndb/r/ndb_alter_table_online_multi.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table_online_multi.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online_multi.result	2011-06-17 10:15:34 +0000
@@ -0,0 +1,61 @@
+*******************************
+* basic concurent online alter test
+*******************************
+* With Commit
+*******************************
+CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
+begin;
+update t1 set b = 0 where a = 1;
+update t1 set b = 1 where a = 2;
+delete from t1      where a = 3;
+insert into t1 values (5,5),(6,6);
+update t1 set b = 0 where a = 6;
+ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+update t1 set b = 0 where a = 2;
+update t1 set b = 0 where a = 4;
+update t1 set b = 0 where a = 5;
+insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
+commit;
+SELECT * FROM t1 ORDER BY a;
+a	b	c	d	e
+1	0	NULL	NULL	NULL
+2	0	NULL	NULL	NULL
+4	0	NULL	NULL	NULL
+5	0	NULL	NULL	NULL
+6	0	NULL	NULL	NULL
+7	0	NULL	NULL	NULL
+8	0	8	8	8
+DROP TABLE t1;
+*******************************
+* basic concurent online alter test
+*******************************
+* With Rollback
+*******************************
+CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
+begin;
+update t1 set b = 0 where a = 1;
+update t1 set b = 1 where a = 2;
+delete from t1      where a = 3;
+insert into t1 values (5,5),(6,6);
+update t1 set b = 0 where a = 6;
+ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+update t1 set b = 0 where a = 2;
+update t1 set b = 0 where a = 4;
+update t1 set b = 0 where a = 5;
+insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
+rollback;
+SELECT * FROM t1 ORDER BY a;
+a	b	c	d	e
+1	1	NULL	NULL	NULL
+2	2	NULL	NULL	NULL
+3	3	NULL	NULL	NULL
+4	4	NULL	NULL	NULL
+DROP TABLE t1;

=== modified file 'mysql-test/suite/ndb/r/ndb_index_ordered.result'
--- a/mysql-test/suite/ndb/r/ndb_index_ordered.result	2011-06-22 08:09:31 +0000
+++ b/mysql-test/suite/ndb/r/ndb_index_ordered.result	2011-06-22 08:20:35 +0000
@@ -637,21 +637,6 @@ select count(*)- 4 from t1 use index (v)
 count(*)- 4
 0
 drop table t1;
-create table t1(a int primary key, b int not null, index(b));
-insert into t1 values (1,1), (2,2);
-set autocommit=0;
-begin;
-select count(*) from t1;
-count(*)
-2
-ALTER TABLE t1 ADD COLUMN c int;
-select a from t1 where b = 2;
-a
-2
-show tables;
-Tables_in_test
-t1
-drop table t1;
 create table t1 (a int, c varchar(10),
 primary key using hash (a), index(c)) engine=ndb;
 insert into t1 (a, c) values (1,'aaa'),(3,'bbb');

=== modified file 'mysql-test/suite/ndb/r/ndb_multi.result'
--- a/mysql-test/suite/ndb/r/ndb_multi.result	2011-03-22 08:32:32 +0000
+++ b/mysql-test/suite/ndb/r/ndb_multi.result	2011-06-17 10:15:04 +0000
@@ -196,3 +196,19 @@ insert into t1 values(37);
 alter table t1 engine ndb;
 truncate t1;
 drop table t1;
+create table t1(a int primary key, b int not null, index(b)) engine = ndb;
+insert into t1 values (1,1), (2,2);
+set autocommit=0;
+begin;
+select count(*) from t1;
+count(*)
+2
+ALTER OFFLINE TABLE t1 ADD COLUMN c int;
+select a from t1 where b = 2;
+a
+2
+commit;
+show tables;
+Tables_in_test
+t1
+drop table t1;

=== added file 'mysql-test/suite/ndb/r/ndb_select_count.result'
--- a/mysql-test/suite/ndb/r/ndb_select_count.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_select_count.result	2011-06-20 12:34:27 +0000
@@ -0,0 +1,19 @@
+create table t1(
+k int not null auto_increment primary key,
+i int,
+j int
+) engine=ndbcluster;
+insert into t1(i,j) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+select count(*) from t1;
+count(*)
+7
+begin;
+delete from t1 where k = 10000;
+select count(*) from t1;
+count(*)
+7
+commit;
+select count(*) from t1;
+count(*)
+7
+drop table t1;

=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table_online.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online.test	2011-04-14 15:47:23 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online.test	2011-06-22 08:20:35 +0000
@@ -140,91 +140,6 @@ select name from ndb_show_tables_results
 DROP TABLE t1;
 
 --echo *******************************
---echo * basic concurent online alter test
---echo *******************************
---echo * With Commit
---echo *******************************
-
-connection server1;
-
-CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
-let $v=4;
-disable_query_log;
-while ($v)
-{
-  --eval INSERT INTO t1 VALUES($v,$v); 
-  dec $v;
-}
-enable_query_log;
-
-
-connection server2;
-begin;
-update t1 set b = 0 where a = 1;
-update t1 set b = 1 where a = 2;
-delete from t1      where a = 3;
-
-insert into t1 values (5,5),(6,6);
-update t1 set b = 0 where a = 6;
-
-connection server1;
-ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
-
-connection server2;
-update t1 set b = 0 where a = 2;
-update t1 set b = 0 where a = 4;
-update t1 set b = 0 where a = 5;
-insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
-commit;
-
-connection server1;
-SELECT * FROM t1 ORDER BY a;
-
-DROP TABLE t1;
-
---echo *******************************
---echo * basic concurent online alter test
---echo *******************************
---echo * With Rollback
---echo *******************************
-
-connection server1;
-
-CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
-let $v=4;
-disable_query_log;
-while ($v)
-{
-  --eval INSERT INTO t1 VALUES($v,$v); 
-  dec $v;
-}
-enable_query_log;
-
-connection server2;
-begin;
-update t1 set b = 0 where a = 1;
-update t1 set b = 1 where a = 2;
-delete from t1      where a = 3;
-
-insert into t1 values (5,5),(6,6);
-update t1 set b = 0 where a = 6;
-
-connection server1;
-ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
-
-connection server2;
-update t1 set b = 0 where a = 2;
-update t1 set b = 0 where a = 4;
-update t1 set b = 0 where a = 5;
-insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
-rollback;
-
-connection server1;
-SELECT * FROM t1 ORDER BY a;
-
-DROP TABLE t1;
-
---echo *******************************
 --echo * The following ALTER operations are not supported on-line
 --echo *******************************
 --echo * Not supported Test#1

=== added file 'mysql-test/suite/ndb/t/ndb_alter_table_online_multi.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online_multi.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online_multi.test	2011-06-17 10:15:34 +0000
@@ -0,0 +1,88 @@
+-- source include/not_embedded.inc
+-- source include/have_multi_ndb.inc
+
+--echo *******************************
+--echo * basic concurent online alter test
+--echo *******************************
+--echo * With Commit
+--echo *******************************
+
+connection server1;
+
+CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
+let $v=4;
+disable_query_log;
+while ($v)
+{
+  --eval INSERT INTO t1 VALUES($v,$v); 
+  dec $v;
+}
+enable_query_log;
+
+
+connection server2;
+begin;
+update t1 set b = 0 where a = 1;
+update t1 set b = 1 where a = 2;
+delete from t1      where a = 3;
+
+insert into t1 values (5,5),(6,6);
+update t1 set b = 0 where a = 6;
+
+connection server1;
+ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
+
+connection server2;
+update t1 set b = 0 where a = 2;
+update t1 set b = 0 where a = 4;
+update t1 set b = 0 where a = 5;
+insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
+commit;
+
+connection server1;
+SELECT * FROM t1 ORDER BY a;
+
+DROP TABLE t1;
+
+--echo *******************************
+--echo * basic concurent online alter test
+--echo *******************************
+--echo * With Rollback
+--echo *******************************
+
+connection server1;
+
+CREATE TABLE t1 (a INT UNSIGNED KEY, b INT UNSIGNED) ENGINE NDB;
+let $v=4;
+disable_query_log;
+while ($v)
+{
+  --eval INSERT INTO t1 VALUES($v,$v); 
+  dec $v;
+}
+enable_query_log;
+
+connection server2;
+begin;
+update t1 set b = 0 where a = 1;
+update t1 set b = 1 where a = 2;
+delete from t1      where a = 3;
+
+insert into t1 values (5,5),(6,6);
+update t1 set b = 0 where a = 6;
+
+connection server1;
+ALTER TABLE t1 ADD c CHAR(19), ADD d VARCHAR(255), ADD e char(255);
+
+connection server2;
+update t1 set b = 0 where a = 2;
+update t1 set b = 0 where a = 4;
+update t1 set b = 0 where a = 5;
+insert into t1 values (7,0,null,null,null),(8,0,'8','8','8');
+rollback;
+
+connection server1;
+SELECT * FROM t1 ORDER BY a;
+
+DROP TABLE t1;
+

=== modified file 'mysql-test/suite/ndb/t/ndb_index_ordered.test'
--- a/mysql-test/suite/ndb/t/ndb_index_ordered.test	2011-06-22 08:09:31 +0000
+++ b/mysql-test/suite/ndb/t/ndb_index_ordered.test	2011-06-22 08:20:35 +0000
@@ -332,22 +332,6 @@ select count(*)- 4 from t1 use index (v)
 
 drop table t1;
 
-# bug#7798
-create table t1(a int primary key, b int not null, index(b));
-insert into t1 values (1,1), (2,2);
-connect (con1,localhost,root,,test);
-connect (con2,localhost,root,,test);
-connection con1;
-set autocommit=0;
-begin;
-select count(*) from t1;
-connection con2;
-ALTER TABLE t1 ADD COLUMN c int;
-connection con1;
-select a from t1 where b = 2;
-show tables;
-drop table t1;
-
 # mysqld 5.0.13 crash, no bug#
 create table t1 (a int, c varchar(10),
   primary key using hash (a), index(c)) engine=ndb;

=== modified file 'mysql-test/suite/ndb/t/ndb_multi.test'
--- a/mysql-test/suite/ndb/t/ndb_multi.test	2011-03-22 08:32:32 +0000
+++ b/mysql-test/suite/ndb/t/ndb_multi.test	2011-06-17 10:15:04 +0000
@@ -246,3 +246,18 @@ truncate t1;
 # Cleanup
 drop table t1;
 connection server1;
+
+# bug#7798
+create table t1(a int primary key, b int not null, index(b)) engine = ndb;
+insert into t1 values (1,1), (2,2);
+set autocommit=0;
+begin;
+select count(*) from t1;
+connection server2;
+ALTER OFFLINE TABLE t1 ADD COLUMN c int;
+connection server1;
+select a from t1 where b = 2;
+commit;
+show tables;
+drop table t1;
+

=== added file 'mysql-test/suite/ndb/t/ndb_select_count.test'
--- a/mysql-test/suite/ndb/t/ndb_select_count.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_select_count.test	2011-06-20 12:34:27 +0000
@@ -0,0 +1,18 @@
+-- source include/have_ndb.inc
+
+create table t1(
+  k int not null auto_increment primary key,
+  i int,
+  j int
+) engine=ndbcluster;
+
+insert into t1(i,j) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+
+select count(*) from t1;
+begin;
+delete from t1 where k = 10000; # none existant, rbwr
+select count(*) from t1;
+commit;
+select count(*) from t1;
+
+drop table t1;

=== modified file 'sql/ha_ndb_index_stat.cc'
--- a/sql/ha_ndb_index_stat.cc	2011-06-22 08:09:31 +0000
+++ b/sql/ha_ndb_index_stat.cc	2011-06-22 09:20:53 +0000
@@ -1590,7 +1590,7 @@ ndb_index_stat_thread_func(void *arg __a
   {
     set_timespec(abstime, 1);
     mysql_cond_timedwait(&COND_server_started, &LOCK_server_started,
-                         &abstime);
+	                 &abstime);
     if (ndbcluster_terminating)
     {
       mysql_mutex_unlock(&LOCK_server_started);
@@ -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);
 
-    mysql_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);
-    mysql_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-22 08:09:31 +0000
+++ b/sql/ha_ndbcluster.cc	2011-06-22 09:20:53 +0000
@@ -256,7 +256,10 @@ static MYSQL_THDVAR_UINT(
 */
 bool ndb_index_stat_get_enable(THD *thd)
 {
-  return THDVAR(thd, index_stat_enable);
+  mysql_mutex_lock(&LOCK_global_system_variables);
+  const bool value = THDVAR(thd, index_stat_enable);
+  mysql_mutex_unlock(&LOCK_global_system_variables);
+  return value;
 }
 
 static int ndbcluster_end(handlerton *hton, ha_panic_function flag);
@@ -596,9 +599,9 @@ SHOW_VAR ndb_status_variables_dynamic[]=
 };
 
 SHOW_VAR ndb_status_conflict_variables[]= {
-  {"fn_max",       (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_MAX], SHOW_LONG},
-  {"fn_old",       (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_OLD], SHOW_LONG},
-  {"fn_max_del_win", (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_MAX_DEL_WIN], SHOW_LONG},
+  {"fn_max",       (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_MAX], SHOW_LONGLONG},
+  {"fn_old",       (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_OLD], SHOW_LONGLONG},
+  {"fn_max_del_win", (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_MAX_DEL_WIN], SHOW_LONGLONG},
   {NullS, NullS, SHOW_LONG}
 };
 
@@ -5034,6 +5037,7 @@ int ha_ndbcluster::end_bulk_delete()
 
   assert(m_rows_deleted >= ignore_count);
   m_rows_deleted-= ignore_count;
+  no_uncommitted_rows_update(ignore_count);
   DBUG_RETURN(0);
 }
 
@@ -5226,6 +5230,7 @@ int ha_ndbcluster::ndb_delete_row(const 
   {
     assert(m_rows_deleted >= ignore_count);
     m_rows_deleted-= ignore_count;
+    no_uncommitted_rows_update(ignore_count);
   }
   DBUG_RETURN(0);
 }
@@ -11103,7 +11108,15 @@ ha_ndbcluster::records_in_range(uint inx
       ha_rows rows= HA_POS_ERROR;
       int err= ndb_index_stat_get_rir(inx, min_key, max_key, &rows);
       if (err == 0)
+      {
+        /**
+         * optmizer thinks that all values < 2 are exact...but
+         * but we don't provide exact statistics
+         */
+        if (rows < 2)
+          rows = 2;
         DBUG_RETURN(rows);
+      }
       /*fall through*/
     }
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-06-22 08:09:31 +0000
+++ b/sql/ha_ndbcluster.h	2011-06-22 09:20:53 +0000
@@ -38,7 +38,6 @@ class NdbIndexScanOperation; 
 class NdbBlob;
 class NdbIndexStat;
 class NdbEventOperation;
-class NdbInterpretedCode;
 class ha_ndbcluster_cond;
 class Ndb_event_data;
 

=== modified file 'storage/ndb/clusterj/clusterj-core/Makefile.am'
--- a/storage/ndb/clusterj/clusterj-core/Makefile.am	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-core/Makefile.am	2011-06-20 23:34:36 +0000
@@ -60,6 +60,7 @@ clusterj_core_java = \
   $(clusterj_core_src)/com/mysql/clusterj/core/spi/DomainFieldHandler.java \
   $(clusterj_core_src)/com/mysql/clusterj/core/spi/DomainTypeHandler.java \
   $(clusterj_core_src)/com/mysql/clusterj/core/spi/DomainTypeHandlerFactory.java \
+  $(clusterj_core_src)/com/mysql/clusterj/core/spi/QueryExecutionContext.java \
   $(clusterj_core_src)/com/mysql/clusterj/core/spi/SessionSPI.java \
   $(clusterj_core_src)/com/mysql/clusterj/core/spi/ValueHandler.java \
   $(clusterj_core_src)/com/mysql/clusterj/core/StateManager.java \

=== 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-03-23 22:41:01 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/AbstractDomainFieldHandlerImpl.java	2011-06-20 23:34:36 +0000
@@ -22,6 +22,7 @@ import com.mysql.clusterj.ClusterJFatalI
 import com.mysql.clusterj.ClusterJUserException;
 import com.mysql.clusterj.ColumnMetadata;
 import com.mysql.clusterj.ColumnType;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.spi.ValueHandler;
 import com.mysql.clusterj.core.spi.DomainTypeHandler;
 import com.mysql.clusterj.core.query.CandidateIndexImpl;
@@ -245,6 +246,10 @@ public abstract class AbstractDomainFiel
         }
     }
 
+    public Object getValue(QueryExecutionContext context, String index) {
+        return objectOperationHandlerDelegate.getValue(context, index);
+    }
+
     void objectSetDefaultValue(ValueHandler handler) {
         objectOperationHandlerDelegate.objectInitializeJavaDefaultValue(this, handler);
     }
@@ -424,6 +429,8 @@ public abstract class AbstractDomainFiel
 
         boolean isPrimitive();
 
+        Object getValue(QueryExecutionContext context, String index);
+
         void objectInitializeJavaDefaultValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler);
 
         void operationGetValue(AbstractDomainFieldHandlerImpl fmd, Operation op);
@@ -511,6 +518,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getByte(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerBoolean = new ObjectOperationHandler() {
@@ -569,6 +580,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBoolean(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectBoolean = new ObjectOperationHandler() {
@@ -631,6 +646,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBoolean(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerBytes = new ObjectOperationHandler() {
@@ -704,6 +723,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBytes(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerKeyBytes = new ObjectOperationHandler() {
@@ -768,6 +791,10 @@ public abstract class AbstractDomainFiel
             partitionKey.addBytesKey(fmd.storeColumn, keyValueHandler.getBytes(fmd.fieldNumber));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBytes(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerBytesLob = new ObjectOperationHandler() {
@@ -875,6 +902,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBoolean(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerStringLob = new ObjectOperationHandler() {
@@ -982,6 +1013,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getString(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerDecimal = new ObjectOperationHandler() {
@@ -1046,6 +1081,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBigDecimal(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerBigInteger = new ObjectOperationHandler() {
@@ -1110,6 +1149,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getBigInteger(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerDouble = new ObjectOperationHandler() {
@@ -1168,6 +1211,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getDouble(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerFloat = new ObjectOperationHandler() {
@@ -1226,6 +1273,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getFloat(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerInt = new ObjectOperationHandler() {
@@ -1294,6 +1345,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getInt(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerJavaSqlDate = new ObjectOperationHandler() {
@@ -1364,6 +1419,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getJavaSqlDate(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerJavaSqlTime = new ObjectOperationHandler() {
@@ -1430,6 +1489,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getJavaSqlTime(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerJavaSqlTimestamp = new ObjectOperationHandler() {
@@ -1496,6 +1559,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getJavaSqlTimestamp(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerJavaUtilDate = new ObjectOperationHandler() {
@@ -1562,6 +1629,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getJavaUtilDate(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerKeyInt = new ObjectOperationHandler() {
@@ -1628,6 +1699,10 @@ public abstract class AbstractDomainFiel
             partitionKey.addIntKey(fmd.storeColumn, keyValueHandler.getInt(fmd.fieldNumber));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getInt(index);
+        }
+
     };
     protected static ObjectOperationHandler objectOperationHandlerKeyLong = new ObjectOperationHandler() {
 
@@ -1690,6 +1765,10 @@ public abstract class AbstractDomainFiel
             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() {
 
@@ -1748,6 +1827,10 @@ public abstract class AbstractDomainFiel
             partitionKey.addStringKey(fmd.storeColumn, keyValueHandler.getString(fmd.fieldNumber));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getString(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerLong = new ObjectOperationHandler() {
@@ -1812,6 +1895,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getLong(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectByte = new ObjectOperationHandler() {
@@ -1876,6 +1963,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getByte(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectDouble = new ObjectOperationHandler() {
@@ -1937,6 +2028,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getDouble(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectFloat = new ObjectOperationHandler() {
@@ -1998,6 +2093,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getFloat(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectInteger = new ObjectOperationHandler() {
@@ -2062,6 +2161,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getInt(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectLong = new ObjectOperationHandler() {
@@ -2126,6 +2229,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getLong(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectShort = new ObjectOperationHandler() {
@@ -2195,6 +2302,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getShort(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerShort = new ObjectOperationHandler() {
@@ -2264,6 +2375,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getShort(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerShortYear = new ObjectOperationHandler() {
@@ -2330,6 +2445,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getShort(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerObjectShortYear = new ObjectOperationHandler() {
@@ -2400,6 +2519,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getShort(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerString = new ObjectOperationHandler() {
@@ -2468,6 +2591,10 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getString(index);
+        }
+
     };
 
     protected static ObjectOperationHandler objectOperationHandlerUnsupportedType = new ObjectOperationHandler() {
@@ -2524,6 +2651,10 @@ public abstract class AbstractDomainFiel
             throw new ClusterJUserException(local.message("ERR_Unsupported_Field_Type", fmd.getTypeName(), fmd.getName()));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            throw new ClusterJFatalInternalException(local.message("ERR_Implementation_Should_Not_Occur"));
+       }
+
     };
 
     /** This operation handler is a no-op for getting and setting values that don't
@@ -2587,9 +2718,13 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            throw new ClusterJFatalInternalException(local.message("ERR_Implementation_Should_Not_Occur"));
+       }
+
     };
 
-    protected static abstract class objectOperationHandlerNotPersistent implements ObjectOperationHandler {
+    protected static abstract class ObjectOperationHandlerNotPersistent implements ObjectOperationHandler {
 
         public boolean isPrimitive() {
             return true;
@@ -2638,9 +2773,13 @@ public abstract class AbstractDomainFiel
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            throw new ClusterJFatalInternalException(local.message("ERR_Implementation_Should_Not_Occur"));
+       }
+
     }
 
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentByte = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentByte = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent primitive byte";
@@ -2650,7 +2789,7 @@ public abstract class AbstractDomainFiel
             handler.setByte(fmd.fieldNumber, (byte) 0);
         }
     };
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentDouble = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentDouble = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent primitive double";
@@ -2660,7 +2799,7 @@ public abstract class AbstractDomainFiel
             handler.setDouble(fmd.fieldNumber, 0.0D);
         }
     };
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentFloat = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentFloat = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent primitive float";
@@ -2670,7 +2809,7 @@ public abstract class AbstractDomainFiel
             handler.setFloat(fmd.fieldNumber, 0.0F);
         }
     };
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentInt = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentInt = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent primitive int";
@@ -2680,7 +2819,7 @@ public abstract class AbstractDomainFiel
             handler.setInt(fmd.fieldNumber, 0);
         }
     };
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentLong = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentLong = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent primitive long";
@@ -2690,7 +2829,7 @@ public abstract class AbstractDomainFiel
             handler.setLong(fmd.fieldNumber, 0L);
         }
     };
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentObject = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentObject = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent Object";
@@ -2704,7 +2843,7 @@ public abstract class AbstractDomainFiel
         public void objectInitializeJavaDefaultValue(AbstractDomainFieldHandlerImpl fmd, ValueHandler handler) {
         }
     };
-    protected static ObjectOperationHandler objectOperationHandlerNotPersistentShort = new objectOperationHandlerNotPersistent() {
+    protected static ObjectOperationHandler objectOperationHandlerNotPersistentShort = new ObjectOperationHandlerNotPersistent() {
 
         public String handler() {
             return "not persistent primitive short";

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.Operation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -90,7 +91,7 @@ public class AndPredicateImpl extends Pr
      * @param op the operation
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op) {
         try {
             ScanFilter filter = op.getScanFilter(context);
@@ -108,7 +109,7 @@ public class AndPredicateImpl extends Pr
     /** Set the keys into the operation for each predicate.
      * Each predicate must be an equal predicate for a primary or unique key.
      */
-    public void operationEqual(QueryExecutionContextImpl context,
+    public void operationEqual(QueryExecutionContext context,
             Operation op) {
         for (PredicateImpl predicate: predicates) {
             if (!(predicate instanceof EqualPredicateImpl)) {
@@ -125,7 +126,7 @@ public class AndPredicateImpl extends Pr
      * @return the best index
      */
     @Override
-    public CandidateIndexImpl getBestCandidateIndex(QueryExecutionContextImpl context) {
+    public CandidateIndexImpl getBestCandidateIndex(QueryExecutionContext context) {
         return getBestCandidateIndexFor(context, predicates.toArray(
                 new PredicateImpl[predicates.size()]));
     }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -19,6 +19,7 @@ package com.mysql.clusterj.core.query;
 
 import com.mysql.clusterj.ClusterJException;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -41,6 +42,8 @@ public class BetweenPredicateImpl extend
         this.lower = lower;
         this.upper = upper;
         this.property = property;
+        lower.setProperty(property);
+        upper.setProperty(property);
     }
 
     public void markParameters() {
@@ -53,16 +56,8 @@ public class BetweenPredicateImpl extend
         upper.unmark();
     }
 
-//    /** Return the name of the index.
-//     * Currently only primary key scans are supported.
-//     * @return the type of scan for the operation
-//     */
-//    public String getIndexName() {
-//        return property.getIndexName();
-//    }
-//
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         if (lower.getParameterValue(context) == null || upper.getParameterValue(context) == null) {
             // null parameters cannot be used with index scans
             return;
@@ -78,7 +73,7 @@ public class BetweenPredicateImpl extend
      * @param op the index scan operation on which to set bounds
      */
     @Override
-    public void operationSetBounds(QueryExecutionContextImpl context,
+    public void operationSetBounds(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         property.operationSetBounds(lower.getParameterValue(context),
                 IndexScanOperation.BoundType.BoundLE, op);
@@ -93,7 +88,7 @@ public class BetweenPredicateImpl extend
      * @param op the index scan operation on which to set bounds
      */
     @Override
-    public void operationSetUpperBound(QueryExecutionContextImpl context,
+    public void operationSetUpperBound(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         property.operationSetBounds(upper.getParameterValue(context),
                 IndexScanOperation.BoundType.BoundGE, op);
@@ -106,7 +101,7 @@ public class BetweenPredicateImpl extend
      * @param op the index scan operation on which to set bounds
      */
     @Override
-    public void operationSetLowerBound(QueryExecutionContextImpl context,
+    public void operationSetLowerBound(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         property.operationSetBounds(lower.getParameterValue(context),
                 IndexScanOperation.BoundType.BoundLE, op);
@@ -118,7 +113,7 @@ public class BetweenPredicateImpl extend
      * @param op the operation
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op) {
         try {
             ScanFilter filter = op.getScanFilter(context);
@@ -137,7 +132,7 @@ public class BetweenPredicateImpl extend
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(lower.getParameterValue(context),
                 ScanFilter.BinaryCondition.COND_GE, filter);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/CandidateIndexImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/CandidateIndexImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/CandidateIndexImpl.java	2011-06-20 23:34:36 +0000
@@ -21,6 +21,7 @@ import com.mysql.clusterj.ClusterJUserEx
 import com.mysql.clusterj.core.metadata.AbstractDomainFieldHandlerImpl;
 
 import com.mysql.clusterj.core.query.PredicateImpl.ScanType;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.Index;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.Operation;
@@ -286,7 +287,7 @@ public class CandidateIndexImpl {
      * @param context the query execution context, containing the parameter values
      * @param op the index scan operation
      */
-    void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op) {
+    void operationSetBounds(QueryExecutionContext context, IndexScanOperation op) {
         if (multiRange) {
             // find how many query terms are inPredicates
             List<Integer> parameterSizes = new ArrayList<Integer>();
@@ -333,7 +334,7 @@ public class CandidateIndexImpl {
         }
     }
 
-    void operationSetKeys(QueryExecutionContextImpl context,
+    void operationSetKeys(QueryExecutionContext context,
             Operation op) {
         for (CandidateColumnImpl candidateColumn:candidateColumns) {
             // execute the equal operation
@@ -369,11 +370,11 @@ public class CandidateIndexImpl {
          * @param context the query context
          * @param op the operation
          */
-        public void operationSetAllBounds(QueryExecutionContextImpl context, IndexScanOperation op) {
+        public void operationSetAllBounds(QueryExecutionContext context, IndexScanOperation op) {
             inPredicate.operationSetAllBounds(context, op);
         }
 
-        public int getParameterSize(QueryExecutionContextImpl context) {
+        public int getParameterSize(QueryExecutionContext context) {
             // TODO Auto-generated method stub
             return inPredicate.getParameterSize(context);
         }
@@ -425,7 +426,7 @@ public class CandidateIndexImpl {
          * @param boundStatus 
          */
         private int operationSetBounds(
-                QueryExecutionContextImpl context, IndexScanOperation op, int index, int boundStatus) {
+                QueryExecutionContext context, IndexScanOperation op, int index, int boundStatus) {
 
             if (logger.isDetailEnabled()) logger.detail("column: " + domainFieldHandler.getName() 
                     + " boundStatus: " + boundStatus
@@ -486,7 +487,7 @@ public class CandidateIndexImpl {
             return boundStatus;
         }
 
-        private void operationSetKeys(QueryExecutionContextImpl context, Operation op) {
+        private void operationSetKeys(QueryExecutionContext context, Operation op) {
             equalPredicate.operationEqual(context, op);
         }
 

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ComparativePredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ComparativePredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ComparativePredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 
 /** This is an abstract superclass for all of the comparison predicates:
@@ -37,6 +38,14 @@ public abstract class ComparativePredica
         super(dobj);
     }
 
+    public ComparativePredicateImpl(QueryDomainTypeImpl<?> dobj,
+            PropertyImpl property, ParameterImpl param) {
+        super(dobj);
+        this.property = property;
+        this.param = param;
+        param.setProperty(property);
+    }
+
     public void markParameters() {
         param.mark();
     }
@@ -46,20 +55,20 @@ public abstract class ComparativePredica
     }
 
     @Override
-    public void objectSetValuesFor(QueryExecutionContextImpl context,
+    public void objectSetValuesFor(QueryExecutionContext context,
             Object row, String indexName) {
         property.objectSetValuesFor(param.getParameterValue(context), row, indexName);
     }
 
     @Override
-    public void operationSetLowerBound(QueryExecutionContextImpl context,
+    public void operationSetLowerBound(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         // delegate to setBounds for most operations
         operationSetBounds(context, op, lastColumn);
     }
 
     @Override
-    public void operationSetUpperBound(QueryExecutionContextImpl context,
+    public void operationSetUpperBound(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         // delegate to setBounds for most operations
         operationSetBounds(context, op, lastColumn);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/EqualPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/EqualPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/EqualPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.Operation;
 import com.mysql.clusterj.core.store.ScanFilter;
@@ -26,13 +27,11 @@ public class EqualPredicateImpl extends 
 
     public EqualPredicateImpl(QueryDomainTypeImpl<?> dobj,
             PropertyImpl property, ParameterImpl param) {
-        super(dobj);
-        this.param = param;
-        this.property = property;
+        super(dobj, property, param);
     }
 
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         if (param.getParameterValue(context) == null) {
             // null parameters cannot be used with indexes
             return;
@@ -41,31 +40,31 @@ public class EqualPredicateImpl extends 
     }
 
     @Override
-    public void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetBounds(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         // can always set boundEQ
         property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundEQ, op);
     }
 
     @Override
-    public void operationSetLowerBound(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetLowerBound(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         // only set lower bound
         property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundLE, op);
     }
 
     @Override
-    public void operationSetUpperBound(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetUpperBound(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         // only set upper bound
         property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundGE, op);
     }
 
     @Override
-    public void operationEqual(QueryExecutionContextImpl context,
+    public void operationEqual(QueryExecutionContext context,
             Operation op) {
         property.operationEqual(param.getParameterValue(context), op);
     }
 
     @Override
-    public void operationEqualFor(QueryExecutionContextImpl context,
+    public void operationEqualFor(QueryExecutionContext context,
             Operation op, String indexName) {
         property.operationEqualFor(param.getParameterValue(context), op, indexName);
     }
@@ -76,7 +75,7 @@ public class EqualPredicateImpl extends 
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context, ScanOperation op, ScanFilter filter) {
+    public void filterCmpValue(QueryExecutionContext context, ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(param.getParameterValue(context),
                 ScanFilter.BinaryCondition.COND_EQ, filter);
     }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterEqualPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterEqualPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterEqualPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -25,13 +26,11 @@ public class GreaterEqualPredicateImpl e
 
     public GreaterEqualPredicateImpl(QueryDomainTypeImpl<?> dobj,
             PropertyImpl property, ParameterImpl param) {
-        super(dobj);
-        this.param = param;
-        this.property = property;
+        super(dobj, property, param);
     }
 
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         if (param.getParameterValue(context) == null) {
             // null parameters cannot be used with indexes
             return;
@@ -40,7 +39,7 @@ public class GreaterEqualPredicateImpl e
     }
 
     @Override
-    public void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetBounds(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundLE, op);
     }
 
@@ -50,7 +49,7 @@ public class GreaterEqualPredicateImpl e
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(param.getParameterValue(context),
                 ScanFilter.BinaryCondition.COND_GE, filter);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterThanPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterThanPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/GreaterThanPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -25,13 +26,11 @@ public class GreaterThanPredicateImpl ex
 
     public GreaterThanPredicateImpl(QueryDomainTypeImpl<?> dobj,
             PropertyImpl property, ParameterImpl param) {
-        super(dobj);
-        this.param = param;
-        this.property = property;
+        super(dobj, property, param);
     }
 
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         if (param.getParameterValue(context) == null) {
             // null parameters cannot be used with indexes
             return;
@@ -40,7 +39,7 @@ public class GreaterThanPredicateImpl ex
     }
 
     @Override
-    public void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetBounds(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         if (lastColumn) {
             // last column may be strict
             property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundLT, op);
@@ -56,7 +55,7 @@ public class GreaterThanPredicateImpl ex
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(param.getParameterValue(context),
                 ScanFilter.BinaryCondition.COND_GT, filter);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -21,6 +21,7 @@ import java.util.List;
 
 import com.mysql.clusterj.ClusterJException;
 import com.mysql.clusterj.ClusterJUserException;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -41,6 +42,9 @@ public class InPredicateImpl extends Pre
         super(dobj);
         this.property = property;
         this.parameter = parameter;
+        parameter.setProperty(property);
+        // mark this property as having complex values
+        property.setComplexParameter();
     }
 
     @Override
@@ -53,7 +57,8 @@ public class InPredicateImpl extends Pre
         parameter.unmark();
     }
 
-    void markBoundsForCandidateIndices(QueryExecutionContextImpl context,
+    @Override
+    void markBoundsForCandidateIndices(QueryExecutionContext context,
             CandidateIndexImpl[] candidateIndices) {
         if (parameter.getParameterValue(context) == null) {
             // null parameters cannot be used with index scans
@@ -70,7 +75,7 @@ public class InPredicateImpl extends Pre
      * @param lastColumn if true, can set strict bound
      */
     public void operationSetBound(
-            QueryExecutionContextImpl context, IndexScanOperation op, int index, boolean lastColumn) {
+            QueryExecutionContext context, IndexScanOperation op, int index, boolean lastColumn) {
         if (lastColumn) {
             // last column can be strict
             operationSetBound(context, op, index, BoundType.BoundEQ);
@@ -81,16 +86,16 @@ public class InPredicateImpl extends Pre
         }
     }
 
-    public void operationSetUpperBound(QueryExecutionContextImpl context, IndexScanOperation op, int index) {
+    public void operationSetUpperBound(QueryExecutionContext context, IndexScanOperation op, int index) {
         operationSetBound(context, op, index, BoundType.BoundGE);
     }
 
-    public void operationSetLowerBound(QueryExecutionContextImpl context, IndexScanOperation op, int index) {
+    public void operationSetLowerBound(QueryExecutionContext context, IndexScanOperation op, int index) {
         operationSetBound(context, op, index, BoundType.BoundLE);
     }
 
     private void operationSetBound(
-            QueryExecutionContextImpl context, IndexScanOperation op, int index, BoundType boundType) {
+            QueryExecutionContext context, IndexScanOperation op, int index, BoundType boundType) {
     Object parameterValue = parameter.getParameterValue(context);
         if (parameterValue == null) {
             throw new ClusterJUserException(
@@ -119,7 +124,7 @@ public class InPredicateImpl extends Pre
      * @param op the operation to set bounds on
      * @param index the index into the parameter list
      */
-    public void operationSetAllBounds(QueryExecutionContextImpl context,
+    public void operationSetAllBounds(QueryExecutionContext context,
             IndexScanOperation op) {
         Object parameterValue = parameter.getParameterValue(context);
         int index = 0;
@@ -152,7 +157,7 @@ public class InPredicateImpl extends Pre
      * @param context the query execution context with the parameter values
      * @param op the operation
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op) {
         try {
             ScanFilter filter = op.getScanFilter(context);
@@ -171,8 +176,7 @@ public class InPredicateImpl extends Pre
      * @param op the operation
      * @param filter the existing filter
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
-            ScanOperation op, ScanFilter filter) {
+    public void filterCmpValue(QueryExecutionContext context, ScanOperation op, ScanFilter filter) {
         try {
             filter.begin(Group.GROUP_OR);
             Object parameterValue = parameter.getParameterValue(context);
@@ -203,7 +207,7 @@ public class InPredicateImpl extends Pre
         }
     }
 
-    public int getParameterSize(QueryExecutionContextImpl context) {
+    public int getParameterSize(QueryExecutionContext context) {
         int result = 1;
         Object parameterValue = parameter.getParameterValue(context);
         if (parameterValue instanceof List<?>) {

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessEqualPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessEqualPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessEqualPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -25,13 +26,11 @@ public class LessEqualPredicateImpl exte
 
     public LessEqualPredicateImpl(QueryDomainTypeImpl<?> dobj,
             PropertyImpl property, ParameterImpl param) {
-        super(dobj);
-        this.param = param;
-        this.property = property;
+        super(dobj, property, param);
     }
 
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         if (param.getParameterValue(context) == null) {
             // null parameters cannot be used with indexes
             return;
@@ -40,7 +39,7 @@ public class LessEqualPredicateImpl exte
     }
 
     @Override
-    public void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetBounds(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundGE, op);
     }
 
@@ -50,7 +49,7 @@ public class LessEqualPredicateImpl exte
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context, ScanOperation op, ScanFilter filter) {
+    public void filterCmpValue(QueryExecutionContext context, ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(param.getParameterValue(context), ScanFilter.BinaryCondition.COND_LE, filter);
     }
 

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessThanPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessThanPredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LessThanPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -25,13 +26,11 @@ public class LessThanPredicateImpl exten
 
     public LessThanPredicateImpl(QueryDomainTypeImpl<?> dobj,
             PropertyImpl property, ParameterImpl param) {
-        super(dobj);
-        this.param = param;
-        this.property = property;
+        super(dobj, property, param);
     }
 
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         if (param.getParameterValue(context) == null) {
             // null parameters cannot be used with indexes
             return;
@@ -40,7 +39,7 @@ public class LessThanPredicateImpl exten
     }
 
     @Override
-    public void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
+    public void operationSetBounds(QueryExecutionContext context, IndexScanOperation op, boolean lastColumn) {
         if (lastColumn) {
             // last column may be strict
             property.operationSetBounds(param.getParameterValue(context), IndexScanOperation.BoundType.BoundGT, op);
@@ -56,7 +55,7 @@ public class LessThanPredicateImpl exten
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context, ScanOperation op, ScanFilter filter) {
+    public void filterCmpValue(QueryExecutionContext context, ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(param.getParameterValue(context), ScanFilter.BinaryCondition.COND_LT, filter);
     }
 

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java	2011-06-02 13:56:47 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.core.query;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
 
@@ -24,13 +25,11 @@ public class LikePredicateImpl extends C
 
     public LikePredicateImpl(QueryDomainTypeImpl<?> dobj,
             PropertyImpl property, ParameterImpl param) {
-        super(dobj);
-        this.param = param;
-        this.property = property;
+        super(dobj, property, param);
     }
 
     @Override
-    public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    public void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         // like does not support index bounds
     }
 
@@ -40,7 +39,7 @@ public class LikePredicateImpl extends C
      * @param filter the filter
      */
     @Override
-    public void filterCmpValue(QueryExecutionContextImpl context, ScanOperation op, ScanFilter filter) {
+    public void filterCmpValue(QueryExecutionContext context, ScanOperation op, ScanFilter filter) {
         property.filterCmpValue(param.getParameterValue(context),
                 ScanFilter.BinaryCondition.COND_LIKE, filter);
     }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -18,6 +18,7 @@
 package com.mysql.clusterj.core.query;
 
 import com.mysql.clusterj.ClusterJException;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter.Group;
@@ -42,7 +43,7 @@ public class NotPredicateImpl extends Pr
         // Nothing to do because "not" can't use indexes
     }
 
-    void markBoundsForCandidateIndices(QueryExecutionContextImpl context,
+    void markBoundsForCandidateIndices(QueryExecutionContext context,
             CandidateIndexImpl[] candidateIndices) {
         // Nothing to do because "not" can't use indexes
     }
@@ -52,7 +53,7 @@ public class NotPredicateImpl extends Pr
      * @param context the query execution context with the parameter values
      * @param op the operation
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op) {
         try {
             ScanFilter filter = op.getScanFilter(context);
@@ -73,7 +74,7 @@ public class NotPredicateImpl extends Pr
      * @param op the operation
      * @param filter the existing filter
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op, ScanFilter filter) {
         try {
             filter.begin(Group.GROUP_NAND);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.List;
 
 import com.mysql.clusterj.ClusterJException;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter.Group;
@@ -75,7 +76,7 @@ public class OrPredicateImpl extends Pre
         // Nothing to do because "or" can't use indexes
     }
 
-    void markBoundsForCandidateIndices(QueryExecutionContextImpl context,
+    void markBoundsForCandidateIndices(QueryExecutionContext context,
             CandidateIndexImpl[] candidateIndices) {
         // Nothing to do because "or" can't use indexes
     }
@@ -85,7 +86,7 @@ public class OrPredicateImpl extends Pre
      * @param context the query execution context with the parameter values
      * @param op the operation
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op) {
         try {
             ScanFilter filter = op.getScanFilter(context);
@@ -108,7 +109,7 @@ public class OrPredicateImpl extends Pre
      * @param op the operation
      * @param filter the existing filter
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op, ScanFilter filter) {
         try {
             filter.begin(Group.GROUP_OR);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ParameterImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ParameterImpl.java	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/ParameterImpl.java	2011-06-20 23:34:36 +0000
@@ -18,6 +18,8 @@
 package com.mysql.clusterj.core.query;
 
 
+import com.mysql.clusterj.ClusterJUserException;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
@@ -39,6 +41,9 @@ public class ParameterImpl implements Pr
     /** My domain object. */
     protected QueryDomainTypeImpl<?> dobj;
 
+    /** My property (set when bound) */
+    protected PropertyImpl property;
+
     /** My parameter name */
     protected String parameterName;
 
@@ -57,7 +62,7 @@ public class ParameterImpl implements Pr
         marked = true;
     }
 
-    boolean isMarkedAndUnbound(QueryExecutionContextImpl context) {
+    boolean isMarkedAndUnbound(QueryExecutionContext context) {
         return marked && !context.isBound(parameterName);
     }
 
@@ -69,8 +74,8 @@ public class ParameterImpl implements Pr
         return parameterName;
     }
 
-    public Object getParameterValue(QueryExecutionContextImpl context) {
-        return context.getParameterValue(parameterName);
+    public Object getParameterValue(QueryExecutionContext context) {
+        return property.getParameterValue(context, parameterName);
     }
 
     public Predicate equal(PredicateOperand predicateOperand) {
@@ -113,4 +118,13 @@ public class ParameterImpl implements Pr
                 local.message("ERR_NotImplemented"));
     }
 
+    public void setProperty(PropertyImpl property) {
+        if (this.property != null && this.property.fmd.getType() != property.fmd.getType()) {
+            throw new ClusterJUserException(local.message("ERR_Multiple_Parameter_Usage", parameterName,
+                    this.property.fmd.getType().getName(), property.fmd.getType().getName()));
+        } else {
+            this.property = property;
+        }
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java	2011-06-20 23:34:36 +0000
@@ -22,6 +22,7 @@ import com.mysql.clusterj.ClusterJExcept
 import com.mysql.clusterj.ClusterJFatalInternalException;
 import com.mysql.clusterj.ClusterJUserException;
 
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.Operation;
 import com.mysql.clusterj.core.store.ScanFilter;
@@ -79,42 +80,42 @@ public abstract class PredicateImpl impl
         return new NotPredicateImpl(this);
     }
 
-    void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
+    void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
     }
 
-    public void operationSetBounds(QueryExecutionContextImpl context,
+    public void operationSetBounds(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
     }
 
-    public void operationSetLowerBound(QueryExecutionContextImpl context,
+    public void operationSetLowerBound(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
     }
 
-    public void operationSetUpperBound(QueryExecutionContextImpl context,
+    public void operationSetUpperBound(QueryExecutionContext context,
             IndexScanOperation op, boolean lastColumn){
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
     }
 
-    public void operationEqual(QueryExecutionContextImpl context,
+    public void operationEqual(QueryExecutionContext context,
             Operation op) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
     }
 
-    public void operationEqualFor(QueryExecutionContextImpl context,
+    public void operationEqualFor(QueryExecutionContext context,
             Operation op, String indexName) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
     }
 
-    public void objectSetValuesFor(QueryExecutionContextImpl context,
+    public void objectSetValuesFor(QueryExecutionContext context,
             Object row, String indexName) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
@@ -125,7 +126,7 @@ public abstract class PredicateImpl impl
      * @param context the query execution context with the parameter values
      * @param op the operation
      */
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op) {
         try {
             ScanFilter filter = op.getScanFilter(context);
@@ -140,7 +141,7 @@ public abstract class PredicateImpl impl
         }
     }
 
-    public void filterCmpValue(QueryExecutionContextImpl context,
+    public void filterCmpValue(QueryExecutionContext context,
             ScanOperation op, ScanFilter filter) {
         throw new ClusterJFatalInternalException(
                 local.message("ERR_Implementation_Should_Not_Occur"));
@@ -176,7 +177,7 @@ public abstract class PredicateImpl impl
         return dobj;
     }
 
-    public CandidateIndexImpl getBestCandidateIndex(QueryExecutionContextImpl context) {
+    public CandidateIndexImpl getBestCandidateIndex(QueryExecutionContext context) {
         return getBestCandidateIndexFor(context, this);
     }
 
@@ -185,7 +186,7 @@ public abstract class PredicateImpl impl
      * @param predicates the predicates
      * @return the best index for the query
      */
-    protected CandidateIndexImpl getBestCandidateIndexFor(QueryExecutionContextImpl context,
+    protected CandidateIndexImpl getBestCandidateIndexFor(QueryExecutionContext context,
             PredicateImpl... predicates) {
         // Create CandidateIndexImpl to decide how to scan.
         CandidateIndexImpl[] candidateIndices = dobj.createCandidateIndexes();

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java	2011-06-02 13:56:47 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java	2011-06-20 23:34:36 +0000
@@ -20,6 +20,7 @@ package com.mysql.clusterj.core.query;
 import com.mysql.clusterj.ClusterJUserException;
 
 import com.mysql.clusterj.core.spi.DomainFieldHandler;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.Operation;
 import com.mysql.clusterj.core.store.ScanFilter;
@@ -45,11 +46,18 @@ public class PropertyImpl implements Pre
     /** My property */
     protected DomainFieldHandler fmd;
 
+    /** Is this property used with a complex parameter? */
+    private boolean complexParameter = false;
+
     public PropertyImpl(QueryDomainTypeImpl<?> dobj, DomainFieldHandler fmd) {
         this.dobj = dobj;
         this.fmd = fmd;
     }
 
+    public void setComplexParameter() {
+        complexParameter = true;
+    }
+
     public void operationSetBounds(Object value, IndexScanOperation.BoundType type, IndexScanOperation op) {
         fmd.operationSetBounds(value, type, op);
     }
@@ -150,4 +158,13 @@ public class PropertyImpl implements Pre
         fmd.markInBounds(candidateIndices, predicate);
     }
 
+    public Object getParameterValue(QueryExecutionContext context, String parameterName) {
+        if (complexParameter) {
+            // the parameter is just an object at this point -- to be checked elsewhere
+            return context.getParameterValue(parameterName);
+        } else {
+            return fmd.getValue(context, parameterName);
+        }
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java	2011-05-10 19:33:25 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java	2011-06-20 23:34:36 +0000
@@ -25,6 +25,7 @@ import com.mysql.clusterj.Query;
 import com.mysql.clusterj.core.query.PredicateImpl.ScanType;
 import com.mysql.clusterj.core.spi.DomainFieldHandler;
 import com.mysql.clusterj.core.spi.DomainTypeHandler;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.spi.SessionSPI;
 import com.mysql.clusterj.core.spi.ValueHandler;
 
@@ -143,7 +144,7 @@ public class QueryDomainTypeImpl<T> impl
      * 
      * @return the results of executing the query
      */
-    public List<T> getResultList(QueryExecutionContextImpl context) {
+    public List<T> getResultList(QueryExecutionContext context) {
         assertAllParametersBound(context);
 
         SessionSPI session = context.getSession();
@@ -181,7 +182,7 @@ public class QueryDomainTypeImpl<T> impl
      * @return the raw result data from the query
      * @throws ClusterJUserException if not all parameters are bound
      */
-    public ResultData getResultData(QueryExecutionContextImpl context) {
+    public ResultData getResultData(QueryExecutionContext context) {
 	SessionSPI session = context.getSession();
         // execute query based on what kind of scan is needed
         // if no where clause, scan the entire table
@@ -279,7 +280,7 @@ public class QueryDomainTypeImpl<T> impl
      * @return the number of instances deleted
      * @throws ClusterJUserException if not all parameters are bound
      */
-    public int deletePersistentAll(QueryExecutionContextImpl context) {
+    public int deletePersistentAll(QueryExecutionContext context) {
                                 SessionSPI session = context.getSession();
         // calculate what kind of scan is needed
         // if no where clause, scan the entire table
@@ -386,7 +387,7 @@ public class QueryDomainTypeImpl<T> impl
      * 
      * @param context the context, including bound parameters
      */
-    public void explain(QueryExecutionContextImpl context) {
+    public void explain(QueryExecutionContext context) {
         assertAllParametersBound(context);
         CandidateIndexImpl index = where==null?
                 CandidateIndexImpl.getIndexForNullWhereClause():
@@ -413,7 +414,7 @@ public class QueryDomainTypeImpl<T> impl
      * @param context the context, including the parameter map
      * @throws ClusterJUserException if not all parameters are bound
      */
-    protected void assertAllParametersBound(QueryExecutionContextImpl context) {
+    protected void assertAllParametersBound(QueryExecutionContext context) {
         if (where != null) {
             // Make sure all marked parameters (used in the query) are bound.
             for (ParameterImpl param: parameters.values()) {

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java	2011-06-20 23:34:36 +0000
@@ -19,6 +19,7 @@ package com.mysql.clusterj.core.query;
 
 import com.mysql.clusterj.ClusterJFatalInternalException;
 import com.mysql.clusterj.ClusterJUserException;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.spi.SessionSPI;
 import com.mysql.clusterj.core.store.ResultData;
 import com.mysql.clusterj.core.store.ScanFilter;
@@ -27,6 +28,11 @@ import com.mysql.clusterj.core.util.Logg
 import com.mysql.clusterj.core.util.LoggerFactoryService;
 import com.mysql.clusterj.query.QueryDomainType;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -36,7 +42,7 @@ import java.util.Map;
  * parameter bindings so as to make query execution thread-safe.
  *
  */
-public class QueryExecutionContextImpl {
+public class QueryExecutionContextImpl implements QueryExecutionContext {
 
     /** My message translator */
     static final I18NHelper local = I18NHelper.getInstance(BetweenPredicateImpl.class);
@@ -112,7 +118,7 @@ public class QueryExecutionContextImpl {
      * @param parameterName the name of the parameter
      * @return whether the parameter has a value
      */
-    boolean isBound(String parameterName) {
+    public boolean isBound(String parameterName) {
         return boundParameters.containsKey(parameterName);
     }
 
@@ -148,4 +154,188 @@ public class QueryExecutionContextImpl {
         return explain;
     }
 
+    public Byte getByte(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Byte) {
+            return (Byte)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Byte"));
+        }
+    }
+
+    public BigDecimal getBigDecimal(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof BigDecimal) {
+            return (BigDecimal)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "BigDecimal"));
+        }
+    }
+
+    public BigInteger getBigInteger(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof BigInteger) {
+            return (BigInteger)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "BigInteger"));
+        }
+    }
+
+    public Boolean getBoolean(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Boolean) {
+            return (Boolean)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Boolean"));
+        }
+    }
+
+    public byte[] getBytes(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof byte[]) {
+            return (byte[])result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "byte[]"));
+        }
+    }
+
+    public Double getDouble(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Double) {
+            return (Double)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Double"));
+        }
+    }
+
+    public Float getFloat(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Float) {
+            return (Float)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Float"));
+        }
+    }
+
+    public Integer getInt(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Integer) {
+            return (Integer)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Integer"));
+        }
+    }
+
+    public Date getJavaSqlDate(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof java.sql.Date) {
+            return (java.sql.Date)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "java.sql.Date"));
+        }
+    }
+
+    public Time getJavaSqlTime(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof java.sql.Time) {
+            return (java.sql.Time)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "java.sql.Time"));
+        }
+    }
+
+    public Timestamp getJavaSqlTimestamp(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof java.sql.Timestamp) {
+            return (java.sql.Timestamp)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "java.sql.Timestamp"));
+        }
+    }
+
+    public java.util.Date getJavaUtilDate(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof java.util.Date) {
+            return (java.util.Date)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "java.util.Date"));
+        }
+    }
+
+    public Long getLong(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Long) {
+            return (Long)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Long"));
+        }
+    }
+
+    public Short getShort(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof Short) {
+            return (Short)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "Short"));
+        }
+    }
+
+    public String getString(String index) {
+        Object result = boundParameters.get(index);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof String) {
+            return (String)result;
+        } else {
+            throw new ClusterJUserException(local.message("ERR_Parameter_Wrong_Type", index, result.getClass(), "String"));
+        }
+    }
+
+    public Object getObject(String index) {
+        return boundParameters.get(index);
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/DomainFieldHandler.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/DomainFieldHandler.java	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/DomainFieldHandler.java	2011-06-20 23:34:36 +0000
@@ -76,4 +76,6 @@ public interface DomainFieldHandler {
 
     boolean isPrimaryKey();
 
+    Object getValue(QueryExecutionContext context, String parameterName);
+
 }

=== added file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/QueryExecutionContext.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/QueryExecutionContext.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/spi/QueryExecutionContext.java	2011-06-20 23:34:36 +0000
@@ -0,0 +1,55 @@
+package com.mysql.clusterj.core.spi;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Map;
+
+import com.mysql.clusterj.core.store.ScanFilter;
+
+public interface QueryExecutionContext {
+
+    Object getByte(String index);
+
+    Boolean getBoolean(String index);
+
+    byte[] getBytes(String index);
+
+    String getString(String index);
+
+    BigDecimal getBigDecimal(String index);
+
+    BigInteger getBigInteger(String index);
+
+    Double getDouble(String index);
+
+    Float getFloat(String index);
+
+    Integer getInt(String index);
+
+    java.sql.Date getJavaSqlDate(String index);
+
+    java.sql.Time getJavaSqlTime(String index);
+
+    java.sql.Timestamp getJavaSqlTimestamp(String index);
+
+    java.util.Date getJavaUtilDate(String index);
+
+    Long getLong(String index);
+
+    Short getShort(String index);
+
+    Object getObject(String index);
+
+    SessionSPI getSession();
+
+    void setExplain(Map<String, Object> explain);
+
+    Object getParameterValue(String parameterName);
+
+    boolean isBound(String parameterName);
+
+    void addFilter(ScanFilter scanFilter);
+
+    void deleteFilters();
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java	2011-06-20 23:34:36 +0000
@@ -17,7 +17,7 @@
 
 package com.mysql.clusterj.core.store;
 
-import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 
 /**
  *
@@ -28,7 +28,7 @@ public interface ScanOperation extends O
 
     public void deleteCurrentTuple();
 
-    public ScanFilter getScanFilter(QueryExecutionContextImpl context);
+    public ScanFilter getScanFilter(QueryExecutionContext context);
 
     public int nextResult(boolean fetch);
 

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties'
--- a/storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties	2011-03-22 01:48:09 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties	2011-06-20 23:34:36 +0000
@@ -106,6 +106,8 @@ NullValue.EXCEPTION and the value of the
 ERR_Convert_String_To_Value:Don't know how to convert {0} to {1}. \
 If you have any ideas, please file an issue.
 ERR_Parameter_Type:The parameter must be of type {0} but is of type {1}.
+ERR_Multiple_Parameter_Usage:Parameters can only be used in multiple places \
+if they have the same type in each place. The parameter {0} has different types ({1} and {2}).
 ERR_Get_Ndb_Index:Error getting NdbIndex for table: {0}, index: {1}.
 ERR_No_Object_Found:No object found from class {0} with key {1}.
 ERR_Invalid_Index_For_Type:For class {0}, field {1}, column {2}, index {3}, type {4}: \

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/Makefile.am'
--- a/storage/ndb/clusterj/clusterj-jdbc/Makefile.am	2011-05-16 22:32:56 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/Makefile.am	2011-06-20 23:34:36 +0000
@@ -38,6 +38,7 @@ clusterj_jdbc_java = \
   $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/DomainFieldHandlerImpl.java \
   $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/DomainTypeHandlerImpl.java \
   $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/InterceptorImpl.java \
+  $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/QueryExecutionContextJDBCImpl.java \
   $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/ResultSetInternalMethodsImpl.java \
   $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/ResultSetInternalMethodsUpdateCount.java \
   $(clusterj_jdbc_src)/com/mysql/clusterj/jdbc/SQLExecutor.java \

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/AbstractResultSetInternalMethods.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/AbstractResultSetInternalMethods.java	2011-04-02 00:30:23 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/AbstractResultSetInternalMethods.java	2011-06-20 23:34:36 +0000
@@ -176,7 +176,6 @@ public abstract class AbstractResultSetI
     }
 
     public void close() throws SQLException {
-        throw new SQLException(local.message("ERR_Should_Not_Occur"));
     }
 
     public void deleteRow() throws SQLException {

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/InterceptorImpl.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/InterceptorImpl.java	2011-05-16 22:32:56 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/InterceptorImpl.java	2011-06-20 23:34:36 +0000
@@ -108,6 +108,8 @@ public class InterceptorImpl {
 
     private boolean autocommit;
 
+    private static String LOTSOBLANKS = "                                                                          "; 
+
     /** Create the interceptor.
      * 
      * @param connection the connection being intercepted
@@ -219,7 +221,7 @@ public class InterceptorImpl {
         }
     }
 
-    SessionSPI getSession() {
+    public SessionSPI getSession() {
         if (session == null) {
             session = (SessionSPI)sessionFactory.getSession();
         }
@@ -262,8 +264,7 @@ public class InterceptorImpl {
                     }
                 }
             }
-            SessionSPI session = getSession();
-            return sQLExecutor.execute(session, preparedStatement.getParameterBindings());
+            return sQLExecutor.execute(this, preparedStatement.getParameterBindings());
         }
         return null;
     }
@@ -272,6 +273,7 @@ public class InterceptorImpl {
      * @param preparedSql
      */
     private Executor createSQLExecutor(String preparedSql) {
+        if (logger.isDetailEnabled()) logger.detail(preparedSql);
         Executor result = null;
         // parse the sql
         CommonTree root = parse(preparedSql);
@@ -310,8 +312,17 @@ public class InterceptorImpl {
                     result = new SQLExecutor.Noop();
                     break;
                 }
-                tableNode = (CommonTree) fromNode.getFirstChildWithType(MySQL51Parser.TABLE);
-                tableName = getTableName(tableNode);
+                try {
+                    // this currently handles only FROM clauses with a single table
+                    tableNode = (CommonTree) fromNode.getFirstChildWithType(MySQL51Parser.TABLE);
+                    tableName = getTableName(tableNode);
+                } catch (Exception e) {
+                    // trouble with the FROM clause; log the SQL statement and the parser output
+                    logger.info("Problem with FROM clause in SQL statement: " + preparedSql);
+                    logger.info(walk(root));
+                    result = new SQLExecutor.Noop();
+                    break;
+                }
                 getSession();
                 dictionary = session.getDictionary();
                 domainTypeHandler = getDomainTypeHandler(tableName, dictionary);
@@ -346,11 +357,14 @@ public class InterceptorImpl {
                         result = new SQLExecutor.Noop();
                         whereType = "non-clusterj";
                     }
-                    walk(root);
+                    if (logger.isDetailEnabled()) logger.detail(walk(root));
                 }
-                if (logger.isDetailEnabled()) logger.detail(
+                if (logger.isDetailEnabled()) {
+                    logger.detail(
                         "SELECT FROM " + tableName
                         + " COLUMNS " + columnNames + " whereType " + whereType);
+                    logger.detail(walk(root));
+                }
                 break;
             case MySQL51Parser.DELETE:
                 tableNode = (CommonTree)root.getFirstChildWithType(MySQL51Parser.TABLE);
@@ -379,7 +393,7 @@ public class InterceptorImpl {
                         result = new SQLExecutor.Noop();
                         whereType = "non-clusterj";
                     }
-                    walk(root);
+                    if (logger.isDetailEnabled()) logger.detail(walk(root));
                 }
                 if (logger.isDetailEnabled()) logger.detail(
                         "DELETE FROM " + tableName
@@ -388,6 +402,7 @@ public class InterceptorImpl {
                 break;
             default:
                 // return a do-nothing ParsedSQL
+                if (logger.isDetailEnabled()) logger.detail("ClusterJ cannot process this SQL statement: unsupported statement type.");
                 result = new SQLExecutor.Noop();
         }
         return result;
@@ -404,26 +419,38 @@ public class InterceptorImpl {
         return result;
     }
 
+    private String walk(CommonTree tree) {
+        StringBuilder buffer = new StringBuilder();
+        walk(tree, buffer, 0);
+        return buffer.toString();
+    }
+
     @SuppressWarnings("unchecked") // tree.getChildren()
-    private void walk(CommonTree tree) {
-        if (logger.isDetailEnabled()) {
+    private void walk(CommonTree tree, StringBuilder buffer, int level) {
+            String indent = LOTSOBLANKS.substring(0, level);
             Token token = tree.token;
             int tokenType = token.getType();
             String tokenText = token.getText();
             int childCount = tree.getChildCount();
             int childIndex = tree.getChildIndex();
-            logger.detail("StatementInterceptorImpl.walk"
-                    + " class: " + tree.getClass().getName()
-                    + " tokenText: " + tokenText + " tokenType " + tokenType
-                    + " child count " + childCount + " child index " + childIndex);
+            buffer.append('\n');
+            buffer.append(indent);
+            buffer.append(tokenText);
+            buffer.append(" class: ");
+            buffer.append(tree.getClass().getName());
+            buffer.append(" tokenType ");
+            buffer.append(tokenType);
+            buffer.append(" child count ");
+            buffer.append(childCount);
+            buffer.append(" child index ");
+            buffer.append(childIndex);
             List<CommonTree> children = tree.getChildren();
             if (children == null) {
                 return;
             }
             for (CommonTree child: children) {
-                walk(child);
+                walk(child, buffer, level + 2);
             }
-        }
     }
 
     private CommonTree parse(String preparedSql) {
@@ -498,16 +525,19 @@ public class InterceptorImpl {
     /** TODO This needs to be rewritten with a proper state machine. */
     public boolean setAutoCommit(boolean autocommit) throws SQLException {
         assertReady();
-        this.autocommit = autocommit;
         logStatus("setAutoCommit(" + autocommit + ")");
+        this.autocommit = autocommit;
+        getSession();
         if (!autocommit) {
             // start a transaction
-            getSession();
             if (!session.currentTransaction().isActive()) {
                 session.begin();
             }
         } else {
             // roll back the previous transaction if active
+            if (session.currentTransaction().isActive()) {
+                session.rollback();
+            }
         }
         return true; // let the driver perform its own autocommit behavior
     }

=== added file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/QueryExecutionContextJDBCImpl.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/QueryExecutionContextJDBCImpl.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/QueryExecutionContextJDBCImpl.java	2011-06-20 23:34:36 +0000
@@ -0,0 +1,233 @@
+/*
+ *  Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+package com.mysql.clusterj.jdbc;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+
+import com.mysql.clusterj.ClusterJUserException;
+import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
+import com.mysql.clusterj.core.spi.SessionSPI;
+import com.mysql.clusterj.core.util.I18NHelper;
+import com.mysql.clusterj.core.util.Logger;
+import com.mysql.clusterj.core.util.LoggerFactoryService;
+import com.mysql.jdbc.ParameterBindings;
+
+/** This class handles retrieving parameter values from the parameterBindings
+ * associated with a PreparedStatement.
+ */
+public class QueryExecutionContextJDBCImpl extends QueryExecutionContextImpl {
+
+    /** My message translator */
+    static final I18NHelper local = I18NHelper.getInstance(QueryExecutionContextJDBCImpl.class);
+
+    /** My logger */
+    static final Logger logger = LoggerFactoryService.getFactory().getInstance(QueryExecutionContextJDBCImpl.class);
+
+    /** The wrapped ParameterBindings */
+    ParameterBindings parameterBindings;
+
+    /** The current offset */
+    int offset = 0;
+
+    /** The number of parameters */
+    int numberOfParameters;
+
+    /** Create a new execution context with parameter bindings.
+     * @param parameterBindings the jdbc parameter bindings for the statement
+     * @param session the session for this context
+     * @param numberOfParameters the number of parameters per statement
+     */
+    public QueryExecutionContextJDBCImpl(SessionSPI session,
+            ParameterBindings parameterBindings, int numberOfParameters) {
+        super(session);
+        this.parameterBindings = parameterBindings;
+        this.numberOfParameters = numberOfParameters;
+    }
+
+    /** Advance to the next statement (and next number of affected rows).
+     */
+    public void nextStatement() {
+        offset += numberOfParameters;
+    }
+
+    public Byte getByte(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Byte result = parameterBindings.getByte(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public BigDecimal getBigDecimal(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            BigDecimal result = parameterBindings.getBigDecimal(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public BigInteger getBigInteger(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            BigInteger result = parameterBindings.getBigDecimal(parameterIndex).toBigInteger();
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Boolean getBoolean(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Boolean result = parameterBindings.getBoolean(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public byte[] getBytes(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            byte[] result = parameterBindings.getBytes(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Double getDouble(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Double result = parameterBindings.getDouble(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Float getFloat(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Float result = parameterBindings.getFloat(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Integer getInt(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Integer result = parameterBindings.getInt(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Date getJavaSqlDate(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            java.sql.Date result = parameterBindings.getDate(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Time getJavaSqlTime(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Time result = parameterBindings.getTime(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Timestamp getJavaSqlTimestamp(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            java.sql.Timestamp result = parameterBindings.getTimestamp(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public java.util.Date getJavaUtilDate(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            java.util.Date result = parameterBindings.getDate(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Long getLong(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Long result = parameterBindings.getLong(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Short getShort(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Short result = parameterBindings.getShort(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public String getString(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            String result = parameterBindings.getString(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+    public Object getObject(String index) {
+        try {
+            int parameterIndex = Integer.valueOf(index) + offset;
+            Object result = parameterBindings.getObject(parameterIndex);
+            return result;
+        } catch (SQLException ex) {
+                throw new ClusterJUserException(local.message("ERR_Getting_Parameter_Value", offset, index), ex);
+        }
+    }
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsImpl.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsImpl.java	2011-02-21 11:53:51 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsImpl.java	2011-06-20 23:34:36 +0000
@@ -54,6 +54,8 @@ public class ResultSetInternalMethodsImp
 
     private Map<String, Integer> columnNameToFieldNumberMap = new HashMap<String, Integer>();
 
+    private boolean autotransaction = true;
+
     public ResultSetInternalMethodsImpl(ResultData resultData, int[] columnIndexToFieldNumberMap, 
             Map<String, Integer> columnNameToFieldNumberMap, SessionSPI session) {
         this.columnIndexToFieldNumberMap = columnIndexToFieldNumberMap;
@@ -70,8 +72,11 @@ public class ResultSetInternalMethodsImp
     @Override
     public boolean next() {
         boolean hasNext = resultData.next();
-        if (!hasNext) {
+        // startAutoTransaction was called in SQLExecutor.Select.execute and 
+        // endAutoTransaction must be called exactly once after all results have been read
+        if (autotransaction & !hasNext) {
             session.endAutoTransaction();
+            autotransaction = false;
         }
         if (logger.isDetailEnabled()) logger.detail("ResultSetInternalMethods.next returned: " + hasNext);
         return hasNext;
@@ -264,6 +269,11 @@ public class ResultSetInternalMethodsImp
 
     @Override
     public void realClose(boolean arg0) throws SQLException {
+        // if next() was never called to end the autotransaction, do so now
+        if (autotransaction) {
+            session.endAutoTransaction();
+            autotransaction = false;
+        }
     }
 
     private int getFieldNumberForColumnName(String columnName) throws SQLException {

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsUpdateCount.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsUpdateCount.java	2011-04-02 00:30:23 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ResultSetInternalMethodsUpdateCount.java	2011-06-20 23:34:36 +0000
@@ -22,6 +22,7 @@ import java.sql.SQLException;
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
+import com.mysql.jdbc.ResultSetInternalMethods;
 
 /** This class is part of the statement interceptor contract with the MySQL JDBC connection.
  * When a statement is intercepted and executed, an instance of this class is returned if there
@@ -38,19 +39,55 @@ public class ResultSetInternalMethodsUpd
     /** My logger */
     static final Logger logger = LoggerFactoryService.getFactory().getInstance(ResultSetInternalMethodsUpdateCount.class);
 
-    private long count;
+    /** Counts for multi-statement result */
+    private long[] counts;
+
+    /** The current result set for multi-statement results */
+    private int current = 0;
 
     /** Construct an instance with the count to be returned.
      * 
      * @param count the number of "rows affected"
      */
     public ResultSetInternalMethodsUpdateCount(long count) {
-        this.count = count;
+        this.counts = new long[1];
+        this.counts[0] = count;
+    }
+
+    /** Construct an instance with the count to be returned.
+     * 
+     * @param counts the number of "rows affected" for each row of a multi-statement result
+     */
+    public ResultSetInternalMethodsUpdateCount(long[] counts) {
+        this.counts = counts;
+    }
+
+    /**
+     * Returns the next ResultSet in a multi-resultset "chain", if any, 
+     * null if none exists.
+     * @return the next ResultSet
+     */
+    @Override
+    public ResultSetInternalMethods getNextResultSet() {
+        if (++current >= counts.length) {
+            return null;
+        } else {
+            return this;
+        }
+    }
+
+    /**
+     * Clears the reference to the next result set in a multi-result set
+     * "chain".
+     */
+    @Override
+    public void clearNextResult() {
+        // nothing to do
     }
 
     @Override
     public long getUpdateCount() {
-        return count;
+        return counts[current];
     }
 
     @Override

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/SQLExecutor.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/SQLExecutor.java	2011-05-16 22:32:56 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/SQLExecutor.java	2011-06-20 23:34:36 +0000
@@ -22,6 +22,7 @@ import com.mysql.clusterj.ClusterJUserEx
 import com.mysql.clusterj.core.query.QueryDomainTypeImpl;
 import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
 import com.mysql.clusterj.core.spi.DomainTypeHandler;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.spi.SessionSPI;
 import com.mysql.clusterj.core.spi.ValueHandler;
 import com.mysql.clusterj.core.store.ResultData;
@@ -72,6 +73,11 @@ public class SQLExecutor {
     /** The query domain type for qualified SELECT and DELETE operations */
     protected QueryDomainTypeImpl<?> queryDomainType;
 
+    public SQLExecutor(DomainTypeHandlerImpl<?> domainTypeHandler, List<String> columnNames, int numberOfParameters) {
+        this(domainTypeHandler, columnNames);
+        this.numberOfParameters = numberOfParameters;
+    }
+
     public SQLExecutor(DomainTypeHandlerImpl<?> domainTypeHandler, List<String> columnNames) {
         this.domainTypeHandler = domainTypeHandler;
         this.columnNames  = columnNames;
@@ -108,7 +114,7 @@ public class SQLExecutor {
          * @return the result of executing the statement, or null
          * @throws SQLException
          */
-        ResultSetInternalMethods execute(SessionSPI session,
+        ResultSetInternalMethods execute(InterceptorImpl interceptor,
                 ParameterBindings parameterBindings) throws SQLException;
     }
 
@@ -117,7 +123,7 @@ public class SQLExecutor {
      */
     public static class Noop implements Executor {
 
-        public ResultSetInternalMethods execute(SessionSPI session,
+        public ResultSetInternalMethods execute(InterceptorImpl interceptor,
                 ParameterBindings parameterBindings) throws SQLException {
             return null;
         }
@@ -134,18 +140,18 @@ public class SQLExecutor {
             }
         }
 
-        public ResultSetInternalMethods execute(SessionSPI session,
+        public ResultSetInternalMethods execute(InterceptorImpl interceptor,
                 ParameterBindings parameterBindings) throws SQLException {
-            logParameterBindings(parameterBindings);
             // create value handler to copy data from parameters to ndb
             // count the parameters
             int count = countParameters(parameterBindings);
+            SessionSPI session = interceptor.getSession();
             Map<String, Object> parameters = createParameterMap(queryDomainType, parameterBindings, 0, count);
-            QueryExecutionContextImpl context = new QueryExecutionContextImpl(session, parameters);
+            QueryExecutionContext context = new QueryExecutionContextImpl(session, parameters);
             session.startAutoTransaction();
             try {
                 ResultData resultData = queryDomainType.getResultData(context);
-                session.endAutoTransaction();
+                // session.endAutoTransaction();
                 return new ResultSetInternalMethodsImpl(resultData, columnNumberToFieldNumberMap, 
                         columnNameToFieldNumberMap, session);
             } catch (Exception e) {
@@ -169,33 +175,33 @@ public class SQLExecutor {
             super(domainTypeHandler);
         }
 
-        public ResultSetInternalMethods execute(SessionSPI session,
+        public ResultSetInternalMethods execute(InterceptorImpl interceptor,
                 ParameterBindings parameterBindings) throws SQLException {
+            SessionSPI session = interceptor.getSession();
             if (queryDomainType == null) {
                 int rowsDeleted = session.deletePersistentAll(domainTypeHandler);
+                if (logger.isDebugEnabled()) logger.debug("deleteAll deleted: " + rowsDeleted);
                 return new ResultSetInternalMethodsUpdateCount(rowsDeleted);
             } else {
-                int totalRowsDeleted = 0;
                 int numberOfBoundParameters = countParameters(parameterBindings);
                 int numberOfStatements = numberOfBoundParameters / numberOfParameters;
-                int offset = 0;
+                long[] deleteResults = new long[numberOfStatements];
                 if (logger.isDebugEnabled()) logger.debug(
                         " numberOfParameters: " + numberOfParameters
                         + " numberOfBoundParameters: " + numberOfBoundParameters
                         + " numberOfStatements: " + numberOfStatements
                         );
+                QueryExecutionContextJDBCImpl context = 
+                    new QueryExecutionContextJDBCImpl(session, parameterBindings, numberOfParameters);
                 for (int i = 0; i < numberOfStatements; ++i) {
                     // this will execute each statement in the batch using different parameters
-                    Map<String, Object> parameters = createParameterMap(queryDomainType, parameterBindings,
-                            offset, numberOfParameters);
-                    offset += numberOfParameters;
-                    QueryExecutionContextImpl context = new QueryExecutionContextImpl(session, parameters);
                     int statementRowsDeleted = queryDomainType.deletePersistentAll(context);
-                    totalRowsDeleted += statementRowsDeleted;
                     if (logger.isDebugEnabled()) logger.debug("statement " + i
                             + " deleted " + statementRowsDeleted);
+                    deleteResults[i] = statementRowsDeleted;
+                    context.nextStatement();
                 }
-                return new ResultSetInternalMethodsUpdateCount(totalRowsDeleted);
+                return new ResultSetInternalMethodsUpdateCount(deleteResults);
             }
         }
     }
@@ -205,24 +211,24 @@ public class SQLExecutor {
     public static class Insert extends SQLExecutor implements Executor {
 
         public Insert(DomainTypeHandlerImpl<?> domainTypeHandler, List<String> columnNames) {
-            super(domainTypeHandler, columnNames);
+            super(domainTypeHandler, columnNames, columnNames.size());
         }
 
-        public ResultSetInternalMethods execute(SessionSPI session,
+        public ResultSetInternalMethods execute(InterceptorImpl interceptor,
                 ParameterBindings parameterBindings) throws SQLException {
-            int numberOfParameters = countParameters(parameterBindings);
-            int numberOfStatements = numberOfParameters / numberOfFields;
+            SessionSPI session = interceptor.getSession();
+            int numberOfBoundParameters = countParameters(parameterBindings);
+            int numberOfStatements = numberOfBoundParameters / numberOfParameters;
             if (logger.isDebugEnabled()) logger.debug("SQLExecutor.Insert.execute"
                     + " numberOfParameters: " + numberOfParameters
+                    + " numberOfBoundParameters: " + numberOfBoundParameters
                     + " numberOfFields: " + numberOfFields
                     + " numberOfStatements: " + numberOfStatements
                     );
             // interceptor.beforeClusterjStart();
             // session asks for values by field number which are converted to parameter number
-            int offset = 0;
-            for (int i = 0; i < numberOfParameters; i += numberOfFields) {
+            for (int offset = 0; offset < numberOfBoundParameters; offset += numberOfParameters) {
                 ValueHandler valueHandler = getValueHandler(parameterBindings, fieldNumberToColumnNumberMap, offset);
-                offset += numberOfFields;
                 session.insert(domainTypeHandler, valueHandler);
             }
             session.flush();
@@ -249,7 +255,8 @@ public class SQLExecutor {
         int last = offset + count + 1;
         for (int i = first; i < last; ++i) {
             Object placeholder = parameterBindings.getObject(i);
-            if (logger.isDetailEnabled()) logger.detail("Put placeholder " + i + " value: " + placeholder);
+            if (logger.isDetailEnabled())
+                logger.detail("Put placeholder " + i + " value: " + placeholder + " of type " + placeholder.getClass());
             result.put(String.valueOf(i), placeholder);
         }
         return result;
@@ -293,6 +300,20 @@ public class SQLExecutor {
                         domainTypeHandler.getTableName()));
             }
         }
+        if (logger.isDetailEnabled()) {
+            StringBuilder buffer = new StringBuilder();
+            for (int i = 0; i < fieldNumberToColumnNumberMap.length; ++i) {
+                int columnNumber = fieldNumberToColumnNumberMap[i];
+                buffer.append("field ");
+                buffer.append(i);
+                buffer.append(" mapped to ");
+                buffer.append(columnNumber);
+                buffer.append("[");
+                buffer.append(columnNumber == -1?"nothing":(columnNames.get(columnNumber - 1)));
+                buffer.append("];");
+            }
+            logger.detail(buffer.toString());
+        }
     }
 
     /** Create a value handler (part of the clusterj spi) to retrieve values from jdbc parameter bindings.
@@ -339,8 +360,9 @@ public class SQLExecutor {
                 // parameters are 1-origin per jdbc specification
                 Object objectValue = parameterBindings.getObject(i);
                 if (logger.isDetailEnabled()) {
-                    String stringValue = objectValue.toString();
-                    logger.detail("parameterBinding: parameter " + i + " has value: " + stringValue);
+                    logger.detail("parameterBinding: parameter " + i
+                            + " has value: " + objectValue
+                            + " of type " + objectValue.getClass());
                 }
             } catch (Exception e) {
                 // we don't know how many parameters are bound...

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerImpl.java	2011-04-02 00:30:23 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerImpl.java	2011-06-20 23:34:36 +0000
@@ -235,7 +235,7 @@ public class ValueHandlerImpl implements
     }
 
     public boolean isModified(int fieldNumber) {
-        throw new ClusterJFatalInternalException(local.message("ERR_Should_Not_Occur"));
+        return fieldNumberMap[fieldNumber] != -1;
     }
 
     public boolean isNull(int fieldNumber) {

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/main/resources/com/mysql/clusterj/jdbc/Bundle.properties'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/main/resources/com/mysql/clusterj/jdbc/Bundle.properties	2011-05-16 22:32:56 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/main/resources/com/mysql/clusterj/jdbc/Bundle.properties	2011-06-20 23:34:36 +0000
@@ -12,3 +12,4 @@ ERR_Parsing_SQL:Error Parsing SQL: {0}.
 ERR_LHS_Not_A_Field:Restriction: left hand side of an arithmetic expression must be a field.
 ERR_RHS_Not_A_Parameter:Restriction: right hand side of an arithmetic expression must be a parameter.
 ERR_Number_Of_Parameters_Not_Initialized: The number of parameters was not initialized.
+ERR_Getting_Parameter_Value:Exception getting parameter value for offset {0} index {1}.

=== added file 'storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/BatchDeleteQueryAllPrimitivesTest.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/BatchDeleteQueryAllPrimitivesTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/BatchDeleteQueryAllPrimitivesTest.java	2011-06-20 23:34:36 +0000
@@ -0,0 +1,112 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+package jdbctest;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class BatchDeleteQueryAllPrimitivesTest extends JDBCQueryTest {
+
+    /** Test delete queries using AllPrimitives.
+drop table if exists allprimitives;
+create table allprimitives (
+ id int not null primary key,
+
+ int_not_null_hash int not null,
+ int_not_null_btree int not null,
+ int_not_null_both int not null,
+ int_not_null_none int not null,
+ int_null_hash int,
+ int_null_btree int,
+ int_null_both int,
+ int_null_none int,
+
+ byte_not_null_hash tinyint not null,
+ byte_not_null_btree tinyint not null,
+ byte_not_null_both tinyint not null,
+ byte_not_null_none tinyint not null,
+ byte_null_hash tinyint,
+ byte_null_btree tinyint,
+ byte_null_both tinyint,
+ byte_null_none tinyint,
+
+ short_not_null_hash smallint not null,
+ short_not_null_btree smallint not null,
+ short_not_null_both smallint not null,
+ short_not_null_none smallint not null,
+ short_null_hash smallint,
+ short_null_btree smallint,
+ short_null_both smallint,
+ short_null_none smallint,
+
+ long_not_null_hash bigint not null,
+ long_not_null_btree bigint not null,
+ long_not_null_both bigint not null,
+ long_not_null_none bigint not null,
+ long_null_hash bigint,
+ long_null_btree bigint,
+ long_null_both bigint,
+ long_null_none bigint
+     */
+
+    @Override
+    public String tableName() {
+        return "allprimitives";
+    }
+
+    @Override
+    public void createInstances(int numberOfInstances) {
+        for (int i = 0; i < numberOfInstances; ++i) {
+            createAllPrimitiveInstance(i);
+        }
+    }
+
+    public void testDeleteEqualByPrimaryKey() {
+        deleteEqualQuery("id", "PRIMARY", 5, 1);
+        deleteEqualQuery("id", "PRIMARY", 5, 0);
+        try {
+            connection.setAutoCommit(false);
+            PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM allprimitives where id = ?");
+            // delete 4 through 9 (excluding 5 which is already gone)
+            for (int i = 4; i < 9; ++i) {
+                preparedStatement.setInt(1, i);
+                preparedStatement.addBatch();
+            }
+            int[] results = preparedStatement.executeBatch();
+            connection.commit();
+            for (int i = 0; i < 5; ++i) {
+                int expected = (i == 1) ? 0:1;
+                errorIfNotEqual("testDeleteEqualByPrimaryKey result " + i, expected, results[i]);
+            }
+        } catch (SQLException e) {
+            error(e.getMessage());
+        }
+        equalQuery("id", "PRIMARY", 0, 0);
+        equalQuery("id", "PRIMARY", 1, 1);
+        equalQuery("id", "PRIMARY", 2, 2);
+        equalQuery("id", "PRIMARY", 3, 3);
+        equalQuery("id", "PRIMARY", 4);
+        equalQuery("id", "PRIMARY", 5);
+        equalQuery("id", "PRIMARY", 6);
+        equalQuery("id", "PRIMARY", 7);
+        equalQuery("id", "PRIMARY", 8);
+        equalQuery("id", "PRIMARY", 9, 9);
+        failOnError();
+    }
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/JDBCQueryTest.java'
--- a/storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/JDBCQueryTest.java	2011-05-16 22:32:56 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/JDBCQueryTest.java	2011-06-20 23:34:36 +0000
@@ -17,6 +17,7 @@ public abstract class JDBCQueryTest exte
     @Override
     public void localSetUp() {
         // initialize the jdbc driver
+        super.localSetUp();
         // delete instances
         deleteAll();
         // create instances

=== 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-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java	2011-06-20 23:34:36 +0000
@@ -24,6 +24,7 @@ import com.mysql.clusterj.ClusterJUserEx
 import com.mysql.clusterj.core.metadata.AbstractDomainFieldHandlerImpl;
 import com.mysql.clusterj.core.query.QueryDomainTypeImpl;
 import com.mysql.clusterj.core.spi.DomainTypeHandler;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.spi.SessionSPI;
 import com.mysql.clusterj.core.spi.ValueHandler;
 import com.mysql.clusterj.core.store.IndexScanOperation;
@@ -930,6 +931,9 @@ public class NdbOpenJPADomainFieldHandle
                     local.message("ERR_Operation_Not_Supported","partitionKeySetPart", "non-key fields"));
         }
 
+        public Object getValue(QueryExecutionContext context, String index) {
+            return context.getObject(index);
+        }
     };
 
     static ObjectOperationHandler objectOperationHandlerRelationIntField =

=== modified file 'storage/ndb/clusterj/clusterj-test/Makefile.am'
--- a/storage/ndb/clusterj/clusterj-test/Makefile.am	2011-06-02 13:56:47 +0000
+++ b/storage/ndb/clusterj/clusterj-test/Makefile.am	2011-06-20 23:34:36 +0000
@@ -92,6 +92,7 @@ clusterj_test_java = \
   $(clusterj_test_src)/testsuite/clusterj/QueryLikeTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryLikeByteArrayTypesTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryMultiColumnIndexInTest.java \
+  $(clusterj_test_src)/testsuite/clusterj/QueryMultipleParameterTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryNotNullTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryNotTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryNullTest.java \

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryAllPrimitivesTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryAllPrimitivesTest.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryAllPrimitivesTest.java	2011-06-20 23:34:36 +0000
@@ -196,291 +196,291 @@ create table allprimitives (
     }
 
     public void btreeIndexScanByte() {
-        equalQuery("byte_not_null_btree", "idx_byte_not_null_btree", 8, 8);
-        greaterEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", 7, 7, 8, 9);
-        greaterThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", 6, 7, 8, 9);
-        lessEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 3, 2, 1, 0);
-        betweenQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", 4, 6, 5);
-
-        equalQuery("byte_null_btree", "idx_byte_null_btree", 8, 8);
-        greaterEqualQuery("byte_null_btree", "idx_byte_null_btree", 7, 7, 8, 9);
-        greaterThanQuery("byte_null_btree", "idx_byte_null_btree", 6, 7, 8, 9);
-        lessEqualQuery("byte_null_btree", "idx_byte_null_btree", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_null_btree", "idx_byte_null_btree", 4, 3, 2, 1, 0);
-        betweenQuery("byte_null_btree", "idx_byte_null_btree", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_null_btree", "idx_byte_null_btree", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_null_btree", "idx_byte_null_btree", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_null_btree", "idx_byte_null_btree", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_null_btree", "idx_byte_null_btree", 4, 6, 5);
+        equalQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)8, 8);
+        greaterEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_not_null_btree", "idx_byte_not_null_btree", (byte)4, (byte)6, 5);
+
+        equalQuery("byte_null_btree", "idx_byte_null_btree", (byte)8, 8);
+        greaterEqualQuery("byte_null_btree", "idx_byte_null_btree", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_null_btree", "idx_byte_null_btree", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_null_btree", "idx_byte_null_btree", (byte)4, (byte)6, 5);
     }
 
     public void hashIndexScanByte() {
-        equalQuery("byte_not_null_hash", "idx_byte_not_null_hash", 8, 8);
-        greaterEqualQuery("byte_not_null_hash", "none", 7, 7, 8, 9);
-        greaterThanQuery("byte_not_null_hash", "none", 6, 7, 8, 9);
-        lessEqualQuery("byte_not_null_hash", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_not_null_hash", "none", 4, 3, 2, 1, 0);
-        betweenQuery("byte_not_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_not_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_not_null_hash", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_not_null_hash", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_not_null_hash", "none", 4, 6, 5);
-
-        equalQuery("byte_null_hash", "idx_byte_null_hash", 8, 8);
-        greaterEqualQuery("byte_null_hash", "none", 7, 7, 8, 9);
-        greaterThanQuery("byte_null_hash", "none", 6, 7, 8, 9);
-        lessEqualQuery("byte_null_hash", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_null_hash", "none", 4, 3, 2, 1, 0);
-        betweenQuery("byte_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_null_hash", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_null_hash", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_null_hash", "none", 4, 6, 5);
+        equalQuery("byte_not_null_hash", "idx_byte_not_null_hash", (byte)8, 8);
+        greaterEqualQuery("byte_not_null_hash", "none", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_not_null_hash", "none", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_not_null_hash", "none", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_not_null_hash", "none", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_not_null_hash", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_not_null_hash", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_not_null_hash", "none", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_not_null_hash", "none", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_not_null_hash", "none", (byte)4, (byte)6, 5);
+
+        equalQuery("byte_null_hash", "idx_byte_null_hash", (byte)8, 8);
+        greaterEqualQuery("byte_null_hash", "none", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_null_hash", "none", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_null_hash", "none", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_null_hash", "none", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_null_hash", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_null_hash", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_null_hash", "none", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_null_hash", "none", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_null_hash", "none", (byte)4, (byte)6, 5);
     }
 
     public void bothIndexScanByte() {
-        equalQuery("byte_not_null_both", "idx_byte_not_null_both", 8, 8);
-        greaterEqualQuery("byte_not_null_both", "idx_byte_not_null_both", 7, 7, 8, 9);
-        greaterThanQuery("byte_not_null_both", "idx_byte_not_null_both", 6, 7, 8, 9);
-        lessEqualQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 3, 2, 1, 0);
-        betweenQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_not_null_both", "idx_byte_not_null_both", 4, 6, 5);
-
-        equalQuery("byte_null_both", "idx_byte_null_both", 8, 8);
-        greaterEqualQuery("byte_null_both", "idx_byte_null_both", 7, 7, 8, 9);
-        greaterThanQuery("byte_null_both", "idx_byte_null_both", 6, 7, 8, 9);
-        lessEqualQuery("byte_null_both", "idx_byte_null_both", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_null_both", "idx_byte_null_both", 4, 3, 2, 1, 0);
-        betweenQuery("byte_null_both", "idx_byte_null_both", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_null_both", "idx_byte_null_both", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_null_both", "idx_byte_null_both", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_null_both", "idx_byte_null_both", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_null_both", "idx_byte_null_both", 4, 6, 5);
+        equalQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)8, 8);
+        greaterEqualQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_not_null_both", "idx_byte_not_null_both", (byte)4, (byte)6, 5);
+
+        equalQuery("byte_null_both", "idx_byte_null_both", (byte)8, 8);
+        greaterEqualQuery("byte_null_both", "idx_byte_null_both", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_null_both", "idx_byte_null_both", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_null_both", "idx_byte_null_both", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_null_both", "idx_byte_null_both", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_null_both", "idx_byte_null_both", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_null_both", "idx_byte_null_both", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_null_both", "idx_byte_null_both", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_null_both", "idx_byte_null_both", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_null_both", "idx_byte_null_both", (byte)4, (byte)6, 5);
     }
 
     public void noneIndexScanByte() {
-        equalQuery("byte_not_null_none", "none", 8, 8);
-        greaterEqualQuery("byte_not_null_none", "none", 7, 7, 8, 9);
-        greaterThanQuery("byte_not_null_none", "none", 6, 7, 8, 9);
-        lessEqualQuery("byte_not_null_none", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_not_null_none", "none", 4, 3, 2, 1, 0);
-        betweenQuery("byte_not_null_none", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_not_null_none", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_not_null_none", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_not_null_none", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_not_null_none", "none", 4, 6, 5);
-
-        equalQuery("byte_null_none", "none", 8, 8);
-        greaterEqualQuery("byte_null_none", "none", 7, 7, 8, 9);
-        greaterThanQuery("byte_null_none", "none", 6, 7, 8, 9);
-        lessEqualQuery("byte_null_none", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("byte_null_none", "none", 4, 3, 2, 1, 0);
-        betweenQuery("byte_null_none", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("byte_null_none", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("byte_null_none", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("byte_null_none", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("byte_null_none", "none", 4, 6, 5);
+        equalQuery("byte_not_null_none", "none", (byte)8, 8);
+        greaterEqualQuery("byte_not_null_none", "none", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_not_null_none", "none", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_not_null_none", "none", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_not_null_none", "none", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_not_null_none", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_not_null_none", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_not_null_none", "none", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_not_null_none", "none", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_not_null_none", "none", (byte)4, (byte)6, 5);
+
+        equalQuery("byte_null_none", "none", (byte)8, 8);
+        greaterEqualQuery("byte_null_none", "none", (byte)7, 7, 8, 9);
+        greaterThanQuery("byte_null_none", "none", (byte)6, 7, 8, 9);
+        lessEqualQuery("byte_null_none", "none", (byte)4, 4, 3, 2, 1, 0);
+        lessThanQuery("byte_null_none", "none", (byte)4, 3, 2, 1, 0);
+        betweenQuery("byte_null_none", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("byte_null_none", "none", (byte)4, (byte)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("byte_null_none", "none", (byte)4, (byte)6, 5, 6);
+        greaterEqualAndLessThanQuery("byte_null_none", "none", (byte)4, (byte)6, 4, 5);
+        greaterThanAndLessThanQuery("byte_null_none", "none", (byte)4, (byte)6, 5);
     }
 
     public void btreeIndexScanShort() {
-        equalQuery("short_not_null_btree", "idx_short_not_null_btree", 8, 8);
-        greaterEqualQuery("short_not_null_btree", "idx_short_not_null_btree", 7, 7, 8, 9);
-        greaterThanQuery("short_not_null_btree", "idx_short_not_null_btree", 6, 7, 8, 9);
-        lessEqualQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 3, 2, 1, 0);
-        betweenQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_not_null_btree", "idx_short_not_null_btree", 4, 6, 5);
-
-        equalQuery("short_null_btree", "idx_short_null_btree", 8, 8);
-        greaterEqualQuery("short_null_btree", "idx_short_null_btree", 7, 7, 8, 9);
-        greaterThanQuery("short_null_btree", "idx_short_null_btree", 6, 7, 8, 9);
-        lessEqualQuery("short_null_btree", "idx_short_null_btree", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_null_btree", "idx_short_null_btree", 4, 3, 2, 1, 0);
-        betweenQuery("short_null_btree", "idx_short_null_btree", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_null_btree", "idx_short_null_btree", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_null_btree", "idx_short_null_btree", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_null_btree", "idx_short_null_btree", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_null_btree", "idx_short_null_btree", 4, 6, 5);
+        equalQuery("short_not_null_btree", "idx_short_not_null_btree", (short)8, 8);
+        greaterEqualQuery("short_not_null_btree", "idx_short_not_null_btree", (short)7, 7, 8, 9);
+        greaterThanQuery("short_not_null_btree", "idx_short_not_null_btree", (short)6, 7, 8, 9);
+        lessEqualQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_not_null_btree", "idx_short_not_null_btree", (short)4, (short)6, 5);
+
+        equalQuery("short_null_btree", "idx_short_null_btree", (short)8, 8);
+        greaterEqualQuery("short_null_btree", "idx_short_null_btree", (short)7, 7, 8, 9);
+        greaterThanQuery("short_null_btree", "idx_short_null_btree", (short)6, 7, 8, 9);
+        lessEqualQuery("short_null_btree", "idx_short_null_btree", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_null_btree", "idx_short_null_btree", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_null_btree", "idx_short_null_btree", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_null_btree", "idx_short_null_btree", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_null_btree", "idx_short_null_btree", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_null_btree", "idx_short_null_btree", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_null_btree", "idx_short_null_btree", (short)4, (short)6, 5);
     }
 
     public void hashIndexScanShort() {
-        equalQuery("short_not_null_hash", "idx_short_not_null_hash", 8, 8);
-        greaterEqualQuery("short_not_null_hash", "none", 7, 7, 8, 9);
-        greaterThanQuery("short_not_null_hash", "none", 6, 7, 8, 9);
-        lessEqualQuery("short_not_null_hash", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_not_null_hash", "none", 4, 3, 2, 1, 0);
-        betweenQuery("short_not_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_not_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_not_null_hash", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_not_null_hash", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_not_null_hash", "none", 4, 6, 5);
-
-        equalQuery("short_null_hash", "idx_short_null_hash", 8, 8);
-        greaterEqualQuery("short_null_hash", "none", 7, 7, 8, 9);
-        greaterThanQuery("short_null_hash", "none", 6, 7, 8, 9);
-        lessEqualQuery("short_null_hash", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_null_hash", "none", 4, 3, 2, 1, 0);
-        betweenQuery("short_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_null_hash", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_null_hash", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_null_hash", "none", 4, 6, 5);
+        equalQuery("short_not_null_hash", "idx_short_not_null_hash", (short)8, 8);
+        greaterEqualQuery("short_not_null_hash", "none", (short)7, 7, 8, 9);
+        greaterThanQuery("short_not_null_hash", "none", (short)6, 7, 8, 9);
+        lessEqualQuery("short_not_null_hash", "none", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_not_null_hash", "none", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_not_null_hash", "none", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_not_null_hash", "none", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_not_null_hash", "none", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_not_null_hash", "none", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_not_null_hash", "none", (short)4, (short)6, 5);
+
+        equalQuery("short_null_hash", "idx_short_null_hash", (short)8, 8);
+        greaterEqualQuery("short_null_hash", "none", (short)7, 7, 8, 9);
+        greaterThanQuery("short_null_hash", "none", (short)6, 7, 8, 9);
+        lessEqualQuery("short_null_hash", "none", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_null_hash", "none", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_null_hash", "none", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_null_hash", "none", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_null_hash", "none", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_null_hash", "none", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_null_hash", "none", (short)4, (short)6, 5);
     }
 
     public void bothIndexScanShort() {
-        equalQuery("short_not_null_both", "idx_short_not_null_both", 8, 8);
-        greaterEqualQuery("short_not_null_both", "idx_short_not_null_both", 7, 7, 8, 9);
-        greaterThanQuery("short_not_null_both", "idx_short_not_null_both", 6, 7, 8, 9);
-        lessEqualQuery("short_not_null_both", "idx_short_not_null_both", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_not_null_both", "idx_short_not_null_both", 4, 3, 2, 1, 0);
-        betweenQuery("short_not_null_both", "idx_short_not_null_both", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_not_null_both", "idx_short_not_null_both", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_not_null_both", "idx_short_not_null_both", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_not_null_both", "idx_short_not_null_both", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_not_null_both", "idx_short_not_null_both", 4, 6, 5);
-
-        equalQuery("short_null_both", "idx_short_null_both", 8, 8);
-        greaterEqualQuery("short_null_both", "idx_short_null_both", 7, 7, 8, 9);
-        greaterThanQuery("short_null_both", "idx_short_null_both", 6, 7, 8, 9);
-        lessEqualQuery("short_null_both", "idx_short_null_both", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_null_both", "idx_short_null_both", 4, 3, 2, 1, 0);
-        betweenQuery("short_null_both", "idx_short_null_both", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_null_both", "idx_short_null_both", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_null_both", "idx_short_null_both", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_null_both", "idx_short_null_both", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_null_both", "idx_short_null_both", 4, 6, 5);
+        equalQuery("short_not_null_both", "idx_short_not_null_both", (short)8, 8);
+        greaterEqualQuery("short_not_null_both", "idx_short_not_null_both", (short)7, 7, 8, 9);
+        greaterThanQuery("short_not_null_both", "idx_short_not_null_both", (short)6, 7, 8, 9);
+        lessEqualQuery("short_not_null_both", "idx_short_not_null_both", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_not_null_both", "idx_short_not_null_both", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_not_null_both", "idx_short_not_null_both", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_not_null_both", "idx_short_not_null_both", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_not_null_both", "idx_short_not_null_both", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_not_null_both", "idx_short_not_null_both", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_not_null_both", "idx_short_not_null_both", (short)4, (short)6, 5);
+
+        equalQuery("short_null_both", "idx_short_null_both", (short)8, 8);
+        greaterEqualQuery("short_null_both", "idx_short_null_both", (short)7, 7, 8, 9);
+        greaterThanQuery("short_null_both", "idx_short_null_both", (short)6, 7, 8, 9);
+        lessEqualQuery("short_null_both", "idx_short_null_both", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_null_both", "idx_short_null_both", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_null_both", "idx_short_null_both", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_null_both", "idx_short_null_both", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_null_both", "idx_short_null_both", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_null_both", "idx_short_null_both", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_null_both", "idx_short_null_both", (short)4, (short)6, 5);
     }
 
     public void noneIndexScanShort() {
-        equalQuery("short_not_null_none", "none", 8, 8);
-        greaterEqualQuery("short_not_null_none", "none", 7, 7, 8, 9);
-        greaterThanQuery("short_not_null_none", "none", 6, 7, 8, 9);
-        lessEqualQuery("short_not_null_none", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_not_null_none", "none", 4, 3, 2, 1, 0);
-        betweenQuery("short_not_null_none", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_not_null_none", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_not_null_none", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_not_null_none", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_not_null_none", "none", 4, 6, 5);
-
-        equalQuery("short_null_none", "none", 8, 8);
-        greaterEqualQuery("short_null_none", "none", 7, 7, 8, 9);
-        greaterThanQuery("short_null_none", "none", 6, 7, 8, 9);
-        lessEqualQuery("short_null_none", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("short_null_none", "none", 4, 3, 2, 1, 0);
-        betweenQuery("short_null_none", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("short_null_none", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("short_null_none", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("short_null_none", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("short_null_none", "none", 4, 6, 5);
+        equalQuery("short_not_null_none", "none", (short)8, 8);
+        greaterEqualQuery("short_not_null_none", "none", (short)7, 7, 8, 9);
+        greaterThanQuery("short_not_null_none", "none", (short)6, 7, 8, 9);
+        lessEqualQuery("short_not_null_none", "none", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_not_null_none", "none", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_not_null_none", "none", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_not_null_none", "none", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_not_null_none", "none", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_not_null_none", "none", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_not_null_none", "none", (short)4, (short)6, 5);
+
+        equalQuery("short_null_none", "none", (short)8, 8);
+        greaterEqualQuery("short_null_none", "none", (short)7, 7, 8, 9);
+        greaterThanQuery("short_null_none", "none", (short)6, 7, 8, 9);
+        lessEqualQuery("short_null_none", "none", (short)4, 4, 3, 2, 1, 0);
+        lessThanQuery("short_null_none", "none", (short)4, 3, 2, 1, 0);
+        betweenQuery("short_null_none", "none", (short)4, (short)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("short_null_none", "none", (short)4, (short)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("short_null_none", "none", (short)4, (short)6, 5, 6);
+        greaterEqualAndLessThanQuery("short_null_none", "none", (short)4, (short)6, 4, 5);
+        greaterThanAndLessThanQuery("short_null_none", "none", (short)4, (short)6, 5);
     }
 
     public void btreeIndexScanLong() {
-        equalQuery("long_not_null_btree", "idx_long_not_null_btree", 8, 8);
-        greaterEqualQuery("long_not_null_btree", "idx_long_not_null_btree", 7, 7, 8, 9);
-        greaterThanQuery("long_not_null_btree", "idx_long_not_null_btree", 6, 7, 8, 9);
-        lessEqualQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 3, 2, 1, 0);
-        betweenQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_not_null_btree", "idx_long_not_null_btree", 4, 6, 5);
-
-        equalQuery("long_null_btree", "idx_long_null_btree", 8, 8);
-        greaterEqualQuery("long_null_btree", "idx_long_null_btree", 7, 7, 8, 9);
-        greaterThanQuery("long_null_btree", "idx_long_null_btree", 6, 7, 8, 9);
-        lessEqualQuery("long_null_btree", "idx_long_null_btree", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_null_btree", "idx_long_null_btree", 4, 3, 2, 1, 0);
-        betweenQuery("long_null_btree", "idx_long_null_btree", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_null_btree", "idx_long_null_btree", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_null_btree", "idx_long_null_btree", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_null_btree", "idx_long_null_btree", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_null_btree", "idx_long_null_btree", 4, 6, 5);
+        equalQuery("long_not_null_btree", "idx_long_not_null_btree", (long)8, 8);
+        greaterEqualQuery("long_not_null_btree", "idx_long_not_null_btree", (long)7, 7, 8, 9);
+        greaterThanQuery("long_not_null_btree", "idx_long_not_null_btree", (long)6, 7, 8, 9);
+        lessEqualQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_not_null_btree", "idx_long_not_null_btree", (long)4, (long)6, 5);
+
+        equalQuery("long_null_btree", "idx_long_null_btree", (long)8, 8);
+        greaterEqualQuery("long_null_btree", "idx_long_null_btree", (long)7, 7, 8, 9);
+        greaterThanQuery("long_null_btree", "idx_long_null_btree", (long)6, 7, 8, 9);
+        lessEqualQuery("long_null_btree", "idx_long_null_btree", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_null_btree", "idx_long_null_btree", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_null_btree", "idx_long_null_btree", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_null_btree", "idx_long_null_btree", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_null_btree", "idx_long_null_btree", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_null_btree", "idx_long_null_btree", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_null_btree", "idx_long_null_btree", (long)4, (long)6, 5);
     }
 
     public void hashIndexScanLong() {
-        equalQuery("long_not_null_hash", "idx_long_not_null_hash", 8, 8);
-        greaterEqualQuery("long_not_null_hash", "none", 7, 7, 8, 9);
-        greaterThanQuery("long_not_null_hash", "none", 6, 7, 8, 9);
-        lessEqualQuery("long_not_null_hash", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_not_null_hash", "none", 4, 3, 2, 1, 0);
-        betweenQuery("long_not_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_not_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_not_null_hash", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_not_null_hash", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_not_null_hash", "none", 4, 6, 5);
-
-        equalQuery("long_null_hash", "idx_long_null_hash", 8, 8);
-        greaterEqualQuery("long_null_hash", "none", 7, 7, 8, 9);
-        greaterThanQuery("long_null_hash", "none", 6, 7, 8, 9);
-        lessEqualQuery("long_null_hash", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_null_hash", "none", 4, 3, 2, 1, 0);
-        betweenQuery("long_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_null_hash", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_null_hash", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_null_hash", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_null_hash", "none", 4, 6, 5);
+        equalQuery("long_not_null_hash", "idx_long_not_null_hash", (long)8, 8);
+        greaterEqualQuery("long_not_null_hash", "none", (long)7, 7, 8, 9);
+        greaterThanQuery("long_not_null_hash", "none", (long)6, 7, 8, 9);
+        lessEqualQuery("long_not_null_hash", "none", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_not_null_hash", "none", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_not_null_hash", "none", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_not_null_hash", "none", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_not_null_hash", "none", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_not_null_hash", "none", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_not_null_hash", "none", (long)4, (long)6, 5);
+
+        equalQuery("long_null_hash", "idx_long_null_hash", (long)8, 8);
+        greaterEqualQuery("long_null_hash", "none", (long)7, 7, 8, 9);
+        greaterThanQuery("long_null_hash", "none", (long)6, 7, 8, 9);
+        lessEqualQuery("long_null_hash", "none", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_null_hash", "none", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_null_hash", "none", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_null_hash", "none", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_null_hash", "none", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_null_hash", "none", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_null_hash", "none", (long)4, (long)6, 5);
     }
 
     public void bothIndexScanLong() {
-        equalQuery("long_not_null_both", "idx_long_not_null_both", 8, 8);
-        greaterEqualQuery("long_not_null_both", "idx_long_not_null_both", 7, 7, 8, 9);
-        greaterThanQuery("long_not_null_both", "idx_long_not_null_both", 6, 7, 8, 9);
-        lessEqualQuery("long_not_null_both", "idx_long_not_null_both", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_not_null_both", "idx_long_not_null_both", 4, 3, 2, 1, 0);
-        betweenQuery("long_not_null_both", "idx_long_not_null_both", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_not_null_both", "idx_long_not_null_both", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_not_null_both", "idx_long_not_null_both", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_not_null_both", "idx_long_not_null_both", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_not_null_both", "idx_long_not_null_both", 4, 6, 5);
-
-        equalQuery("long_null_both", "idx_long_null_both", 8, 8);
-        greaterEqualQuery("long_null_both", "idx_long_null_both", 7, 7, 8, 9);
-        greaterThanQuery("long_null_both", "idx_long_null_both", 6, 7, 8, 9);
-        lessEqualQuery("long_null_both", "idx_long_null_both", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_null_both", "idx_long_null_both", 4, 3, 2, 1, 0);
-        betweenQuery("long_null_both", "idx_long_null_both", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_null_both", "idx_long_null_both", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_null_both", "idx_long_null_both", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_null_both", "idx_long_null_both", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_null_both", "idx_long_null_both", 4, 6, 5);
+        equalQuery("long_not_null_both", "idx_long_not_null_both", (long)8, 8);
+        greaterEqualQuery("long_not_null_both", "idx_long_not_null_both", (long)7, 7, 8, 9);
+        greaterThanQuery("long_not_null_both", "idx_long_not_null_both", (long)6, 7, 8, 9);
+        lessEqualQuery("long_not_null_both", "idx_long_not_null_both", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_not_null_both", "idx_long_not_null_both", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_not_null_both", "idx_long_not_null_both", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_not_null_both", "idx_long_not_null_both", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_not_null_both", "idx_long_not_null_both", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_not_null_both", "idx_long_not_null_both", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_not_null_both", "idx_long_not_null_both", (long)4, (long)6, 5);
+
+        equalQuery("long_null_both", "idx_long_null_both", (long)8, 8);
+        greaterEqualQuery("long_null_both", "idx_long_null_both", (long)7, 7, 8, 9);
+        greaterThanQuery("long_null_both", "idx_long_null_both", (long)6, 7, 8, 9);
+        lessEqualQuery("long_null_both", "idx_long_null_both", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_null_both", "idx_long_null_both", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_null_both", "idx_long_null_both", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_null_both", "idx_long_null_both", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_null_both", "idx_long_null_both", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_null_both", "idx_long_null_both", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_null_both", "idx_long_null_both", (long)4, (long)6, 5);
     }
 
     public void noneIndexScanLong() {
-        equalQuery("long_not_null_none", "none", 8, 8);
-        greaterEqualQuery("long_not_null_none", "none", 7, 7, 8, 9);
-        greaterThanQuery("long_not_null_none", "none", 6, 7, 8, 9);
-        lessEqualQuery("long_not_null_none", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_not_null_none", "none", 4, 3, 2, 1, 0);
-        betweenQuery("long_not_null_none", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_not_null_none", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_not_null_none", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_not_null_none", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_not_null_none", "none", 4, 6, 5);
-
-        equalQuery("long_null_none", "none", 8, 8);
-        greaterEqualQuery("long_null_none", "none", 7, 7, 8, 9);
-        greaterThanQuery("long_null_none", "none", 6, 7, 8, 9);
-        lessEqualQuery("long_null_none", "none", 4, 4, 3, 2, 1, 0);
-        lessThanQuery("long_null_none", "none", 4, 3, 2, 1, 0);
-        betweenQuery("long_null_none", "none", 4, 6, 4, 5, 6);
-        greaterEqualAndLessEqualQuery("long_null_none", "none", 4, 6, 4, 5, 6);
-        greaterThanAndLessEqualQuery("long_null_none", "none", 4, 6, 5, 6);
-        greaterEqualAndLessThanQuery("long_null_none", "none", 4, 6, 4, 5);
-        greaterThanAndLessThanQuery("long_null_none", "none", 4, 6, 5);
+        equalQuery("long_not_null_none", "none", (long)8, 8);
+        greaterEqualQuery("long_not_null_none", "none", (long)7, 7, 8, 9);
+        greaterThanQuery("long_not_null_none", "none", (long)6, 7, 8, 9);
+        lessEqualQuery("long_not_null_none", "none", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_not_null_none", "none", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_not_null_none", "none", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_not_null_none", "none", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_not_null_none", "none", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_not_null_none", "none", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_not_null_none", "none", (long)4, (long)6, 5);
+
+        equalQuery("long_null_none", "none", (long)8, 8);
+        greaterEqualQuery("long_null_none", "none", (long)7, 7, 8, 9);
+        greaterThanQuery("long_null_none", "none", (long)6, 7, 8, 9);
+        lessEqualQuery("long_null_none", "none", (long)4, 4, 3, 2, 1, 0);
+        lessThanQuery("long_null_none", "none", (long)4, 3, 2, 1, 0);
+        betweenQuery("long_null_none", "none", (long)4, (long)6, 4, 5, 6);
+        greaterEqualAndLessEqualQuery("long_null_none", "none", (long)4, (long)6, 4, 5, 6);
+        greaterThanAndLessEqualQuery("long_null_none", "none", (long)4, (long)6, 5, 6);
+        greaterEqualAndLessThanQuery("long_null_none", "none", (long)4, (long)6, 4, 5);
+        greaterThanAndLessThanQuery("long_null_none", "none", (long)4, (long)6, 5);
     }
 
 }

=== added file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryMultipleParameterTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryMultipleParameterTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryMultipleParameterTest.java	2011-06-20 23:34:36 +0000
@@ -0,0 +1,109 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+package testsuite.clusterj;
+
+import java.util.List;
+
+import testsuite.clusterj.model.Employee;
+
+import com.mysql.clusterj.ClusterJUserException;
+import com.mysql.clusterj.Query;
+
+import com.mysql.clusterj.query.PredicateOperand;
+import com.mysql.clusterj.query.QueryBuilder;
+import com.mysql.clusterj.query.QueryDomainType;
+
+public class QueryMultipleParameterTest extends AbstractQueryTest {
+
+    /** The persistent class
+    @PersistenceCapable(table="t_basic")
+    public interface Employee extends IdBase {
+        
+        @PrimaryKey
+        int getId();
+        void setId(int id);
+
+        String getName();
+        void setName(String name);
+
+        @Index(name="idx_unique_hash_magic")
+        int getMagic();
+        void setMagic(int magic);
+
+        @Index(name="idx_btree_age")
+        Integer getAge();
+        void setAge(Integer age);
+        */
+
+    @Override
+    public Class<?> getInstanceType() {
+        return Employee.class;
+    }
+
+    @Override
+    void createInstances(int number) {
+        createEmployeeInstances(10);
+        instances.addAll(employees);
+    }
+
+    public void test() {
+        // QueryBuilder is the sessionFactory for queries
+        QueryBuilder builder = session.getQueryBuilder();
+        // QueryDomainType is the main interface
+        QueryDomainType<Employee>dobj = builder.createQueryDefinition(Employee.class);
+        // parameter
+        PredicateOperand param1 = dobj.param("param1");
+        PredicateOperand param2 = dobj.param("param2");
+        // property
+        PredicateOperand propertyMagic = dobj.get("magic");
+        PredicateOperand propertyId = dobj.get("id");
+        // where
+        // param1 is used in two different places but same type (int) in both
+        dobj.where(propertyMagic.equal(param1).and(propertyId.between(param1, param2)));
+        Query<Employee> query = session.createQuery(dobj);
+        query.setParameter("param1", 4);
+        query.setParameter("param2", 5);
+        List<Employee> result = query.getResultList();
+        errorIfNotEqual("Wrong size of result", 1, result.size());
+        if (result.size() == 1) {
+            errorIfNotEqual("Wrong result", 4, result.get(0).getId());
+        }
+        failOnError();
+    }
+
+    public void testNegative() {
+        try {
+            // QueryBuilder is the sessionFactory for queries
+            QueryBuilder builder = session.getQueryBuilder();
+            // QueryDomainType is the main interface
+            QueryDomainType<Employee>dobj = builder.createQueryDefinition(Employee.class);
+            // parameter
+            PredicateOperand param1 = dobj.param("param1");
+            PredicateOperand param2 = dobj.param("param2");
+            // property
+            PredicateOperand propertyAge = dobj.get("magic");
+            PredicateOperand propertyMagic = dobj.get("name");
+            // where
+            // expect an exception here because param1 is used for String name and int magic
+            dobj.where(propertyAge.equal(param1).and(propertyMagic.between(param1, param2)));
+        } catch (ClusterJUserException e) {
+            // good catch
+        }
+    }
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-tie/pom.xml'
--- a/storage/ndb/clusterj/clusterj-tie/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/pom.xml	2011-06-20 23:34:36 +0000
@@ -117,7 +117,7 @@
         <configuration>
           <instructions>
             <Export-Package>com.mysql.clusterj.tie.*</Export-Package>
-            <Import-Package>com.mysql.clusterj,com.mysql.clusterj.core.store,com.mysql.clusterj.core.query,com.mysql.clusterj.core.util,com.mysql.ndbjtie.mysql,com.mysql.ndbjtie.ndbapi</Import-Package>
+            <Import-Package>com.mysql.clusterj,com.mysql.clusterj.core.store,com.mysql.clusterj.core.spi,com.mysql.clusterj.core.util,com.mysql.ndbjtie.mysql,com.mysql.ndbjtie.ndbapi</Import-Package>
           </instructions>
         </configuration>
       </plugin>

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java	2011-02-02 09:52:33 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java	2011-06-20 23:34:36 +0000
@@ -22,7 +22,7 @@ import com.mysql.ndbjtie.ndbapi.NdbOpera
 import com.mysql.ndbjtie.ndbapi.NdbScanFilter;
 import com.mysql.ndbjtie.ndbapi.NdbScanOperation;
 
-import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
+import com.mysql.clusterj.core.spi.QueryExecutionContext;
 import com.mysql.clusterj.core.store.ResultData;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -50,7 +50,7 @@ class ScanOperationImpl extends Operatio
         handleError(returnCode, ndbScanOperation);
     }
 
-    public ScanFilter getScanFilter(QueryExecutionContextImpl context) {
+    public ScanFilter getScanFilter(QueryExecutionContext context) {
         NdbScanFilter ndbScanFilter = NdbScanFilter.create(ndbScanOperation);
         handleError(ndbScanFilter, ndbScanOperation);
         ScanFilter scanFilter = new ScanFilterImpl(ndbScanFilter);

=== added file 'storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryMultipleParameterTest.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryMultipleParameterTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryMultipleParameterTest.java	2011-06-20 23:34:36 +0000
@@ -0,0 +1,22 @@
+/*
+ Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+package testsuite.clusterj.tie;
+
+public class QueryMultipleParameterTest extends testsuite.clusterj.QueryMultipleParameterTest {
+
+}

=== 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/src/CMakeLists.txt'
--- a/storage/ndb/src/CMakeLists.txt	2011-06-16 09:33:27 +0000
+++ b/storage/ndb/src/CMakeLists.txt	2011-06-21 14:09:17 +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 22:59:16 +0000
+++ b/storage/ndb/src/kernel/CMakeLists.txt	2011-06-21 14:09:17 +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/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-04-04 13:32:06 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp	2011-06-22 08:27:29 +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:45:49 +0000
+++ b/storage/ndb/src/mgmsrv/CMakeLists.txt	2011-06-21 14:01:55 +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:51:41 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-06-21 15:08:34 +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;
 }
 
 
@@ -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 15:08:34 +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:45:49 +0000
+++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp	2011-06-21 13:50:33 +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/src/ndbapi/NdbQueryBuilder.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.hpp	2011-06-16 09:32:43 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.hpp	2011-06-20 13:25:48 +0000
@@ -479,13 +479,8 @@ private:
  * times. It is valid until it is explicitely released().
  *
  * The NdbQueryDef *must* be keept alive until the last thread
- * which executing a query based on this NdbQueryDef has completed execution 
- * *and* result handling. Used from multiple threads this implies either:
- *
- *  - Keep the NdbQueryDef until all threads terminates.
- *  - Implement reference counting on the NdbQueryDef.
- *  - Use the supplied copy constructor to give each thread its own copy
- *    of the NdbQueryDef.
+ * which executing a query based on this NdbQueryDef has called
+ * NdbQuery::close().
  *
  * A NdbQueryDef is scheduled for execution by appending it to an open 
  * transaction - optionally together with a set of parameters specifying 

=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2011-06-16 09:32:43 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2011-06-20 13:25:48 +0000
@@ -1389,7 +1389,7 @@ NdbQueryImpl::NdbQueryImpl(NdbTransactio
   m_state(Initial),
   m_tcState(Inactive),
   m_next(NULL),
-  m_queryDef(queryDef),
+  m_queryDef(&queryDef),
   m_error(),
   m_transaction(trans),
   m_scanTransaction(NULL),
@@ -1452,9 +1452,13 @@ NdbQueryImpl::NdbQueryImpl(NdbTransactio
 
 NdbQueryImpl::~NdbQueryImpl()
 {
- 
-  // Do this to check that m_queryDef still exists.
-  assert(getNoOfOperations() == m_queryDef.getNoOfOperations());
+  /** BEWARE:
+   *  Don't refer NdbQueryDef or NdbQueryOperationDefs after 
+   *  NdbQuery::close() as at this stage the appliaction is 
+   *  allowed to destruct the Def's.
+   */
+  assert(m_state==Closed);
+  assert(m_rootFrags==NULL);
 
   // NOTE: m_operations[] was allocated as a single memory chunk with
   // placement new construction of each operation.
@@ -1465,8 +1469,6 @@ NdbQueryImpl::~NdbQueryImpl()
     }
     m_operations = NULL;
   }
-  delete[] m_rootFrags;
-  m_rootFrags = NULL;
   m_state = Destructed;
 }
 
@@ -1478,6 +1480,9 @@ NdbQueryImpl::postFetchRelease()
     { m_operations[i].postFetchRelease();
     }
   }
+  delete[] m_rootFrags;
+  m_rootFrags = NULL;
+
   m_rowBufferAlloc.reset();
   m_tupleSetAlloc.reset();
   m_resultStreamAlloc.reset();
@@ -1957,7 +1962,7 @@ NdbQueryImpl::awaitMoreResults(bool forc
   assert(m_applFrags.getCurrent() == NULL);
 
   /* Check if there are any more completed fragments available.*/
-  if (m_queryDef.isScanQuery())
+  if (getQueryDef().isScanQuery())
   {
     assert (m_scanTransaction);
     assert (m_state==Executing);
@@ -2052,7 +2057,7 @@ NdbQueryImpl::awaitMoreResults(bool forc
     assert(m_pendingFrags == 0);
     assert(m_finalBatchFrags == getRootFragCount());
     return FetchResult_noMoreData;
-  } // if(m_queryDef.isScanQuery())
+  } // if(getQueryDef().isScanQuery())
 
 } //NdbQueryImpl::awaitMoreResults
 
@@ -2131,32 +2136,41 @@ NdbQueryImpl::close(bool forceSend)
   int res = 0;
 
   assert (m_state >= Initial && m_state < Destructed);
-  Ndb* const ndb = m_transaction.getNdb();
-
-  if (m_tcState != Inactive)
+  if (m_state != Closed)
   {
-    /* We have started a scan, but we have not yet received the last batch
-     * for all root fragments. We must therefore close the scan to release 
-     * the scan context at TC.*/
-    res = closeTcCursor(forceSend);
-  }
+    if (m_tcState != Inactive)
+    {
+      /* We have started a scan, but we have not yet received the last batch
+       * for all root fragments. We must therefore close the scan to release 
+       * the scan context at TC.*/
+      res = closeTcCursor(forceSend);
+    }
 
-  // Throw any pending results
-  m_fullFrags.clear();
-  m_applFrags.clear();
+    // Throw any pending results
+    m_fullFrags.clear();
+    m_applFrags.clear();
 
-  if (m_scanTransaction != NULL)
-  {
-    assert (m_state != Closed);
-    assert (m_scanTransaction->m_scanningQuery == this);
-    m_scanTransaction->m_scanningQuery = NULL;
-    ndb->closeTransaction(m_scanTransaction);
-    ndb->theRemainingStartTransactions--;  // Compensate; m_scanTransaction was not a real Txn
-    m_scanTransaction = NULL;
+    Ndb* const ndb = m_transaction.getNdb();
+    if (m_scanTransaction != NULL)
+    {
+      assert (m_state != Closed);
+      assert (m_scanTransaction->m_scanningQuery == this);
+      m_scanTransaction->m_scanningQuery = NULL;
+      ndb->closeTransaction(m_scanTransaction);
+      ndb->theRemainingStartTransactions--;  // Compensate; m_scanTransaction was not a real Txn
+      m_scanTransaction = NULL;
+    }
+
+    postFetchRelease();
+    m_state = Closed;  // Even if it was previously 'Failed' it is closed now!
   }
 
-  postFetchRelease();
-  m_state = Closed;  // Even if it was previously 'Failed' it is closed now!
+  /** BEWARE:
+   *  Don't refer NdbQueryDef or its NdbQueryOperationDefs after ::close()
+   *  as the application is allowed to destruct the Def's after this point.
+   */
+  m_queryDef= NULL;
+
   return res;
 } //NdbQueryImpl::close
 
@@ -2819,7 +2833,7 @@ NdbQueryImpl::sendFetchMore(NdbRootFragm
 {
   assert(getRoot().m_resultStreams!=NULL);
   assert(!emptyFrag.finalBatchReceived());
-  assert(m_queryDef.isScanQuery());
+  assert(getQueryDef().isScanQuery());
 
   const Uint32 fragNo = emptyFrag.getFragNo();
   emptyFrag.reset();
@@ -2892,7 +2906,7 @@ NdbQueryImpl::sendFetchMore(NdbRootFragm
 int
 NdbQueryImpl::closeTcCursor(bool forceSend)
 {
-  assert (m_queryDef.isScanQuery());
+  assert (getQueryDef().isScanQuery());
 
   NdbImpl* const ndb = m_transaction.getNdb()->theImpl;
   const Uint32 timeout  = ndb->get_waitfor_timeout();

=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.hpp	2011-04-06 14:16:13 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.hpp	2011-06-20 13:25:48 +0000
@@ -180,7 +180,15 @@ public:
   NdbTransaction* getNdbTransaction() const;
 
   /**
-   * Close query
+   * Close query.
+   *
+   * Will release most of the internally allocated objects owned 
+   * by this NdbQuery and detach itself from the NdbQueryDef
+   * used to instantiate it.
+   *
+   * The application may destruct the NdbQueryDef after 
+   * ::close() has been called on *all* NdbQuery objects
+   * instantiated from it.
    */
   void close(bool forceSend = false);
 

=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp	2011-04-06 14:16:13 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp	2011-06-20 13:25:48 +0000
@@ -142,7 +142,8 @@ public:
   /** Close query: 
    *  - Release datanode resources,
    *  - Discard pending result sets,
-   *  - optionaly dealloc NdbQuery structures
+   *  - Delete internal buffer and structures for receiving results.
+   *  - Disconnect with NdbQueryDef - it might now be destructed .
    */
   int close(bool forceSend);
 
@@ -191,7 +192,10 @@ public:
 
   /** Get the (transaction independent) definition of this query. */
   const NdbQueryDefImpl& getQueryDef() const
-  { return m_queryDef; }
+  {
+    assert(m_queryDef);
+    return *m_queryDef;
+  }
 
   /** Process TCKEYCONF message. Return true if query is complete. */
   bool execTCKEYCONF();
@@ -213,7 +217,7 @@ public:
    */
   void setStartIndicator()
   { 
-    assert(!m_queryDef.isScanQuery());
+    assert(!getQueryDef().isScanQuery());
     m_startIndicator = true; 
   }
 
@@ -224,7 +228,7 @@ public:
    */
   void setCommitIndicator()
   {  
-    assert(!m_queryDef.isScanQuery());
+    assert(!getQueryDef().isScanQuery());
     m_commitIndicator = true; 
   }
 
@@ -415,7 +419,7 @@ private:
   /** Next query in same transaction.*/
   NdbQueryImpl* m_next;
   /** Definition of this query.*/
-  const NdbQueryDefImpl& m_queryDef;
+  const NdbQueryDefImpl* m_queryDef;
 
   /** Possible error status of this query.*/
   NdbError m_error;

=== modified file 'storage/ndb/src/ndbjtie/mysql/CMakeLists.txt'
--- a/storage/ndb/src/ndbjtie/mysql/CMakeLists.txt	2011-01-31 09:07:01 +0000
+++ b/storage/ndb/src/ndbjtie/mysql/CMakeLists.txt	2011-06-21 14:04:38 +0000
@@ -19,5 +19,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
 		${CMAKE_SOURCE_DIR}/storage/ndb/include/util 
 		${CMAKE_SOURCE_DIR}/storage/ndb/include/portlib )
 
-ADD_LIBRARY(mysqlutils decimal_utils.cpp CharsetMap.cpp CharsetMapImpl.cpp)
+ADD_CONVENIENCE_LIBRARY(mysqlutils
+  decimal_utils.cpp
+  CharsetMap.cpp
+  CharsetMapImpl.cpp)
 

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java	2011-06-09 21:09:40 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java	2011-06-20 23:47:37 +0000
@@ -64,6 +64,15 @@ abstract public class CrundDriver extend
     protected final Set<String> exclude = new HashSet<String>();
     protected final Set<String> include = new HashSet<String>();
 
+    // the name of the test currently being performed
+    protected String operationName;
+
+    /** The errors for the current test */
+    protected StringBuilder errorBuffer;
+
+    /** Throw an exception if an error is reported */
+    protected boolean failOnError;
+
     // ----------------------------------------------------------------------
     // benchmark intializers/finalizers
     // ----------------------------------------------------------------------
@@ -146,6 +155,7 @@ abstract public class CrundDriver extend
         renewOperations = parseBoolean("renewOperations", false);
         logSumOfOps = parseBoolean("logSumOfOps", true);
         allowExtendedPC = parseBoolean("allowExtendedPC", false);
+        failOnError = parseBoolean("failOnError", false);
 
         nOpsStart = parseInt("nOpsStart", 256);
         if (nOpsStart < 1) {
@@ -389,22 +399,45 @@ abstract public class CrundDriver extend
                 clearPersistenceContext();
             }
             runOperation(op, nOps);
+            reportErrors();
         }
     }
 
     // XXX move to generic load class
     protected void runOperation(Op op, int nOps) throws Exception {
-        final String name = op.getName();
+        operationName = op.getName();
         // if there is an include list and this test is included, or
         // there is not an include list and this test is not excluded
-        if ((include.size() != 0 && include.contains(name))
-                || (include.size() == 0 && !exclude.contains(name))) {
-            begin(name);
+        if ((include.size() != 0 && include.contains(operationName))
+                || (include.size() == 0 && !exclude.contains(operationName))) {
+            begin(operationName);
             op.run(nOps);
-            finish(name);
+            finish(operationName);
         }
     }
 
+    /** Add an error to the existing errors */
+    protected void appendError(String where) {
+        if (errorBuffer == null) {
+            errorBuffer = new StringBuilder();
+        }
+        errorBuffer.append("Error in operation ");
+        errorBuffer.append(operationName);
+        errorBuffer.append(": ");
+        errorBuffer.append(where);
+        errorBuffer.append('\n');
+    }
+
+    /** Report errors and reset the error buffer */
+    protected void reportErrors() {
+        if (errorBuffer != null) {
+            if (failOnError) {
+                throw new RuntimeException(errorBuffer.toString());
+            }
+            System.out.println(errorBuffer.toString());
+            errorBuffer = null;
+        }
+    }
     // XXX move to generic load class
     // reports an error if a condition is not met
     static protected final void verify(boolean cond) {
@@ -422,6 +455,14 @@ abstract public class CrundDriver extend
     }
 
     // XXX move to generic load class
+    protected final void verify(String where, int exp, int act) {
+        if (exp != act)
+            appendError(" data verification failed:"
+                    + " expected = " + exp
+                    + ", actual = " + act);
+    }
+
+    // XXX move to generic load class
     static protected final void verify(String exp, String act) {
         if ((exp == null && act != null)
             || (exp != null && !exp.equals(act)))
@@ -533,7 +574,6 @@ abstract public class CrundDriver extend
         out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
 
         // XXX move to generic load class
-        clearData();
         closeOperations();
 
         closeConnection();

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java	2011-06-09 21:09:40 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java	2011-06-20 23:47:37 +0000
@@ -311,7 +311,7 @@ abstract public class Driver {
                 logger.createNewFile();
             }
             out = new FileOutputStream(logger);
-            props.store(out, "Consolidated crund properties");
+            props.store(out, "**** WARNING: DO NOT EDIT THIS FILE; IT IS GENERATED EACH RUN.");
         } catch (FileNotFoundException e) {
             throw new RuntimeException("Unexpected exception opening file logger.properties.", e);
         } catch (IOException e) {

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java	2011-06-07 17:37:44 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java	2011-06-20 23:47:37 +0000
@@ -236,7 +236,7 @@ public class JdbcLoad extends CrundDrive
                         if (mode == CrundDriver.XMode.BULK) {
                             int[] cnts = stmt.executeBatch();
                             for (int i = 0; i < cnts.length; i++) {
-                                verify(cnts[i] == 1);
+                                verify(name + " " + i, 1, cnts[i]);
                             }
                         }
                         if (mode != CrundDriver.XMode.INDY)
@@ -662,7 +662,7 @@ public class JdbcLoad extends CrundDrive
                             // fetch a.id
                             stmt0.setInt(1, i);
                             ResultSet rs0 = stmt0.executeQuery();
-                            rs0.next();
+                            verify(rs0.next());
                             int aId = rs0.getInt(1);
                             verify(aId == ((i - 1) % nOps) + 1);
                             verify(!rs0.next());
@@ -785,7 +785,7 @@ public class JdbcLoad extends CrundDrive
                 });
 
             ops.add(
-                new JdbcOp("insA_attr_" + mode.toString().toLowerCase(),
+                new JdbcOp("insAattr_" + mode.toString().toLowerCase(),
                            "INSERT INTO a (id, cint, clong, cfloat, cdouble) VALUES (?, ?, ?, ?, ?)") {
                     public void run(int nOps) throws SQLException {
                         conn.setAutoCommit(mode == CrundDriver.XMode.INDY);
@@ -811,7 +811,7 @@ public class JdbcLoad extends CrundDrive
                 });
 
             ops.add(
-                new JdbcOp("insB0_attr_" + mode.toString().toLowerCase(),
+                new JdbcOp("insB0attr_" + mode.toString().toLowerCase(),
                            "INSERT INTO b0 (id, cint, clong, cfloat, cdouble) VALUES (?, ?, ?, ?, ?)") {
                     public void run(int nOps) throws SQLException {
                         conn.setAutoCommit(mode == CrundDriver.XMode.INDY);

=== 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:45:49 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp	2011-06-21 13:50:33 +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-22 08:09:31 +0000
+++ b/storage/ndb/tools/ndb_dump_frm_data.cpp	2011-06-22 09:20:53 +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.5-cluster branch (magnus.blaudd:3364 to 3367) magnus.blaudd22 Jun